Merge branch 'master' of 192.168.0.7:/home/tim/gitsrc/open_pdks/
diff --git a/VERSION b/VERSION
index b668c3b..f8f3c08 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.0.16
+1.0.18
diff --git a/common/convert_spectre.py b/common/convert_spectre.py
index 9127712..6c3655c 100755
--- a/common/convert_spectre.py
+++ b/common/convert_spectre.py
@@ -30,14 +30,17 @@
 def parse_param_line(line, inparam, insub):
 
     # Regexp patterns
-    parm1rex = re.compile('parameters' + '[ \t]*(.*)')
-    parm2rex = re.compile('\+[ \t]*(.*)')
-    parm3rex = re.compile('[ \t]*([^= \t]+)[ \t]*=[ \t]*([^ \t]+)[ \t]*(.*)')
+    parm1rex = re.compile('[ \t]*parameters[ \t]*(.*)')
+    parm2rex = re.compile('[ \t]*params:[ \t]*(.*)')
+    parm3rex = re.compile('\+[ \t]*(.*)')
+    parm4rex = re.compile('[ \t]*([^= \t]+)[ \t]*=[ \t]*([^ \t]+)[ \t]*(.*)')
+    parm5rex = re.compile('[ \t]*([^= \t]+)[ \t]*(.*)')
 
     fmtline = []
+    iscdl = False
     
     if inparam:
-        pmatch = parm2rex.match(line)
+        pmatch = parm3rex.match(line)
         if pmatch:
             fmtline.append('+')
             rest = pmatch.group(1)
@@ -52,10 +55,19 @@
                 fmtline.append('.param')
             rest = pmatch.group(1)
         else:
-            return ''
+            pmatch = parm2rex.match(line)
+            if pmatch:
+                if insub:
+                    fmtline.append('+')
+                else:
+                    return ''
+                rest = pmatch.group(1)
+                iscdl = True
+            else:
+                return ''
 
     while rest != '':
-        pmatch = parm3rex.match(rest)
+        pmatch = parm4rex.match(rest)
         if pmatch:
             fmtline.append(pmatch.group(1))
             fmtline.append('=')
@@ -72,10 +84,18 @@
             # ngspice.  So put them in an in-line comment
 
             if rest != '':
-                nmatch = parm3rex.match(rest)
+                nmatch = parm4rex.match(rest)
                 if not nmatch:
                     fmtline.append(' $ ' + rest.replace(' ', '').replace('\t', ''))
                     rest = ''
+        elif iscdl:
+            # Match to a CDL subckt parameter that does not have an '=' and so
+            # assumes that the parameter is always passed.  That is not legal SPICE,
+            # so supply a default value of 1.
+            pmatch = parm5rex.match(rest)
+            if pmatch:
+                fmtline.append(pmatch.group(1) + '=1')
+                rest = pmatch.group(2)
         else:
             break
 
@@ -87,6 +107,7 @@
     statrex = re.compile('[ \t]*statistics[ \t]*\{(.*)')
     simrex = re.compile('[ \t]*simulator[ \t]+([^= \t]+)[ \t]*=[ \t]*(.+)')
     insubrex = re.compile('[ \t]*inline[ \t]+subckt[ \t]+([^ \t]+)[ \t]*\(([^)]*)')
+    cdlsubrex = re.compile('\.subckt[ \t]+([^ \t]+)[ \t]*\(([^)]*)')
     endsubrex = re.compile('[ \t]*ends[ \t]+(.+)')
     modelrex = re.compile('[ \t]*model[ \t]+([^ \t]+)[ \t]+([^ \t]+)[ \t]+\{(.*)')
     binrex = re.compile('[ \t]*([0-9]+):[ \t]+type[ \t]*=[ \t]*(.*)')
@@ -99,6 +120,7 @@
     # Devices (resistor, capacitor, subcircuit as resistor or capacitor)
     caprex = re.compile('c([^ \t]+)[ \t]*\(([^)]*)\)[ \t]*capacitor[ \t]*(.*)', re.IGNORECASE)
     resrex = re.compile('r([^ \t]+)[ \t]*\(([^)]*)\)[ \t]*resistor[ \t]*(.*)', re.IGNORECASE)
