Update to sky130 to replace the "sky130gds.tech" file with a new and more complete tech file. Modified the "generate_fill.py" script to use this new tech file, as it is more comprensive when working with GDS files from any origin. Corrected the analog pad used in the Caravan chip to fix a DRC error with a well-to-tap spacing.
diff --git a/VERSION b/VERSION index b61b912..51ae719 100644 --- a/VERSION +++ b/VERSION
@@ -1 +1 @@ -1.0.526 +1.0.527
diff --git a/sky130/custom/scripts/generate_fill.py b/sky130/custom/scripts/generate_fill.py index c2a16ce..d163b3a 100755 --- a/sky130/custom/scripts/generate_fill.py +++ b/sky130/custom/scripts/generate_fill.py
@@ -17,7 +17,7 @@ # # generate_fill.py --- # -# Run the fill generation on a layout top level. +# Run the fill generation on a layout top level GDS file. # import sys @@ -33,14 +33,14 @@ print("generate_fill.py <layout_name> [-keep] [-test] [-dist]") print("") print("where:") - print(" <layout_name> is the path to the .mag or .gds file to be filled.") + print(" <layout_name> is the path to the GDS 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.") print(" If '-dist' is specified, then run distributed (multi-processing).") return 0 -def makegds(file, rcfile): +def makegds(file, techfile): # Procedure for multiprocessing only: Run the distributed processing # script to load a .mag file of one flattened square area of the layout, # and run the fill generator to produce a .gds file output from it. @@ -55,7 +55,7 @@ 'magic', '-dnull', '-noconsole', - '-rcfile', rcfile, + '-T', techfile, layoutpath + '/generate_fill_dist.tcl', filename] @@ -141,7 +141,7 @@ proj_extension = '.' + layoutfiles[0].split(os.extsep, 1)[1] user_project_path = layoutfiles[0] elif len(layoutfiles) == 0: - print('Error: Project is not a magic database or GDS file!') + print('Error: Project is not a GDS file!') sys.exit(1) else: print('Error: Project name is ambiguous!') @@ -149,15 +149,12 @@ else: proj_extension = '.' + project[1] - is_mag = False is_gds = False - if proj_extension == '.mag' or proj_extension == '.mag.gz': - is_mag = True - elif proj_extension == '.gds' or proj_extension == '.gds.gz': + if proj_extension == '.gds' or proj_extension == '.gds.gz': is_gds = True else: - print('Error: Project is not a magic database or GDS file!') + print('Error: Project is not a GDS file!') sys.exit(1) if not os.path.isfile(user_project_path): @@ -168,22 +165,25 @@ # path where the magic startup script resides, for the same PDK scriptpath = os.path.dirname(os.path.realpath(__file__)) - # Search for magic startup script. Order of precedence: - # 1. PDK_ROOT environment variable - # 2. Local .magicrc - # 3. The location of this script + # The PDK should be found via the PDK_ROOT environment variable. If not, + # then flag this as a warning. + # NOTES: + # 1) There are three or so "standard" locations for the PDK root directory + # that should be checked in the absence of a PDK_ROOT environment variable, + # and/or it should be possible to specify the PDK root directory from the + # command line. + # 2) The PDK variant defaults to "sky130B" because it is a superset of sky130A. + # 3) This script uses sky130B-GDS.tech (sky130A-GDS.tech) which exactly + # represents all layout layers without conversion to generated layers, + # which is preferable for doing fill generation. if os.environ.get('PDK'): pdk_name = os.environ.get('PDK') else: - pdk_name = 'sky130A' + pdk_name = 'sky130B' if os.environ.get('PDK_ROOT'): - rcfile_path = os.environ.get('PDK_ROOT') + '/' + pdk_name + '/libs.tech/magic/' + pdk_name + '.magicrc' - elif os.path.isfile(layoutpath + '/.magicrc'): - rcfile_path = layoutpath + '/.magicrc' - elif os.path.isfile(scriptpath + '/' + pdk_name + '.magicrc'): - rcfile_path = scriptpath + '/' + pdk_name + '.magicrc' + techfile_path = os.environ.get('PDK_ROOT') + '/' + pdk_name + '/libs.tech/magic/' + pdk_name + '-GDS.tech' else: print('Unknown path to magic startup script. Please set $PDK_ROOT') sys.exit(1) @@ -203,7 +203,9 @@ print('#!/usr/bin/env wish', file=ofile) print('drc off', file=ofile) print('crashbackups stop', file=ofile) + print('locking disable', file=ofile) print('tech unlock *', file=ofile) + print('scalegrid 1 2', file=ofile) print('snap internal', file=ofile) print('box values 0 0 0 0', file=ofile) print('box size 700um 700um', file=ofile) @@ -214,8 +216,8 @@ print('set starttime [orig_clock format [orig_clock seconds] -format "%D %T"]', file=ofile) print('puts stdout "Started: $starttime"', file=ofile) print('', file=ofile) - if is_gds: - print('gds read ' + project_file, file=ofile) + print('gds rescale false', file=ofile) + print('gds read ' + project_file, file=ofile) # NOTE: No guarantee that the filename matches the top level cell name; # might want to query using "cellname list top" print('load ' + project + ' -dereference', file=ofile) @@ -263,12 +265,12 @@ # Remove any GDS_FILE reference (there should not be any?) print(' property GDS_FILE ""', file=ofile) - # Set boundary using comment layer, to the size of the step box + # Set boundary using COMMENT layer, to the size of the step box # This corresponds to the "topbox" rule in the wafflefill(tiled) style print(' select top cell', file=ofile) - print(' erase comment', file=ofile) + print(' erase COMMENT', file=ofile) print(' box values $xlo $ylo $xhi $yhi', file=ofile) - print(' paint comment', file=ofile) + print(' paint COMMENT', file=ofile) if not distmode: print(' puts stdout "Writing GDS. . . "', file=ofile) @@ -306,6 +308,7 @@ print('#!/usr/bin/env wish', file=ofile) print('drc off', file=ofile) print('tech unlock *', file=ofile) + print('scalegrid 1 2', file=ofile) print('snap internal', file=ofile) print('box values 0 0 0 0', file=ofile) print('set filename [file root [lindex $argv $argc-1]]', file=ofile) @@ -318,6 +321,7 @@ print('#!/usr/bin/env wish', file=ofile) print('drc off', file=ofile) print('tech unlock *', file=ofile) + print('scalegrid 1 2', file=ofile) print('snap internal', file=ofile) print('box values 0 0 0 0', file=ofile) @@ -342,7 +346,7 @@ print(' set yhi [expr $ylo + $stepheight]', file=ofile) print(' load ' + project + '_fill_pattern_${x}_$y -silent', file=ofile) print(' box values $xlo $ylo $xhi $yhi', file=ofile) - print(' paint comment', 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) @@ -383,7 +387,7 @@ 'magic', '-dnull', '-noconsole', - '-rcfile', rcfile_path, + '-T', techfile_path, layoutpath + '/generate_fill.tcl'] if debugmode: @@ -417,7 +421,7 @@ # try to read it from the command line as well as passing it as an # argument to the script. We only want it passed as an argument. magxfiles = list(item + 'x' for item in magfiles) - makegdsfunc = functools.partial(makegds, rcfile=rcfile_path) + makegdsfunc = functools.partial(makegds, techfile=techfile_path) pool.map(makegdsfunc, magxfiles) # If using distributed mode, then remove all of the temporary .mag files @@ -429,7 +433,7 @@ 'magic', '-dnull', '-noconsole', - '-rcfile', rcfile_path, + '-T', techfile_path, layoutpath + '/generate_fill_final.tcl'] mproc = subprocess.run(magic_run_opts,
diff --git a/sky130/custom/scripts/generate_fill_mag.py b/sky130/custom/scripts/generate_fill_mag.py new file mode 100755 index 0000000..a09919b --- /dev/null +++ b/sky130/custom/scripts/generate_fill_mag.py
@@ -0,0 +1,477 @@ +#!/usr/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_mag.py --- +# +# Run the fill generation on a layout top level. This may be used with +# .mag or GDS files. WARNING: Layout containing abstracted views +# pointing to vendor GDS may not accurately represent layers PSDM, NSDM, +# and HVI, resulting in fill shapes illegally overlapping with those +# layers. Instead, use the "generate_fill.py" script and run it on an +# input file in GDS format. +# + +import sys +import os +import re +import glob +import functools +import subprocess +import multiprocessing + +def usage(): + print("Usage:") + print("generate_fill_mag.py <layout_name> [-keep] [-test] [-dist]") + print("") + print("where:") + print(" <layout_name> is the path to the .mag or .gds 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.") + print(" If '-dist' is specified, then run distributed (multi-processing).") + return 0 + +def makegds(file, rcfile): + # Procedure for multiprocessing only: Run the distributed processing + # script to load a .mag file of one flattened square area of the layout, + # and run the fill generator to produce a .gds file output from it. + + layoutpath = os.path.split(file)[0] + filename = os.path.split(file)[1] + + myenv = os.environ.copy() + myenv['MAGTYPE'] = 'mag' + + magic_run_opts = [ + 'magic', + '-dnull', + '-noconsole', + '-rcfile', rcfile, + layoutpath + '/generate_fill_dist.tcl', + filename] + + mproc = subprocess.run(magic_run_opts, + stdin = subprocess.DEVNULL, + stdout = subprocess.PIPE, + stderr = subprocess.PIPE, + cwd = layoutpath, + 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 __name__ == '__main__': + + optionlist = [] + arguments = [] + + debugmode = False + keepmode = False + testmode = False + distmode = 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_mag.py.") + usage() + sys.exit(1) + + # Process options + + if '-debug' in optionlist: + debugmode = True + print('Running in debug mode.') + if '-keep' in optionlist: + keepmode = True + if debugmode: + print('Keeping all files after running.') + elif debugmode: + print('Files other than final layout will be removed after running.') + if '-test' in optionlist: + testmode = True + if debugmode: + print('Running in test mode: No output files will be created.') + if '-dist' in optionlist: + distmode = True + if debugmode: + print('Running in distributed (multi-processing) mode.') + elif debugmode: + print('Running in single-processor mode.') + + # Find layout from command-line argument + + user_project_path = arguments[0] + + if os.path.split(user_project_path)[0] == '': + layoutpath = os.getcwd() + else: + layoutpath = os.getcwd() + '/' + os.path.split(user_project_path)[0] + + # Use os.extsep, not os.path.splitext(), because gzipped files have + # multiple periods (e.g., "layout.gds.gz") + + project = user_project_path.split(os.extsep, 1) + + if len(project) == 1: + # No file extension given; figure it out + layoutfiles = glob.glob(user_project_path + '.*') + if len(layoutfiles) == 1: + proj_extension = '.' + layoutfiles[0].split(os.extsep, 1)[1] + user_project_path = layoutfiles[0] + elif len(layoutfiles) == 0: + print('Error: Project is not a magic database or GDS file!') + sys.exit(1) + else: + print('Error: Project name is ambiguous!') + sys.exit(1) + else: + proj_extension = '.' + project[1] + + is_mag = False + is_gds = False + + if proj_extension == '.mag' or proj_extension == '.mag.gz': + is_mag = True + elif proj_extension == '.gds' or proj_extension == '.gds.gz': + is_gds = True + else: + print('Error: Project is not a magic database or GDS 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) + + # The path where the fill generation script resides should be the same + # path where the magic startup script resides, for the same PDK + scriptpath = os.path.dirname(os.path.realpath(__file__)) + + # Search for magic startup script. Order of precedence: + # 1. PDK_ROOT environment variable + # 2. Local .magicrc + # 3. The location of this script + + if os.environ.get('PDK'): + pdk_name = os.environ.get('PDK') + else: + pdk_name = 'sky130A' + + if os.environ.get('PDK_ROOT'): + rcfile_path = os.environ.get('PDK_ROOT') + '/' + pdk_name + '/libs.tech/magic/' + pdk_name + '.magicrc' + elif os.path.isfile(layoutpath + '/.magicrc'): + rcfile_path = layoutpath + '/.magicrc' + elif os.path.isfile(scriptpath + '/' + pdk_name + '.magicrc'): + rcfile_path = scriptpath + '/' + pdk_name + '.magicrc' + else: + print('Unknown path to magic startup script. Please set $PDK_ROOT') + sys.exit(1) + + if os.path.isdir(layoutpath + '/gds'): + gdspath = layoutpath + '/gds' + elif os.path.isdir(layoutpath + '/../gds'): + gdspath = layoutpath + '/../gds' + else: + gdspath = layoutpath + + project_file = os.path.split(user_project_path)[1] + project = project_file.split(os.extsep, 1)[0] + + ofile = open(layoutpath + '/generate_fill.tcl', 'w') + + print('#!/usr/bin/env wish', file=ofile) + print('drc off', file=ofile) + print('crashbackups stop', 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) + if is_gds: + print('gds read ' + project_file, file=ofile) + # NOTE: No guarantee that the filename matches the top level cell name; + # might want to query using "cellname list top" + print('load ' + project + ' -dereference', file=ofile) + print('select top cell', file=ofile) + print('expand', file=ofile) + if not distmode: + print('cif ostyle wafflefill(tiled)', file=ofile) + print('', file=ofile) + # Use FIXED_BBOX as the boundary if it exists + print('select top cell', file=ofile) + print('catch {box values {*}[property FIXED_BBOX]}', 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 + 0.0) / $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 + 0.0) / $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(' if {$xhi > $fullwidth} {set xhi $fullwidth}', file=ofile) + print(' if {$yhi > $fullheight} {set yhi $fullheight}', 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 (there should not be any?) + print(' property GDS_FILE ""', file=ofile) + # Set boundary using comment layer, to the size of the step box + # This corresponds to the "topbox" rule in the wafflefill(tiled) style + print(' select top cell', file=ofile) + print(' erase comment', file=ofile) + print(' box values $xlo $ylo $xhi $yhi', file=ofile) + print(' paint comment', file=ofile) + + if not distmode: + print(' puts stdout "Writing GDS. . . "', file=ofile) + + print(' flush stdout', file=ofile) + print(' update idletasks', file=ofile) + + if distmode: + print(' writeall force ' + project + '_fill_pattern_${x}_$y', file=ofile) + else: + 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) + + if distmode: + print('set ofile [open fill_gen_info.txt w]', file=ofile) + print('puts $ofile "$stepwidth"', file=ofile) + print('puts $ofile "$stepheight"', file=ofile) + print('puts $ofile "$xtiles"', file=ofile) + print('puts $ofile "$ytiles"', file=ofile) + print('puts $ofile "$xbase"', file=ofile) + print('puts $ofile "$ybase"', file=ofile) + print('close $ofile', file=ofile) + print('quit -noprompt', file=ofile) + ofile.close() + + with open(layoutpath + '/generate_fill_dist.tcl', 'w') as ofile: + print('#!/usr/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('set filename [file root [lindex $argv $argc-1]]', file=ofile) + print('load $filename', file=ofile) + print('cif ostyle wafflefill(tiled)', file=ofile) + print('gds write [file root $filename].gds', file=ofile) + print('quit -noprompt', file=ofile) + + ofile = open(layoutpath + '/generate_fill_final.tcl', 'w') + print('#!/usr/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('set ifile [open fill_gen_info.txt r]', file=ofile) + print('gets $ifile stepwidth', file=ofile) + print('gets $ifile stepheight', file=ofile) + print('gets $ifile xtiles', file=ofile) + print('gets $ifile ytiles', file=ofile) + print('gets $ifile xbase', file=ofile) + print('gets $ifile ybase', file=ofile) + print('close $ifile', file=ofile) + print('cif ostyle wafflefill(tiled)', file=ofile) + + # Now create simple "fake" views of all the tiles. + print('gds readonly true', file=ofile) + print('gds rescale false', 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(' 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 -silent', 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 -silent', 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) + print('gds compress 9', file=ofile) + print('gds write ' + gdspath + '/' + project + '_fill_pattern.gds.gz', 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) + ofile.close() + + myenv = os.environ.copy() + myenv['MAGTYPE'] = 'mag' + + if not testmode: + # Diagnostic + # print('This script will generate file ' + project + '_fill_pattern.gds.gz') + 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) + + magic_run_opts = [ + 'magic', + '-dnull', + '-noconsole', + '-rcfile', rcfile_path, + layoutpath + '/generate_fill.tcl'] + + if debugmode: + print('Running: ' + ' '.join(magic_run_opts)) + + mproc = subprocess.run(magic_run_opts, + stdin = subprocess.DEVNULL, + stdout = subprocess.PIPE, + stderr = subprocess.PIPE, + cwd = layoutpath, + 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 distmode: + # If using distributed mode, then run magic on each of the generated + # layout files + pool = multiprocessing.Pool() + magfiles = glob.glob(layoutpath + '/' + project + '_fill_pattern_*.mag') + # NOTE: Adding 'x' to the end of each filename, or else magic will + # try to read it from the command line as well as passing it as an + # argument to the script. We only want it passed as an argument. + magxfiles = list(item + 'x' for item in magfiles) + makegdsfunc = functools.partial(makegds, rcfile=rcfile_path) + pool.map(makegdsfunc, magxfiles) + + # If using distributed mode, then remove all of the temporary .mag files + # and then run the final generation script. + for file in magfiles: + os.remove(file) + + magic_run_opts = [ + 'magic', + '-dnull', + '-noconsole', + '-rcfile', rcfile_path, + layoutpath + '/generate_fill_final.tcl'] + + mproc = subprocess.run(magic_run_opts, + stdin = subprocess.DEVNULL, + stdout = subprocess.PIPE, + stderr = subprocess.PIPE, + cwd = layoutpath, + 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(layoutpath + '/generate_fill.tcl') + # Remove all individual fill tiles, leaving only the composite GDS. + filelist = os.listdir(layoutpath) + for file in filelist: + if os.path.splitext(layoutpath + '/' + file)[1] == '.gds': + if file.startswith(project + '_fill_pattern_'): + os.remove(layoutpath + '/' + file) + + if distmode: + os.remove(layoutpath + '/generate_fill_dist.tcl') + os.remove(layoutpath + '/generate_fill_final.tcl') + os.remove(layoutpath + '/fill_gen_info.txt') + if testmode: + magfiles = glob.glob(layoutpath + '/' + project + '_fill_pattern_*.mag') + for file in magfiles: + os.remove(file) + + print('Done!') + exit(0)
diff --git a/sky130/custom/sky130_fd_io/gds/sky130_ef_io__analog.gds b/sky130/custom/sky130_fd_io/gds/sky130_ef_io__analog.gds index ff0e5cc..2c2c73d 100644 --- a/sky130/custom/sky130_fd_io/gds/sky130_ef_io__analog.gds +++ b/sky130/custom/sky130_fd_io/gds/sky130_ef_io__analog.gds Binary files differ
diff --git a/sky130/magic/sky130.tech b/sky130/magic/sky130.tech index 5fb3e7d..ab4cf90 100644 --- a/sky130/magic/sky130.tech +++ b/sky130/magic/sky130.tech
@@ -759,7 +759,7 @@ cifoutput #---------------------------------------------------------------- -style gdsii +style gdsii variants (),(origfill) # NOTE: This section is used for actual GDS output #---------------------------------------------------------------- scalefactor 10 nanometers @@ -1056,10 +1056,9 @@ layer RPM bloat-all xhrpoly xpc - grow 200 - grow-min 1270 - grow 420 + grow 620 shrink 420 + mask-hints RPM calma 86 20 #---------------------------------------------------------------- @@ -1068,10 +1067,9 @@ layer URPM bloat-all uhrpoly xpc - grow 200 - grow-min 1270 - grow 420 + grow 620 shrink 420 + mask-hints URPM calma 79 20 #---------------------------------------------------------------- @@ -1083,6 +1081,7 @@ grow 185 grow 345 shrink 345 + mask-hints LDNTM calma 11 44 #---------------------------------------------------------------- @@ -1485,6 +1484,8 @@ #---------------------------------------------------------------- # FILLBLOCK #---------------------------------------------------------------- + variants (origfill) + layer FILLOBSFOM obsactive calma 22 24 @@ -1500,11 +1501,42 @@ layer FILLOBSM3 fillblock,obsm3 calma 107 24 +#ifdef METAL5 layer FILLOBSM4 fillblock,obsm4 calma 112 4 layer FILLOBSM5 fillblock,obsm5 calma 117 4 +#endif + + variants () + + layer FILLOBSFOM obsactive + calma 65 98 + + # NOTE: should there be an "obspoly" layer? + + layer FILLOBSLI fillblock,obsli + calma 67 98 + + layer FILLOBSM1 fillblock,obsm1 + calma 68 98 + + layer FILLOBSM2 fillblock,obsm2 + calma 69 98 + + layer FILLOBSM3 fillblock,obsm3 + calma 70 98 + +#ifdef METAL5 + layer FILLOBSM4 fillblock,obsm4 + calma 71 98 + + layer FILLOBSM5 fillblock,obsm5 + calma 72 98 +#endif + + variants * render DNWELL cwell -0.1 0.1 render NWELL nwell 0.0 0.2062 @@ -1802,12 +1834,17 @@ and-not hvntm_block # RPM spacing checks require recreating RPM + templayer rpm_block *psd,*mvpsd + grow 185 + + # Check RPM spacing across a p-tap templayer rpm_generate bloat-all xhrpoly,uhrpoly xpc - grow 200 - grow-min 1270 - grow 420 + grow 620 shrink 420 + mask-hints RPM + mask-hints URPM + and-not rpm_block # Check distance RPM to NSDM templayer rpm_nsd_check rpm_generate @@ -1936,6 +1973,10 @@ #---------------------------------------------------------------- # Style used by scripts for automatically generating fill layers # NOTE: Be sure to generate output on flattened layout. +# Also note: This fill generator script uses the older GDS +# layer assignments for fill layers. The generator script that +# uses the sky130gds.tech (e.g., sky130A-GDS.tech) technology file +# is preferred. #---------------------------------------------------------------- scalefactor 10 nanometers options calma-permissive-labels @@ -4271,13 +4312,13 @@ #endif # Alternate layer purpose used for obstruction (fill block) - calma LIBLOCK 67 10 - calma MET1BLOCK 68 10 - calma MET2BLOCK 69 10 - calma MET3BLOCK 70 10 + calma LIBLOCK 67 98 + calma MET1BLOCK 68 98 + calma MET2BLOCK 69 98 + calma MET3BLOCK 70 98 #ifdef METAL5 - calma MET4BLOCK 71 10 - calma MET5BLOCK 72 10 + calma MET4BLOCK 71 98 + calma MET5BLOCK 72 98 #endif #----------------------------------------------------------------------- @@ -4572,6 +4613,17 @@ variants * #-------------------------------------------------------------------- +# RPM, URPM +#-------------------------------------------------------------------- + +variants (full) + # This requires extra spacing of poly resistors if a ptap is in between + cifwidth rpm_generate 1270 "Width of RPM/URPM < %d (rpm.1)" + cifspacing rpm_generate rpm_generate 840 touching_ok \ + "RPM spacing < %d (rpm.2)" +variants * + +#-------------------------------------------------------------------- # NPC (Nitride poly Cut) #--------------------------------------------------------------------
diff --git a/sky130/magic/sky130gds.tech b/sky130/magic/sky130gds.tech index 11e66a4..5f9d8b9 100644 --- a/sky130/magic/sky130gds.tech +++ b/sky130/magic/sky130gds.tech
@@ -1,4 +1,3 @@ -#undef RERAM tech format 32 TECHNAME-GDS @@ -6,254 +5,410 @@ version version REVISION - description "SkyWater SKY130: Vendor GDS layers and supplementary DRC" + description "Google/SkyWater SKY130: Vendor GDS layers and supplementary DRC" requires magic-8.3.124 end +#------------------------------------------------------------------------------ +# This tech file represents all GDS layers exactly in magic with no boolean +# transforms to generated layer types. It can be used to manipulate GDS and +# is better for some DRC checks and for fill pattern generation. However, it +# does not properly understand connectivity and cannot be used for extraction. +#------------------------------------------------------------------------------ + planes - p1 - p2 - p3 - p4 - p5 - p6 - p7 - p8 - p9 - p10 - p11 - p12 - p13 - p14 - p15 - p16 - p17 - p18 - p19 - p20 - p21 - p22 - p23 - p24 - p25 - p26 - p27 - p28 - p29 - p30 - p31 - p32 - p33 - p34 - p35 - p36 - p37 - p38 - p39 - p40 - p41 - p42 - p43 - p44 + dnwell,dw + well,w + implant1,i1 + implant2,i2 + implant3,i3 + implant4,i4 + implant5,i5 + implant6,i6 + implant7,i7 + implant8,i8 + active,a + poly,p + mcon,mc + locali,li1,li + licon,lc + metal1,m1 +#ifdef RERAM + reram,rr +#endif + via1,v1 + metal2,m2 + via2,v2 + metal3,m3 + cap1,c1 + via3,v3 + metal4,m4 + cap2,c2 + via4,v4 + metal5,m5 + glass,g + blockd,bd + blockp,bp + blockl,bl + block1,b1 + block2,b2 + block3,b3 + block4,b4 + block5,b5 + ident1,id1 + ident2,id2 + ident3,id3 + ident4,id4 + ident5,id5 + ident6,id6 + ident7,id7 + ident8,id8 + ident9,id9 + comment,c + error,e end types - p1 NWELL,l1 - p1 NWELLT,l60 - p1 NWELLP,l62 - p2 DNWELL,l2 - p3 DIFF,l3 - p3 TAP,l4 - p4 LVTN,l5 - p4 HVTP,l6 - p5 HVI,l7 - p6 TUNM,l8 - p7 POLY,l9 - p7 POLYP,l63 - p7 POLYT,l70 - p8 NPC,l10 - p9 PSDM,l11 - p9 NSDM,l12 - p10 LICON1,l13 - p11 LI1,l14 - p11 LI1T,l15 - p11 LI1P,l16 - p12 MCON,l17 - p12 MET1,l18 - p12 MET1T,l19 - p12 MET1P,l20 - p13 VIA1,l21 - p13 MET2,l22 - p13 MET2T,l23 - p13 MET2P,l24 - p14 VIA2,l25 - p14 MET3,l26 - p14 MET3T,l27 - p14 MET3P,l28 - p15 VIA3,l29 - p15 MET4,l30 - p15 MET4T,l31 - p15 MET4P,l32 - p16 VIA4,l33 - p16 MET5,l34 - p16 MET5T,l35 - p16 MET5P,l36 - p17 PAD,l37 - p17 PADT,l38 - p17 PADP,l39 - p18 AREAID,l40 - p19 TEXT,l41 - p20 HVTR,l42 - p21 NCM,l43 - p22 RPM,l44 - p23 NSM,l45 - p24 RDL,l46 - p25 VHVI,l47 - p26 LDNTM,l48 - p26 HVNTM,l49 - p27 PMM,l50 - p28 PNP,l51 - p29 CAP,l52 - p30 IND,l53 - p31 PWRES,l54 - p32 POLYRES,l55 - p33 DIFFRES,l56 - p34 DIODE,l57 - p35 POLYM,l58 - p36 COREID,l59 - p37 PWELLT,l61 - p37 PWELLP,l64 - p38 CFOMDROP,l65 - p39 CLI1MADD,l66 - p40 CNTMADD,l67 - p41 CP1MADD,l68 - p42 BOUND,l69 - p43 RERAM,l71 - p44 ESDID,l72 + dw DNWELL + + w NWELL + w NWELLTXT + w NWELLPIN + w PWELL + w PWELLTXT + w PWELLPIN + w PWELLRES + + a TAP + a DIFF + a DIFFTXT + a DIFFPIN + a DIFFRES + a DIFFCUT + a DIFFFILL + + i1 LVTN + i1 HVTP + i1 TUNM + i1 NCM + i2 THKOX + i3 NPC + i4 PSDM,PPLUS + i5 NSDM,NPLUS + i6 HVTR + i6 RPM + i6 URPM + i7 LDNTM + i8 HVNTM + + p POLY + p POLYPIN + p POLYTXT + p POLYRES + p POLYMOD + p POLYCUT + p POLYGATE + p POLYFILL + p POLYSHORT + + mc MCON + + li LI1,LI + li LI1TXT,LITXT + li LI1PIN,LIPIN + li LI1RES,LIRES + li LI1FILL,LIFILL + li LI1SHORT,LISHORT + + lc LICON1,LICON + + m1 MET1 + m1 MET1TXT + m1 MET1PIN + m1 MET1RES + m1 MET1FILL + m1 MET1SHORT + + v1 VIA1 +#ifdef RERAM +#undef RERAM + rr RERAM +#define RERAM 1 +#endif + + m2 MET2 + m2 MET2TXT + m2 MET2PIN + m2 MET2RES + m2 MET2FILL + m2 MET2SHORT + + v2 VIA2 + + m3 MET3 + m3 MET3TXT + m3 MET3PIN + m3 MET3RES + m3 MET3FILL + m3 MET3SHORT + + c1 CAPM + v3 VIA3 + + m4 MET4 + m4 MET4TXT + m4 MET4PIN + m4 MET4RES + m4 MET4FILL + m4 MET4SHORT + + c2 CAPM2,CAP2M + v4 VIA4 + + m5 MET5 + m5 MET5TXT + m5 MET5PIN + m5 MET5RES + m5 MET5FILL + m5 MET5SHORT + + g PAD + g PADTXT + g PADPIN + + id1 SUBCUT + id2 COREID + id2 HVNWELLID + id3 STDCELLID + id4 ESDID + id5 BOUND + id5 BOUND2 + id6 PNPID,PNP + id6 NPNID,NPN + id6 DIODEID,DIODE + id6 PHOTOID,PHOTO + id6 SEALID,SEAL + id6 PADDIFFID + id6 LVID,LOWVOLTAGE + id7 INDID,IND + id7 EDID,EXTDRAINID + id7 CAPID,CAP + id7 PADMETALID + id8 LOWTAPDENSITY + id8 PADCENTERID + id8 OUTLINE + id9 V5 + id9 V12 + id9 V20 + + bd DIFFBLOCK + bp POLYBLOCK + bl LIBLOCK + b1 MET1BLOCK + b2 MET2BLOCK + b3 MET3BLOCK + b4 MET4BLOCK + b5 MET5BLOCK + + bp CP1MADD + bp CP1MDROP + bd CFOMDROP + bl CLI1MADD + bl CLI1MDROP + id7 CNTMADD + + c TEXT + c LVSTEXT + c COMMENT + c UNKNOWN1 + c UNKNOWN2 + c UNKNOWN3 + + e ERROR + end contact end +aliases + ALLNWELL NWELL,NWELLTXT,NWELLPIN + ALLPWELL PWELL,PWELLTXT,PWELLPIN,PWELLRES + ALLDIFF TAP,DIFF,DIFFTXT,DIFFPIN,DIFFRES,DIFFCUT + ALLPOLY POLY,POLYTXT,POLYPIN,POLYRES,POLYMOD,POLYCUT,POLYGATE + ALLLI LI1,LI1TXT,LI1PIN,LI1RES + ALLM1 MET1,MET1TXT,MET1PIN,MET1RES + ALLM2 MET2,MET2TXT,MET2PIN,MET2RES + ALLM3 MET3,MET3TXT,MET3PIN,MET3RES + ALLM4 MET4,MET4TXT,MET4PIN,MET4RES + ALLM5 MET5,MET5TXT,MET5PIN,MET5RES + ALLPAD PAD,PADTXT,PADPIN +end + styles - styletype mos - l1 nwell - l2 cwell - l3 ndiffusion - l4 pdiffusion - l5 implant1 - l6 implant2 - l7 implant3 - l8 subcircuit - l9 polysilicon - l10 implant4 - l11 pdop_stripes - l12 ndop_stripes - l13 obsmetal1 contact_X'es - l14 metal1 - l15 metal1 - l16 metal1 - l17 metal1 metal2 via1 - l18 metal2 - l19 metal2 - l20 metal2 - l21 metal2 metal3 via2 - l22 metal3 - l23 metal3 - l24 metal3 - l25 metal3 metal4 via3 - l26 metal4 - l27 metal4 - l28 metal4 - l29 metal4 metal5 via4 - l30 metal5 - l31 metal5 - l32 metal5 - l33 metal5 metal6 via5 - l34 metal6 - l35 metal6 - l36 metal6 - l37 overglass - l38 overglass - l39 overglass - l40 subcircuit - l41 comment - l42 implant1 - l43 mim_top - l44 mim_bottom - l45 ntransistor_stripes - l46 metal7 - l47 electrode - l48 nwell_field_implant - l49 hvndiff_mask - l50 poly_light - l51 mvpdiff - l52 mvndiff - l53 hvpdiff - l54 cwellnsc - l55 poly_resist poly_resist_stripes - l56 ptransistor_stripes - l57 hvpdiff_mask - l58 poly_resist - l59 subcircuit - l60 nwell - l61 pwell - l62 nwell - l63 polysilicon - l64 pwell - l65 implant1 - l66 implant2 - l67 implant3 - l68 implant4 - l69 subcircuit - l70 polysilicon - l71 electrode_stripes - l72 cwell + styletype mos + + NWELL nwell + NWELLTXT nwell + NWELLPIN nwell + PWELL pwell + PWELLTXT pwell + PWELLPIN pwell + PWELLRES pwell poly_resist_stripes + DNWELL cwell + TAP pdiffusion + DIFF ndiffusion + DIFFTXT ndiffusion + DIFFPIN ndiffusion + DIFFFILL ndiffusion + DIFFCUT ndiffusion + DIFFRES ndiffusion poly_resist_stripes + BOUND subcircuit + BOUND2 subcircuit + OUTLINE subcircuit + POLY polysilicon + POLYTXT polysilicon + POLYPIN polysilicon + POLYRES poly_resist poly_resist_stripes + POLYCUT polysilicon + POLYSHORT polysilicon + POLYFILL polysilicon + POLYGATE polysilicon + POLYMOD polysilicon + PSDM pdop_stripes + NSDM ndop_stripes + MCON contact_X'es + LI1 metal1 + LI1TXT metal1 + LI1PIN metal1 + LI1FILL metal1 + LI1RES metal1 poly_resist_stripes + LI1SHORT metal1 + LICON metal1 metal2 via1 + MET1 metal2 + MET1TXT metal2 + MET1PIN metal2 + MET1FILL metal2 + MET1RES metal2 poly_resist_stripes + MET1SHORT metal2 + VIA1 metal2 metal3 via2 + MET2 metal3 + MET2TXT metal3 + MET2PIN metal3 + MET2FILL metal3 + MET2RES metal3 poly_resist_stripes + MET2SHORT metal3 + VIA2 metal3 metal4 via3 + MET3 metal4 + MET3TXT metal4 + MET3PIN metal4 + MET3FILL metal4 + MET3RES metal4 poly_resist_stripes + MET3SHORT metal4 + CAPM mim_top + VIA3 metal4 metal5 via4 + MET4 metal5 + MET4TXT metal5 + MET4PIN metal5 + MET4FILL metal5 + MET4SHORT metal5 + MET4RES metal5 poly_resist_stripes + CAP2M mim_bottom + VIA4 metal5 metal6 via5 + MET5 metal6 + MET5TXT metal6 + MET5PIN metal6 + MET5FILL metal6 + MET5RES metal6 poly_resist_stripes + MET5SHORT metal6 + PAD overglass + PADTXT overglass + PADPIN overglass + THKOX implant1 + NPC implant2 + RPM implant3 + URPM implant3 + LVTN implant4 + LVTN implant1 + HVTP implant2 + TUNM implant3 + NCM implant4 + V5 subcircuit + V12 subcircuit + V20 subcircuit + HVTR implant1 + LDNTM implant2 + HVNTM implant3 + SUBCUT subcircuit + STDCELLID subcircuit + DIFFBLOCK poly_resist_stripes + POLYBLOCK poly_resist_stripes + LIBLOCK poly_resist_stripes + MET1BLOCK poly_resist_stripes + MET2BLOCK poly_resist_stripes + MET3BLOCK poly_resist_stripes + MET4BLOCK poly_resist_stripes + MET5BLOCK poly_resist_stripes + TEXT electrode + LVSTEXT electrode + COMMENT comment + ERROR error_waffle error_p error_waffle error_s error_waffle error_ps error_waffle end compose - paint MCON MET1 MCON - paint VIA1 MET2 VIA1 - paint VIA2 MET3 VIA2 - paint VIA3 MET4 VIA3 - paint VIA4 MET5 VIA4 - - paint MCON MET1P MCON - paint VIA1 MET2P VIA1 - paint VIA2 MET3P VIA2 - paint VIA3 MET4P VIA3 - paint VIA4 MET5P VIA4 - - paint MCON MET1T MCON - paint VIA1 MET2T VIA1 - paint VIA2 MET3T VIA2 - paint VIA3 MET4T VIA3 - paint VIA4 MET5T VIA4 end connect + # This is a very primitive connection table, and may not be useful. + # It does not correctly handle ReRAM or MiM caps. + DIFF MCON + TAP MCON + POLY MCON + MCON LI1 + LI1 LICON + LICON MET1 + MET1 VIA1 + VIA1 MET2 + MET2 VIA2 + VIA2 MET3 + MET3 VIA3 + VIA3 MET4 + MET4 VIA4 + VIA4 MET5 end cifoutput -style gdsii +style sky130 variants (),(altfill) scalefactor 10 nanometers options calma-permissive-labels gridlimit 1 - layer NWELL NWELL,NWELLT,NWELLP + layer NWELL ALLNWELL calma 64 20 - layer NWELLT - labels NWELLT noport + layer NWELLTXT + labels NWELLTXT noport calma 64 16 - layer NWELLP - labels NWELLP port + layer NWELLPIN + labels NWELLPIN port calma 64 5 + layer PWELL PWELL + labels PWELL + calma 81 53 + + layer PWELLTXT PWELLTXT + labels PWELLTXT noport + calma 122 16 + + layer PWELLPIN PWELLPIN + labels PWELLPIN port + calma 64 59 + layer DNWELL DNWELL labels DNWELL calma 64 18 @@ -262,21 +417,53 @@ labels DIFF calma 65 20 + layer DIFFTXT + labels DIFFTXT noport + calma 65 6 + + layer DIFFPIN + labels DIFFPIN noport + calma 65 16 + + layer DIFFRES DIFFRES + labels DIFFRES + calma 65 13 + + layer DIFFCUT DIFFCUT + labels DIFFCUT + calma 65 14 + layer TAP TAP labels TAP calma 65 44 - layer POLY POLY,POLYP,POLYT + layer POLY ALLPOLY calma 66 20 - layer POLYT - labels POLYT noport + layer POLYTTXT + labels POLYTXT noport calma 66 16 - layer POLYP - labels POLYP port + layer POLYPIN + labels POLYPIN port calma 66 5 + layer POLYCUT POLYCUT + labels POLYCUT + calma 66 14 + + layer POLYGATE POLYGATE + labels POLYGATE + calma 66 9 + + layer POLYMOD POLYMOD + labels POLYMOD + calma 66 83 + + layer POLYSHORT POLYSHORT + labels POLYSHORT + calma 66 15 + layer LVTN LVTN labels LVTN calma 125 44 @@ -285,8 +472,8 @@ labels HVTP calma 78 44 - layer HVI HVI - labels HVI + layer HVI THKOX + labels THKOX calma 75 20 layer TUNM TUNM @@ -297,6 +484,10 @@ labels NPC calma 95 20 + layer NCM NCM + labels NCM + calma 92 44 + layer PSDM PSDM labels PSDM calma 94 20 @@ -309,110 +500,121 @@ labels LICON1 calma 66 44 - # Note: LICON1 not on LI1 plane, may not be coincident with LI1. - layer LI1 LI1,LI1T,LI1P + layer LI1 ALLLI calma 67 20 - layer LI1T - labels LI1T noport + layer LI1TXT + labels LI1TXT noport calma 67 16 - layer LI1P - labels LI1P port + layer LI1PIN + labels LI1PIN port calma 67 5 - layer MET1 MET1,MET1T,MET1P,MCON + layer MET1 ALLM1 calma 68 20 - layer MET1T - labels MET1T noport + layer MET1TXT + labels MET1TXT noport calma 68 16 - layer MET1P - labels MET1P port + layer MET1PIN + labels MET1PIN port calma 68 5 layer MCON MCON labels MCON calma 67 44 - layer MET2 MET2,MET2T,MET2P,VIA1 + layer MET2 ALLM2 calma 69 20 - layer MET2T - labels MET2T noport + layer MET2TXT + labels MET2TXT noport calma 69 16 - layer MET2P - labels MET2P port + layer MET2PIN + labels MET2PIN port calma 69 5 layer VIA1 VIA1 labels VIA1 calma 68 44 +#ifdef RERAM +#undef RERAM layer RERAM RERAM labels RERAM calma 201 20 +#define RERAM 1 +#endif - layer MET3 MET3,MET3T,MET3P,VIA2 + layer MET3 ALLM3 calma 70 20 - layer MET3T - labels MET3T noport + layer MET3TXT + labels MET3TXT noport calma 70 16 - layer MET3P - labels MET3P port + layer MET3PIN + labels MET3PIN port calma 70 5 layer VIA2 VIA2 labels VIA2 calma 69 44 - layer MET4 MET4,MET4T,MET4P,VIA3 + layer CAPM CAPM + labels CAPM + calma 89 44 + + layer MET4 ALLM4 calma 71 20 - layer MET4T - labels MET4T noport + layer MET4TXT + labels MET4TXT noport calma 71 16 - layer MET4P - labels MET4P port + layer MET4PIN + labels MET4PIN port calma 71 5 layer VIA3 VIA3 labels VIA3 calma 70 44 - layer MET5 MET5,MET5T,MET5P,VIA4 + layer CAP2M CAP2M + labels CAP2M + calma 97 44 + + layer MET5 ALLM5 calma 72 20 - layer MET5T - labels MET5T noport + layer MET5TXT + labels MET5TXT noport calma 72 16 - layer MET5P - labels MET5P port + layer MET5PIN + labels MET5PIN port calma 72 5 layer VIA4 VIA4 labels VIA4 calma 71 44 - layer PAD PAD,PADT,PADP + layer PAD ALLPAD calma 76 20 - layer PADT - labels PADT noport + layer PADTXT + labels PADTXT noport calma 76 16 - layer PADP - labels PADP port + layer PADPIN + labels PADPIN port calma 76 5 - layer AREAID AREAID - labels AREAID + layer STDCELLID STDCELLID + labels STDCELLID calma 81 4 layer TEXT TEXT @@ -423,25 +625,13 @@ labels HVTR calma 18 20 - layer NCM NCM - labels NCM - calma 92 44 - layer RPM RPM labels RPM calma 86 20 - layer NSM NSM - labels NSM - calma 61 20 - - layer RDL RDL - labels RDL - calma 74 20 - - layer VHVI VHVI - labels VHVI - calma 74 21 + layer URPM URPM + labels URPM + calma 79 20 layer LDNTM LDNTM labels LDNTM @@ -451,14 +641,14 @@ labels HVNTM calma 125 20 - layer PMM PMM - labels PMM - calma 85 44 - layer PNP PNP labels PNP calma 82 44 + layer NPN NPN + labels NPN + calma 82 20 + layer CAP CAP labels CAP calma 82 64 @@ -467,37 +657,17 @@ labels IND calma 82 24 - layer PWRES PWRES - labels PWRES - calma 64 13 + layer LVID LVID + labels LVID + calma 81 60 - layer POLYRES POLYRES - labels POLYRES - calma 66 13 + layer CP1MADD CP1MADD + labels CP1MADD + calma 33 43 - layer DIFFRES DIFFRES - labels DIFFRES - calma 65 13 - - layer DIODE DIODE - labels DIODE - calma 81 23 - - layer POLYM POLYM - labels POLYM - calma 66 83 - - layer COREID COREID - labels COREID - calma 81 2 - - layer PWELLT PWELLT - labels PWELLT noport - calma 122 16 - - layer PWELLP PWELLP - labels PWELLP port - calma 64 59 + layer CP1MDROP CP1MDROP + labels CP1MDROP + calma 33 42 layer CFOMDROP CFOMDROP labels CFOMDROP @@ -507,99 +677,923 @@ labels CLI1MADD calma 115 43 + layer CLI1MDROP CLI1MDROP + labels CLI1MDROP + calma 115 42 + layer CNTMADD CNTMADD labels CNTMADD calma 22 21 - layer CP1MADD CP1MADD - labels CP1MADD - calma 33 43 + layer PWELLRES PWELLRES + labels PWELLRES + calma 64 13 + layer POLYRES POLYRES + labels POLYRES + calma 66 13 + + layer DIODE DIODE + labels DIODE + calma 81 23 + + layer COREID COREID + labels COREID + calma 81 2 + + # Is BOUND2 preferable here? layer BOUND BOUND labels BOUND calma 235 4 + layer BOUND2 BOUND2 + labels BOUND2 + calma 235 0 + + layer OUTLINE OUTLINE + labels OUTLINE + calma 236 0 + layer ESDID ESDID labels ESDID calma 81 19 + + layer UNKNOWN1 UNKNOWN1 + labels UNKNOWN1 + calma 230 241 + + layer UNKNOWN2 UNKNOWN2 + labels UNKNOWN2 + calma 230 242 + + layer UNKNOWN3 UNKNOWN3 + labels UNKNOWN3 + calma 64 44 + + variants () + + layer DIFFFILL DIFFFILL + labels DIFFFILL + calma 23 28 + + layer POLYFILL POLYFILL + labels POLYFILL + calma 28 28 + + layer LI1FILL LI1FILL + labels LI1FILL + calma 56 28 + + layer MET1FILL MET1FILL + labels MET1FILL + calma 36 28 + + layer MET2FILL MET2FILL + labels MET2FILL + calma 41 28 + + layer MET3FILL MET3FILL + labels MET3FILL + calma 34 28 + + layer MET4FILL MET4FILL + labels MET4FILL + calma 51 28 + + layer MET5FILL MET5FILL + labels MET5FILL + calma 59 28 + + variants (altfill) + + layer DIFFFILL DIFFFILL + labels DIFFFILL + calma 65 99 + + layer POLYFILL POLYFILL + labels POLYFILL + calma 66 99 + + layer LI1FILL LI1FILL + labels LI1FILL + calma 67 99 + + layer MET1FILL MET1FILL + labels MET1FILL + calma 68 99 + + layer MET2FILL MET2FILL + labels MET2FILL + calma 69 99 + + layer MET3FILL MET3FILL + labels MET3FILL + calma 70 99 + + layer MET4FILL MET4FILL + labels MET4FILL + calma 71 99 + + layer MET5FILL MET5FILL + labels MET5FILL + calma 72 99 + + variants * + + layer DIFFBLOCK DIFFBLOCK + labels DIFFBLOCK + calma 22 24 + + layer POLYBLOCK POLYBLOCK + labels POLYBLOCK + calma 33 24 + + layer MET1BLOCK MET1BLOCK + labels MET1BLOCK + calma 62 24 + + layer MET2BLOCK MET2BLOCK + labels MET2BLOCK + calma 105 52 + + layer MET3BLOCK MET3BLOCK + labels MET3BLOCK + calma 107 24 + + layer MET4BLOCK MET4BLOCK + labels MET4BLOCK + calma 112 4 + + layer MET5BLOCK MET5BLOCK + labels MET5BLOCK + calma 117 4 + + layer LISHORT LISHORT + labels LISHORT + calma 67 15 + + layer MET1SHORT MET1SHORT + labels MET1SHORT + calma 68 15 + + layer MET2SHORT MET2SHORT + labels MET2SHORT + calma 69 15 + + layer MET3SHORT MET3SHORT + labels MET3SHORT + calma 70 15 + + layer MET4SHORT MET4SHORT + labels MET4SHORT + calma 71 15 + + layer MET5SHORT MET5SHORT + labels MET5SHORT + calma 72 15 + + layer MET1RES MET1RES + labels MET1RES + calma 68 13 + + layer MET2RES MET2RES + labels MET2RES + calma 69 13 + + layer MET3RES MET3RES + labels MET3RES + calma 70 13 + + layer MET4RES MET4RES + labels MET4RES + calma 71 13 + + layer MET5RES MET5RES + labels MET5RES + calma 72 13 + +#---------------------------------------------------------------- +style wafflefill variants (),(tiled) +#---------------------------------------------------------------- +# Style used by scripts for automatically generating fill layers +# NOTE: Be sure to generate output on flattened layout. +#---------------------------------------------------------------- + scalefactor 10 nanometers + options calma-permissive-labels + gridlimit 5 + +#---------------------------------------------------------------- +# 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. +#---------------------------------------------------------------- + + 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 +# Spacing from LV nwell = Diff/Tap 9 = 0.34um +# Spacing from HV nwell = Diff/Tap 18 = 0.43um (= 0.18 + 0.25) +# Enclosure by nwell = Diff/Tap 8 = 0.18um +#---------------------------------------------------------------- + + templayer alldiffmv ALLDIFF + and THKOX + + templayer mvnwell + bloat-all alldiffmv ALLNWELL + + templayer lvnwell ALLNWELL + and-not mvnwell + + templayer well_shrink mvnwell + shrink 250 + or lvnwell + shrink 180 + + templayer well_guardband ALLNWELL + grow 340 + and-not well_shrink + +# Generate guard-band around THKOX edge to keep FOM from crossing +# spacing from THKOX to diff 0.18um + + templayer hvi_shrink THKOX + shrink 180 + + templayer hvi_guardband THKOX + grow 180 + and-not hvi_shrink + +#--------------------------------------------------- +# Diffusion and poly keep-out areas +#--------------------------------------------------- + templayer obstruct_fom ALLDIFF,ALLPOLY,DIFFFILL,POLYFILL,DIFFBLOCK,POLYBLOCK + or PWELLRES,PNP,NPN + grow 500 + or well_guardband,hvi_guardband,NSDM,PSDM + + templayer obstruct_poly ALLDIFF,ALLPOLY,DIFFFILL,POLYFILL,DIFFBLOCK,POLYBLOCK + or PWELLRES,PNP,NPN + grow 1000 + or NSDM,PSDM + +#--------------------------------------------------- +# FOM and POLY fill +#--------------------------------------------------- + templayer fomfill_pass1 topbox + slots 0 4080 1600 0 4080 1600 1360 0 + and-not obstruct_fom + and topbox + orthogonal remove + shrink 2035 + grow 2035 + +#--------------------------------------------------- + + templayer obstruct_poly_pass1 fomfill_pass1 + grow 300 + or obstruct_poly + templayer polyfill_pass1 topbox + slots 0 720 360 0 720 360 240 0 + and-not obstruct_poly_pass1 + and topbox + orthogonal remove + shrink 355 + grow 355 + +#--------------------------------------------------- + + templayer obstruct_fom_pass2 fomfill_pass1 + grow 1290 + or polyfill_pass1 + grow 300 + or obstruct_fom + templayer fomfill_pass2 topbox + slots 0 2500 1320 0 2500 1320 1360 0 + and-not obstruct_fom_pass2 + and topbox + orthogonal remove + shrink 1245 + grow 1245 + +#--------------------------------------------------- + + templayer obstruct_poly_coarse polyfill_pass1 + grow 60 + or fomfill_pass1,fomfill_pass2 + grow 300 + or obstruct_poly + templayer polyfill_coarse topbox + slots 0 720 360 0 720 360 240 120 + and-not obstruct_poly_coarse + and topbox + orthogonal remove + shrink 355 + grow 355 + +#--------------------------------------------------- + templayer obstruct_poly_medium polyfill_pass1,polyfill_coarse + grow 60 + or fomfill_pass1,fomfill_pass2 + grow 300 + or obstruct_poly + templayer polyfill_medium topbox + slots 0 540 360 0 540 360 240 100 + and-not obstruct_poly_medium + and topbox + orthogonal remove + shrink 265 + grow 265 + +#--------------------------------------------------- + templayer obstruct_poly_fine polyfill_pass1,polyfill_coarse,polyfill_medium + grow 60 + or fomfill_pass1,fomfill_pass2 + grow 300 + or obstruct_poly + templayer polyfill_fine topbox + slots 0 480 360 0 480 360 240 200 + and-not obstruct_poly_fine + and topbox + orthogonal remove + shrink 235 + grow 235 + +#--------------------------------------------------- + + templayer obstruct_fom_coarse fomfill_pass1,fomfill_pass2 + grow 1290 + or polyfill_pass1,polyfill_coarse,polyfill_medium,polyfill_fine + grow 300 + or obstruct_fom + templayer fomfill_coarse topbox + slots 0 1500 1320 0 1500 1320 1360 0 + and-not obstruct_fom_coarse + and topbox + orthogonal remove + shrink 745 + grow 745 + +#--------------------------------------------------- + + templayer obstruct_fom_fine fomfill_pass1,fomfill_pass2,fomfill_coarse + grow 1290 + or polyfill_pass1,polyfill_coarse,polyfill_medium,polyfill_fine + grow 300 + or obstruct_fom + templayer fomfill_fine topbox + slots 0 500 400 0 500 400 160 0 + and-not obstruct_fom_fine + and topbox + orthogonal remove + shrink 245 + grow 245 + +#--------------------------------------------------- + layer FOMFILL fomfill_pass1 + or fomfill_pass2 + or fomfill_coarse + or fomfill_fine + # calma 23 28 + calma 65 99 + + layer POLYFILL polyfill_pass1 + or polyfill_coarse + or polyfill_medium + or polyfill_fine + # calma 28 28 + calma 66 99 + +#--------------------------------------------------------- +# LI fill +# Note requirement that LI fill may not overlap (non-fill) +# diff or poly. +# +# Important note: sky130 does not define an LI mask fill +# blockage layer, because LI fill requirements were added +# to the process after the open PDK was made. While +# obstruction layers can be used in magic to block LI +# fill, this does not translate into GDS, so running fill +# on a GDS top level cell will result in LI fill shapes +# being placed in the corner and under the seal ring. To +# work around this, I have added obsm1 to the layers that +# obstruct LI, which is a bit of a hack but should not +# cause issues in practice. +#--------------------------------------------------------- + + templayer obstruct_li_coarse ALLLI,LI1FILL,LIBLOCK + grow 2800 + or ALLDIFF,ALLPOLY + grow 200 + or MET1BLOCK + templayer lifill_coarse topbox + # slots 0 3000 650 0 3000 650 700 0 + slots 0 3000 900 0 3000 900 700 0 + and-not obstruct_li_coarse + and topbox + orthogonal remove + shrink 1495 + grow 1495 + + templayer obstruct_li_medium ALLLI,LI1FILL,LIBLOCK + grow 2500 + or lifill_coarse + grow 300 + or ALLDIFF,ALLPOLY + grow 200 + or MET1BLOCK + templayer lifill_medium topbox + slots 0 1500 500 0 1500 500 700 0 + and-not obstruct_li_medium + and topbox + orthogonal remove + shrink 745 + grow 745 + + templayer obstruct_li_fine ALLLI,LI1FILL,LIBLOCK + or lifill_coarse,lifill_medium + grow 300 + or ALLDIFF,ALLPOLY + grow 200 + or MET1BLOCK + templayer lifill_fine topbox + slots 0 580 500 0 580 500 700 0 + and-not obstruct_li_fine + and topbox + orthogonal remove + shrink 285 + grow 285 + + layer LIFILL lifill_coarse + or lifill_medium + or lifill_fine + # calma 56 28 + calma 67 99 + +#--------------------------------------------------- +# MET1 fill +#--------------------------------------------------- + + templayer obstruct_m1_coarse ALLM1,PAD,MET1FILL,MET1BLOCK + grow 3000 + templayer met1fill_coarse topbox + # slots 0 2000 200 0 2000 200 700 0 + slots 0 2000 800 0 2000 800 700 350 + and-not obstruct_m1_coarse + and topbox + orthogonal remove + shrink 995 + grow 995 + + templayer obstruct_m1_medium ALLM1,PAD,MET1FILL,MET1BLOCK + grow 2800 + or met1fill_coarse + grow 200 + templayer met1fill_medium topbox + slots 0 1000 200 0 1000 200 700 0 + and-not obstruct_m1_medium + and topbox + orthogonal remove + shrink 495 + grow 495 + + templayer obstruct_m1_fine ALLM1,PAD,MET1FILL,MET1BLOCK + grow 300 + or met1fill_coarse,met1fill_medium + grow 200 + templayer met1fill_fine topbox + slots 0 580 200 0 580 200 700 0 + and-not obstruct_m1_fine + and topbox + orthogonal remove + shrink 285 + grow 285 + + templayer obstruct_m1_veryfine ALLM1,PAD,MET1FILL,MET1BLOCK + grow 100 + or met1fill_coarse,met1fill_medium,met1fill_fine + grow 200 + templayer met1fill_veryfine topbox + slots 0 300 200 0 300 200 100 50 + and-not obstruct_m1_veryfine + and topbox + orthogonal remove + shrink 145 + grow 145 + + layer MET1FILL met1fill_coarse + or met1fill_medium + or met1fill_fine + or met1fill_veryfine + # calma 36 28 + calma 68 99 + +#--------------------------------------------------- +# MET2 fill +#--------------------------------------------------- + templayer obstruct_m2 ALLM2,PAD,MET2FILL,MET2BLOCK + grow 3000 + templayer met2fill_coarse topbox + # slots 0 2000 200 0 2000 200 700 350 + slots 0 2000 800 0 2000 800 700 350 + and-not obstruct_m2 + and topbox + orthogonal remove + shrink 995 + grow 995 + + templayer obstruct_m2_medium ALLM2,PAD,MET2FILL,MET2BLOCK + grow 2800 + or met2fill_coarse + grow 200 + templayer met2fill_medium topbox + slots 0 1000 200 0 1000 200 700 350 + and-not obstruct_m2_medium + and topbox + orthogonal remove + shrink 495 + grow 495 + + templayer obstruct_m2_fine ALLM2,PAD,MET2FILL,MET2BLOCK + grow 300 + or met2fill_coarse,met2fill_medium + grow 200 + templayer met2fill_fine topbox + slots 0 580 200 0 580 200 700 350 + and-not obstruct_m2_fine + and topbox + orthogonal remove + shrink 285 + grow 285 + + templayer obstruct_m2_veryfine ALLM2,PAD,MET2FILL,MET2BLOCK + grow 100 + or met2fill_coarse,met2fill_medium,met2fill_fine + grow 200 + templayer met2fill_veryfine topbox + slots 0 300 200 0 300 200 100 100 + and-not obstruct_m2_veryfine + and topbox + orthogonal remove + shrink 145 + grow 145 + + layer MET2FILL met2fill_coarse + or met2fill_medium + or met2fill_fine + or met2fill_veryfine + # calma 41 28 + calma 69 99 + +#--------------------------------------------------- +# MET3 fill +#--------------------------------------------------- + templayer obstruct_m3 ALLM3,PAD,MET3FILL,MET3BLOCK + grow 3000 + templayer met3fill_coarse topbox + # slots 0 2000 300 0 2000 300 700 700 + slots 0 2000 800 0 2000 800 700 350 + and-not obstruct_m3 + and topbox + orthogonal remove + shrink 995 + grow 995 + + templayer obstruct_m3_medium ALLM3,PAD,MET3FILL,MET3BLOCK + grow 2700 + or met3fill_coarse + grow 300 + templayer met3fill_medium topbox + slots 0 1000 300 0 1000 300 700 700 + and-not obstruct_m3_medium + and topbox + orthogonal remove + shrink 495 + grow 495 + + templayer obstruct_m3_fine CAPM + grow 840 + or ALLM3,PAD,MET3FILL,MET3BLOCK + grow 200 + or met3fill_coarse,met3fill_medium + grow 300 + templayer met3fill_fine topbox + slots 0 580 300 0 580 300 700 700 + and-not obstruct_m3_fine + and topbox + orthogonal remove + shrink 285 + grow 285 + + templayer obstruct_m3_veryfine CAPM + grow 940 + or ALLM3,PAD,MET3FILL,MET3BLOCK + # Note: Adding 0.1 to waffle rule to clear wide spacing rule + grow 100 + or met3fill_coarse,met3fill_medium,met3fill_fine + grow 300 + templayer met3fill_veryfine topbox + slots 0 500 300 0 500 300 150 200 + and-not obstruct_m3_veryfine + and topbox + orthogonal remove + shrink 245 + grow 245 + + layer MET3FILL met3fill_coarse + or met3fill_medium + or met3fill_fine + or met3fill_veryfine + # calma 34 28 + calma 70 99 + +#--------------------------------------------------- +# MET4 fill +#--------------------------------------------------- + templayer obstruct_m4 PAD + grow 2500 + or ALLM4,MET4FILL,MET4BLOCK + grow 3000 + templayer met4fill_coarse topbox + # slots 0 2000 300 0 2000 300 700 1050 + slots 0 2000 800 0 2000 800 700 350 + and-not obstruct_m4 + and topbox + orthogonal remove + shrink 995 + grow 995 + + templayer obstruct_m4_medium PAD + grow 2500 + or ALLM4,MET4FILL,MET4BLOCK + grow 2700 + or met4fill_coarse + grow 300 + templayer met4fill_medium topbox + slots 0 1000 300 0 1000 300 700 1050 + and-not obstruct_m4_medium + and topbox + orthogonal remove + shrink 495 + grow 495 + + templayer obstruct_m4_fine PAD + grow 4160 + or CAPM2 + grow 840 + or ALLM4,MET4FILL,MET4BLOCK + grow 200 + or met4fill_coarse,met4fill_medium + grow 300 + templayer met4fill_fine topbox + slots 0 580 300 0 580 300 700 1050 + and-not obstruct_m4_fine + and topbox + orthogonal remove + shrink 285 + grow 285 + + templayer obstruct_m4_veryfine PAD + grow 4160 + or CAPM2 + grow 940 + or ALLM4,MET4FILL,MET4BLOCK + # Note: Adding 0.1 to waffle rule to clear wide spacing rule + grow 100 + or met4fill_coarse,met4fill_medium,met4fill_fine + grow 300 + templayer met4fill_veryfine topbox + slots 0 500 300 0 500 300 150 300 + and-not obstruct_m4_veryfine + and topbox + orthogonal remove + shrink 245 + grow 245 + + layer MET4FILL met4fill_coarse + or met4fill_medium + or met4fill_fine + or met4fill_veryfine + # calma 51 28 + calma 71 99 + +#--------------------------------------------------- +# MET5 fill +#--------------------------------------------------- + templayer obstruct_m5 ALLM5,PAD,MET5FILL,MET5BLOCK + grow 3000 + templayer met5fill_coarse topbox + slots 0 5000 1600 0 5000 1600 1000 100 + and-not obstruct_m5 + and topbox + orthogonal remove + shrink 2495 + grow 2495 + + templayer obstruct_m5_medium ALLM5,PAD,MET5FILL,MET5BLOCK + grow 1400 + or met5fill_coarse + grow 1600 + templayer met5fill_medium topbox + slots 0 3000 1600 0 3000 1600 1000 100 + and-not obstruct_m5_medium + and topbox + orthogonal remove + shrink 1495 + grow 1495 + + layer MET5FILL met5fill_coarse + or met5fill_medium + # calma 59 28 + calma 72 99 end cifinput -style default +style sky130 scalefactor 10 nanometers - layer l1 NWELL - layer l2 DNWELL - layer l3 DIFF - layer l4 TAP - layer l5 LVTN - layer l6 HVTP - layer l7 HVI - layer l8 TUNM - layer l9 POLY - layer l10 NPC - layer l11 PSDM - layer l12 NSDM - layer l13 LICON1 - layer l14 LI1 - layer l15 LI1T - layer l16 LI1P - layer l17 MCON - layer l18 MET1 - layer l19 MET1T - layer l20 MET1P - layer l21 VIA1 - layer l22 MET2 - layer l23 MET2T - layer l24 MET2P - layer l25 VIA2 - layer l26 MET3 - layer l27 MET3T - layer l28 MET3P - layer l29 VIA3 - layer l30 MET4 - layer l31 MET4T - layer l32 MET4P - layer l33 VIA4 - layer l34 MET5 - layer l35 MET5T - layer l36 MET5P - layer l37 PAD - layer l38 PADT - layer l39 PADP - layer l40 AREAID - layer l41 TEXT - layer l42 HVTR - layer l43 NCM - layer l44 RPM - layer l45 NSM - layer l46 RDL - layer l47 VHVI - layer l48 LDNTM - layer l49 HVNTM - layer l50 PMM - layer l51 PNP - layer l52 CAP - layer l53 IND - layer l54 PWRES - layer l55 POLYRES - layer l56 DIFFRES - layer l57 DIODE - layer l58 POLYM - layer l59 COREID - layer l60 NWELLT - layer l61 PWELLT - layer l62 NWELLP - layer l63 POLYP - layer l64 PWELLP - layer l65 CFOMDROP - layer l66 CLI1MADD - layer l67 CNTMADD - layer l68 CP1MADD - layer l69 BOUND - layer l70 POLYT - layer l71 RERAM - layer l72 ESDID + layer DNWELL DNWELL + + layer NWELL NWELL,NWELLTXT,NWELLPIN + labels NWELL + labels NWELLPIN port + labels NWELLTXT text + + layer PWELL PWELL,PWELLTXT,PWELLPIN + labels PWELL + labels PWELLPIN port + labels PWELLTXT text + + layer LVTN LVTN + layer HVTP HVTP + layer THKOX HVI + layer TUNM TUNM + + layer DIFF DIFF,TAP,DIFFTXT,DIFFPIN + labels DIFF + labels DIFFPIN port + labels DIFFTXT text + + layer DIFFCUT DIFFCUT + layer DIFFRES DIFFRES + layer DIFFFILL DIFFFILL,ALTDIFFFILL + layer DIFFBLOCK DIFFBLOCK + + layer POLY POLY,POLYTXT,POLYPIN + labels POLY + labels POLYPIN port + labels POLYTXT text + + layer POLYMOD POLYMOD + layer POLYRES POLYRES + layer POLYCUT POLYCUT + layer POLYGATE POLYGATE + layer POLYFILL POLYFILL,ALTPOLYFILL + layer POLYBLOCK POLYBLOCK + layer POLYSHORT POLYSHORT + + layer NPC NPC + layer NCM NCM + layer PSDM PSDM + layer NSDM NSDM + + layer LICON LICON1 + + layer LI1 LI1,LI1TXT,LI1PIN + labels LI1 + labels LI1PIN port + labels LI1TXT text + + layer LI1RES LI1RES + layer LI1FILL LI1FILL,ALTLI1FILL + layer LIBLOCK LIBLOCK + layer LISHORT LISHORT + + layer MCON MCON + + layer MET1 MET1,MET1TXT,MET1PIN + labels MET1 + labels MET1PIN port + labels MET1TXT text + + layer MET1RES MET1RES + layer MET1FILL MET1FILL,ALTMET1FILL + layer MET1BLOCK MET1BLOCK + layer MET1SHORT MET1SHORT + + layer VIA1 VIA1 + + layer MET2 MET2,MET2TXT,MET2PIN + labels MET2 + labels MET2PIN port + labels MET2TXT text + + layer MET2RES MET2RES + layer MET2FILL MET2FILL,ALTMET2FILL + layer MET2BLOCK MET2BLOCK + layer MET2SHORT MET2SHORT + + layer VIA2 VIA2 + + layer MET3 MET3,MET3TXT,MET3PIN + labels MET3 + labels MET3PIN port + labels MET3TXT text + + layer MET3RES MET3RES + layer MET3FILL MET3FILL,ALTMET3FILL + layer MET3BLOCK MET3BLOCK + layer MET3SHORT MET3SHORT + + layer VIA3 VIA3 + + layer MET4 MET4,MET4TXT,MET4PIN + labels MET4 + labels MET4PIN port + labels MET4TXT text + + layer MET4RES MET4RES + layer MET4FILL MET4FILL,ALTMET4FILL + layer MET4BLOCK MET4BLOCK + layer MET4SHORT MET4SHORT + + layer VIA4 VIA4 + + layer MET5 MET5,MET5TXT,MET5PIN + labels MET5 + labels MET5PIN port + labels MET5TXT text + + layer MET5RES MET5RES + layer MET5FILL MET5FILL,ALTMET5FILL + layer MET5BLOCK MET5BLOCK + layer MET5SHORT MET5SHORT + + layer PAD PAD,PADTXT,PADPIN + labels PAD + labels PADPIN port + labels PADTXT text + + layer STDCELLID STDCELLID + layer COREID COREID + layer TEXT TEXT + layer HVTR HVTR + layer RPM RPM + layer URPM URPM + layer LDNTM LDNTM + layer HVNTM HVNTM + layer PNP PNP + layer NPN NPN + layer CAP CAP + layer LVID LVID + layer IND IND + layer ESD ESDID + layer DIODE DIODE + layer BOUND BOUND + layer BOUND2 BOUND2 + layer OUTLINE OUTLINE +#ifdef RERAM +#undef RERAM + layer RERAM RERAM +#define RERAM 1 +#endif + layer CAPM CAPM + layer CAP2M CAP2M + layer PWELLRES PWELLRES + layer LOWTAPDENSITY LOWTAPDENSITY + layer PADDIFFID PADDIFFID + layer PADMETALID PADMETALID + layer PADCENTERID PADCENTERID + layer CP1MADD CP1MADD + layer CP1MDROP CP1MDROP + layer CNTMADD CNTMADD + layer CLI1MADD CLI1MADD + layer CLI1MDROP CLI1MDROP + layer CFOMDROP CFOMDROP + layer UNKNOWN1 UNKNOWN1 + layer UNKNOWN2 UNKNOWN2 + layer UNKNOWN3 UNKNOWN3 + calma NWELL 64 20 + calma PWELL 81 53 calma DNWELL 64 18 calma DIFF 65 20 calma TAP 65 44 @@ -609,68 +1603,125 @@ calma TUNM 80 20 calma POLY 66 20 calma NPC 95 20 + calma NCM 92 44 calma PSDM 94 20 calma NSDM 93 44 calma LICON1 66 44 calma LI1 67 20 - calma LI1T 67 16 - calma LI1P 67 5 + calma LI1TXT 67 16 + calma LI1PIN 67 5 calma MCON 67 44 calma MET1 68 20 - calma MET1T 68 16 - calma MET1P 68 5 + calma MET1TXT 68 16 + calma MET1PIN 68 5 calma VIA1 68 44 +#ifdef RERAM +#undef RERAM + calma RERAM 201 20 +#define RERAM 1 +#endif calma MET2 69 20 - calma MET2T 69 16 - calma MET2P 69 5 + calma MET2TXT 69 16 + calma MET2PIN 69 5 calma VIA2 69 44 calma MET3 70 20 - calma MET3T 70 16 - calma MET3P 70 5 + calma MET3TXT 70 16 + calma MET3PIN 70 5 + calma CAPM 89 44 calma VIA3 70 44 calma MET4 71 20 - calma MET4T 71 16 - calma MET4P 71 5 + calma MET4TXT 71 16 + calma MET4PIN 71 5 + calma CAP2M 97 44 calma VIA4 71 44 calma MET5 72 20 - calma MET5T 72 16 - calma MET5P 72 5 + calma MET5TXT 72 16 + calma MET5PIN 72 5 calma PAD 76 20 - calma PADT 76 16 - calma PADP 76 5 - calma AREAID 81 4 + calma PADTXT 76 16 + calma PADPIN 76 5 + calma STDCELLID 81 4 calma TEXT 83 44 calma HVTR 18 20 - calma NCM 92 44 calma RPM 86 20 - calma NSM 61 20 - calma RDL 74 20 - calma VHVI 74 21 + calma URPM 79 20 calma LDNTM 11 44 calma HVNTM 125 20 - calma PMM 85 44 calma PNP 82 44 + calma NPN 82 20 calma CAP 82 64 + calma LVID 81 60 calma IND 82 24 - calma PWRES 64 13 + calma LOWTAPDENSITY 81 14 + calma PWELLRES 64 13 calma POLYRES 66 13 + calma POLYGATE 66 9 + calma POLYCUT 66 14 calma DIFFRES 65 13 + calma DIFFCUT 65 14 calma DIODE 81 23 - calma POLYM 66 83 + calma POLYMOD 66 83 calma COREID 81 2 - calma NWELLT 64 16 - calma PWELLT 122 16 - calma NWELLP 64 5 - calma POLYP 66 5 - calma PWELLP 64 59 - calma CFOMDROP 22 22 + calma PADDIFFID 81 6 + calma PADMETALID 81 8 + calma PADCENTERID 81 20 + calma CP1MADD 33 43 + calma CP1MDROP 33 42 + calma CNTMADD 22 21 calma CLI1MADD 115 43 - calma CNTMADD 22 21 - calma CP1MADD 33 43 + calma CLI1MDROP 115 42 + calma CFOMDROP 22 22 + calma UNKNOWN1 230 241 + calma UNKNOWN2 230 242 + calma UNKNOWN3 64 44 + calma NWELLTXT 64 16 + calma PWELLTXT 122 16 + calma NWELLPIN 64 5 + calma POLYTXT 66 16 + calma POLYPIN 66 5 + calma PWELLPIN 64 59 calma BOUND 235 4 - calma POLYT 66 16 - calma RERAM 201 20 + calma BOUND2 235 0 + calma OUTLINE 236 0 calma ESDID 81 19 + calma DIFFBLOCK 22 24 + calma POLYBLOCK 33 24 + calma LIBLOCK 67 10 + calma MET1BLOCK 62 24 + calma MET2BLOCK 105 52 + calma MET3BLOCK 107 24 + calma MET4BLOCK 112 4 + calma MET5BLOCK 117 4 + calma DIFFFILL 23 28 + calma POLYFILL 28 28 + calma LI1FILL 56 28 + calma MET1FILL 36 28 + calma MET2FILL 41 28 + calma MET3FILL 34 28 + calma MET4FILL 51 28 + calma MET5FILL 59 28 + calma POLYSHORT 66 15 + calma LISHORT 67 15 + calma MET1SHORT 68 15 + calma MET2SHORT 69 15 + calma MET3SHORT 70 15 + calma MET4SHORT 71 15 + calma MET5SHORT 72 15 + calma LI1RES 67 13 + calma MET1RES 68 13 + calma MET2RES 69 13 + calma MET3RES 70 13 + calma MET4RES 71 13 + calma MET5RES 72 13 + calma ALTDIFFFILL 65 99 + calma ALTPOLYFILL 66 99 + calma ALTLI1FILL 67 99 + calma ALTMET1FILL 68 99 + calma ALTMET2FILL 69 99 + calma ALTMET3FILL 70 99 + calma ALTMET4FILL 71 99 + calma ALTMET5FILL 72 99 + end mzrouter @@ -700,13 +1751,13 @@ angles HVTP 45 "Only 45 degree angles allowed on HVTP (X.3)" off_grid HVTP 5 "HVTP shape not on %d grid (X.1b)" - # HVI rules + # THKOX rules - width HVI 600 "HVI width < %d (HVI.1)" - spacing HVI HVI 700 touching_ok "HVI to HVI spacing < %d (HVI.2)" - spacing HVI NWELL 700 surround_ok "HVI to NWELL spacint < %d (HVI.5)" - no_overlap HVI TUNM - off_grid HVI 5 "HVI shape not on %d grid (X.1b)" + width THKOX 600 "HVI width < %d (HVI.1)" + spacing THKOX THKOX 700 touching_ok "THKOX to THKOX spacing < %d (HVI.2)" + spacing THKOX NWELL 700 surround_ok "THKOX to NWELL spacint < %d (HVI.5)" + no_overlap THKOX TUNM + off_grid THKOX 5 "THKOX shape not on %d grid (X.1b)" # NSDM rules @@ -726,48 +1777,85 @@ extract style default - planeorder p1 0 - planeorder p2 1 - planeorder p3 2 - planeorder p4 3 - planeorder p5 4 - planeorder p6 5 - planeorder p7 6 - planeorder p8 7 - planeorder p9 8 - planeorder p10 9 - planeorder p11 10 - planeorder p12 11 - planeorder p13 12 - planeorder p14 13 - planeorder p15 14 - planeorder p16 15 - planeorder p17 16 - planeorder p18 17 - planeorder p19 18 - planeorder p20 19 - planeorder p21 20 - planeorder p22 21 - planeorder p23 22 - planeorder p24 23 - planeorder p25 24 - planeorder p26 25 - planeorder p27 26 - planeorder p28 27 - planeorder p29 28 - planeorder p30 29 - planeorder p31 30 - planeorder p32 31 - planeorder p33 32 - planeorder p34 33 - planeorder p35 34 - planeorder p36 35 - planeorder p37 36 - planeorder p38 37 - planeorder p39 38 - planeorder p40 39 - planeorder p41 40 - planeorder p42 41 - planeorder p43 42 - planeorder p44 43 + planeorder dw 0 + planeorder w 1 + planeorder i1 2 + planeorder i2 3 + planeorder i3 4 + planeorder i4 5 + planeorder i5 6 + planeorder i6 7 + planeorder i7 8 + planeorder i8 9 + planeorder a 10 + planeorder p 11 + planeorder mc 12 + planeorder li 13 + planeorder lc 14 +#ifdef RERAM + planeorder rr 15 + planeorder m1 16 + planeorder v1 17 + planeorder m2 18 + planeorder v2 19 + planeorder m3 20 + planeorder c1 21 + planeorder v3 22 + planeorder m4 23 + planeorder c2 24 + planeorder v4 25 + planeorder m5 26 + planeorder g 27 + planeorder bd 28 + planeorder bp 29 + planeorder bl 30 + planeorder b1 31 + planeorder b2 32 + planeorder b3 33 + planeorder b4 34 + planeorder b5 35 + planeorder id1 36 + planeorder id2 37 + planeorder id3 38 + planeorder id4 39 + planeorder id5 40 + planeorder id6 41 + planeorder id7 42 + planeorder id8 43 + planeorder id9 44 + planeorder c 45 + planeorder e 46 +#else + planeorder m1 15 + planeorder v1 16 + planeorder m2 17 + planeorder v2 18 + planeorder m3 19 + planeorder c1 20 + planeorder v3 21 + planeorder m4 22 + planeorder c2 23 + planeorder v4 24 + planeorder m5 25 + planeorder g 26 + planeorder bd 27 + planeorder bp 28 + planeorder bl 29 + planeorder b1 30 + planeorder b2 31 + planeorder b3 32 + planeorder b4 33 + planeorder b5 34 + planeorder id1 35 + planeorder id2 36 + planeorder id3 37 + planeorder id4 38 + planeorder id5 39 + planeorder id6 40 + planeorder id7 41 + planeorder id8 42 + planeorder id9 43 + planeorder c 44 + planeorder e 45 +#endif end