Removed the "minenclosedarea" patch for the HD and HDLL libraries and
moved the fix to the "fix_techlefA|B.py" scripts.  This avoids the use
of patch files and avoids having to re-do the patch files to deal with
the change in the technology LEF files to cover process corners.  Also:
made some enhancements to the spectre_to_spice.py script stemming from
conversion of the SkyWater continuous models.
diff --git a/VERSION b/VERSION
index 2bae0e1..ca94b4b 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.0.297
+1.0.298
diff --git a/common/spectre_to_spice.py b/common/spectre_to_spice.py
index 4243a1a..38cd2ec 100755
--- a/common/spectre_to_spice.py
+++ b/common/spectre_to_spice.py
@@ -27,7 +27,7 @@
 # If inside a subcircuit, remove the keyword "parameters".  If outside,
 # change it to ".param"
 
-def parse_param_line(line, inparam, insub, iscall, ispassed):
+def parse_param_line(line, inparam, insub, iscall, ispassed, linenum):
 
     # Regexp patterns
     parm1rex = re.compile('[ \t]*parameters[ \t]*(.*)')
@@ -69,16 +69,15 @@
                 return '', ispassed
 
     while rest != '':
-        if iscall:
-            # It is hard to believe that this is legal even in spectre.
-            # Parameter expression given with no braces or quotes around
-            # the expression.  Fix the expression by removing the spaces
-            # around '*'.
-            rest = re.sub('[ \t]*\*[ \t]*', '*', rest)
+        # It is hard to believe that this is legal even in spectre.
+        # Parameter expression given with no braces or quotes around
+        # the expression.  Fix the expression by removing the spaces
+        # around '*'.
+        rest = re.sub('[ \t]*([\*\+\-])[ \t]*', '\g<1>', rest)
 
         pmatch = parm4rex.match(rest)
         if pmatch:
-            if ispassed:
+            if ispassed and not iscall:
                 # End of passed parameters.  Break line and generate ".param"
                 ispassed = False
                 fmtline.append('\n.param ')
@@ -97,14 +96,14 @@
 
             # Watch for spaces in expressions (have they no rules??!)
             # as indicated by something after a space not being an
-            # alphabetical character (parameter name) or '$' (comment)
+            # alphabetical character (parameter name) or ';' (comment)
 
             needmore = False
             while rest != '':
                 rmatch = rtok.match(rest)
                 if rmatch:
                     expch = rmatch.group(1)[0]
-                    if expch == '$':
+                    if expch == ';' or expch == '$':
                         break
                     elif expch.isalpha() and not needmore:
                         break
@@ -141,10 +140,10 @@
             if rest != '':
                 nmatch = parm4rex.match(rest)
                 if not nmatch:
-                    if rest.lstrip().startswith('$ '):
+                    if rest.lstrip().startswith('; '):
                         fmtline.append(rest)
                     elif rest.strip() != '':
-                        fmtline.append(' $ ' + rest.replace(' ', '').replace('\t', ''))
+                        fmtline.append(' ; ' + rest.replace(' ', '').replace('\t', ''))
                     rest = ''
         else:
             # Match to a CDL subckt parameter that does not have an '=' and so
@@ -211,6 +210,40 @@
             break
     return paramnames
 
+# Dump any saved model lines to a list.  Check for "type =" syntax in a
+# binned model
+
+def addmodel(modellines, linenum):
+    typerex = re.compile('([ \t]*type[ \t]*=[ \t]*)([^ \t]+)[ \t]*', re.IGNORECASE)
+  
+    # 'ZYXW' was left as a placeholder for the device type
+    if len(modellines) > 0:
+        typename = None
+        for j in range(len(modellines) - 1, -1, -1):
+            line = modellines[j]
+            pmatch = typerex.search(line)
+            if pmatch:
+                typename = pmatch.group(2).strip('{}').strip()
+                newline = typerex.sub(' ', line)
+                modellines[j] = newline
+                line = newline
+
+            if 'ZYXW' in line:
+                if typename:
+                    if typename == 'n':
+                        newtype = 'nmos'
+                    elif typename == 'p':
+                        newtype = 'pmos'
+                    else:
+                        newtype = typename
+                    modellines[j] = re.sub('ZYXW', newtype, line)
+                    typename = None
+                else:
+                    print('Error:  No type name for model at line ' + str(linenum))
+                    modellines[j] = re.sub('ZYXW', 'unknown', line)
+ 
+    return modellines
+
 # Run the spectre-to-ngspice conversion
 
 def convert_file(in_file, out_file):