+    cdlrex = re.compile('[ \t]*([crdlmqx])([^ \t]+)[ \t]*\(([^)]*)\)[ \t]*([^ \t]+)[ \t]*(.*)', re.IGNORECASE)
 
     with open(in_file, 'r') as ifile:
         speclines = ifile.read().splitlines()
@@ -107,7 +129,7 @@
     inparam = False
     inmodel = False
     inpinlist = False
-    isspectre = True
+    isspectre = False
     spicelines = []
     calllines = []
     modellines = []
@@ -140,7 +162,7 @@
                 spicelines.append(line.strip())
             continue
 
-        # Item 3.  Flag continuation lines
+        # Item 4.  Flag continuation lines
         if line.strip().startswith('+'):
             contline = True
         else:
@@ -150,7 +172,17 @@
             if inpinlist:
                 inpinlist = False 
 
-        # Item 4.  Count through { ... } blocks that are not SPICE syntax
+        # Item 3.  Handle blank lines like comment lines
+        if line.strip() == '':
+            if modellines != []:
+                modellines.append(line.strip())
+            elif calllines != []:
+                calllines.append(line.strip())
+            else:
+                spicelines.append(line.strip())
+            continue
+
+        # Item 5.  Count through { ... } blocks that are not SPICE syntax
         if blockskip > 0:
             # Warning:  Assumes one brace per line, may or may not be true
             if '{' in line:
@@ -165,7 +197,7 @@
             spicelines.append('* ' + line)
             continue
 
-        # Item 5.  Handle continuation lines
+        # Item 6.  Handle continuation lines
         if contline:
             if inparam:
                 # Continue handling parameters
@@ -179,7 +211,7 @@
                         spicelines.append(fmtline)
                     continue
 
-        # Item 6.  Regexp matching
+        # Item 7.  Regexp matching
 
         # Catch "simulator lang="
         smatch = simrex.match(line)
@@ -213,7 +245,6 @@
         else:
             mmatch = stdmodelrex.match(line)
         if mmatch:
-            modellines = []
             modname = mmatch.group(1)
             modtype = mmatch.group(2)
 
@@ -233,23 +264,30 @@
             if isspectre:
                 imatch = insubrex.match(line)
             else:
-                imatch = stdsubrex.match(line)
+                # Check for CDL format .subckt lines first
+                imatch = cdlsubrex.match(line)
+                if not imatch:
+                    imatch = stdsubrex.match(line)
 
             if imatch:
+                # If a model block is pending, then dump it
+                if modellines != []:
+                    for line in modellines:
+                        spicelines.append(line)
+                    modellines = []
+                    inmodel = False
+
                 insub = True
                 subname = imatch.group(1)
-                calllines = []
                 if isspectre:
                     devrex = re.compile(subname + '[ \t]*\(([^)]*)\)[ \t]*([^ \t]+)[ \t]*(.*)', re.IGNORECASE)
-                    # If there is no close-parenthesis then we should expect it on
-                    # a continuation line
-                    inpinlist = True if ')' not in line else False
-                    # Remove parentheses groups from subcircuit arguments
-                    spicelines.append('.subckt ' + ' ' + subname + ' ' + imatch.group(2))
                 else:
                     devrex = re.compile(subname + '[ \t]*([^ \t]+)[ \t]*([^ \t]+)[ \t]*(.*)', re.IGNORECASE)
-                    inpinlist = True
-                    spicelines.append(line)
+                # If there is no close-parenthesis then we should expect it on
+                # a continuation line
+                inpinlist = True if ')' not in line else False
+                # Remove parentheses groups from subcircuit arguments
+                spicelines.append('.subckt ' + ' ' + subname + ' ' + imatch.group(2))
                 continue
 
         else:
@@ -300,6 +338,7 @@
 
                     for line in calllines[1:]:
                         spicelines.append(line)
+                    calllines = []
 
                     spicelines.append('.ends ' + subname)
 
@@ -307,6 +346,7 @@
                     spicelines.append('')
                     for line in modellines:
                         spicelines.append(line)
+                    modellines = []
                     
                     insub = False
                     inmodel = False
