Finished first draft of ReRAM support for Sky130.  This completes
the modifications started with yesterday's commit, which split the
ReRAM-enabled process to PDK name sky130B.  Today's commit handles
the differences between PDK variants A and B, which are namely
(1) The technology LEF files (parasitic capacitance values for metals
from metal2 and up changed), and (2) The magic tech file (parasitic
capacitance values changed, and layer heights changed).
diff --git a/VERSION b/VERSION
index 6f664cc..3656d57 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.0.268
+1.0.269
diff --git a/docs.txt b/docs.txt
index 0b1345f..60fa77f 100644
--- a/docs.txt
+++ b/docs.txt
@@ -3,7 +3,7 @@
 
 ----------------------------------------------------------------------------------
 
-Written by Tim Edwards 2019 - 2021 for efabless (efabless.com)
+Written by Tim Edwards 2019 - 2022 for efabless (efabless.com)
 and Open Circuit Design (opencircuitdesign.com)
 
 URL: http://opencircuitdesign.com/open_pdks
diff --git a/sky130/Makefile.in b/sky130/Makefile.in
index 1f49f67..7edf57f 100644
--- a/sky130/Makefile.in
+++ b/sky130/Makefile.in
@@ -1099,7 +1099,7 @@
 		-library digital sky130_fd_sc_hd 2>&1 | tee -a ${SKY130$*}_make.log
 	# Install all SkyWater digital standard cells.
 	${STAGE} -source ${SKYWATER_LIBS_PATH} -target ${STAGING_PATH}/${SKY130$*} \
-		-techlef %l/latest/tech/*.tlef filter=custom/scripts/fix_techlef.py \
+		-techlef %l/latest/tech/*.tlef filter=custom/scripts/fix_techlef$*.py \
 		-spice %l/latest/cells/*/*.spice compile-only \
 			sort=../common/sort_pdkfiles.py \
 			filter=custom/scripts/fix_device_models.py \
@@ -1148,7 +1148,7 @@
 digital-hdll-%:
 	# Install all SkyWater digital standard cells.
 	${STAGE} -source ${SKYWATER_LIBS_PATH} -target ${STAGING_PATH}/${SKY130$*} \
-		-techlef %l/latest/tech/*.tlef filter=custom/scripts/fix_techlef.py \
+		-techlef %l/latest/tech/*.tlef filter=custom/scripts/fix_techlef$*.py \
 		-spice %l/latest/cells/*/*.spice compile-only \
 			sort=../common/sort_pdkfiles.py \
 			filter=custom/scripts/fix_device_models.py \
@@ -1187,7 +1187,7 @@
 		-library digital sky130_fd_sc_hvl 2>&1 | tee -a ${SKY130$*}_make.log
 	# Install all SkyWater digital standard cells.
 	${STAGE} -source ${SKYWATER_LIBS_PATH} -target ${STAGING_PATH}/${SKY130$*} \
-		-techlef %l/latest/tech/*.tlef filter=custom/scripts/fix_techlef.py \
+		-techlef %l/latest/tech/*.tlef filter=custom/scripts/fix_techlef$*.py \
 		-spice %l/latest/cells/*/*.spice compile-only \
 			no-copy=custom/sky130_fd_sc_hvl/spice/sky130_fd*.spice \
 			sort=../common/sort_pdkfiles.py \
@@ -1229,7 +1229,7 @@
 digital-lp-%:
 	# Install all SkyWater digital standard cells.
 	${STAGE} -source ${SKYWATER_LIBS_PATH} -target ${STAGING_PATH}/${SKY130$*} \
-		-techlef %l/latest/tech/*.tlef filter=custom/scripts/fix_techlef.py \
+		-techlef %l/latest/tech/*.tlef filter=custom/scripts/fix_techlef$*.py \
 		-spice %l/latest/cells/*/*.spice compile-only \
 			sort=../common/sort_pdkfiles.py \
 			filter=custom/scripts/fix_device_models.py \
@@ -1263,7 +1263,7 @@
 		-library digital sky130_fd_sc_hs 2>&1 | tee -a ${SKY130$*}_make.log
 	# Install all SkyWater digital standard cells.
 	${STAGE} -source ${SKYWATER_LIBS_PATH} -target ${STAGING_PATH}/${SKY130$*} \
-		-techlef %l/latest/tech/*.tlef filter=custom/scripts/fix_techlef.py \
+		-techlef %l/latest/tech/*.tlef filter=custom/scripts/fix_techlef$*.py \
 		-spice %l/latest/cells/*/*.spice compile-only \
 			sort=../common/sort_pdkfiles.py \
 			filter=custom/scripts/fix_device_models.py \