@@ -223,13 +256,13 @@
     endsubrex = re.compile('[ \t]*ends[ \t]+(.+)')
     endonlysubrex = re.compile('[ \t]*ends[ \t]*')
     modelrex = re.compile('[ \t]*model[ \t]+([^ \t]+)[ \t]+([^ \t]+)[ \t]+\{(.*)')
-    cdlmodelrex = re.compile('[ \t]*model[ \t]+([^ \t]+)[ \t]+([^ \t]+)[ \t]+(.*)')
-    binrex = re.compile('[ \t]*([0-9]+):[ \t]+type[ \t]*=[ \t]*(.*)')
+    cdlmodelrex = re.compile('[ \t]*model[ \t]+([^ \t]+)[ \t]+([^ \t]+)[ \t]*(.*)')
+    binrex = re.compile('[ \t]*([0-9]+):[ \t]*(.*)')
     shincrex = re.compile('\.inc[ \t]+')
     isexprrex = re.compile('[^0-9a-zA-Z_]')
     paramrex = re.compile('\.param[ \t]+(.*)')
 
-    stdsubrex = re.compile('\.subckt[ \t]+([^ \t]+)[ \t]+(.*)')
+    stdsubrex = re.compile('\.?subckt[ \t]+([^ \t]+)[ \t]+(.*)')
     stdmodelrex = re.compile('\.model[ \t]+([^ \t]+)[ \t]+([^ \t]+)[ \t]*(.*)')
     stdendsubrex = re.compile('\.ends[ \t]+(.+)')
     stdendonlysubrex = re.compile('\.ends[ \t]*')
@@ -242,7 +275,6 @@
     stddev2rex = re.compile('[ \t]*([cr])([^ \t]+)[ \t]+([^ \t]+[ \t]+[^ \t]+)[ \t]+([^ \t\'{]+[\'{][^\'}]+[\'}])[ \t]*(.*)', re.IGNORECASE)
     stddev3rex = re.compile('[ \t]*([npcrdlmqx])([^ \t]+)[ \t]+(.*)', re.IGNORECASE)
 
-
     with open(in_file, 'r') as ifile:
         try:
             speclines = ifile.read().splitlines()
@@ -266,8 +298,12 @@
     subnames = []
     modname = ''
     modtype = ''
+    othermodnames = []
+    othermodtypes = []
+    linenum = 0
 
     for line in speclines:
+        linenum = linenum + 1
 
         # Item 1a.  C++-style // comments get replaced with * comment character
         if line.strip().startswith('//'):
@@ -280,13 +316,13 @@
                 spicelines.append(line.strip().replace('//', '*', 1))
             continue
 
-        # Item 1b.  In-line C++-style // comments get replaced with $ comment character
+        # Item 1b.  In-line C++-style // comments get replaced with ; comment character
         elif ' //' in line:
-            line = line.replace(' //', ' $ ', 1)
+            line = line.replace(' //', ' ; ', 1)
         elif '//' in line:
-            line = line.replace('//', ' $ ', 1)
+            line = line.replace('//', ' ; ', 1)
         elif '\t//' in line:
-            line = line.replace('\t//', '\t$ ', 1) 
+            line = line.replace('\t//', '\t; ', 1) 
 
         # Item 2.  Handle SPICE-style comment lines
         if line.strip().startswith('*'):
@@ -338,7 +374,7 @@
         if contline:
             if inparam:
                 # Continue handling parameters
-                fmtline, ispassed = parse_param_line(line, inparam, insub, False, ispassed)
+                fmtline, ispassed = parse_param_line(line, inparam, insub, False, ispassed, linenum)
                 if fmtline != '':
                     if modellines != []:
                         modellines.append(fmtline)
@@ -362,7 +398,7 @@
 
         # If inside a subcircuit, remove "parameters".  If outside,
         # change it to ".param"