@@ -342,6 +382,18 @@
                     spicelines.append('r' + dmatch.group(1) + ' ' + dmatch.group(2) + ' ' + dmatch.group(3))
                     continue
 
+            if not isspectre:
+                cmatch = cdlrex.match(line)
+                if cmatch:
+                    fmtline = parse_param_line(cmatch.group(5), True, insub)
+                    if fmtline != '':
+                        inparam = True
+                        spicelines.append(cmatch.group(1) + cmatch.group(2) + ' ' + cmatch.group(3) + ' ' + cmatch.group(4) + ' ' + fmtline)
+                        continue
+                    else:
+                        spicelines.append(cmatch.group(1) + cmatch.group(2) + ' ' + cmatch.group(3) + ' ' + cmatch.group(4) + ' ' + cmatch.group(5))
+                        continue
+
             # Check for a line that begins with the subcircuit name
           
             dmatch = devrex.match(line)
@@ -447,6 +499,10 @@
             if fileext == '.v' or fileext == '.va':
                 continue
 
+            # .scs files are purely spectre and meaningless to SPICE, so ignore them.
+            if fileext == '.scs':
+                continue
+
             froot = os.path.split(filename)[1]
             convert_file(filename, spicepath + '/' + froot)
 
diff --git a/common/create_lef_library.py b/common/create_lef_library.py
index 2d56b41..4b8ecf3 100755
--- a/common/create_lef_library.py
+++ b/common/create_lef_library.py
@@ -75,7 +75,7 @@
                                 else:
                                     headerseen = True
                         ltok = lline.split()
-                        if ltok[0] == 'END' and ltok[1] == 'LIBRARY':
+                        if len(ltok) > 1 and ltok[0] == 'END' and ltok[1] == 'LIBRARY':
                             # Remove "END LIBRARY" line from individual files
                             pass
                         else:
@@ -83,6 +83,10 @@
                     headerdone = True
                 print('#--------EOF---------\n', file=ofile)
 
+            # Add "END LIBRARY" to the end of the library file
+            print('', file=ofile)
+            print('END LIBRARY', file=ofile)
+
         if do_compile_only == True:
             print('Compile-only:  Removing individual LEF files')
             for lfile in llist:
diff --git a/common/split_gds.py b/common/split_gds.py
index a673c2f..5336d8e 100755
--- a/common/split_gds.py
+++ b/common/split_gds.py
@@ -1,4 +1,7 @@
 #!/bin/env python3
+#
+# split_gds.py --
+#
 # Script to read a GDS library and write into individual GDS files, one per cell
 
 import os