@@ -1294,7 +1294,7 @@
 digital-ms-%:
 	# Install all SkyWater digital standard cells.
 	${STAGE} -source ${SKYWATER_LIBS_PATH} -target ${STAGING_PATH}/${SKY130$*} \
-		-techlef %l/latest/tech/*.tlef filter=custom/scripts/fix_techlef.py \
+		-techlef %l/latest/tech/*.tlef filter=custom/scripts/fix_techlef$*.py \
 		-spice %l/latest/cells/*/*.spice compile-only \
 			sort=../common/sort_pdkfiles.py \
 			filter=custom/scripts/fix_device_models.py \
@@ -1324,7 +1324,7 @@
 digital-ls-%:
 	# Install all SkyWater digital standard cells.
 	${STAGE} -source ${SKYWATER_LIBS_PATH} -target ${STAGING_PATH}/${SKY130$*} \
-		-techlef %l/latest/tech/*.tlef filter=custom/scripts/fix_techlef.py \
+		-techlef %l/latest/tech/*.tlef filter=custom/scripts/fix_techlef$*.py \
 		-spice %l/latest/cells/*/*.spice compile-only \
 			sort=../common/sort_pdkfiles.py \
 			filter=custom/scripts/fix_device_models.py \
diff --git a/sky130/README b/sky130/README
index 0f192f8..11fdea5 100644
--- a/sky130/README
+++ b/sky130/README
@@ -41,6 +41,12 @@
     the path
 		/usr/share/pdks/sky130A/
 
+    From open_pdks version 1.0.269, there is a process variant
+
+		/usr/share/pdks/sky130B/
+
+    which reflects support for ReRAM.
+
 -------------------------------------------------------------------------------
 Detailed instructions for the patient reader:
 -------------------------------------------------------------------------------
@@ -252,8 +258,7 @@
 Summary of the installation directories:
 
     The Makefile script takes the source files and generates files for local
-    PDK names "SKY130A", "SKY130B", etc.  (Note there is currently only one
-    PDK variant "A".)
+    PDK names "SKY130A", "SKY130B", etc.
 
     The definition of each PDK is made in the Makefile using defines; e.g.,
 	-DMETAL5, etc.
diff --git a/sky130/custom/scripts/fix_techlef.py b/sky130/custom/scripts/fix_techlefA.py
similarity index 94%
rename from sky130/custom/scripts/fix_techlef.py
rename to sky130/custom/scripts/fix_techlefA.py
index af2af2b..76cc12e 100755
--- a/sky130/custom/scripts/fix_techlef.py
+++ b/sky130/custom/scripts/fix_techlefA.py
@@ -1,12 +1,13 @@
 #!/usr/bin/env python3
 #
-# fix_techlef ---
+# fix_techlefA ---
 #
 # This script adds the missing statement "USEMINSPACING OBS OFF" from
 # the technology LEF files for Sky130.
 #
 # 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 sky130 Makefile.
+# the value to "filter=" for the model install in the sky130 Makefile for
+# variant sky130A.
 
 import re
 import os
@@ -20,7 +21,7 @@
             ltext = inFile.read()
             llines = ltext.splitlines()
     except:
-        print('fix_techlef.py: failed to open ' + inname + ' for reading.', file=sys.stderr)
+        print('fix_techlefA.py: failed to open ' + inname + ' for reading.', file=sys.stderr)
         return 1
 
     # Process input with regexp
