Added a full fill generation script which breaks a design up into tiles for faster, more memory-efficient processing. This includes some changes to the techfile to create two variants for the fill patterning, one that should be used for a full-chip pattern, and one to be used with the script. Also removed the patch file from yesterday's commit.
diff --git a/VERSION b/VERSION index f42a27c..7776610 100644 --- a/VERSION +++ b/VERSION
@@ -1 +1 @@ -1.0.96 +1.0.97
diff --git a/pdk.patch b/pdk.patch deleted file mode 100644 index 166dda4..0000000 --- a/pdk.patch +++ /dev/null
@@ -1,337 +0,0 @@ -commit c8e490f65d8624cc2e39147afd1c0269cac7f8b4 -Author: Donn <me@donn.website> -Date: Tue Dec 29 01:38:02 2020 +0200 - - Looking for PDKs in standard directories then downloading - -diff --git a/scripts/.gitignore b/scripts/.gitignore -index b1083e1..1383243 100644 ---- a/scripts/.gitignore -+++ b/scripts/.gitignore -@@ -4,4 +4,4 @@ - !configure.ac - !tools.txt - !print_tools_make.pl --!dl -\ No newline at end of file -+!download.sh -\ No newline at end of file -diff --git a/scripts/configure b/scripts/configure -index ba4f0c8..5e03076 100755 ---- a/scripts/configure -+++ b/scripts/configure -@@ -628,6 +628,7 @@ infodir - docdir - oldincludedir - includedir -+runstatedir - localstatedir - sharedstatedir - sysconfdir -@@ -706,6 +707,7 @@ datadir='${datarootdir}' - sysconfdir='${prefix}/etc' - sharedstatedir='${prefix}/com' - localstatedir='${prefix}/var' -+runstatedir='${localstatedir}/run' - includedir='${prefix}/include' - oldincludedir='/usr/include' - docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' -@@ -958,6 +960,15 @@ do - | -silent | --silent | --silen | --sile | --sil) - silent=yes ;; - -+ -runstatedir | --runstatedir | --runstatedi | --runstated \ -+ | --runstate | --runstat | --runsta | --runst | --runs \ -+ | --run | --ru | --r) -+ ac_prev=runstatedir ;; -+ -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ -+ | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ -+ | --run=* | --ru=* | --r=*) -+ runstatedir=$ac_optarg ;; -+ - -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) - ac_prev=sbindir ;; - -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ -@@ -1095,7 +1106,7 @@ fi - for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ - datadir sysconfdir sharedstatedir localstatedir includedir \ - oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ -- libdir localedir mandir -+ libdir localedir mandir runstatedir - do - eval ac_val=\$$ac_var - # Remove trailing slashes. -@@ -1248,6 +1259,7 @@ Fine tuning of the installation directories: - --sysconfdir=DIR read-only single-machine data [PREFIX/etc] - --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] - --localstatedir=DIR modifiable single-machine data [PREFIX/var] -+ --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] - --libdir=DIR object code libraries [EPREFIX/lib] - --includedir=DIR C header files [PREFIX/include] - --oldincludedir=DIR C header files for non-gcc [/usr/include] -@@ -1279,7 +1291,7 @@ Optional Features: - --enable-FEATURE[=ARG] include FEATURE [ARG=yes] - --enable-sky130-pdk=[/path/to/sky130/] --disable-sky130-pdk - "location of the source files for the sky130 (pdks -- with a pdk_url file can automatically download them -+ with a pdk_info file can automatically download them - if the path is omitted)" - --enable-klayout - Enable or disable klayout [default=enabled] -@@ -1797,22 +1809,22 @@ $as_echo "$as_me: Found technology directories: sky130" >&6;} - SKY130_LINK_TARGETS="none" - - pdk_get() { -- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ../sky130/pdk_url" >&5 --$as_echo_n "checking for ../sky130/pdk_url... " >&6; } --if ${ac_cv_file____sky130_pdk_url+:} false; then : -+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ../sky130/pdk_info" >&5 -+$as_echo_n "checking for ../sky130/pdk_info... " >&6; } -+if ${ac_cv_file____sky130_pdk_info+:} false; then : - $as_echo_n "(cached) " >&6 - else - test "$cross_compiling" = yes && - as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 --if test -r "../sky130/pdk_url"; then -- ac_cv_file____sky130_pdk_url=yes -+if test -r "../sky130/pdk_info"; then -+ ac_cv_file____sky130_pdk_info=yes - else -- ac_cv_file____sky130_pdk_url=no -+ ac_cv_file____sky130_pdk_info=no - fi - fi --{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_file____sky130_pdk_url" >&5 --$as_echo "$ac_cv_file____sky130_pdk_url" >&6; } --if test "x$ac_cv_file____sky130_pdk_url" = xyes; then : -+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_file____sky130_pdk_info" >&5 -+$as_echo "$ac_cv_file____sky130_pdk_info" >&6; } -+if test "x$ac_cv_file____sky130_pdk_info" = xyes; then : - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ../pdks/sky130" >&5 - $as_echo_n "checking for ../pdks/sky130... " >&6; } -@@ -1835,9 +1847,11 @@ if test "x$ac_cv_file____pdks_sky130" = xyes; then : - - else - -- mkdir -p ../pdks/sky130 -- sh dl $(cat "../sky130/pdk_get") ../pdks/sky130.tar.gz; -- (echo "Extracting sky130" && cd ../pdks && tar -xf sky130.tar.gz --strip-components 1 -C ../pdks/sky130) -+ REPO=$(cat "../sky130/pdk_info" | sed -n "1p") -+ POST_CLONE_COMMANDS=$(cat "../sky130/pdk_info" | sed "1d") -+ mkdir -p ../pdks -+ git clone "$REPO" ../pdks/sky130; -+ (cd ../pdks/sky130 && sh -c "$POST_CLONE_COMMANDS") - - fi - -@@ -1851,11 +1865,26 @@ fi - - } - -+ pdk_find() { -+ FOUND=0 -+ for path in /opt/pdks/sky130 /usr/share/pdks/sky130 /usr/local/share/pdks/sky130; do -+ if [ -d $path ] ; then -+ echo "Found sky130 in $path, using this installation..." -+ export SKY130_SOURCE_PATH=$path -+ FOUND=1 -+ fi -+ done -+ if [ "$FOUND" = "sky130" ]; then -+ echo "Could not found sky130 in standard search paths, manually downloading to ../pdks/sky130 ..." -+ pdk_find -+ fi -+ } -+ - # Check whether --enable-sky130-sky130 was given. - if test "${enable_sky130_pdk+set}" = set; then : - enableval=$enable_sky130_pdk; - if test "$enableval" == "yes" -o "$enableval" == "YES"; then -- pdk_get -+ pdk_find - elif test "$enableval" == "no" -o "$enableval" == "NO"; then - echo "Disabling sky130..." - else -@@ -1864,7 +1893,7 @@ if test "${enable_sky130_pdk+set}" = set; then : - - else - -- pdk_get -+ pdk_find - - - fi -@@ -2455,7 +2484,7 @@ if ${am_cv_pathless_PYTHON+:} false; then : - $as_echo_n "(cached) " >&6 - else - -- for am_cv_pathless_PYTHON in python python2 python3 python3.3 python3.2 python3.1 python3.0 python2.7 python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 python2.0 none; do -+ for am_cv_pathless_PYTHON in python python2 python3 python3.8 python3.7 python3.6 python3.5 python3.4 python3.3 python3.2 python3.1 python3.0 python2.7 python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 python2.0 none; do - test "$am_cv_pathless_PYTHON" = none && break - prog="import sys - # split strings by '.' and convert to numeric. Append some zeros -@@ -2678,28 +2707,33 @@ $as_echo "$am_cv_python_pyexecdir" >&6; } - - if test -z $PYTHON; - then -- PYTHON="python" -+ if test -z ""; -+ then -+ PYTHON="python3" -+ else -+ PYTHON="" -+ fi - fi - PYTHON_NAME=`basename $PYTHON` - { $as_echo "$as_me:${as_lineno-$LINENO}: checking $PYTHON_NAME module: distutils" >&5 - $as_echo_n "checking $PYTHON_NAME module: distutils... " >&6; } -- $PYTHON -c "import distutils" 2>/dev/null -- if test $? -eq 0; -- then -- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -+ $PYTHON -c "import distutils" 2>/dev/null -+ if test $? -eq 0; -+ then -+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 - $as_echo "yes" >&6; } -- eval HAVE_PYMOD_DISTUTILS=yes -- else -- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -+ eval HAVE_PYMOD_DISTUTILS=yes -+ else -+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 - $as_echo "no" >&6; } -- eval HAVE_PYMOD_DISTUTILS=no -- # -- if test -n "" -- then -- as_fn_error $? "failed to find required module distutils" "$LINENO" 5 -- exit 1 -- fi -- fi -+ eval HAVE_PYMOD_DISTUTILS=no -+ # -+ if test -n "" -+ then -+ as_fn_error $? "failed to find required module distutils" "$LINENO" 5 -+ exit 1 -+ fi -+ fi - - - # Check for "--with-ef-style" -diff --git a/scripts/configure.ac b/scripts/configure.ac -index 1c06fcf..03866fc 100755 ---- a/scripts/configure.ac -+++ b/scripts/configure.ac -@@ -24,13 +24,15 @@ AC_DEFUN([M4_GEN_WITH_PDK_ARGS], [ - pdkvar[]_LINK_TARGETS="none" - - pdk_get() { -- AC_CHECK_FILE(../pdk/[pdk]_url, [ -+ AC_CHECK_FILE(../pdk/[pdk]_info, [ - AC_CHECK_FILE(../pdks/pdk,[ - echo "Using pre-existing pdk download..." - ], [ -- mkdir -p ../pdks/pdk -- sh dl $(cat "../pdk/pdk_get") ../pdks/pdk.tar.gz; -- (echo "Extracting pdk..." && cd ../pdks && tar -xf pdk.tar.gz --strip-components 1 -C ../pdks/pdk) -+ REPO=$(cat "../pdk/pdk_info" | sed -n "1p") -+ POST_CLONE_COMMANDS=$(cat "../pdk/pdk_info" | sed "1d") -+ mkdir -p ../pdks -+ git clone "$REPO" ../pdks/pdk; -+ (cd ../pdks/pdk && sh -c "$POST_CLONE_COMMANDS") - ]) - export pdkvar[]_SOURCE_PATH=../pdks/pdk - ], [ -@@ -38,18 +40,33 @@ AC_DEFUN([M4_GEN_WITH_PDK_ARGS], [ - ]) - } - -+ pdk_find() { -+ FOUND=0 -+ for path in /opt/pdks/pdk /usr/share/pdks/pdk /usr/local/share/pdks/pdk; do -+ if @<:@ -d $path @:>@ ; then -+ echo "Found pdk in $path, using this installation..." -+ export pdkvar[]_SOURCE_PATH=$path -+ FOUND=1 -+ fi -+ done -+ if @<:@ "$FOUND" = "$1" @:>@; then -+ echo "Could not found pdk in standard search paths, manually downloading to ../pdks/pdk ..." -+ pdk_find -+ fi -+ } -+ - AC_ARG_ENABLE(pdk-[pdk], - [AS_HELP_STRING([--enable-pdk-[pdk]=@<:@/path/to/pdk/@:>@ --disable-pdk-[pdk]], "location of the source files for the pdk (pdks with a [pdk]_url file can automatically download them if the path is omitted)")], - [ - if test "$enableval" == "yes" -o "$enableval" == "YES"; then -- pdk_get -+ pdk_find - elif test "$enableval" == "no" -o "$enableval" == "NO"; then - echo "Disabling pdk..." - else - export pdkvar[]_SOURCE_PATH=$enableval - fi - ], [ -- pdk_get -+ pdk_find - ] - ) - # # Require this argument -diff --git a/scripts/download.sh b/scripts/download.sh -new file mode 100755 -index 0000000..7623f32 ---- /dev/null -+++ b/scripts/download.sh -@@ -0,0 +1,22 @@ -+#!/bin/sh -+# -+# Neither curl or wget are guaranteed to be included in all *nix systems, -+# (but most have *one* of them). This tools tries its best to find one. -+# -+ -+DL_CMD= -+if type "wget" > /dev/null; then -+ DL_CMD="wget -qO" -+fi -+ -+if type "curl" > /dev/null; then -+ DL_CMD="curl -sLo" -+fi -+ -+if [ "$DL_CMD" = "" ]; then -+ echo "Either curl or wget are required to automatically install tools." -+ exit 1 -+fi -+ -+echo "Downloading $1 to $2..." -+$DL_CMD $2 $1 -\ No newline at end of file -diff --git a/sky130/pdk_info b/sky130/pdk_info -new file mode 100644 -index 0000000..ee872cd ---- /dev/null -+++ b/sky130/pdk_info -@@ -0,0 +1,10 @@ -+https://github.com/google/skywater-pdk -+ -+# Post Clone Commands -+for i in $(git submodule | grep /latest | awk '{print $2}'); do -+ git submodule init $i -+done -+ -+git submodule update -+ -+make timing -\ No newline at end of file -diff --git a/sky130/pdk_url b/sky130/pdk_url -deleted file mode 100644 -index 11a17e1..0000000 ---- a/sky130/pdk_url -+++ /dev/null -@@ -1 +0,0 @@ --https://github.com/google/skywater-pdk/archive/master.tar.gz -\ No newline at end of file
diff --git a/sky130/custom/scripts/generate_fill.py b/sky130/custom/scripts/generate_fill.py new file mode 100755 index 0000000..9a1e3dc --- /dev/null +++ b/sky130/custom/scripts/generate_fill.py
@@ -0,0 +1,239 @@ +#!/bin/env python3 +# SPDX-FileCopyrightText: 2020 Efabless Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# SPDX-License-Identifier: Apache-2.0 + +# +# generate_fill.py --- +# +# Run the fill generation on a layout top level. +# + +import sys +import os +import re +import subprocess + +def usage(): + print("Usage:") + print("generate_fill.py <layout_name> [-keep] [-test]") + print("") + print("where:") + print(" <layout_name> is the path to the .mag file to be filled.") + print("") + print(" If '-keep' is specified, then keep the generation script.") + print(" If '-test' is specified, then create but do not run the generation script.") + return 0 + +if __name__ == '__main__': + + optionlist = [] + arguments = [] + + debugmode = False + keepmode = False + testmode = False + + for option in sys.argv[1:]: + if option.find('-', 0) == 0: + optionlist.append(option) + else: + arguments.append(option) + + if len(arguments) != 1: + print("Wrong number of arguments given to generate_fill.py.") + usage() + sys.exit(1) + + user_project_path = arguments[0] + + magpath = os.path.split(user_project_path)[0] + if magpath == '': + magpath = os.getcwd() + + if os.path.splitext(user_project_path)[1] != '.mag': + if os.path.splitext(user_project_path)[1] == '': + user_project_path += '.mag' + else: + print('Error: Project is not a magic database .mag file!') + sys.exit(1) + + if not os.path.isfile(user_project_path): + print('Error: Project "' + user_project_path + '" does not exist or is not readable.') + sys.exit(1) + + if '-debug' in optionlist: + debugmode = True + if '-keep' in optionlist: + keepmode = True + if '-test' in optionlist: + testmode = True + + rcfile = magpath + '/.magicrc' + if not os.path.isfile(rcfile): + rcfile = None + + project = os.path.splitext(os.path.split(user_project_path)[1])[0] + + topdir = os.path.split(magpath)[0] + gdsdir = topdir + '/gds' + hasgdsdir = True if os.path.isdir(gdsdir) else False + + with open(magpath + '/generate_fill.tcl', 'w') as ofile: + print('#!/bin/env wish', file=ofile) + print('drc off', file=ofile) + print('tech unlock *', file=ofile) + print('snap internal', file=ofile) + print('box values 0 0 0 0', file=ofile) + print('box size 700um 700um', file=ofile) + print('set stepbox [box values]', file=ofile) + print('set stepwidth [lindex $stepbox 2]', file=ofile) + print('set stepheight [lindex $stepbox 3]', file=ofile) + print('', file=ofile) + print('set starttime [orig_clock format [orig_clock seconds] -format "%D %T"]', file=ofile) + print('puts stdout "Started: $starttime"', file=ofile) + print('', file=ofile) + print('load ' + project + ' -dereference', file=ofile) + print('select top cell', file=ofile) + print('expand', file=ofile) + print('cif ostyle wafflefill(tiled)', file=ofile) + print('', file=ofile) + print('set fullbox [box values]', file=ofile) + print('set xmax [lindex $fullbox 2]', file=ofile) + print('set xmin [lindex $fullbox 0]', file=ofile) + print('set fullwidth [expr {$xmax - $xmin}]', file=ofile) + print('set xtiles [expr {int(ceil($fullwidth / $stepwidth))}]', file=ofile) + print('set ymax [lindex $fullbox 3]', file=ofile) + print('set ymin [lindex $fullbox 1]', file=ofile) + print('set fullheight [expr {$ymax - $ymin}]', file=ofile) + print('set ytiles [expr {int(ceil($fullheight / $stepheight))}]', file=ofile) + print('box size $stepwidth $stepheight', file=ofile) + print('set xbase [lindex $fullbox 0]', file=ofile) + print('set ybase [lindex $fullbox 1]', file=ofile) + print('', file=ofile) + + # Break layout into tiles and process each separately + print('for {set y 0} {$y < $ytiles} {incr y} {', file=ofile) + print(' for {set x 0} {$x < $xtiles} {incr x} {', file=ofile) + print(' set xlo [expr $xbase + $x * $stepwidth]', file=ofile) + print(' set ylo [expr $ybase + $y * $stepheight]', file=ofile) + print(' set xhi [expr $xlo + $stepwidth]', file=ofile) + print(' set yhi [expr $ylo + $stepheight]', file=ofile) + print(' box values $xlo $ylo $xhi $yhi', file=ofile) + # The flattened area must be larger than the fill tile by >1.5um + print(' box grow c 1.6um', file=ofile) + + # Flatten into a cell with a new name + print(' puts stdout "Flattening layout of tile x=$x y=$y. . . "', file=ofile) + print(' flush stdout', file=ofile) + print(' update idletasks', file=ofile) + print(' flatten -dobox -nolabels ' + project + '_fill_pattern_${x}_$y', file=ofile) + print(' load ' + project + '_fill_pattern_${x}_$y', file=ofile) + + # Remove any GDS_FILE reference + print(' property GDS_FILE ""', file=ofile) + # Set boundary using comment layer, to the size of the step box + print(' box values $xlo $ylo $xhi $yhi', file=ofile) + print(' paint comment', file=ofile) + print(' puts stdout "Writing GDS. . . "', file=ofile) + print(' flush stdout', file=ofile) + print(' update idletasks', file=ofile) + print(' gds write ' + project + '_fill_pattern_${x}_$y.gds', file=ofile) + + # Reload project top + print(' load ' + project, file=ofile) + + # Remove last generated cell to save memory + print(' cellname delete ' + project + '_fill_pattern_${x}_$y', file=ofile) + + print(' }', file=ofile) + print('}', file=ofile) + + # Now create simple "fake" views of all the tiles. + print('gds readonly true') + print('gds rescale false') + print('for {set y 0} {$y < $ytiles} {incr y} {', file=ofile) + print(' for {set x 0} {$x < $xtiles} {incr x} {', file=ofile) + print(' set xlo [expr $xbase + $x * $stepwidth]', file=ofile) + print(' set ylo [expr $ybase + $y * $stepheight]', file=ofile) + print(' set xhi [expr $xlo + $stepwidth]', file=ofile) + print(' set yhi [expr $ylo + $stepheight]', file=ofile) + print(' load ' + project + '_fill_pattern_${x}_$y', file=ofile) + print(' box values $xlo $ylo $xhi $yhi', file=ofile) + print(' paint comment', file=ofile) + print(' property FIXED_BBOX "$xlo $ylo $xhi $yhi"', file=ofile) + print(' property GDS_FILE ' + project + '_fill_pattern_${x}_${y}.gds', file=ofile) + print(' property GDS_START 0', file=ofile) + print(' }', file=ofile) + print('}', file=ofile) + + # Now tile everything back together + print('load ' + project + '_fill_pattern', file=ofile) + print('for {set y 0} {$y < $ytiles} {incr y} {', file=ofile) + print(' for {set x 0} {$x < $xtiles} {incr x} {', file=ofile) + print(' box values 0 0 0 0', file=ofile) + print(' getcell ' + project + '_fill_pattern_${x}_$y child 0 0', file=ofile) + print(' }', file=ofile) + print('}', file=ofile) + + # And write final GDS + print('puts stdout "Writing final GDS"', file=ofile) + + print('cif *hier write disable', file=ofile) + print('cif *array write disable', file=ofile) + if hasgdsdir: + print('gds write ../gds/' + project + '_fill_pattern.gds', file=ofile) + else: + print('gds write ' + project + '_fill_pattern.gds', file=ofile) + print('set endtime [orig_clock format [orig_clock seconds] -format "%D %T"]', file=ofile) + print('puts stdout "Ended: $endtime"', file=ofile) + print('quit -noprompt', file=ofile) + myenv = os.environ.copy() + myenv['MAGTYPE'] = 'mag' + + if not testmode: + # Diagnostic + # print('This script will generate file ' + project + '_fill_pattern.gds') + print('This script will generate files ' + project + '_fill_pattern_x_y.gds') + print('Now generating fill patterns. This may take. . . quite. . . a while.', flush=True) + mproc = subprocess.run(['magic', '-dnull', '-noconsole', + '-rcfile', rcfile, magpath + '/generate_fill.tcl'], + stdin = subprocess.DEVNULL, + stdout = subprocess.PIPE, + stderr = subprocess.PIPE, + cwd = magpath, + env = myenv, + universal_newlines = True) + if mproc.stdout: + for line in mproc.stdout.splitlines(): + print(line) + if mproc.stderr: + print('Error message output from magic:') + for line in mproc.stderr.splitlines(): + print(line) + if mproc.returncode != 0: + print('ERROR: Magic exited with status ' + str(mproc.returncode)) + + if not keepmode: + # Remove fill generation script + os.remove(magpath + '/generate_fill.tcl') + # Remove all individual fill tiles, leaving only the composite GDS. + filelist = os.listdir(magpath) + for file in filelist: + if os.path.splitext(magpath + '/' + file)[1] == '.gds': + if file.startswith(project + '_fill_pattern_') + os.remove(magpath + '/' + file + + print('Done!') + exit(0)
diff --git a/sky130/magic/sky130.tech b/sky130/magic/sky130.tech index 95fc2f4..67047b2 100644 --- a/sky130/magic/sky130.tech +++ b/sky130/magic/sky130.tech
@@ -1707,7 +1707,7 @@ #endif (EXPERIMENTAL) #---------------------------------------------------------------- -style wafflefill +style wafflefill variants (),(tiled) #---------------------------------------------------------------- # Style used by scripts for automatically generating fill layers # NOTE: Be sure to generate output on flattened layout. @@ -1717,10 +1717,30 @@ gridlimit 5 #---------------------------------------------------------------- -# Generate and retain a layer representing the bounding box +# Generate and retain a layer representing the bounding box. +# +# For variant (): +# The bounding box is the full extent of geometry on the top level +# cell. +# +# For variant (tiled): +# Use with a script that breaks layout into flattened tiles and runs +# fill individually on each. The tiles should be larger than the +# step size, and each should draw a layer "comment" the size of the +# step box. #---------------------------------------------------------------- - templayer topbox - bbox top + + variants () + templayer topbox + bbox top + + variants (tiled) + templayer topbox comment + # Each tile imposes the full keepout distance rule of + # 3um on all sides. + shrink 1500 + + variants * #---------------------------------------------------------------- # Generate guard-band around nwells to keep FOM from crossing @@ -1732,25 +1752,27 @@ templayer mvnwell bloat-all alldiffmv nwell - templayer lvnwell nwell + templayer lvnwell allnwell and-not mvnwell templayer well_shrink mvnwell shrink 250 or lvnwell shrink 180 - templayer well_guardband nwell + templayer well_guardband allnwell grow 340 and-not well_shrink #--------------------------------------------------- # Diffusion and poly keep-out areas #--------------------------------------------------- - templayer obstruct_fom alldiff,allpoly,rpw + templayer obstruct_fom alldiff,allpoly,fomfill,polyfill,obspoly,obsactive + or rpw,pnp,npn grow 500 or well_guardband - templayer obstruct_poly alldiff,allpoly,rpw + templayer obstruct_poly alldiff,allpolyfomfill,polyfill,obspoly,obsactive + or rpw,pnp,npn grow 1000 #--------------------------------------------------- @@ -2045,6 +2067,7 @@ templayer met4fill_medium topbox slots 0 1000 300 0 1000 300 700 1050 and-not obstruct_m4_medium + and topbox shrink 495 grow 495