diff --git a/common/split_spice.py b/common/split_spice.py
new file mode 100755
index 0000000..d8c5539
--- /dev/null
+++ b/common/split_spice.py
@@ -0,0 +1,229 @@
+#!/bin/env python3
+#
+# split_spice.py --
+#
+# Script that reads the SPICE output from the convert_spectre.py script,
+# which typically has parsed through files containing inline subcircuits
+# and recast them as normal SPICE .subckt ... .ends entries, and pulled
+# any model blocks inside the inline subckt out.  This script removes
+# each .subckt ... .ends block from every file and moves it to its own
+# file named <subckt_name>.spice.
+#
+# The arguments are <path_to_input> and <path_to_output>.  If there is
+# only one argument, or if <path_to_input> is equal to <path_to_output>,
+# then the new .spice files are added to the directory and the model
+# files are modified in place.  Otherwise, all modified files are placed
+# in <path_to_output>.
+
+import os
+import sys
+import re
+import glob
+
+def usage():
+    print('split_spice.py <path_to_input> <path_to_output>')
+
+def convert_file(in_file, out_path, out_file):
+
+    # Regexp patterns
+    paramrex = re.compile('\.param[ \t]+(.*)')
+    subrex = re.compile('\.subckt[ \t]+([^ \t]+)[ \t]+([^ \t]*)')
+    modelrex = re.compile('\.model[ \t]+([^ \t]+)[ \t]+([^ \t]+)[ \t]+(.*)')
+    endsubrex = re.compile('\.ends[ \t]+(.+)')
+    increx = re.compile('\.include[ \t]+')
+
+    with open(in_file, 'r') as ifile:
+        inplines = ifile.read().splitlines()
+
+    insubckt = False
+    inparam = False
+    inmodel = False
+    inpinlist = False
+    spicelines = []
+    subcktlines = []
+    savematch = None
+    subname = ''
+    modname = ''
+    modtype = ''
+
+    for line in inplines:
+
+        if subname == 'xrdn':
+            print('handling line in xrdn, file ' + in_file + ': "' + line + '"')
+
+        # Item 1.  Handle comment lines
+        if line.startswith('*'):
+            if subcktlines != []:
+                subcktlines.append(line.strip())
+            else:
+                spicelines.append(line.strip())
+            continue
+
+        # Item 2.  Flag continuation lines
+        if line.startswith('+'):
+            contline = True
+        else:
+            contline = False
+            if inparam:
+                inparam = False 
+            if inpinlist:
+                inpinlist = False 
+
+        # Item 3.  Handle blank lines like comment lines
+        if line.strip() == '':
+            if subname == 'xrdn':
+                print('blank line in xrdn subcircuit')
+            if subcktlines != []:
+                subcktlines.append(line)
+            else:
+                spicelines.append(line)
+            continue
+
+        # Item 4.  Handle continuation lines
+        if contline:
+            if inparam:
+                # Continue handling parameters
+                if subcktlines != []:
+                    subcktlines.append(line)
+                else:
+                    spicelines.append(line)
+                continue
+
+        # Item 5.  Regexp matching
+
+        # If inside a subcircuit, remove "parameters".  If outside,
+        # change it to ".param"
+        pmatch = paramrex.match(line)
+        if pmatch:
+            inparam = True
+            if insubckt:
+                subcktlines.append(line)
+            else:
+                spicelines.append(line)
+            continue
+        
+        # model
+        mmatch = modelrex.match(line)
+        if mmatch:
+            modellines = []
+            modname = mmatch.group(1)
+            modtype = mmatch.group(2)
+
+            spicelines.append(line)
+            inmodel = 2
+            continue
+
+        if not insubckt:
+            # Things to parse if not in a subcircuit
+
+            imatch = subrex.match(line)
+            if imatch:
+                insubckt = True
+                subname = imatch.group(1)
+                devrex = re.compile(subname + '[ \t]*([^ \t]+)[ \t]*([^ \t]+)[ \t]*(.*)', re.IGNORECASE)
+                inpinlist = True
+                subcktlines.append(line)
+                continue
+
+        else:
+            # Things to parse when inside of a ".subckt" block
+
+            if inpinlist:
+                # Watch for pin list continuation line.
+                subcktlines.append(line)
+                continue
+                
+            else:
+                ematch = endsubrex.match(line)
+                if ematch:
+                    if ematch.group(1) != subname:
+                        print('Error:  "ends" name does not match "subckt" name!')
+                        print('"ends" name = ' + ematch.group(1))
+                        print('"subckt" name = ' + subname)
+
+                    subcktlines.append(line)
+
+                    # Dump the contents of subcktlines into a file
+                    subckt_file = subname + '.spice'
+                    with open(out_path + '/' + subckt_file, 'w') as ofile:
+                        print('* Subcircuit definition of cell ' + subname, file=ofile)
+                        for line in subcktlines:
+                            print(line, file=ofile)
+                        subcktlines = []
+
+                    insubckt = False
+                    inmodel = False
+                    subname = ''
+                    continue
+
+        # Copy line as-is
+        if insubckt:
+            subcktlines.append(line)
+        else:
+            spicelines.append(line)
+
+    # Output the result to out_file.
+    with open(out_path + '/' + out_file, 'w') as ofile:
+        for line in spicelines:
+            print(line, file=ofile)
+
+if __name__ == '__main__':
+    debug = False
+
+    if len(sys.argv) == 1:
+        print("No options given to split_spice.py.")
+        usage()
+        sys.exit(0)
+
+    optionlist = []
+    arguments = []
+
+    for option in sys.argv[1:]:
+        if option.find('-', 0) == 0:
+            optionlist.append(option)
+        else:
+            arguments.append(option)
+
+    if len(arguments) != 2:
+        print("Wrong number of arguments given to split_spice.py.")
+        usage()
+        sys.exit(0)
+
+    if '-debug' in optionlist:
+        debug = True
+
+    inpath = arguments[0]
+    outpath = arguments[1]
+    do_one_file = False
+
+    if not os.path.exists(inpath):
+        print('No such source directory ' + inpath)
+        sys.exit(1)
+
+    if os.path.isfile(inpath):
+        do_one_file = True
+
+    if do_one_file:
+        if os.path.exists(outpath):
+            print('Error:  File ' + outpath + ' exists.')
+            sys.exit(1)
+        convert_file(inpath, outpath)
+
+    else:
+        if not os.path.exists(outpath):
+            os.makedirs(outpath)
+
+        infilelist = glob.glob(inpath + '/*')
+
+        for filename in infilelist:
+            fileext = os.path.splitext(filename)[1]
+
+            # Ignore verilog or verilog-A files that might be in a model directory
+            if fileext == '.v' or fileext == '.va':
+                continue
+
+            froot = os.path.split(filename)[1]
+            convert_file(filename, outpath, froot)
+
+    print('Done.')
+    exit(0)
diff --git a/sky130/Makefile b/sky130/Makefile
index 186ff6b..d8eb452 100644
--- a/sky130/Makefile
+++ b/sky130/Makefile
@@ -72,9 +72,8 @@
 # from source, where they don't.
 
 # LINK_TARGETS = source