diff --git a/sky130/custom/scripts/fix_techlefB.py b/sky130/custom/scripts/fix_techlefB.py
new file mode 100755
index 0000000..bb18e90
--- /dev/null
+++ b/sky130/custom/scripts/fix_techlefB.py
@@ -0,0 +1,133 @@
+#!/usr/bin/env python3
+#
+# fix_techlefB ---
+#
+# This script adds the missing statement "USEMINSPACING OBS OFF" from
+# the technology LEF files for Sky130.
+#
+# This script also replaces the plate and fringing capacitance values for
+# route layers from metal2 to metal5 based on the ReRAM stackup (sky130B).
+#
+# 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 sky130 Makefile for
+# variant sky130B.
+
+import re
+import os
+import sys
+
+def filter(inname, outname):
+
+    # Read input
+    try:
+        with open(inname, 'r') as inFile:
+            ltext = inFile.read()
+            llines = ltext.splitlines()
+    except:
+        print('fix_techlefB.py: failed to open ' + inname + ' for reading.', file=sys.stderr)
+        return 1
+
+    # These edge capacitance values get modified
+    edgevalues =   [['37.759E-6', '32.918E-6'],
+		    ['40.989E-6', '37.065E-6'],
+		    ['36.676E-6', '34.169E-6'],
+		    ['38.851E-6', '36.828E-6']]
+
+    # These plate capacitance values get modified
+    platevalues =  [['16.9423E-6', '14.7703E-6'],
+		    ['12.3729E-6', '11.1883E-6'],
+		    ['8.41537E-6', '7.84019E-6'],
+		    ['6.32063E-6', '5.99155E-6']]
+
+    # Process input with regexp
+
+    fixedlines = []
+    modified = False
+
+    proprex  = re.compile('[ \t]*MANUFACTURINGGRID')
+    edgerex  = re.compile('[ \t]*EDGECAPACITANCE')
+    platerex = re.compile('[ \t]*CAPACITANCE[ \t]+CPERSQDIST')
+
+    for line in llines:
+
+        # Check for the MANUFACTURINGGRID statement in the file, and
+        # add the USEMINSPACING statement after it.
+
+        pmatch = proprex.match(line)
+        if pmatch:
+            fixedlines.append(line)
+            fixedlines.append('USEMINSPACING OBS OFF ;')
+            modified = True
+        else:
+            ematch = edgerex.match(line)
+            pmatch = platerex.match(line)
+            if ematch:
+                found = False
+                for ecap in edgevalues:
+                    if ecap[0] in line:
+                        fixedlines.append(re.sub(ecap[0], ecap[1], line))
+                        modified = True
+                        found = True
+                        break
+                if not found:
+                    fixedlines.append(line)
+            elif pmatch:
+                found = False
+                for pcap in platevalues:
+                    if pcap[0] in line:
+                        fixedlines.append(re.sub(pcap[0], pcap[1], line))
+                        modified = True
+                        found = True
+                        break
+                if not found:
+                    fixedlines.append(line)
+            else:
+                fixedlines.append(line)
+
+    # 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('fix_techlef.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/magic/sky130.tech b/sky130/magic/sky130.tech
index 0a8563e..0ceb6fb 100644
--- a/sky130/magic/sky130.tech
+++ b/sky130/magic/sky130.tech
@@ -5106,30 +5106,56 @@
  height allm1	     1.3761 0.36
  height m1fill	     1.3761 0.36
 #ifdef RERAM
- # TO-DO:  Rework all heights based on ReRAM!
-#endif (RERAM)
+ height v1	     1.7361 0.565
+ height allm2	     2.3011 0.36
+ height m2fill	     2.3011 0.36
+ height v2	     2.6611 0.42
+ height allm3	     3.0811 0.845
+ height m3fill	     3.0811 0.845
+#ifdef MIM
+ height mimcap	     2.7611 0.2
+ height mimcap2	     4.0261 0.2
+ height mimcc	     2.9611 0.12
+ height mim2cc	     4.2261 0.09
+#endif (MIM)
+#ifdef METAL5
+ height v3	     3.9261 0.39
+ height allm4	     4.3161 0.845
+ height m4fill	     4.3161 0.845
+ height v4	     5.1611 0.505
+ height allm5	     5.6661 1.26
+ height m5fill	     5.6661 1.26
+#ifdef REDISTRIBUTION
+ height mrdlc	     6.9261 0.63
+ height mrdl	     7.5561 3.0
+#endif (!REDISTRIBUTION)
+#endif (!METAL5)
+#else (!RERAM)
  height v1	     1.7361 0.27
  height allm2	     2.0061 0.36
- height m2fill	     1.3761 0.36
+ height m2fill	     2.0061 0.36
  height v2	     2.3661 0.42
  height allm3	     2.7861 0.845
- height m3fill	     1.3761 0.36
-#ifdef METAL5
- height v3	     3.6311 0.39
- height allm4	     4.0211 0.845
- height m4fill	     1.3761 0.36
- height v4	     4.8661 0.505
- height allm5	     5.3711 1.26
- height m5fill	     1.3761 0.36
+ height m3fill	     2.7861 0.845
+#ifdef MIM
  height mimcap	     2.4661 0.2
  height mimcap2	     3.7311 0.2
  height mimcc	     2.6661 0.12
  height mim2cc	     3.9311 0.09
