Initial commit of public repository open_pdks.
diff --git a/sky130/custom/scripts/fixspice.py b/sky130/custom/scripts/fixspice.py
new file mode 100755
index 0000000..92cca88
--- /dev/null
+++ b/sky130/custom/scripts/fixspice.py
@@ -0,0 +1,96 @@
+#!/bin/env python3
+#
+# fixspice ---
+#
+# This script fixes problems in the SkyWater SPICE models.  This should be
+# made obsolete by the forthcoming set of models from the foundry, but the
+# script will get the original set working with ngspice.
+#
+# This script is a filter to be run by setting the name of this script as
+# the value to "filter=" for the model install in the s8 Makefile.
+
+import re
+import os
+import sys
+
+def filter(inname, outname):
+
+    # Read input
+    try:
+        with open(inname, 'r') as inFile:
+            spitext = inFile.read()
+            # (Don't) unwrap continuation lines
+            # spilines = spitext.replace('\n+', ' ').splitlines()
+            spilines = spitext.splitlines()
+    except:
+        print('fixspice.py: failed to open ' + fnmIn + ' for reading.', file=sys.stderr)
+        return 1
+
+    # Process input with regexp
+
+    fixedlines = []
+    modified = False
+
+    for line in spilines:
+
+        # Fix 1:  ngspice does not understand the syntax used for the dev/gauss lines,
+        #  so remove them.
+        fixedline = re.sub('dev/gauss[ \t]*=.*$', '', line)
+
+        # Fix 2: Remove references to *_dlc_rotweak
+        # fixedline = re.sub('\+[ \t]*[^ \t_]+_dlc_rotweak', '', fixedline)
+
+        # Fix 2: Remove references to *_[a,p]junction_mult
+        # fixedline = re.sub('\*[ \t]*[^ \t_]+_[ap]junction_mult', '', fixedline)
+
+        fixedlines.append(fixedline)
+        if fixedline != line:
+            modified = True
+
+    # Write output
+    if outname == None:
+        for i in fixedlines:
+            print(i)
+    else:
+        # If the output is a symbolic link but no modifications have been made,
+        # then leave it alone.  If it was modified, then remove the symbolic
+        # link before writing.
+        if os.path.islink(outname):
+            if not modified:
+                return 0
+            else:
+                os.unlink(outname)
+        try:
+            with open(outname, 'w') as outFile:
+                for i in fixedlines:
+                    print(i, file=outFile)
+        except:
+            print('fixspice.py: failed to open ' + outname + ' for writing.', file=sys.stderr)
+            return 1
+
+
+if __name__ == '__main__':
+
+    # This script expects to get one or two arguments.  One argument is
+    # mandatory and is the input file.  The other argument is optional and
+    # is the output file.  The output file and input file may be the same
+    # name, in which case the original input is overwritten.
+
+    options = []
+    arguments = []
+    for item in sys.argv[1:]:
+        if item.find('-', 0) == 0:
+            options.append(item[1:])
+        else:
+            arguments.append(item)
+
+    if len(arguments) > 0:
+        infilename = arguments[0]
+
+    if len(arguments) > 1:
+        outfilename = arguments[1]
+    else:
+        outfilename = None
+
+    result = filter(infilename, outfilename)
+    sys.exit(result)
diff --git a/sky130/custom/scripts/seal_ring_generator/.magicrc b/sky130/custom/scripts/seal_ring_generator/.magicrc
new file mode 100644
index 0000000..2a18665
--- /dev/null
+++ b/sky130/custom/scripts/seal_ring_generator/.magicrc
@@ -0,0 +1,3 @@
+scalegrid 1 10
+tech load s8seal_ring.tech
+drc off
diff --git a/sky130/custom/scripts/seal_ring_generator/README b/sky130/custom/scripts/seal_ring_generator/README
new file mode 100644
index 0000000..af48894
--- /dev/null
+++ b/sky130/custom/scripts/seal_ring_generator/README
@@ -0,0 +1,37 @@
+# This directory contains a seal ring generator for SkyWater s8 using magic.
+# Because the seal ring contains many layers that do not appear in standard
+# layout editing, they are all specially implemented in the s8seal_ring.tech
+# file in this directory.
+#
+# An example seal ring was generated by SkyWater and imported using magic's
+# gdsquery.sh script.  It was then hand-edited to contain only the bottom
+# quarter.  Then it was saved in .mag databases.
+#
+# The generator script s8_gen_sealring.py calls magic using the s8seal_ring.tech
+# file, and automatically modifies the geometry to stretch to the half width
+# and height of the specified dimensions.  Then the lower-left cells are
+# copied and folded over the centerline to make the complete seal ring.
+# The seal ring is then written out in GDS format.  Then a simplified magic
+# view is generated in the usual user-facing s8 technology file, with the
+# GDS_FILE property pointing to the seal ring GDS.  This layout and GDS can
+# then be imported into a layout.
+#
+# Usage:
+#
+#   s8_gen_sealring.py width height target_dir [-force] [-outer]
+#
+# Where:
+#   width = the full-chip layout width
+#   height = the full-chip layout height
+#   target_dir = location of the full-chip layout
+#
+#   -force = overwrite existing files in the target directory
+#   -outer = width and height represent the seal ring outer edge, not the chip area
+#
+# Results:
+#   Files advSeal_6u_gen.mag and advSeal_6um_gen.gds are generated and placed in
+#   target_dir.  advSeal_6u_gen.mag is an "abstract" view that represents the
+#   seal ring in diffusion and the nikon cross in metal1, and references
+#   the advSeal_6um_gen.gds file in the same directory as a GDS_FILE property.
+#
+
diff --git a/sky130/custom/scripts/seal_ring_generator/generate_gds.tcl b/sky130/custom/scripts/seal_ring_generator/generate_gds.tcl
new file mode 100644
index 0000000..9aedf7b
--- /dev/null
+++ b/sky130/custom/scripts/seal_ring_generator/generate_gds.tcl
@@ -0,0 +1,10 @@
+# Tcl script input to magic to generate seal ring GDS
+tech load s8seal_ring -noprompt
+drc off
+load advSeal_6um_gen
+select top cell
+expand
+cif *hier write disable
+cif *array write disable
+gds write advSeal_6um_gen
+quit
diff --git a/sky130/custom/scripts/seal_ring_generator/nikon_sealring_shape.mag b/sky130/custom/scripts/seal_ring_generator/nikon_sealring_shape.mag
new file mode 100644
index 0000000..caf7cc9
--- /dev/null
+++ b/sky130/custom/scripts/seal_ring_generator/nikon_sealring_shape.mag
@@ -0,0 +1,130 @@
+magic
+tech s8seal_ring
+timestamp 1584558468
+<< checkpaint >>
+rect 0 0 400 400
+<< type21 >>
+rect 175 225 225 320
+rect 80 175 320 225
+rect 175 80 225 175
+<< type22 >>
+rect 175 225 225 320
+rect 80 175 320 225
+rect 175 80 225 175
+<< type23 >>
+rect 175 225 225 320
+rect 80 175 320 225
+rect 175 80 225 175
+<< type27 >>
+rect 175 225 225 320
+rect 80 175 320 225
+rect 175 80 225 175
+<< type28 >>
+rect 175 225 225 320
+rect 80 175 320 225
+rect 175 80 225 175
+<< type30 >>
+rect 175 225 225 320
+rect 80 175 320 225
+rect 175 80 225 175
+<< type32 >>
+rect 175 225 225 320
+rect 80 175 320 225
+rect 175 80 225 175
+<< type34 >>
+rect 175 225 225 320
+rect 80 175 320 225
+rect 175 80 225 175
+<< type35 >>
+rect 175 225 225 320
+rect 80 175 320 225
+rect 175 80 225 175
+<< type36 >>
+rect 175 225 225 320
+rect 80 175 320 225
+rect 175 80 225 175
+<< type40 >>
+rect 175 225 225 320
+rect 80 175 320 225
+rect 175 80 225 175
+<< type41 >>
+rect 175 225 225 320
+rect 80 175 320 225
+rect 175 80 225 175
+<< type43 >>
+rect 175 225 225 320
+rect 80 175 320 225
+rect 175 80 225 175
+<< type44 >>
+rect 175 225 225 320
+rect 80 175 320 225
+rect 175 80 225 175
+<< type46 >>
+rect 175 225 225 320
+rect 80 175 320 225
+rect 175 80 225 175
+<< type50 >>
+rect 175 225 225 320
+rect 80 175 320 225
+rect 175 80 225 175
+<< type51 >>
+rect 175 225 225 320
+rect 80 175 320 225
+rect 175 80 225 175
+<< type56 >>
+rect 175 225 225 320
+rect 80 175 320 225
+rect 175 80 225 175
+<< type58 >>
+rect 175 225 225 320
+rect 80 175 320 225
+rect 175 80 225 175
+<< type59 >>
+rect 175 225 225 320
+rect 80 175 320 225
+rect 175 80 225 175
+<< type88 >>
+rect 175 225 225 320
+rect 80 175 320 225
+rect 175 80 225 175
+<< type96 >>
+rect 175 225 225 320
+rect 80 175 320 225
+rect 175 80 225 175
+<< type97 >>
+rect 175 225 225 320
+rect 80 175 320 225
+rect 175 80 225 175
+<< type98 >>
+rect 175 225 225 320
+rect 80 175 320 225
+rect 175 80 225 175
+use sr_polygon00006  sr_polygon00006_0
+timestamp 1584558468
+transform 1 0 0 0 1 0
+box 0 0 400 400
+use sr_polygon00005  sr_polygon00005_0
+timestamp 1584558468
+transform 1 0 0 0 1 0
+box 0 0 400 400
+use sr_polygon00004  sr_polygon00004_0
+timestamp 1584558468
+transform 1 0 0 0 1 0
+box 0 0 400 400
+use sr_polygon00003  sr_polygon00003_0
+timestamp 1584558468
+transform 1 0 0 0 1 0
+box 0 0 400 400
+use sr_polygon00002  sr_polygon00002_0
+timestamp 1584558468
+transform 1 0 0 0 1 0
+box 0 0 400 400
+use sr_polygon00001  sr_polygon00001_0
+timestamp 1584558468
+transform 1 0 0 0 1 0
+box 0 0 400 400
+use sr_polygon00007  sr_polygon00007_0
+timestamp 1584558468
+transform 1 0 0 0 1 0
+box 0 0 400 400
+<< end >>
diff --git a/sky130/custom/scripts/seal_ring_generator/s8_gen_sealring.py b/sky130/custom/scripts/seal_ring_generator/s8_gen_sealring.py
new file mode 100755
index 0000000..d1c3761
--- /dev/null
+++ b/sky130/custom/scripts/seal_ring_generator/s8_gen_sealring.py
@@ -0,0 +1,349 @@
+#!/bin/env python3
+#-------------------------------------------------------------------------
+# s8_gen_sealring.py ---  a seal ring generator for SkyWater s8 using magic.
+#
+# Because the seal ring contains many layers that do not appear in standard
+# layout editing, they are all specially implemented in the s8seal_ring.tech
+# file in this directory.
+#
+# An example seal ring was generated by SkyWater and imported using magic's
+# gdsquery.sh script.  It was then hand-edited to contain only the bottom
+# quarter.  Then it was saved in .mag databases.
+#
+# The generator script s8_gen_sealring.py calls magic using the s8seal_ring.tech
+# file, and automatically modifies the geometry to stretch to the half width
+# and height of the specified dimensions.  Then the lower-left cells are
+# copied and folded over the centerline to make the complete seal ring.
+# The seal ring is then written out in GDS format.  Then a simplified magic
+# view is generated in the usual user-facing s8 technology file, with the
+# GDS_FILE property pointing to the seal ring GDS.  This layout and GDS can
+# then be imported into a layout.
+#
+# Usage:
+#
+#   s8_gen_sealring.py width height target_dir [-force] [-outer] [-keep]
+#
+# Where:
+#   width = the full-chip layout width
+#   height = the full-chip layout height
+#   target_dir = location of the full-chip layout
+#
+#   -force = overwrite any existing files at the target
+#   -outer = width and height are the seal ring outer edge, not the chip area
+#   -keep = keep local working directory of results
+#
+# Results:
+#   Files advSeal_6um_gen.mag and advSeal_6um_gen.gds are generated and placed in
+#   target_dir.  advSeal_6um_gen.mag is an "abstract" view that represents the
+#   seal ring in diffusion and the nikon cross in metal1, and references
+#   the advSeal_6um_gen.gds file in the same directory as a GDS_FILE property.
+#-------------------------------------------------------------------------
+
+import subprocess
+import shutil
+import sys
+import os
+import re
+
+def generate_sealring(width, height, target_dir, force, keep):
+
+    # All files of interest are listed below.
+
+    script = 'generate_gds.tcl'
+    tech = 's8seal_ring.tech'
+    corner = 'seal_ring_corner.mag'
+    abstract = 'seal_ring_corner_abstract.mag'
+    slots = 'sealring_slots.mag'
+    array = 'seal_ring_slots_array.mag'
+    nikon = 'nikon_sealring_shape.mag'
+    polygons = ['sr_polygon00007.mag',
+	    'sr_polygon00027.mag', 'sr_polygon00011.mag', 'sr_polygon00028.mag',
+	    'sr_polygon00001.mag', 'sr_polygon00015.mag', 'sr_polygon00031.mag',
+	    'sr_polygon00002.mag', 'sr_polygon00016.mag', 'sr_polygon00032.mag',
+	    'sr_polygon00003.mag', 'sr_polygon00019.mag', 'sr_polygon00035.mag',
+	    'sr_polygon00004.mag', 'sr_polygon00020.mag', 'sr_polygon00036.mag',
+	    'sr_polygon00005.mag', 'sr_polygon00023.mag', 'sr_polygon00039.mag',
+	    'sr_polygon00006.mag', 'sr_polygon00024.mag']
+
+
+    # Create temporary directory
+    if os.path.exists('temp'):
+        print('temp/ directory exists.  Please remove it before running.')
+        sys.exit(0)
+
+    os.makedirs('temp')
+    os.chdir('temp')
+
+    # Copy all .mag files, .magicrc file, and s8seal_ring.tech file to temp/
+    files_to_copy = polygons[:]
+    files_to_copy.append(nikon)
+    files_to_copy.append(slots)
+    files_to_copy.append(array)
+    files_to_copy.append(corner)
+    files_to_copy.append(abstract)
+    files_to_copy.append(tech)
+    files_to_copy.append(script)
+
+    for file in files_to_copy:
+        shutil.copy('../' + file, '.')
+
+    # Seal ring is placed 6um outside of the chip, so add 12um to width and height
+    fwidth = float(width) + 12
+    fheight = float(height) + 12
+
+    dbhwidth = int(fwidth * 100)
+    dbhheight = int(fheight * 100)
+
+    swidth = str(dbhwidth)
+    sheight = str(dbhheight)
+
+    swidthx5 = str(dbhwidth * 5)
+
+    dwidth = str(int(fwidth * 200))
+    dheight = str(int(fheight * 200))
+
+    # Modify every polygon to half width and height
+
+    for file in polygons:
+        with open(file, 'r') as ifile:
+            maglines = ifile.read().splitlines()
+
+        with open(file, 'w') as ofile:
+            for line in maglines:
+                newline = re.sub('51200', swidth, line)
+                newline = re.sub('51210', sheight, newline)
+                # NOTE: polygon 39 is at scale 10, not 2, due to
+                # corner positions of 45 degree angled geometry.
+                newline = re.sub('256000', swidthx5, newline)
+                print(newline, file=ofile)
+
+    # Abstract corner view gets the same treatment
+
+    qwidth = str(int(fwidth * 50))
+    qheight = str(int(fheight * 50))
+
+    with open(abstract, 'r') as ifile:
+        maglines = ifile.read().splitlines()
+
+    with open(abstract, 'w') as ofile:
+        for line in maglines:
+            newline = re.sub('25600', qwidth, line)
+            newline = re.sub('25605', qheight, newline)
+            print(newline, file=ofile)
+
+    # Slots arrays are recalculated to span the width and height
+
+    with open(array, 'r') as ifile:
+        maglines = ifile.read().splitlines()
+
+    slotsX = False
+    with open(array, 'w') as ofile:
+        for line in maglines:
+            newline = line
+            if 'slots_X' in line:
+                slotsX = True
+            elif 'array 0' in line:
+                if slotsX:
+                    nslots = int((fwidth - 25.0) / 25.0) - 1
+                    newline = 'array 0 ' + str(nslots) + ' 5000 0 0 430'
+                else:
+                    nslots = int((fheight - 25.0) / 25.0) - 1
+                    newline = 'array 0 ' + str(nslots) + ' 5000 0 0 430'
+
+            print(newline, file=ofile)
+
+    # Corner cell changes bounding boxes to half width and height.
+
+    with open(corner, 'r') as ifile:
+        maglines = ifile.read().splitlines()
+
+    slotsX = False
+    with open(corner, 'w') as ofile:
+        for line in maglines:
+            newline = re.sub('51200', swidth, line)
+            newline = re.sub('51210', sheight, newline)
+            print(newline, file=ofile)
+
+    # Create a new top-level layout called 'advSeal_6um_gen.mag'
+    # Mirrors uses in X and Y, and adds slots arrays at lower left
+    # and upper right
+
+    with open('advSeal_6um_gen.mag', 'w') as ofile:
+        print('magic', file=ofile)
+        print('tech s8seal_ring', file=ofile)
+        print('magscale 1 2', file=ofile)
+        print('timestamp 1584630000', file=ofile)
+
+        # Lower left original
+        print('use seal_ring_corner seal_ring_corner_0', file=ofile)
+        print('timestamp 1584562315', file=ofile)
+        print('transform 1 0 0 0 1 0', file=ofile)
+        print('box -30480 -30480 ' + swidth + ' ' + sheight, file=ofile)
+
+        # Mirrored in X
+        print('use seal_ring_corner seal_ring_corner_3', file=ofile)
+        print('timestamp 1584562315', file=ofile)
+        print('transform -1 0 ' + dwidth + ' 0 1 0', file=ofile)
+        print('box -30480 -30480 ' + swidth + ' ' + sheight, file=ofile)
+	
+        # Mirrored in Y
+        print('use seal_ring_corner seal_ring_corner_1', file=ofile)
+        print('timestamp 1584562315', file=ofile)
+        print('transform 1 0 0 0 -1 ' + dheight, file=ofile)
+        print('box -30480 -30480 ' + swidth + ' ' + sheight, file=ofile)
+
+        # Mirrored in both X and Y 
+        print('use seal_ring_corner seal_ring_corner_2', file=ofile)
+        print('timestamp 1584562315', file=ofile)
+        print('transform -1 0 ' + dwidth + ' 0 -1 ' + dheight, file=ofile)
+        print('box -30480 -30480 ' + swidth + ' ' + sheight, file=ofile)
+
+        # Lower left slot arrays (bottom and left sides slots)
+        print('use seal_ring_slots_array seal_ring_slots_array_0', file=ofile)
+        print('timestamp 1584629764', file=ofile)
+        print('transform 1 0 0 0 1 0', file=ofile)
+        print('box 285 285 ' + swidth + ' ' + sheight, file=ofile)
+
+        # Upper right slot arrays (top and right sides slots)
+        print('use seal_ring_slots_array seal_ring_slots_array_1', file=ofile)
+        print('timestamp 1584629764', file=ofile)
+        print('transform -1 0 ' + dwidth + ' 0 -1 ' + dheight, file=ofile)
+        print('box 285 285 ' + swidth + ' ' + sheight, file=ofile)
+
+        print('<< end >>', file=ofile)
+    
+    # Create a new abstract layout TO BE called 'advSeal_6um_gen.mag'
+    # This is the view in technology EFS8A.  Since there is already
+    # a cell with this name that is used to generate GDS, the cell
+    # will be called "seal_ring.mag" and copied to "advSeal_6um_gen.mag"
+    # in the target directory.
+
+    xwidth = str(dbhwidth)
+    xheight = str(dbhheight)
+
+    with open('seal_ring.mag', 'w') as ofile:
+        print('magic', file=ofile)
+        print('tech EFS8A', file=ofile)
+        print('timestamp 1584566829', file=ofile)
+
+        # Lower left original
+        print('use seal_ring_corner_abstract seal_ring_corner_abstract_0', file=ofile)
+        print('timestamp 1584566221', file=ofile)
+        print('transform 1 0 0 0 1 0', file=ofile)
+        print('box 0 0 ' + qwidth + ' ' + qheight, file=ofile)
+
+        # Mirrored in X
+        print('use seal_ring_corner_abstract seal_ring_corner_abstract_3', file=ofile)
+        print('timestamp 1584566221', file=ofile)
+        print('transform -1 0 ' + xwidth + ' 0 1 0', file=ofile)
+        print('box 0 0 ' + qwidth + ' ' + qheight, file=ofile)
+	
+        # Mirrored in Y
+        print('use seal_ring_corner_abstract seal_ring_corner_abstract_1', file=ofile)
+        print('timestamp 1584566221', file=ofile)
+        print('transform 1 0 0 0 -1 ' + xheight, file=ofile)
+        print('box 0 0 ' + qwidth + ' ' + qheight, file=ofile)
+
+        # Mirrored in both X and Y 
+        print('use seal_ring_corner_abstract seal_ring_corner_abstract_2', file=ofile)
+        print('timestamp 1584566221', file=ofile)
+        print('transform -1 0 ' + xwidth + ' 0 -1 ' + xheight, file=ofile)
+        print('box 0 0 ' + qwidth + ' ' + qheight, file=ofile)
+
+        print('<< properties >>', file=ofile)
+        print('string LEFview no_prefix', file=ofile)
+        print('string GDS_FILE advSeal_6um_gen.gds', file=ofile)
+        print('string GDS_START 0', file=ofile)
+        print('string FIXED_BBOX 0 0 ' + swidth + ' ' + sheight, file=ofile)
+
+        print('<< end >>', file=ofile)
+
+    # Create the GDS of the seal ring
+
+    mproc = subprocess.run(['magic', '-dnull', '-noconsole',
+	    'generate_gds.tcl'],
+	    stdin = subprocess.DEVNULL, stdout = subprocess.PIPE,
+	    stderr = subprocess.PIPE, 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))
+
+    # Copy the GDS file and the abstract view to the target directory
+
+    os.chdir('..')
+
+    if not os.path.exists(target_dir):
+        os.makedirs(target_dir)
+
+    print('Installing files to ' + target_dir)
+    if force or not os.path.exists(target_dir + '/advSeal_6um_gen.gds'):
+        shutil.copy('temp/advSeal_6um_gen.gds', target_dir)
+    else:
+        print('ERROR: advSeal_6um_gen.gds already exists at target!  Use -force to overwrite.')
+    if force or not os.path.exists(target_dir + '/advSeal_6um_gen.mag'):
+        shutil.copy('temp/seal_ring.mag', target_dir + '/advSeal_6um_gen.mag')
+    else:
+        print('ERROR: advSeal_6um_gen.mag already exists at target!  Use -force to overwrite.')
+    if force or not os.path.exists(target_dir + '/seal_ring_corner_abstract.mag'):
+        shutil.copy('temp/seal_ring_corner_abstract.mag', target_dir)
+    else:
+        print('ERROR: seal_ring_corner_abstract.mag already exists at target!  Use -force to overwrite.')
+    
+    # Remove the temporary directory and its contents
+
+    if not keep:
+        shutil.rmtree('temp')
+    else:
+        print('Retaining generated files in temp/ directory')
+
+    # Done!
+    print('Done generating files advSeal_6um_gen.gds and advSeal_6um_gen.mag in ' + target_dir)
+    print('Place the seal ring cell in the final layout at (0um, 0um) before generating GDS.')
+    print('The top level layout minus seal ring must have a lower left corner of (6um, 6um)')
+
+# If called as main, run generate_sealring()
+
+if __name__ == '__main__':
+
+    # Divide up command line into options and arguments
+    options = []
+    arguments = []
+    for item in sys.argv[1:]:
+        if item.find('-', 0) == 0:
+            options.append(item)
+        else:
+            arguments.append(item)
+
+    force = True if '-force' in options else False
+    keep = True if '-keep' in options else False
+    outer = True if '-outer' in options else False
+
+    # Need one argument:  path to verilog netlist
+    # If two arguments, then 2nd argument is the output file.
+
+    if len(arguments) == 3:
+        width = arguments[0]
+        height = arguments[1]
+        target_dir = arguments[2]
+
+        # Seal ring is 12um thick, so if "outer" option is used, subtract 12um
+        # from both width and height.
+        if outer:
+            width = str(float(width) - 12.0)
+            height = str(float(height) - 12.0)
+
+        generate_sealring(width, height, target_dir, force, keep)
+    else:
+        print("Usage:  s8_gen_sealring.py <width> <height> <target_dir> [options]")
+        print("Options:")
+        print("   -outer : Width and height are seal ring outer edge, not chip area")
+        print("   -force : Overwrite any existing files at <target_dir>")
+        print("   -keep :  Keep generated files in temp/ directory")
+    
+
diff --git a/sky130/custom/scripts/seal_ring_generator/s8seal_ring.tech b/sky130/custom/scripts/seal_ring_generator/s8seal_ring.tech
new file mode 100644
index 0000000..e5d37f3
--- /dev/null
+++ b/sky130/custom/scripts/seal_ring_generator/s8seal_ring.tech
@@ -0,0 +1,506 @@
+tech
+   30
+   s8seal_ring
+end
+
+version
+   version 0.0
+   description "Auto-generated techfile for unknown GDS read-in"
+end
+
+planes
+   plane11
+   plane20
+   plane21
+   plane22
+   plane23
+   plane25
+   plane27
+   plane28
+   plane30
+   plane32
+   plane34
+   plane35
+   plane36
+   plane37
+   plane39
+   plane40
+   plane41
+   plane43
+   plane44
+   plane46
+   plane48
+   plane49
+   plane50
+   plane51
+   plane56
+   plane58
+   plane59
+   plane61
+   plane65
+   plane81
+   plane88
+   plane96
+   plane97
+   plane98
+end
+
+types
+   plane11 type11
+   plane20 type20
+   plane21 type21
+   plane22 type22
+   plane22 type22_22
+   plane23 type23
+   plane25 type25
+   plane27 type27
+   plane28 type28
+   plane30 type30
+   plane32 type32
+   plane34 type34
+   plane35 type35
+   plane36 type36
+   plane37 type37
+   plane39 type39
+   plane40 type40
+   plane41 type41
+   plane43 type43
+   plane44 type44
+   plane46 type46
+   plane48 type48
+   plane49 type49
+   plane50 type50
+   plane51 type51
+   plane56 type56
+   plane58 type58
+   plane59 type59
+   plane61 type61_20
+   plane65 type65_20
+   plane81 type81_1
+   plane81 type81_51
+   plane81 type81_52
+   plane88 type88
+   plane96 type96
+   plane97 type97
+   plane98 type98
+end 
+
+contact
+end
+
+styles
+   styletype mos
+   type11 polysilicon
+   type20 ndiffusion
+   type21 pdiffusion
+   type22 capacitor
+   type22_22 metal1
+   type23 metal2
+   type25 metal3
+   type27 metal4
+   type28 metal5
+   type30 metal6
+   type32 metal7
+   type34 metal8
+   type35 metal9
+   type36 implant1
+   type37 implant2
+   type39 implant3
+   type40 implant4
+   type41 ntransistor
+   type43 ptransistor
+   type44 electrode
+   type46 poly_light
+   type48 mvndiff
+   type49 hvndiff
+   type50 ncontact
+   type51 mvpdiff
+   type56 hvpdiff
+   type58 pcontact
+   type59 poly_resist
+   type61_20 metal10
+   type65_20 mems
+   type81_1 cwell
+   type81_51 cwellnsc
+   type81_52 highvolt_nwell
+   type88 highvolt_pwell
+   type96 nwell
+   type97 pwell
+   type98 poly_light
+end
+
+compose
+end
+
+connect
+end
+
+cifoutput
+style generic
+   scalefactor 1
+
+   layer GDS11 type11
+   labels type11
+   calma 11 0
+
+   layer GDS20 type20
+   labels type20
+   calma 20 0
+
+   layer GDS21 type21
+   labels type21
+   calma 21 0
+
+   layer GDS22 type22
+   labels type22
+   calma 22 0
+
+   layer GDS22_22 type22_22
+   labels type22_22
+   calma 22 22
+
+   layer GDS23 type23
+   labels type23
+   calma 23 0
+
+   layer GDS25 type25
+   labels type25
+   calma 25 0
+
+   layer GDS27 type27
+   labels type27
+   calma 27 0
+
+   layer GDS28 type28
+   labels type28
+   calma 28 0
+
+   layer GDS30 type30
+   labels type30
+   calma 30 0
+
+   layer GDS32 type32
+   labels type32
+   calma 32 0
+
+   layer GDS34 type34
+   labels type34
+   calma 34 0
+
+   layer GDS35 type35
+   labels type35
+   calma 35 0
+
+   layer GDS36 type36
+   labels type36
+   calma 36 0
+
+   layer GDS37 type37
+   labels type37
+   calma 37 0
+
+   layer GDS39 type39
+   labels type39
+   calma 39 0
+
+   layer GDS40 type40
+   labels type40
+   calma 40 0
+
+   layer GDS41 type41
+   labels type41
+   calma 41 0
+
+   layer GDS43 type43
+   labels type43
+   calma 43 0
+
+   layer GDS44 type44
+   labels type44
+   calma 44 0
+
+   layer GDS46 type46
+   labels type46
+   calma 46 0
+
+   layer GDS48 type48
+   labels type48
+   calma 48 0
+
+   layer GDS49 type49
+   labels type49
+   calma 49 0
+
+   layer GDS50 type50
+   labels type50
+   calma 50 0
+
+   layer GDS51 type51
+   labels type51
+   calma 51 0
+
+   layer GDS56 type56
+   labels type56
+   calma 56 0
+
+   layer GDS58 type58
+   labels type58
+   calma 58 0
+
+   layer GDS59 type59
+   labels type59
+   calma 59 0
+
+   layer GDS61_20 type61_20
+   labels type61_20
+   calma 61 20
+
+   layer GDS65_20 type65_20
+   labels type65_20
+   calma 65 20
+
+   layer GDS81_1 type81_1
+   labels type81_1
+   calma 81 1
+
+   layer GDS81_51 type81_51
+   labels type81_51
+   calma 81 51
+
+   layer GDS81_52 type81_52
+   labels type81_52
+   calma 81 52
+
+   layer GDS88 type88
+   labels type88
+   calma 88 0
+
+   layer GDS96 type96
+   labels type96
+   calma 96 0
+
+   layer GDS97 type97
+   labels type97
+   calma 97 0
+
+   layer GDS98 type98
+   labels type98
+   calma 98 0
+
+end
+
+cifinput
+style generic
+   scalefactor 1
+
+   layer type11 GDS11
+   labels GDS11
+
+   layer type20 GDS20
+   labels GDS20
+
+   layer type21 GDS21
+   labels GDS21
+
+   layer type22 GDS22
+   labels GDS22
+
+   layer type22_22 GDS22_22
+   labels GDS22_22
+
+   layer type23 GDS23
+   labels GDS23
+
+   layer type25 GDS25
+   labels GDS25
+
+   layer type27 GDS27
+   labels GDS27
+
+   layer type28 GDS28
+   labels GDS28
+
+   layer type30 GDS30
+   labels GDS30
+
+   layer type32 GDS32
+   labels GDS32
+
+   layer type34 GDS34
+   labels GDS34
+
+   layer type35 GDS35
+   labels GDS35
+
+   layer type36 GDS36
+   labels GDS36
+
+   layer type37 GDS37
+   labels GDS37
+
+   layer type39 GDS39
+   labels GDS39
+
+   layer type40 GDS40
+   labels GDS40
+
+   layer type41 GDS41
+   labels GDS41
+
+   layer type43 GDS43
+   labels GDS43
+
+   layer type44 GDS44
+   labels GDS44
+
+   layer type46 GDS46
+   labels GDS46
+
+   layer type48 GDS48
+   labels GDS48
+
+   layer type49 GDS49
+   labels GDS49
+
+   layer type50 GDS50
+   labels GDS50
+
+   layer type51 GDS51
+   labels GDS51
+
+   layer type56 GDS56
+   labels GDS56
+
+   layer type58 GDS58
+   labels GDS58
+
+   layer type59 GDS59
+   labels GDS59
+
+   layer type61_20 GDS61_20
+   labels GDS61_20
+
+   layer type65_20 GDS65_20
+   labels GDS65_20
+
+   layer type81_1 GDS81_1
+   labels GDS81_1
+
+   layer type81_51 GDS81_51
+   labels GDS81_51
+
+   layer type81_52 GDS81_52
+   labels GDS81_52
+
+   layer type88 GDS88
+   labels GDS88
+
+   layer type96 GDS96
+   labels GDS96
+
+   layer type97 GDS97
+   labels GDS97
+
+   layer type98 GDS98
+   labels GDS98
+
+   calma GDS11 11 0
+   calma GDS20 20 0
+   calma GDS21 21 0
+   calma GDS22 22 0
+   calma GDS22_22 22 22
+   calma GDS23 23 0
+   calma GDS25 25 0
+   calma GDS27 27 0
+   calma GDS28 28 0
+   calma GDS30 30 0
+   calma GDS32 32 0
+   calma GDS34 34 0
+   calma GDS35 35 0
+   calma GDS36 36 0
+   calma GDS37 37 0
+   calma GDS39 39 0
+   calma GDS40 40 0
+   calma GDS41 41 0
+   calma GDS43 43 0
+   calma GDS44 44 0
+   calma GDS46 46 0
+   calma GDS48 48 0
+   calma GDS49 49 0
+   calma GDS50 50 0
+   calma GDS51 51 0
+   calma GDS56 56 0
+   calma GDS58 58 0
+   calma GDS59 59 0
+   calma GDS61_20 61 20
+   calma GDS65_20 65 20
+   calma GDS81_1 81 1
+   calma GDS81_51 81 51
+   calma GDS81_52 81 52
+   calma GDS88 88 0
+   calma GDS96 96 0
+   calma GDS97 97 0
+   calma GDS98 98 0
+end
+
+# mzrouter
+# end
+
+drc
+end
+
+extract
+style generic
+   cscale 1
+   lambda 1
+   step 10
+   sidehalo 0
+
+  planeorder plane11 0
+  planeorder plane20 1
+  planeorder plane21 2
+  planeorder plane22 3
+  planeorder plane23 4
+  planeorder plane25 5
+  planeorder plane27 6
+  planeorder plane28 7
+  planeorder plane30 8
+  planeorder plane32 9
+  planeorder plane34 10
+  planeorder plane35 11
+  planeorder plane36 12
+  planeorder plane37 13
+  planeorder plane39 14
+  planeorder plane40 15
+  planeorder plane41 16
+  planeorder plane43 17
+  planeorder plane44 18
+  planeorder plane46 19
+  planeorder plane48 20
+  planeorder plane49 21
+  planeorder plane50 22
+  planeorder plane51 23
+  planeorder plane56 24
+  planeorder plane58 25
+  planeorder plane59 26
+  planeorder plane61 27
+  planeorder plane65 28
+  planeorder plane81 29
+  planeorder plane88 30
+  planeorder plane96 31
+  planeorder plane97 32
+  planeorder plane98 33
+end
+
+# wiring
+# end
+
+# router
+# end
+
+# plowing
+# end
+
+plot
+  style pnm
+end
diff --git a/sky130/custom/scripts/seal_ring_generator/seal_ring_corner.mag b/sky130/custom/scripts/seal_ring_generator/seal_ring_corner.mag
new file mode 100644
index 0000000..e15ffc8
--- /dev/null
+++ b/sky130/custom/scripts/seal_ring_generator/seal_ring_corner.mag
@@ -0,0 +1,68 @@
+magic
+tech s8seal_ring
+magscale 1 2
+timestamp 1584562315
+<< type81_52 >>
+rect 0 20320 20320 51210
+rect 0 0 51200 20320
+use sr_polygon00028  sr_polygon00028_0
+timestamp 1584558827
+transform 1 0 0 0 1 0
+box 650 2369 710 51210
+use sr_polygon00024  sr_polygon00024_0
+timestamp 1584558827
+transform 1 0 0 0 1 0
+box 530 2319 590 51210
+use sr_polygon00020  sr_polygon00020_0
+timestamp 1584558827
+transform 1 0 0 0 1 0
+box 410 2269 470 51210
+use sr_polygon00016  sr_polygon00016_0
+timestamp 1584558827
+transform 1 0 0 0 1 0
+box 290 2219 350 51210
+use sr_polygon00032  sr_polygon00032_0
+timestamp 1584558827
+transform 1 0 0 0 1 0
+box 0 2099 1000 51210
+use sr_polygon00031  sr_polygon00031_0
+timestamp 1584558827
+transform 1 0 0 0 1 0
+box 650 650 51200 2394
+use sr_polygon00027  sr_polygon00027_0
+timestamp 1584558827
+transform 1 0 0 0 1 0
+box 530 530 51200 2344
+use sr_polygon00023  sr_polygon00023_0
+timestamp 1584558827
+transform 1 0 0 0 1 0
+box 410 410 51200 2294
+use sr_polygon00019  sr_polygon00019_0
+timestamp 1584558827
+transform 1 0 0 0 1 0
+box 290 290 51200 2244
+use nikon_sealring_shape  nikon_sealring_shape_0
+timestamp 1584558468
+transform 1 0 200 0 1 200
+box 0 0 800 800
+use sr_polygon00036  sr_polygon00036_0
+timestamp 1584558827
+transform 1 0 0 0 1 0
+box 0 0 1200 51210
+use sr_polygon00015  sr_polygon00015_0
+timestamp 1584558468
+transform 1 0 0 0 1 0
+box 0 0 2099 2099
+use sr_polygon00035  sr_polygon00035_0
+timestamp 1584558827
+transform 1 0 0 0 1 0
+box 0 0 51200 2514
+use sr_polygon00039  sr_polygon00039_0
+timestamp 1584558827
+transform 1 0 0 0 1 0
+box 0 0 51200 2597
+use sr_polygon00011  sr_polygon00011_0
+timestamp 1584558468
+transform 1 0 0 0 1 0
+box -30480 -30480 30480 30480
+<< end >>
diff --git a/sky130/custom/scripts/seal_ring_generator/seal_ring_corner_abstract.mag b/sky130/custom/scripts/seal_ring_generator/seal_ring_corner_abstract.mag
new file mode 100644
index 0000000..1477b9c
--- /dev/null
+++ b/sky130/custom/scripts/seal_ring_generator/seal_ring_corner_abstract.mag
@@ -0,0 +1,27 @@
+magic
+tech EFS8A
+timestamp 1584566221
+<< psubstratepdiff >>
+rect 145 1110 355 25605
+tri 145 900 355 1110 ne
+tri 355 900 652 1197 sw
+tri 355 652 603 900 ne
+rect 603 652 652 900
+tri 652 652 900 900 sw
+tri 603 355 900 652 ne
+tri 900 355 1197 652 sw
+tri 900 145 1110 355 ne
+rect 1110 145 25600 355
+<< locali >>
+tri 100 383 217 500 se
+rect 217 383 383 500
+tri 383 383 500 500 sw
+rect 100 217 500 383
+tri 100 100 217 217 ne
+rect 217 100 383 217
+tri 383 100 500 217 nw
+<< metal1 >>
+rect 275 325 325 420
+rect 180 275 420 325
+rect 275 180 325 275
+<< end >>
diff --git a/sky130/custom/scripts/seal_ring_generator/seal_ring_slots_array.mag b/sky130/custom/scripts/seal_ring_generator/seal_ring_slots_array.mag
new file mode 100644
index 0000000..f38f77c
--- /dev/null
+++ b/sky130/custom/scripts/seal_ring_generator/seal_ring_slots_array.mag
@@ -0,0 +1,15 @@
+magic
+tech s8seal_ring
+magscale 1 2
+timestamp 1584629764
+use sealring_slots  sealring_slots_Y
+array 0 7 5000 0 0 430
+timestamp 1584628639
+transform 0 -1 1000 1 0 -7000
+box 9500 285 12200 715
+use sealring_slots  sealring_slots_X
+array 0 7 5000 0 0 430
+timestamp 1584628639
+transform 1 0 -7000 0 1 0
+box 9500 285 12200 715
+<< end >>
diff --git a/sky130/custom/scripts/seal_ring_generator/sealring_slots.mag b/sky130/custom/scripts/seal_ring_generator/sealring_slots.mag
new file mode 100644
index 0000000..c3ee669
--- /dev/null
+++ b/sky130/custom/scripts/seal_ring_generator/sealring_slots.mag
@@ -0,0 +1,13 @@
+magic
+tech s8seal_ring
+magscale 1 2
+timestamp 1584628639
+<< checkpaint >>
+rect 6900 285 7100 355
+rect 9500 285 9700 355
+<< type22_22 >>
+rect 12000 645 12200 715
+rect 9500 525 9700 595
+rect 12000 405 12200 475
+rect 9500 285 9700 355
+<< end >>
diff --git a/sky130/custom/scripts/seal_ring_generator/sr_polygon00001.mag b/sky130/custom/scripts/seal_ring_generator/sr_polygon00001.mag
new file mode 100644
index 0000000..e7c32b8
--- /dev/null
+++ b/sky130/custom/scripts/seal_ring_generator/sr_polygon00001.mag
@@ -0,0 +1,21 @@
+magic
+tech s8seal_ring
+timestamp 1584558468
+<< type48 >>
+tri 0 283 117 400 se
+rect 117 320 283 400
+rect 117 283 175 320
+rect 0 225 175 283
+rect 225 283 283 320
+tri 283 283 400 400 sw
+rect 225 225 400 283
+rect 0 175 80 225
+rect 320 175 400 225
+rect 0 117 175 175
+tri 0 0 117 117 ne
+rect 117 80 175 117
+rect 225 117 400 175
+rect 225 80 283 117
+rect 117 0 283 80
+tri 283 0 400 117 nw
+<< end >>
diff --git a/sky130/custom/scripts/seal_ring_generator/sr_polygon00002.mag b/sky130/custom/scripts/seal_ring_generator/sr_polygon00002.mag
new file mode 100644
index 0000000..51355fa
--- /dev/null
+++ b/sky130/custom/scripts/seal_ring_generator/sr_polygon00002.mag
@@ -0,0 +1,21 @@
+magic
+tech s8seal_ring
+timestamp 1584558468
+<< type25 >>
+tri 0 283 117 400 se
+rect 117 320 283 400
+rect 117 283 175 320
+rect 0 225 175 283
+rect 225 283 283 320
+tri 283 283 400 400 sw
+rect 225 225 400 283
+rect 0 175 80 225
+rect 320 175 400 225
+rect 0 117 175 175
+tri 0 0 117 117 ne
+rect 117 80 175 117
+rect 225 117 400 175
+rect 225 80 283 117
+rect 117 0 283 80
+tri 283 0 400 117 nw
+<< end >>
diff --git a/sky130/custom/scripts/seal_ring_generator/sr_polygon00003.mag b/sky130/custom/scripts/seal_ring_generator/sr_polygon00003.mag
new file mode 100644
index 0000000..7c2dd29
--- /dev/null
+++ b/sky130/custom/scripts/seal_ring_generator/sr_polygon00003.mag
@@ -0,0 +1,21 @@
+magic
+tech s8seal_ring
+timestamp 1584558468
+<< type20 >>
+tri 0 283 117 400 se
+rect 117 320 283 400
+rect 117 283 175 320
+rect 0 225 175 283
+rect 225 283 283 320
+tri 283 283 400 400 sw
+rect 225 225 400 283
+rect 0 175 80 225
+rect 320 175 400 225
+rect 0 117 175 175
+tri 0 0 117 117 ne
+rect 117 80 175 117
+rect 225 117 400 175
+rect 225 80 283 117
+rect 117 0 283 80
+tri 283 0 400 117 nw
+<< end >>
diff --git a/sky130/custom/scripts/seal_ring_generator/sr_polygon00004.mag b/sky130/custom/scripts/seal_ring_generator/sr_polygon00004.mag
new file mode 100644
index 0000000..7721108
--- /dev/null
+++ b/sky130/custom/scripts/seal_ring_generator/sr_polygon00004.mag
@@ -0,0 +1,21 @@
+magic
+tech s8seal_ring
+timestamp 1584558468
+<< type39 >>
+tri 0 283 117 400 se
+rect 117 320 283 400
+rect 117 283 175 320
+rect 0 225 175 283
+rect 225 283 283 320
+tri 283 283 400 400 sw
+rect 225 225 400 283
+rect 0 175 80 225
+rect 320 175 400 225
+rect 0 117 175 175
+tri 0 0 117 117 ne
+rect 117 80 175 117
+rect 225 117 400 175
+rect 225 80 283 117
+rect 117 0 283 80
+tri 283 0 400 117 nw
+<< end >>
diff --git a/sky130/custom/scripts/seal_ring_generator/sr_polygon00005.mag b/sky130/custom/scripts/seal_ring_generator/sr_polygon00005.mag
new file mode 100644
index 0000000..27e8081
--- /dev/null
+++ b/sky130/custom/scripts/seal_ring_generator/sr_polygon00005.mag
@@ -0,0 +1,21 @@
+magic
+tech s8seal_ring
+timestamp 1584558468
+<< type11 >>
+tri 0 283 117 400 se
+rect 117 320 283 400
+rect 117 283 175 320
+rect 0 225 175 283
+rect 225 283 283 320
+tri 283 283 400 400 sw
+rect 225 225 400 283
+rect 0 175 80 225
+rect 320 175 400 225
+rect 0 117 175 175
+tri 0 0 117 117 ne
+rect 117 80 175 117
+rect 225 117 400 175
+rect 225 80 283 117
+rect 117 0 283 80
+tri 283 0 400 117 nw
+<< end >>
diff --git a/sky130/custom/scripts/seal_ring_generator/sr_polygon00006.mag b/sky130/custom/scripts/seal_ring_generator/sr_polygon00006.mag
new file mode 100644
index 0000000..8b44cb9
--- /dev/null
+++ b/sky130/custom/scripts/seal_ring_generator/sr_polygon00006.mag
@@ -0,0 +1,21 @@
+magic
+tech s8seal_ring
+timestamp 1584558468
+<< type49 >>
+tri 0 283 117 400 se
+rect 117 320 283 400
+rect 117 283 175 320
+rect 0 225 175 283
+rect 225 283 283 320
+tri 283 283 400 400 sw
+rect 225 225 400 283
+rect 0 175 80 225
+rect 320 175 400 225
+rect 0 117 175 175
+tri 0 0 117 117 ne
+rect 117 80 175 117
+rect 225 117 400 175
+rect 225 80 283 117
+rect 117 0 283 80
+tri 283 0 400 117 nw
+<< end >>
diff --git a/sky130/custom/scripts/seal_ring_generator/sr_polygon00007.mag b/sky130/custom/scripts/seal_ring_generator/sr_polygon00007.mag
new file mode 100644
index 0000000..89547c6
--- /dev/null
+++ b/sky130/custom/scripts/seal_ring_generator/sr_polygon00007.mag
@@ -0,0 +1,21 @@
+magic
+tech s8seal_ring
+timestamp 1584558468
+<< type37 >>
+tri 0 283 117 400 se
+rect 117 320 283 400
+rect 117 283 175 320
+rect 0 225 175 283
+rect 225 283 283 320
+tri 283 283 400 400 sw
+rect 225 225 400 283
+rect 0 175 80 225
+rect 320 175 400 225
+rect 0 117 175 175
+tri 0 0 117 117 ne
+rect 117 80 175 117
+rect 225 117 400 175
+rect 225 80 283 117
+rect 117 0 283 80
+tri 283 0 400 117 nw
+<< end >>
diff --git a/sky130/custom/scripts/seal_ring_generator/sr_polygon00011.mag b/sky130/custom/scripts/seal_ring_generator/sr_polygon00011.mag
new file mode 100644
index 0000000..47854ae
--- /dev/null
+++ b/sky130/custom/scripts/seal_ring_generator/sr_polygon00011.mag
@@ -0,0 +1,99 @@
+magic
+tech s8seal_ring
+magscale 1 10
+timestamp 1584558468
+<< type81_51 >>
+tri -14938 151666 0 152400 se
+tri 0 151666 14938 152400 sw
+tri -29732 149472 -14938 151666 se
+rect -14938 149472 14938 151666
+tri 14938 149472 29732 151666 sw
+tri -44239 145838 -29732 149472 se
+rect -29732 145838 29732 149472
+tri 29732 145838 44239 149472 sw
+tri -58321 140799 -44239 145838 se
+rect -44239 140799 44239 145838
+tri 44239 140799 58321 145838 sw
+tri -71841 134405 -58321 140799 se
+rect -58321 134405 58321 140799
+tri 58321 134405 71841 140799 sw
+tri -84669 126716 -71841 134405 se
+rect -71841 126716 71841 134405
+tri 71841 126716 84669 134405 sw
+tri -96682 117807 -84669 126716 se
+rect -84669 117807 84669 126716
+tri 84669 117807 96682 126716 sw
+tri -107763 107763 -96682 117807 se
+rect -96682 107763 96682 117807
+tri 96682 107763 107763 117807 sw
+tri -117807 96682 -107763 107763 se
+rect -107763 96682 107763 107763
+tri 107763 96682 117807 107763 sw
+tri -126716 84669 -117807 96682 se
+rect -117807 84669 117807 96682
+tri 117807 84669 126716 96682 sw
+tri -134405 71841 -126716 84669 se
+rect -126716 71841 126716 84669
+tri 126716 71841 134405 84669 sw
+tri -140799 58321 -134405 71841 se
+rect -134405 58321 134405 71841
+tri 134405 58321 140799 71841 sw
+tri -145838 44239 -140799 58321 se
+rect -140799 44239 140799 58321
+tri 140799 44239 145838 58321 sw
+tri -149472 29732 -145838 44239 se
+rect -145838 29732 145838 44239
+tri 145838 29732 149472 44239 sw
+tri -151666 14938 -149472 29732 se
+rect -149472 14938 149472 29732
+tri 149472 14938 151666 29732 sw
+tri -152400 0 -151666 14938 se
+tri -152400 -14938 -151666 0 ne
+rect -151666 -14938 151666 14938
+tri 151666 0 152400 14938 sw
+tri 151666 -14938 152400 0 nw
+tri -151666 -29732 -149472 -14938 ne
+rect -149472 -29732 149472 -14938
+tri 149472 -29732 151666 -14938 nw
+tri -149472 -44239 -145838 -29732 ne
+rect -145838 -44239 145838 -29732
+tri 145838 -44239 149472 -29732 nw
+tri -145838 -58321 -140799 -44239 ne
+rect -140799 -58321 140799 -44239
+tri 140799 -58321 145838 -44239 nw
+tri -140799 -71841 -134405 -58321 ne
+rect -134405 -71841 134405 -58321
+tri 134405 -71841 140799 -58321 nw
+tri -134405 -84669 -126716 -71841 ne
+rect -126716 -84669 126716 -71841
+tri 126716 -84669 134405 -71841 nw
+tri -126716 -96682 -117807 -84669 ne
+rect -117807 -96682 117807 -84669
+tri 117807 -96682 126716 -84669 nw
+tri -117807 -107763 -107763 -96682 ne
+rect -107763 -107763 107763 -96682
+tri 107763 -107763 117807 -96682 nw
+tri -107763 -117807 -96682 -107763 ne
+rect -96682 -117807 96682 -107763
+tri 96682 -117807 107763 -107763 nw
+tri -96682 -126716 -84669 -117807 ne
+rect -84669 -126716 84669 -117807
+tri 84669 -126716 96682 -117807 nw
+tri -84669 -134405 -71841 -126716 ne
+rect -71841 -134405 71841 -126716
+tri 71841 -134405 84669 -126716 nw
+tri -71841 -140799 -58321 -134405 ne
+rect -58321 -140799 58321 -134405
+tri 58321 -140799 71841 -134405 nw
+tri -58321 -145838 -44239 -140799 ne
+rect -44239 -145838 44239 -140799
+tri 44239 -145838 58321 -140799 nw
+tri -44239 -149472 -29732 -145838 ne
+rect -29732 -149472 29732 -145838
+tri 29732 -149472 44239 -145838 nw
+tri -29732 -151666 -14938 -149472 ne
+rect -14938 -151666 14938 -149472
+tri 14938 -151666 29732 -149472 nw
+tri -14938 -152400 0 -151666 ne
+tri 0 -152400 14938 -151666 nw
+<< end >>
diff --git a/sky130/custom/scripts/seal_ring_generator/sr_polygon00015.mag b/sky130/custom/scripts/seal_ring_generator/sr_polygon00015.mag
new file mode 100644
index 0000000..d91c7fb
--- /dev/null
+++ b/sky130/custom/scripts/seal_ring_generator/sr_polygon00015.mag
@@ -0,0 +1,15 @@
+magic
+tech s8seal_ring
+magscale 1 2
+timestamp 1584558468
+<< type37 >>
+tri 0 1000 1099 2099 sw
+rect 0 200 200 1000
+tri 200 766 434 1000 nw
+tri 766 766 1000 1000 ne
+tri 200 200 434 434 sw
+tri 766 200 1000 434 se
+rect 1000 200 1099 1000
+rect 0 0 1099 200
+tri 1099 0 2099 1000 sw
+<< end >>
diff --git a/sky130/custom/scripts/seal_ring_generator/sr_polygon00016.mag b/sky130/custom/scripts/seal_ring_generator/sr_polygon00016.mag
new file mode 100644
index 0000000..7aa89fc
--- /dev/null
+++ b/sky130/custom/scripts/seal_ring_generator/sr_polygon00016.mag
@@ -0,0 +1,8 @@
+magic
+tech s8seal_ring
+magscale 1 2
+timestamp 1584558827
+<< type65_20 >>
+rect 290 2244 350 51210
+tri 290 2219 350 2244 nw
+<< end >>
diff --git a/sky130/custom/scripts/seal_ring_generator/sr_polygon00019.mag b/sky130/custom/scripts/seal_ring_generator/sr_polygon00019.mag
new file mode 100644
index 0000000..b316735
--- /dev/null
+++ b/sky130/custom/scripts/seal_ring_generator/sr_polygon00019.mag
@@ -0,0 +1,55 @@
+magic
+tech s8seal_ring
+magscale 1 2
+timestamp 1584558827
+<< type65_20 >>
+tri 290 2219 350 2244 se
+tri 350 2219 375 2244 sw
+tri 290 2134 375 2219 ne
+tri 375 2134 460 2219 sw
+tri 375 2049 460 2134 ne
+tri 460 2049 545 2134 sw
+tri 460 1964 545 2049 ne
+tri 545 1964 630 2049 sw
+tri 545 1879 630 1964 ne
+tri 630 1879 715 1964 sw
+tri 630 1794 715 1879 ne
+tri 715 1794 800 1879 sw
+tri 715 1709 800 1794 ne
+tri 800 1709 885 1794 sw
+tri 800 1624 885 1709 ne
+tri 885 1624 970 1709 sw
+tri 885 1539 970 1624 ne
+tri 970 1539 1055 1624 sw
+tri 970 1454 1055 1539 ne
+tri 1055 1454 1140 1539 sw
+tri 1055 1369 1140 1454 ne
+tri 1140 1369 1225 1454 sw
+tri 1140 1284 1225 1369 ne
+tri 1225 1284 1310 1369 sw
+tri 1225 1199 1310 1284 ne
+tri 1310 1199 1395 1284 sw
+tri 1310 1114 1395 1199 ne
+tri 1395 1114 1480 1199 sw
+tri 1395 1029 1480 1114 ne
+tri 1480 1029 1565 1114 sw
+tri 1480 944 1565 1029 ne
+tri 1565 944 1650 1029 sw
+tri 1565 859 1650 944 ne
+tri 1650 859 1735 944 sw
+tri 1650 774 1735 859 ne
+tri 1735 774 1820 859 sw
+tri 1735 689 1820 774 ne
+tri 1820 689 1905 774 sw
+tri 1820 604 1905 689 ne
+tri 1905 604 1990 689 sw
+tri 1905 519 1990 604 ne
+tri 1990 519 2075 604 sw
+tri 1990 434 2075 519 ne
+tri 2075 434 2160 519 sw
+tri 2075 349 2160 434 ne
+tri 2160 350 2244 434 sw
+rect 2160 349 51200 350
+tri 2160 290 2219 349 ne
+rect 2219 290 51200 349
+<< end >>
diff --git a/sky130/custom/scripts/seal_ring_generator/sr_polygon00020.mag b/sky130/custom/scripts/seal_ring_generator/sr_polygon00020.mag
new file mode 100644
index 0000000..9e328f8
--- /dev/null
+++ b/sky130/custom/scripts/seal_ring_generator/sr_polygon00020.mag
@@ -0,0 +1,8 @@
+magic
+tech s8seal_ring
+magscale 1 2
+timestamp 1584558827
+<< type65_20 >>
+rect 410 2294 470 51210
+tri 410 2269 470 2294 nw
+<< end >>
diff --git a/sky130/custom/scripts/seal_ring_generator/sr_polygon00023.mag b/sky130/custom/scripts/seal_ring_generator/sr_polygon00023.mag
new file mode 100644
index 0000000..fe8335d
--- /dev/null
+++ b/sky130/custom/scripts/seal_ring_generator/sr_polygon00023.mag
@@ -0,0 +1,54 @@
+magic
+tech s8seal_ring
+magscale 1 2
+timestamp 1584558827
+<< type65_20 >>
+tri 410 2269 470 2294 se
+tri 470 2269 495 2294 sw
+tri 410 2184 495 2269 ne
+tri 495 2184 580 2269 sw
+tri 495 2099 580 2184 ne
+tri 580 2099 665 2184 sw
+tri 580 2014 665 2099 ne
+tri 665 2014 750 2099 sw
+tri 665 1929 750 2014 ne
+tri 750 1929 835 2014 sw
+tri 750 1844 835 1929 ne
+tri 835 1844 920 1929 sw
+tri 835 1759 920 1844 ne
+tri 920 1759 1005 1844 sw
+tri 920 1674 1005 1759 ne
+tri 1005 1674 1090 1759 sw
+tri 1005 1589 1090 1674 ne
+tri 1090 1589 1175 1674 sw
+tri 1090 1504 1175 1589 ne
+tri 1175 1504 1260 1589 sw
+tri 1175 1419 1260 1504 ne
+tri 1260 1419 1345 1504 sw
+tri 1260 1334 1345 1419 ne
+tri 1345 1334 1430 1419 sw
+tri 1345 1249 1430 1334 ne
+tri 1430 1249 1515 1334 sw
+tri 1430 1164 1515 1249 ne
+tri 1515 1164 1600 1249 sw
+tri 1515 1079 1600 1164 ne
+tri 1600 1079 1685 1164 sw
+tri 1600 994 1685 1079 ne
+tri 1685 994 1770 1079 sw
+tri 1685 909 1770 994 ne
+tri 1770 909 1855 994 sw
+tri 1770 824 1855 909 ne
+tri 1855 824 1940 909 sw
+tri 1855 739 1940 824 ne
+tri 1940 739 2025 824 sw
+tri 1940 654 2025 739 ne
+tri 2025 654 2110 739 sw
+tri 2025 569 2110 654 ne
+tri 2110 569 2195 654 sw
+tri 2110 484 2195 569 ne
+tri 2195 484 2280 569 sw
+tri 2195 410 2269 484 ne
+rect 2269 470 2280 484
+tri 2280 470 2294 484 sw
+rect 2269 410 51200 470
+<< end >>
diff --git a/sky130/custom/scripts/seal_ring_generator/sr_polygon00024.mag b/sky130/custom/scripts/seal_ring_generator/sr_polygon00024.mag
new file mode 100644
index 0000000..eb9f364
--- /dev/null
+++ b/sky130/custom/scripts/seal_ring_generator/sr_polygon00024.mag
@@ -0,0 +1,8 @@
+magic
+tech s8seal_ring
+magscale 1 2
+timestamp 1584558827
+<< type65_20 >>
+rect 530 2344 590 51210
+tri 530 2319 590 2344 nw
+<< end >>
diff --git a/sky130/custom/scripts/seal_ring_generator/sr_polygon00027.mag b/sky130/custom/scripts/seal_ring_generator/sr_polygon00027.mag
new file mode 100644
index 0000000..c6d2ad1
--- /dev/null
+++ b/sky130/custom/scripts/seal_ring_generator/sr_polygon00027.mag
@@ -0,0 +1,53 @@
+magic
+tech s8seal_ring
+magscale 1 2
+timestamp 1584558827
+<< type65_20 >>
+tri 530 2319 590 2344 se
+tri 590 2319 615 2344 sw
+tri 530 2234 615 2319 ne
+tri 615 2234 700 2319 sw
+tri 615 2149 700 2234 ne
+tri 700 2149 785 2234 sw
+tri 700 2064 785 2149 ne
+tri 785 2064 870 2149 sw
+tri 785 1979 870 2064 ne
+tri 870 1979 955 2064 sw
+tri 870 1894 955 1979 ne
+tri 955 1894 1040 1979 sw
+tri 955 1809 1040 1894 ne
+tri 1040 1809 1125 1894 sw
+tri 1040 1724 1125 1809 ne
+tri 1125 1724 1210 1809 sw
+tri 1125 1639 1210 1724 ne
+tri 1210 1639 1295 1724 sw
+tri 1210 1554 1295 1639 ne
+tri 1295 1554 1380 1639 sw
+tri 1295 1469 1380 1554 ne
+tri 1380 1469 1465 1554 sw
+tri 1380 1384 1465 1469 ne
+tri 1465 1384 1550 1469 sw
+tri 1465 1299 1550 1384 ne
+tri 1550 1299 1635 1384 sw
+tri 1550 1214 1635 1299 ne
+tri 1635 1214 1720 1299 sw
+tri 1635 1129 1720 1214 ne
+tri 1720 1129 1805 1214 sw
+tri 1720 1044 1805 1129 ne
+tri 1805 1044 1890 1129 sw
+tri 1805 959 1890 1044 ne
+tri 1890 959 1975 1044 sw
+tri 1890 874 1975 959 ne
+tri 1975 874 2060 959 sw
+tri 1975 789 2060 874 ne
+tri 2060 789 2145 874 sw
+tri 2060 704 2145 789 ne
+tri 2145 704 2230 789 sw
+tri 2145 619 2230 704 ne
+tri 2230 619 2315 704 sw
+tri 2230 534 2315 619 ne
+tri 2315 590 2344 619 sw
+rect 2315 534 51200 590
+tri 2315 530 2319 534 ne
+rect 2319 530 51200 534
+<< end >>
diff --git a/sky130/custom/scripts/seal_ring_generator/sr_polygon00028.mag b/sky130/custom/scripts/seal_ring_generator/sr_polygon00028.mag
new file mode 100644
index 0000000..3db918a
--- /dev/null
+++ b/sky130/custom/scripts/seal_ring_generator/sr_polygon00028.mag
@@ -0,0 +1,8 @@
+magic
+tech s8seal_ring
+magscale 1 2
+timestamp 1584558827
+<< type65_20 >>
+rect 650 2394 710 51210
+tri 650 2369 710 2394 nw
+<< end >>
diff --git a/sky130/custom/scripts/seal_ring_generator/sr_polygon00031.mag b/sky130/custom/scripts/seal_ring_generator/sr_polygon00031.mag
new file mode 100644
index 0000000..1eb8648
--- /dev/null
+++ b/sky130/custom/scripts/seal_ring_generator/sr_polygon00031.mag
@@ -0,0 +1,51 @@
+magic
+tech s8seal_ring
+magscale 1 2
+timestamp 1584558827
+<< type65_20 >>
+tri 650 2369 710 2394 se
+tri 710 2369 735 2394 sw
+tri 650 2284 735 2369 ne
+tri 735 2284 820 2369 sw
+tri 735 2199 820 2284 ne
+tri 820 2199 905 2284 sw
+tri 820 2114 905 2199 ne
+tri 905 2114 990 2199 sw
+tri 905 2029 990 2114 ne
+tri 990 2029 1075 2114 sw
+tri 990 1944 1075 2029 ne
+tri 1075 1944 1160 2029 sw
+tri 1075 1859 1160 1944 ne
+tri 1160 1859 1245 1944 sw
+tri 1160 1774 1245 1859 ne
+tri 1245 1774 1330 1859 sw
+tri 1245 1689 1330 1774 ne
+tri 1330 1689 1415 1774 sw
+tri 1330 1604 1415 1689 ne
+tri 1415 1604 1500 1689 sw
+tri 1415 1519 1500 1604 ne
+tri 1500 1519 1585 1604 sw
+tri 1500 1434 1585 1519 ne
+tri 1585 1434 1670 1519 sw
+tri 1585 1349 1670 1434 ne
+tri 1670 1349 1755 1434 sw
+tri 1670 1264 1755 1349 ne
+tri 1755 1264 1840 1349 sw
+tri 1755 1179 1840 1264 ne
+tri 1840 1179 1925 1264 sw
+tri 1840 1094 1925 1179 ne
+tri 1925 1094 2010 1179 sw
+tri 1925 1009 2010 1094 ne
+tri 2010 1009 2095 1094 sw
+tri 2010 924 2095 1009 ne
+tri 2095 924 2180 1009 sw
+tri 2095 839 2180 924 ne
+tri 2180 839 2265 924 sw
+tri 2180 754 2265 839 ne
+tri 2265 754 2350 839 sw
+tri 2265 669 2350 754 ne
+tri 2350 710 2394 754 sw
+rect 2350 669 51200 710
+tri 2350 650 2369 669 ne
+rect 2369 650 51200 669
+<< end >>
diff --git a/sky130/custom/scripts/seal_ring_generator/sr_polygon00032.mag b/sky130/custom/scripts/seal_ring_generator/sr_polygon00032.mag
new file mode 100644
index 0000000..395db17
--- /dev/null
+++ b/sky130/custom/scripts/seal_ring_generator/sr_polygon00032.mag
@@ -0,0 +1,8 @@
+magic
+tech s8seal_ring
+magscale 1 2
+timestamp 1584558827
+<< type61_20 >>
+rect 0 2514 1000 51210
+tri 0 2099 1000 2514 nw
+<< end >>
diff --git a/sky130/custom/scripts/seal_ring_generator/sr_polygon00035.mag b/sky130/custom/scripts/seal_ring_generator/sr_polygon00035.mag
new file mode 100644
index 0000000..934e4e1
--- /dev/null
+++ b/sky130/custom/scripts/seal_ring_generator/sr_polygon00035.mag
@@ -0,0 +1,13 @@
+magic
+tech s8seal_ring
+magscale 1 2
+timestamp 1584558827
+<< type61_20 >>
+tri 0 2099 1000 2514 se
+tri 1000 2099 1415 2514 sw
+tri 0 684 1415 2099 ne
+tri 1415 1000 2514 2099 sw
+rect 1415 684 51200 1000
+tri 1415 0 2099 684 ne
+rect 2099 0 51200 684
+<< end >>
diff --git a/sky130/custom/scripts/seal_ring_generator/sr_polygon00036.mag b/sky130/custom/scripts/seal_ring_generator/sr_polygon00036.mag
new file mode 100644
index 0000000..7e944a4
--- /dev/null
+++ b/sky130/custom/scripts/seal_ring_generator/sr_polygon00036.mag
@@ -0,0 +1,8 @@
+magic
+tech s8seal_ring
+magscale 1 2
+timestamp 1584558827
+<< type81_1 >>
+rect 0 2597 1200 51210
+tri 0 0 1200 2597 nw
+<< end >>
diff --git a/sky130/custom/scripts/seal_ring_generator/sr_polygon00039.mag b/sky130/custom/scripts/seal_ring_generator/sr_polygon00039.mag
new file mode 100644
index 0000000..24dfe83
--- /dev/null
+++ b/sky130/custom/scripts/seal_ring_generator/sr_polygon00039.mag
@@ -0,0 +1,10 @@
+magic
+tech s8seal_ring
+magscale 1 10
+timestamp 1584558827
+<< type81_1 >>
+tri 2772 6000 6000 12985 se
+tri 6000 6000 12985 12985 sw
+tri 0 0 2772 5999 se
+rect 2772 0 256000 6000
+<< end >>