-# LINK_TARGETS = none
+LINK_TARGETS = none
 # LINK_TARGETS = sky130A
-LINK_TARGETS = source
 
 # Paths:
 
@@ -118,8 +117,8 @@
 
 # Module definitions for each process node
 # (Note that MOS is default and therefore not used anywhere)
-# SKY130A_DEFS += -DMETAL5 -DMIM -DREDISTRIBUTION
-SKY130A_DEFS += -DMETAL5 -DMIM
+SKY130A_DEFS += -DMETAL5 -DMIM -DREDISTRIBUTION
+# SKY130A_DEFS += -DMETAL5 -DMIM
 
 # Add staging path
 SKY130A_DEFS += -DSTAGING_PATH=${STAGING_PATH}
@@ -173,7 +172,7 @@
 INSTALL = ../common/staging_install.py ${EF_FORMAT}
 
 # The script(s) below are used for custom changes to the vendor PDK files
-ADDPROP = ../common/insert_property.py ${EF_FORMAT} 
+ADDPROP = ../common/insert_property.py ${EF_FORMAT}
 
 # List the EDA tools to install local setup files for
 TOOLS = magic qflow netgen klayout openlane
@@ -330,12 +329,12 @@
 		-cdl %l/v%v/cells/*/*.cdl ignore=topography \
 		-spice %l/v%v/cells/*/*.spice  \
 		-library general sky130_fd_io |& tee -a ${SKY130A}_install.log
-        # Install all SkyWater digital standard cells.
+	# Install all SkyWater digital standard cells.
 	${STAGE} -source ${SKYWATER_PATH} -target ${STAGING_PATH}/${SKY130A} \
 		-techlef %l/latest/tech/*.tlef \
 		-spice %l/latest/cells/*/*.spice compile-only \
 		-cdl %l/latest/cells/*/*.cdl ignore=topography compile-only \
-		-lef %l/latest/cells/*/*.lef exclude=*.*.v compile-only \
+		-lef %l/latest/cells/*/*.lef exclude=*.*.lef compile-only \
 		-doc %l/latest/cells/*/*.pdf \
 		-lib %l/latest/timing/*.lib \
 		-gds %l/latest/cells/*/*.gds compile-only \
@@ -348,30 +347,30 @@
 		-library digital sky130_fd_sc_ms \
 		-library digital sky130_fd_sc_lp |& tee -a ${SKY130A}_install.log
         # Install OSU digital standard cells.