+#endif (MIM)
+#ifdef METAL5
+ height v3	     3.6311 0.39
+ height allm4	     4.0211 0.845
+ height m4fill	     4.0211 0.845
+ height v4	     4.8661 0.505
+ height allm5	     5.3711 1.26
+ height m5fill	     5.3711 1.26
 #ifdef REDISTRIBUTION
  height mrdlc	     6.6311 0.63
  height mrdl	     7.2611 3.0
 #endif (!REDISTRIBUTION)
 #endif (!METAL5)
+#endif (!RERAM)
 
  # Antenna check parameters
  # Note that checks w/diode diffusion are not modeled
@@ -5305,12 +5331,39 @@
  defaultsideoverlap allm1 metal1 allli locali 59
  defaultsideoverlap allli locali allm1 metal1 35
 
-#ifdef RERAM
-# TO-DO:  Modify all metal stack parasitics above metal1 based on ReRAM!
-#endif (RERAM)
-
 #metal2
  defaultsidewall    allm2 metal2      50
+
+#ifdef RERAM
+# For ReRAM, all parasitics account for the additional 0.295um between
+# metal1 and metal2
+
+ defaultoverlap	    allm2 metal2 dnwell,isosub	     dwell 15
+ defaultareacap     allm2 metal2 nwell,obswell,pwell well 15
+ defaultperimeter   allm2 metal2 nwell,obswell,pwell well 33
+ defaultoverlap     allm2 metal2 nwell,obswell,pwell well 15
+ defaultsideoverlap allm2 metal2 nwell,obswell,pwell well 33
+
+#metal2->diff
+ defaultoverlap     allm2 metal2 allactivenonfet active 15
+ defaultsideoverlap allm2 metal2 allactivenonfet active 33
+
+#metal2->poly
+ defaultoverlap     allm2 metal2 allpolynonres active 20
+ defaultsideoverlap allm2 metal2 allpolynonres active 34
+ defaultsideoverlap *poly active allm2 metal2 9
+
+#metal2->locali
+ defaultoverlap     allm2 metal2 allli locali 29
+ defaultsideoverlap allm2 metal2 allli locali 35
+ defaultsideoverlap allli locali allm2 metal2 17
+
+#metal2->metal1
+ defaultoverlap     allm2 metal2 allm1 metal1 64
+ defaultsideoverlap allm2 metal2 allm1 metal1 32
+ defaultsideoverlap allm1 metal1 allm2 metal2 23
+
+#else (!RERAM)
  defaultoverlap	    allm2 metal2 dnwell,isosub	     dwell 17
  defaultareacap     allm2 metal2 nwell,obswell,pwell well 17
  defaultperimeter   allm2 metal2 nwell,obswell,pwell well 38
@@ -5336,8 +5389,38 @@
  defaultsideoverlap allm2 metal2 allm1 metal1 67
  defaultsideoverlap allm1 metal1 allm2 metal2 48
 
+#endif (!RERAM)
+
 #metal3
  defaultsidewall    allm3 metal3     63
+
+#ifdef RERAM
+ defaultoverlap	    allm3 metal3 dnwell,isosub	     dwell 11
+ defaultareacap     allm3 metal3 nwell,obswell,pwell well 11
+ defaultperimeter   allm3 metal3 nwell,obswell,pwell well 37
+ defaultoverlap     allm3 metal3 nwell,obswell,pwell well 11
+ defaultsideoverlap allm3 metal3 nwell,obswell,pwell well 37
+
+#metal3->diff
+ defaultoverlap     allm3 metal3 allactive active 11
+ defaultsideoverlap allm3 metal3 allactive active 37
+
+#metal3->poly
+ defaultoverlap     allm3 metal3 allpolynonres active 14
+ defaultsideoverlap allm3 metal3 allpolynonres active 39
+ defaultsideoverlap *poly active allm3 metal3 8
+
+#metal3->locali
+ defaultoverlap     allm3 metal3 allli locali 18
+ defaultsideoverlap allm3 metal3 allli locali 40
+ defaultsideoverlap allli locali allm3 metal3 13
+
+#metal3->metal1
+ defaultoverlap     allm3 metal3 allm1 metal1 27
+ defaultsideoverlap allm3 metal3 allm1 metal1 43
+ defaultsideoverlap allm1 metal1 allm3 metal3 21
+
+#else (!RERAM)
  defaultoverlap	    allm3 metal3 dnwell,isosub	     dwell 12
  defaultareacap     allm3 metal3 nwell,obswell,pwell well 12
  defaultperimeter   allm3 metal3 nwell,obswell,pwell well 41