-        fmtline, ispassed = parse_param_line(line, inparam, insub, False, ispassed)
+        fmtline, ispassed = parse_param_line(line, inparam, insub, False, ispassed, linenum)
         if fmtline != '':
             inparam = True
             spicelines.append(fmtline)
@@ -388,6 +424,9 @@
             mmatch = stdmodelrex.match(line)
 
         if mmatch:
+            if modname:
+                othermodnames.append(modname)
+                othermodtypes.append(modtype)
             modname = mmatch.group(1)
             modtype = mmatch.group(2)
 
@@ -396,9 +435,13 @@
                 inmodel = 1
                 # Continue to "if inmodel == 1" block below
             else:
-                fmtline, ispassed = parse_param_line(mmatch.group(3), True, False, True, ispassed)
+                fmtline, ispassed = parse_param_line(mmatch.group(3), True, False, True, ispassed, linenum)
                 if isspectre and (modtype == 'resistor' or modtype == 'r2'):
                     modtype = 'r'
+                if isspectre and (modtype == 'bsim4'):
+                    # "bsim4"---cast to special string so that it can be later
+                    # converted to "nmos" or "pmos" based on the "type" parameter
+                    modtype = 'ZYXW'
                 modellines.append('.model ' + modname + ' ' + modtype + ' ' + fmtline)
                 if fmtline != '':
                     inparam = True
@@ -415,10 +458,9 @@
                 imatch = cdlsubrex.match(line)
 
             if not imatch:
-                if not isspectre:
-                    # Check for standard SPICE format .subckt lines
-                    imatch = stdsubrex.match(line)
-
+                # Check for standard SPICE format .subckt lines
+                # or CDL format subckt line without parentheses
+                imatch = stdsubrex.match(line)
             if imatch:
                 # If a model block is pending, then dump it
                 if modellines != []:
@@ -432,16 +474,15 @@
                 subname = imatch.group(1)
                 subnames.append(subname)
                 if isspectre:
-                    devrex = re.compile(subname + '[ \t]*\(([^)]*)\)[ \t]*([^ \t]+)[ \t]*(.*)', re.IGNORECASE)
+                    devrex = re.compile('[ \t]*' + subname + '[ \t]*\(([^)]*)\)[ \t]*([^ \t]+)[ \t]*(.*)', re.IGNORECASE)
                 else:
-                    devrex = re.compile(subname + '[ \t]*([^ \t]+)[ \t]*([^ \t]+)[ \t]*(.*)', re.IGNORECASE)
+                    devrex = re.compile('[ \t]*' + subname + '[ \t]*([^ \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))
                 continue
-
         else:
             # Things to parse when inside of an "inline subckt" block
 
@@ -476,29 +517,58 @@
                             print('Error:  "ends" name does not match "subckt" name!')
                             print('"ends" name = ' + endname)
                             print('"subckt" name = ' + subname)
-                    if len(calllines) > 0:
-                        line = calllines[0]
-                        if modtype.startswith('bsim'):
-                            line = 'M' + line
-                        elif modtype.startswith('nmos'):
-                            line = 'M' + line
-                        elif modtype.startswith('pmos'):
-                            line = 'M' + line
-                        elif modtype.startswith('res'):
-                            line = 'R' + line
-                        elif modtype.startswith('cap'):
-                            line = 'C' + line
-                        elif modtype.startswith('pnp'):
-                            line = 'Q' + line
-                        elif modtype.startswith('npn'):
-                            line = 'Q' + line
-                        elif modtype.startswith('d'):
-                            line = 'D' + line
-                        spicelines.append(line)
+                    if modname:
+                        othermodnames.append(modname)
+                        othermodtypes.append(modtype)
 
-                        for line in calllines[1:]:
-                            spicelines.append(line)
-                        calllines = []
+                    for line in calllines:
+                        modified = False
+                        for j in range(len(othermodnames)):
+                            if othermodnames[j] in line:
+                                modtype = othermodtypes[j]
+                                if modtype.startswith('bsim'):
+                                    line = 'M' + line
+                                    modified = True
+                                elif modtype.startswith('nmos'):
+                                    line = 'M' + line
+                                    modified = True
+                                elif modtype.startswith('pmos'):
+                                    line = 'M' + line
+                                    modified = True
+                                elif modtype.startswith('res'):
+                                    line = 'R' + line
+                                    modified = True
+                                elif modtype.startswith('cap'):
+                                    line = 'C' + line
+                                    modified = True
+                                elif modtype.startswith('pnp'):
+                                    line = 'Q' + line
+                                    modified = True
+                                elif modtype.startswith('npn'):
+                                    line = 'Q' + line
+                                    modified = True
+                                elif modtype.startswith('d'):
+                                    line = 'D' + line
+                                    modified = True
+                                elif modtype.startswith('ZYXW'):
+                                    line = 'M' + line
+                                    modified = True
+                                else:
+                                    print('Error:  No prefix at line ' + str(linenum))
+                                    print('   Model type is ' + modtype)
+                            if modified:
+                                break
+                        if not modified:
+                            # Also check for "standard" models, e.g. "resistor"
+                            pnames = line.split()
+                            if 'resistor' in pnames[1:]:
+                                pnames.remove('resistor')
+                                line = 'R' + ' '.join(pnames)
+                            elif 'capacitor' in pnames[1:]:
+                                pnames.remove('capacitor')
+                                line = 'C' + ' '.join(pnames)
+                        spicelines.append(line)
+                    calllines = []
 
                     # Last check:  Do any model types confict with the way they
                     # are called within the subcircuit?  Spectre makes it very
@@ -529,16 +599,18 @@
 
                     # Now add any in-circuit models
                     spicelines.append('')
-                    for line in modellines:
-                        spicelines.append(line)
+                    spicelines.extend(addmodel(modellines, linenum))
                     modellines = []
 
                     # Complete the subcircuit definition
                     spicelines.append('.ends ' + subname)
-
                     insub = False
                     inmodel = False
                     subname = ''
+                    modname = ''
+                    modtype = ''
+                    othermodnames = []
+                    othermodtypes = []
                     paramnames = []
                     continue
 
@@ -551,7 +623,7 @@
             # Check for devices R and C.
             dmatch = caprex.match(line)
             if dmatch:
-                fmtline, ispassed = parse_param_line(dmatch.group(3), True, insub, True, ispassed)
+                fmtline, ispassed = parse_param_line(dmatch.group(3), True, insub, True, ispassed, linenum)
                 if fmtline != '':
                     inparam = True
                     spicelines.append('c' + dmatch.group(1) + ' ' + dmatch.group(2) + ' ' + fmtline)
@@ -562,7 +634,7 @@
 
             dmatch = resrex.match(line)
             if dmatch:
-                fmtline, ispassed = parse_param_line(dmatch.group(3), True, insub, True, ispassed)
+                fmtline, ispassed = parse_param_line(dmatch.group(3), True, insub, True, ispassed, linenum)
                 if fmtline != '':
                     inparam = True
                     spicelines.append('r' + dmatch.group(1) + ' ' + dmatch.group(2) + ' ' + fmtline)
@@ -598,7 +670,7 @@
                 # it must be enclosed in single quotes.  Otherwise, if the named
                 # device model is a subcircuit, then the devtype must be "x".
 
-                elif devtype.lower() == 'c' or devtype.lower() == 'r':
+                elif devtype.lower() == 'c' or devtype.lower() == 'r' or devtype.lower() == 'd':
                     if devmodel in subnames:
                         devtype = 'x' + devtype
                     else:
@@ -622,7 +694,7 @@
                                 if devmodel.strip("'") == devmodel:
                                     devmodel = "'" + devmodel + "'"
 
-                fmtline, ispassed = parse_param_line(cmatch.group(5), True, insub, True, ispassed)
+                fmtline, ispassed = parse_param_line(cmatch.group(5), True, insub, True, ispassed, linenum)
                 if fmtline != '':
                     inparam = True
                     spicelines.append(devtype + cmatch.group(2) + ' ' + cmatch.group(3) + ' ' + devmodel + ' ' + fmtline)
@@ -640,12 +712,13 @@
 
             dmatch = devrex.match(line)
             if dmatch:
-                fmtline, ispassed = parse_param_line(dmatch.group(3), True, insub, True, ispassed)
+                fmtline, ispassed = parse_param_line(dmatch.group(3), True, insub, True, ispassed, linenum)
                 if fmtline != '':
                     inparam = True
                     calllines.append(subname + ' ' + dmatch.group(1) + ' ' + dmatch.group(2) + ' ' + fmtline)
                     continue
                 else:
+                    inparam = True
                     calllines.append(subname + ' ' + dmatch.group(1) + ' ' + dmatch.group(2) + ' ' + dmatch.group(3))
                     continue
 
@@ -659,39 +732,65 @@
 
             if bmatch:
                 bin = bmatch.group(1)
-                type = bmatch.group(2)
-
-                if type == 'n':
-                    convtype = 'nmos'
-                elif type == 'p':
-                    convtype = 'pmos'
-                else:
-                    convtype = type
+                rest = bmatch.group(2)
 
                 # If there is a binned model then it replaces any original
                 # model line that was saved.
                 if modellines[-1].startswith('.model'):
                     modellines = modellines[0:-1]
                 modellines.append('')
-                modellines.append('.model ' + modname + '.' + bin + ' ' + convtype)
-                continue
+                modellines.append('.model ' + modname + '.' + bin + ' ZYXW')
 
-            else:
-                fmtline, ispassed = parse_param_line(line, True, True, False, ispassed)
-                if fmtline != '':
-                    modellines.append(fmtline)
+                if rest != '':
+                    # Somehow model numbers are allowed to break syntax and
+                    # not start a new line with a continuation character.
+                    if rest[0] == '+':
+                        line = rest
+                    else:
+                        line = '+' + rest
+                else:
                     continue
 
+            fmtline, ispassed = parse_param_line(line, True, True, False, ispassed, linenum)
+            if fmtline != '':
+                modellines.append(fmtline)
+                continue
+
         # Copy line as-is
         spicelines.append(line)
 
     # If any model lines remain at end, append them before output
     if modellines != []:
-        for line in modellines:
-            spicelines.append(line)
+        spicelines.extend(addmodel(modellines, linenum))
         modellines = []
         inmodel = False
 
+    # Catching the spectre use of "m" is difficult, so do a 2nd pass
+    # on "spicelines" to catch which subcircuits use "*m" expressions,
+    # then for those subcircuits, add "mult=1" to the subcircuit
+    # parameters.  (NOTE:  Need a more generic regular expression here)
+
+    sqrtrex = re.compile('.*(sqrt\([ \t]*[^ \t]+[ \t]*\*[ \t]*)m[ \t]*\)', re.IGNORECASE)
+    sqsubrex = re.compile('(sqrt\([ \t]*[^ \t]+[ \t]*\*[ \t]*)m[ \t]*\)', re.IGNORECASE)
+    subrex = re.compile('\.subckt[ \t]+([^ \t\(]+)[ \t]*')
+    needmult = []
+    for j in range(len(spicelines)):
+        line = spicelines[j]
+        smatch = subrex.match(line)
+        if smatch:
+            cursub = smatch.group(1)
+        smatch = sqrtrex.match(line)
+        if smatch:
+            spicelines[j] = sqsubrex.sub('\g<1>mult)', line)
+            needmult.append(cursub)
+
+    # Now add "mult=1" parameter to any subcircuit in the "needmult" list
+    for j in range(len(spicelines)):
+        line = spicelines[j]
+        smatch = subrex.match(line)
+        if smatch:
+            spicelines[j] = line + ' mult=1'
+
     # Output the result to out_file.
     with open(out_file, 'w') as ofile:
         for line in spicelines:
diff --git a/sky130/Makefile.in b/sky130/Makefile.in
index 6715ffa..07ca4c4 100644
--- a/sky130/Makefile.in
+++ b/sky130/Makefile.in
@@ -1275,9 +1275,6 @@
 	# the libraries
 	${RM} ${STAGING_PATH}/${SKY130$*}/libs.ref/${HD_VERILOG}/*.*.v
 	# Apply extra PDK patches until they get fixed properly in the source
-	${PATCH} -p1 -f -d ${STAGING_PATH}/${SKY130$*}/libs.ref/${HD_TECHLEF} \
-		< custom/patches/hd_minenclosed.squeaky.patch \
-		2>&1 | tee -a ${SKY130$*}_make.log || true
 	${PATCH} -p1 -f -d ${STAGING_PATH}/${SKY130$*}/libs.ref/${HD_VERILOG} \
 		< custom/patches/hd_wire_syntax.patch \
 		2>&1 | tee -a ${SKY130$*}_make.log || true
@@ -1315,10 +1312,6 @@
 	# Remove the base verilog files which have already been included into
 	# the libraries
 	${RM} ${STAGING_PATH}/${SKY130$*}/libs.ref/${HDLL_VERILOG}/*.*.v
-	# Apply extra PDK patches until they get fixed properly in the source
-	${PATCH} -p1 -f -d ${STAGING_PATH}/${SKY130$*}/libs.ref/${HDLL_TECHLEF} \
-		< custom/patches/hdll_minenclosed.squeaky.patch \
-		2>&1 | tee -a ${SKY130$*}_make.log || true
 
 digital-hvl-%:
 	# Install custom additions to standard cell libraries
diff --git a/sky130/custom/patches/hd_minenclosed.squeaky.patch b/sky130/custom/patches/hd_minenclosed.squeaky.patch
deleted file mode 100644
index 64376e7..0000000
--- a/sky130/custom/patches/hd_minenclosed.squeaky.patch
+++ /dev/null
@@ -1,20 +0,0 @@
-diff --git a/sky130_fd_sc_hd.tlef b/sky130_fd_sc_hd.tlef
-index 1c913ba..815b750 100644
---- a/sky130_fd_sc_hd.tlef
-+++ b/sky130_fd_sc_hd.tlef
-@@ -107,6 +107,7 @@ LAYER met1
-      WIDTH 3 0.28 ;
-   AREA 0.083 ;                     # Met1 6
-   THICKNESS 0.35 ;
-+  MINENCLOSEDAREA 0.14 ;
-
-   ANTENNAMODEL OXIDE1 ;
-   ANTENNADIFFSIDEAREARATIO PWL ( ( 0 400 ) ( 0.0125 400 ) ( 0.0225 2609 ) ( 22.5 11600 ) ) ;
-@@ -149,6 +150,7 @@ LAYER met2
-      WIDTH 3 0.28 ;
-   AREA 0.0676 ;                       # Met2 6
-   THICKNESS 0.35 ;
-+  MINENCLOSEDAREA 0.14 ;
-
-   EDGECAPACITANCE 37.759E-6 ;
-   CAPACITANCE CPERSQDIST 16.9423E-6 ;
diff --git a/sky130/custom/patches/hdll_minenclosed.squeaky.patch b/sky130/custom/patches/hdll_minenclosed.squeaky.patch
deleted file mode 100644
index 5d8dba5..0000000
--- a/sky130/custom/patches/hdll_minenclosed.squeaky.patch
+++ /dev/null
@@ -1,21 +0,0 @@
-diff --git a/sky130_fd_sc_hdll.tlef b/sky130_fd_sc_hdll.tlef
-index 1c913ba..815b750 100644
---- a/sky130_fd_sc_hdll.tlef
-+++ b/sky130_fd_sc_hdll.tlef
-@@ -107,6 +107,7 @@ LAYER met1
-      WIDTH 3 0.28 ;
-   AREA 0.083 ;                     # Met1 6
-   THICKNESS 0.35 ;
-+  MINENCLOSEDAREA 0.14 ;
-
-   ANTENNAMODEL OXIDE1 ;
-   ANTENNADIFFSIDEAREARATIO PWL ( ( 0 400 ) ( 0.0125 400 ) ( 0.0225 2609 ) ( 22.5 11600 ) ) ;
-@@ -149,6 +150,7 @@ LAYER met2
-      WIDTH 3 0.28 ;
-   AREA 0.0676 ;                       # Met2 6
-   THICKNESS 0.35 ;
-+  MINENCLOSEDAREA 0.14 ;
-
-   EDGECAPACITANCE 37.759E-6 ;
-   CAPACITANCE CPERSQDIST 16.9423E-6 ;
-
diff --git a/sky130/custom/scripts/fix_techlefA.py b/sky130/custom/scripts/fix_techlefA.py
index fa992d9..6c61f54 100755
--- a/sky130/custom/scripts/fix_techlefA.py
+++ b/sky130/custom/scripts/fix_techlefA.py
@@ -45,9 +45,19 @@
     resrex   = re.compile('[ \t]*ENCLOSURE ABOVE')
     layerrex = re.compile('[ \t]*LAYER ([^ \t\n]+)') 
     resrex2  = re.compile('[ \t]*RESISTANCE RPERSQ 12.2 ;')
+    thickrex = re.compile('[ \t]*THICKNESS')
+    emptyrex = re.compile('^[ \t]*$')
     curlayer = None
+    thickness_seen = False
 
     for line in llines:
+        if thickness_seen:
+            thickness_seen = False
+            if curlayer and (curlayer == 'met1' or curlayer == 'met2'):
+                ematch = emptyrex.match(line)
+                if ematch:
+                    fixedlines.append('  MINENCLOSEDAREA 0.14 ;')
+
         rmatch = resrex2.match(line)
         if rmatch:
             fixedlines.append('  RESISTANCE RPERSQ 12.8 ;')
@@ -72,6 +82,10 @@
         if lmatch:
             curlayer = lmatch.group(1)
 
+        tmatch = thickrex.match(line)
+        if tmatch:
+            thickness_seen = True
+
     # Write output
     if outname == None:
         for i in fixedlines:
diff --git a/sky130/custom/scripts/fix_techlefB.py b/sky130/custom/scripts/fix_techlefB.py
index 731851d..f34b51b 100755
--- a/sky130/custom/scripts/fix_techlefB.py
+++ b/sky130/custom/scripts/fix_techlefB.py
@@ -62,9 +62,18 @@
     resrex   = re.compile('[ \t]*ENCLOSURE ABOVE')
     layerrex = re.compile('[ \t]*LAYER ([^ \t\n]+)')
     resrex2  = re.compile('[ \t]*RESISTANCE RPERSQ 12.2 ;')
+    thickrex = re.compile('[ \t]*THICKNESS')
+    emptyrex = re.compile('^[ \t]*$')
     curlayer = None
+    thickness_seen = False
 
     for line in llines:
+        if thickness_seen:
+            thickness_seen = False
+            if curlayer and (curlayer == 'met1' or curlayer == 'met2'):
+                ematch = emptyrex.match(line)
+                if ematch:
+                    fixedlines.append('  MINENCLOSEDAREA 0.14 ;')
 
         # Check for the MANUFACTURINGGRID statement in the file, and
         # add the USEMINSPACING statement after it.
diff --git a/sky130/custom/scripts/mismatch_params.py b/sky130/custom/scripts/mismatch_params.py
index 0053542..c9388cc 100755
--- a/sky130/custom/scripts/mismatch_params.py
+++ b/sky130/custom/scripts/mismatch_params.py
@@ -36,7 +36,7 @@
 
 mismatch_params = []
 
-mmrex = re.compile('^\*[ \t]*mismatch[ \t]+\{')
+mmrex = re.compile('^\*[ \t]*mismatch[ \t]*\{')
 endrex = re.compile('^\*[ \t]*\}')
 
 filelist = []
@@ -72,10 +72,32 @@
                         tokens = line.split()
                         if 'vary' in tokens:
                             if ('dist=gauss' in tokens) or ('gauss' in tokens):
+                                gtype = 'A'
                                 mismatch_param = tokens[2]
-                                std_dev = float(tokens[-1].split('=')[-1])
-                                replacement = '{}*AGAUSS(0,{!s},1)'.format(mm_switch_param, std_dev)
+                                for token in tokens[3:]:
+                                    gparam = token.split('=')
+                                    if len(gparam) == 2:
+                                        if gparam[0] == 'std':
+                                            std_dev = float(gparam[1])
+                                        elif gparam[0] == 'percent' and gparam[1] == 'yes':
+                                            gtype = ''
+
+                                if gtype == '':
+                                    # Convert percentage to a fraction
+                                    std_dev = std_dev / 100
+                                repltext = '{}*' + gtype + 'GAUSS(0,{!s},1)'
+                                replacement = repltext.format(mm_switch_param, std_dev)
                                 mismatch_params.append((mismatch_param, replacement))
+                            elif ('dist=lnorm' in tokens) or ('lnorm' in tokens):
+                                mismatch_param = tokens[2]
+                                for token in tokens[3:]:
+                                    gparam = token.split('=')
+                                    if len(gparam) == 2:
+                                        if gparam[0] == 'std':
+                                            std_dev = float(gparam[1])
+                                replacement = '{}*EXP(AGAUSS(0,{!s},1))'.format(mm_switch_param, std_dev)
+                                mismatch_params.append((mismatch_param, replacement))
+
 
             infile.close()
 
diff --git a/sky130/custom/scripts/pdk_update.sh b/sky130/custom/scripts/pdk_update.sh
index 47910b2..c6bb970 100755
--- a/sky130/custom/scripts/pdk_update.sh
+++ b/sky130/custom/scripts/pdk_update.sh
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/bin/bash
 #
 #  pdk_update.sh --
 #
@@ -8,8 +8,8 @@
 #  Usage:	pdk_update.sh <directory>
 #
 
-if [ ! test -d $1 ] ; then
-    echo "Project does not exist in $pdir ;  Cannot update."
+if [ ! -d $1 ] ; then
+    echo "Project does not exist in $1 ;  Cannot update."
     exit 0
 fi
 
diff --git a/sky130/custom/scripts/process_params.py b/sky130/custom/scripts/process_params.py
index c27840a..9cfc122 100755
--- a/sky130/custom/scripts/process_params.py
+++ b/sky130/custom/scripts/process_params.py
@@ -37,7 +37,7 @@
 process_params = []
 
 parmrex = re.compile('^\.param[ \t]+')
-prrex = re.compile('^\*[ \t]*process[ \t]+\{')
+prrex = re.compile('^\*[ \t]*process[ \t]*\{')
 endrex = re.compile('^\*[ \t]*\}')
 
 filelist = []
@@ -73,10 +73,31 @@
                         tokens = line.split()
                         if 'vary' in tokens:
                             if ('dist=gauss' in tokens) or ('gauss' in tokens):
+                                gtype = 'A'
                                 process_param = tokens[2]
-                                std_dev = float(tokens[-1].split('=')[-1])
-                                replacement = ' + {}*AGAUSS(0,{!s},1)'.format(pr_switch_param, std_dev)
+                                for token in tokens[3:]:
+                                    gparam = token.split('=')
+                                    if len(gparam) == 2:
+                                        if gparam[0] == 'std':
+                                            std_dev = float(gparam[1])
+                                        elif gparam[0] == 'percent' and gparam[1] == 'yes':
+                                            gtype = ''
+                                if gtype == '':
+                                    # Convert percentage to a fraction
+                                    std_dev = std_dev / 100
+                                repltext = ' + {}*' + gtype + 'GAUSS(0,{!s},1)'
+                                replacement = repltext.format(pr_switch_param, std_dev)
                                 process_params.append((process_param, replacement))
+                            elif ('dist=lnorm' in tokens) or ('lnorm' in tokens):
+                                process_param = tokens[2]
+                                for token in tokens[3:]:
+                                    gparam = token.split('=')
+                                    if len(gparam) == 2:
+                                        if gparam[0] == 'std':
+                                            std_dev = float(gparam[1])
+                                replacement = ' + {}*EXP(AGAUSS(0,{!s},1))'.format(pr_switch_param, std_dev)
+                                process_params.append((process_param, replacement))
+
 
             infile.close()
 
diff --git a/sky130/qflow/sky130.sh b/sky130/qflow/sky130.sh
index 31a1fc9..effc569 100644
--- a/sky130/qflow/sky130.sh
+++ b/sky130/qflow/sky130.sh
@@ -32,9 +32,9 @@
 
 #ifdef METAL5
 #ifdef EF_FORMAT
-set techleffile=STAGING_PATH/TECHNAME/libs.ref/techLEF/LIBRARY/LIBRARY.tlef
+set techleffile=STAGING_PATH/TECHNAME/libs.ref/techLEF/LIBRARY/LIBRARY__nom.tlef
 #else (!EF_FORMAT)
-set techleffile=STAGING_PATH/TECHNAME/libs.ref/LIBRARY/techlef/LIBRARY.tlef
+set techleffile=STAGING_PATH/TECHNAME/libs.ref/LIBRARY/techlef/LIBRARY__nom.tlef
 #endif (!EF_FORMAT)
 #else
 # NOTE:  There is no technology LEF file for the 3-metal stack!