-	${STAGE} -source ${OSU_PATH} -target ${STAGING_PATH}/${SKY130A} \
-		-techlef char/techfiles/scs8.lef rename sky130_osu_sc.tlef \
-		-spice lib/spice/*.spice compile-only \
-		-lef outputs/s8_osu130.lef rename sky130_osu_sc.lef \
-		-lib outputs/*.lib \
-		-gds lib/gds/*.gds compile-only \
-		-verilog outputs/VERILOG/*.v \
-		-library digital sky130_osu_sc
+	# ${STAGE} -source ${OSU_PATH} -target ${STAGING_PATH}/${SKY130A} \
+	# 	-techlef char/techfiles/scs8.lef rename sky130_osu_sc.tlef \
+	# 	-spice lib/spice/*.spice compile-only \
+	# 	-lef outputs/s8_osu130.lef rename sky130_osu_sc.lef \
+	# 	-lib outputs/*.lib \
+	# 	-gds lib/gds/*.gds compile-only \
+	# 	-verilog outputs/VERILOG/*.v \
+	# 	-library digital sky130_osu_sc
 	# Install additional model file (efabless)
-	${STAGE} -source ./custom -target ${STAGING_PATH}/${SKY130A} \
-		-ngspice models/*.lib rename ${SKY130A}.lib \
-		|& tee -a ${SKY130A}_install.log
-	# Install custom additions to I/O pad library
-	${STAGE} -source ./custom -target ${STAGING_PATH}/${SKY130A} \
-		-gds %l/gds/*.gds \
-		-verilog %l/verilog/*.v \
-		-lef %l/lef/*.lef \
-		-spice %l/spice/*.spice \
-		-library general sky130_fd_io |& tee -a ${SKY130A}_install.log
-	# Add correct bounding boxes on Magic layouts
-	${ADDPROP} ${STAGING_PATH}/${SKY130A} sky130_fd_io sky130_fd_io_top_gpio_ovtv2 \
-		"FIXED_BBOX 0 407 28000 40000"
-	${ADDPROP} ${STAGING_PATH}/${SKY130A} sky130_fd_io sky130_fd_io_top_xres4v2 \
-		"FIXED_BBOX 0 407 15000 40000"
+	# ${STAGE} -source ./custom -target ${STAGING_PATH}/${SKY130A} \
+	# 	-ngspice models/*.lib rename ${SKY130A}.lib \
+	# 	|& tee -a ${SKY130A}_install.log
+	# # Install custom additions to I/O pad library
+	# ${STAGE} -source ./custom -target ${STAGING_PATH}/${SKY130A} \
+	# 	-gds %l/gds/*.gds \
+	# 	-verilog %l/verilog/*.v \
+	# 	-lef %l/lef/*.lef \
+	# 	-spice %l/spice/*.spice \
+	# 	-library general sky130_fd_io |& tee -a ${SKY130A}_install.log
+	# # Add correct bounding boxes on Magic layouts
+	# ${ADDPROP} ${STAGING_PATH}/${SKY130A} sky130_fd_io sky130_fd_io_top_gpio_ovtv2 \
+	# 	"FIXED_BBOX 0 407 28000 40000"
+	# ${ADDPROP} ${STAGING_PATH}/${SKY130A} sky130_fd_io sky130_fd_io_top_xres4v2 \
+	# 	"FIXED_BBOX 0 407 15000 40000"
 
 install: install-local
 
diff --git a/sky130/README b/sky130/README
index 0772cd4..4f650ca 100644
--- a/sky130/README
+++ b/sky130/README
@@ -74,10 +74,13 @@
     Edit the Makefile to set the following definitions for your host system:
 
 	EF_STYLE = Select "1" for an efabless-style file structure, "0"
-			otherwise.  There are only minor differences in
-			these two styles, namely for version tracking of
-			the Magic setup files, and the location of the
-			technology LEF file.
+			otherwise. There are some differences in
+			these two styles, the most important of which being
+			that the order of directories for the IP libraries
+			is <file_format>/<library_name> instead of
+			<library_name>/<file_format>. Other differences
+			include version tracking of the Magic setup files
+			and the location of the technology LEF file.
 
 	LINK_TARGETS = "none" or "source".  "none" copies files from the source
 			directories to the target.  "source" makes symbolic links
diff --git a/sky130/custom/sky130_fd_io/lef/power_pads_lib.lef b/sky130/custom/sky130_fd_io/lef/power_pads_lib.lef
index b140e33..3869db2 100644
--- a/sky130/custom/sky130_fd_io/lef/power_pads_lib.lef
+++ b/sky130/custom/sky130_fd_io/lef/power_pads_lib.lef
@@ -5388,4 +5388,4 @@
 	    RECT 2.8700 0.1000 72.1300 13.0000 ;
    END
 END sky130_fd_io__vssd_lvc_pad
-END LIBRARY ;
+END LIBRARY
diff --git a/sky130/klayout/sky130.lyt b/sky130/klayout/sky130.lyt
index 139f6cc..09b916f 100644
--- a/sky130/klayout/sky130.lyt
+++ b/sky130/klayout/sky130.lyt
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
 <technology>
- <name>EFS8A</name>
- <description>EFS8A 5-metals</description>
- <layer-properties_file>EFS8A.lyp</layer-properties_file>
+ <name>TECHNAME</name>
+ <description>TECHNAME-metals</description>
+ <layer-properties_file>TECHNAME.lyp</layer-properties_file>
  <add-other-layers>true</add-other-layers>
  <layer-map>
 '66/15 : PY_SHORT	';
diff --git a/sky130/magic/sky130.magicrc b/sky130/magic/sky130.magicrc
index feaf6b5..e0cf60a 100644
--- a/sky130/magic/sky130.magicrc
+++ b/sky130/magic/sky130.magicrc
@@ -79,7 +79,7 @@
 
 # add path to GDS cells
 #ifdef FULLTECH
-if {[file isdir ${PDKPATH}/libs.ref/gds}]} {
+if {[file isdir ${PDKPATH}/libs.ref/gds]} {
     path cell ${PDKPATH}/libs.ref/gds/sky130_fd_pr_base
     path cell ${PDKPATH}/libs.ref/gds/sky130_fd_pr_rf
     path cell ${PDKPATH}/libs.ref/gds/sky130_fd_pr_rf2
diff --git a/sky130/magic/sky130.tech b/sky130/magic/sky130.tech
index d000ffd..90e4240 100644
--- a/sky130/magic/sky130.tech
+++ b/sky130/magic/sky130.tech
@@ -3870,6 +3870,9 @@
  defaultsideoverlap allm4 metal4 allm5 metal5 47
 #endif (METAL5)
 
+#ifdef REDISTRIBUTION
+#endif (REDISTRIBUTION)
+
 # Devices:  Use document (...)
 
 variants (sim)
diff --git a/sky130/netgen/sky130_setup.tcl b/sky130/netgen/sky130_setup.tcl
index af90784..bb5c574 100644
--- a/sky130/netgen/sky130_setup.tcl
+++ b/sky130/netgen/sky130_setup.tcl
@@ -230,18 +230,18 @@
 #---------------------------------------------------------------
 
 foreach cell $cells1 {
-    if {[regexp "sky130_fc_sc_hd_decap_\[0-9\]+" $cell match]} {
+    if {[regexp {sky130_fd_sc_\w\w__decap_[[:digit:]]+} $cell match]} {
         ignore class "-circuit1 $cell"
     }
-    if {[regexp "sky130_fc_sc_hd_fill_\[0-9\]+" $cell match]} {
+    if {[regexp {sky130_fd_sc_\w\w__fill_[[:digit:]]+} $cell match]} {
         ignore class "-circuit1 $cell"
     }
 }
 foreach cell $cells2 {
-    if {[regexp "sky130_fc_sc_hd_decap_\[0-9\]+" $cell match]} {
+    if {[regexp {sky130_fd_sc_\w\w__decap_[[:digit:]]+} $cell match]} {
         ignore class "-circuit2 $cell"
     }
-    if {[regexp "sky130_fc_sc_hd_fill_\[0-9\]+" $cell match]} {
+    if {[regexp {sky130_fd_sc_\w\w__fill_[[:digit:]]+} $cell match]} {
         ignore class "-circuit2 $cell"
     }
 }
@@ -257,6 +257,7 @@
 #---------------------------------------------------------------
 # e.g., hydra_spi_controller__hydra_spi_controller
 #---------------------------------------------------------------
+
 foreach cell $cells1 {
     if {[regexp "(.+)__(.+)" $cell match library cellname]} {
         if {([lsearch $cells2 $cell] < 0) && \