@@ -5363,6 +5446,8 @@
  defaultsideoverlap allm3 metal3 allm1 metal1 55
  defaultsideoverlap allm1 metal1 allm3 metal3 27
 
+#endif (!RERAM)
+
 #metal3->metal2
  defaultoverlap     allm3 metal3 allm2 metal2 86
  defaultsideoverlap allm3 metal3 allm2 metal2 70
@@ -5371,6 +5456,34 @@
 #ifdef METAL5
 #metal4
  defaultsidewall    allm4 metal4       67
+#ifdef RERAM
+# defaultareacap     alltopm metal4 well  6
+ defaultoverlap	    allm4 metal4 dnwell,isosub	     dwell 8
+ areacap     	    allm4/m4 8
+ defaultperimeter   allm4 metal4 nwell,obswell,pwell well 34
+ defaultoverlap     allm4 metal4 nwell,obswell,pwell well 8
+ defaultsideoverlap allm4 metal4 nwell,obswell,pwell well 34
+
+#metal4->diff
+ defaultoverlap     allm4 metal4 allactivenonfet active 8
+ defaultsideoverlap allm4 metal4 allactivenonfet active 34
+
+#metal4->poly
+ defaultoverlap     allm4 metal4 allpolynonres active 9
+ defaultsideoverlap allm4 metal4 allpolynonres active 35
+ defaultsideoverlap *poly active allm4 metal4 6
+
+#metal4->locali
+ defaultoverlap     allm4 metal4 allli locali 11
+ defaultsideoverlap allm4 metal4 allli locali 36
+ defaultsideoverlap allli locali allm4 metal4 9
+
+#metal4->metal1
+ defaultoverlap     allm4 metal4 allm1 metal1 13
+ defaultsideoverlap allm4 metal4 allm1 metal1 38
+ defaultsideoverlap allm1 metal1 allm4 metal4 15
+
+#else (!RERAM)
 # defaultareacap     alltopm metal4 well  6
  defaultoverlap	    allm4 metal4 dnwell,isosub	     dwell 8
  areacap     	    allm4/m4 8
@@ -5397,6 +5510,8 @@
  defaultsideoverlap allm4 metal4 allm1 metal1 43
  defaultsideoverlap allm1 metal1 allm4 metal4 16
 
+#endif (!RERAM)
+
 #metal4->metal2
  defaultoverlap     allm4 metal4 allm2 metal2 20
  defaultsideoverlap allm4 metal4 allm2 metal2 46
@@ -5409,6 +5524,34 @@
 
 #metal5
  defaultsidewall    allm5 metal5       127
+#ifdef RERAM
+# defaultareacap     allm5 metal5 well  6
+ defaultoverlap	    allm5 metal5 dnwell,isosub	     dwell 6
+ areacap     	    allm5/m5 6
+ defaultoverlap     allm5 metal5 nwell,obswell,pwell well  6
+ defaultperimeter   allm5 metal5 nwell,obswell,pwell well  36
+ defaultsideoverlap allm5 metal5 nwell,obswell,pwell well  36
+
+#metal5->diff
+ defaultoverlap     allm5 metal5 allactivenonfet active 6
+ defaultsideoverlap allm5 metal5 allactivenonfet active 36
+
+#metal5->poly
+ defaultoverlap     allm5 metal5 allpolynonres active 7
+ defaultsideoverlap allm5 metal5 allpolynonres active 38
+ defaultsideoverlap *poly active allm5 metal5 6
+
+#metal5->locali
+ defaultoverlap     allm5 metal5 allli locali 8
+ defaultsideoverlap allm5 metal5 allli locali 39
+ defaultsideoverlap allli locali allm5 metal5 7
+
+#metal5->metal1
+ defaultoverlap     allm5 metal5 allm1 metal1 9
+ defaultsideoverlap allm5 metal5 allm1 metal1 40
+ defaultsideoverlap allm1 metal1 allm5 metal5 11
+
+#else (!RERAM)
 # defaultareacap     allm5 metal5 well  6
  defaultoverlap	    allm5 metal5 dnwell,isosub	     dwell 6
  areacap     	    allm5/m5 6
@@ -5435,6 +5578,8 @@
  defaultsideoverlap allm5 metal5 allm1 metal1 43
  defaultsideoverlap allm1 metal1 allm5 metal5 12
 
+#endif (!RERAM)
+
 #metal5->metal2
  defaultoverlap     allm5 metal5 allm2 metal2 11
  defaultsideoverlap allm5 metal5 allm2 metal2 46