Modified the SRAM layout GDS to correct a wayward P+ layer that
made hierarchical extraction difficult.  Added an import script
for the SRAM to flatten various cells with difficult hierarchy,
so that the SRAM extracts properly.  Updated the JSON file for
the latest PDK updates.
diff --git a/VERSION b/VERSION
index 4480980..21a05c7 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.0.367
+1.0.368
diff --git a/gf180mcu/Makefile.in b/gf180mcu/Makefile.in
index e1b6b6e..620f997 100644
--- a/gf180mcu/Makefile.in
+++ b/gf180mcu/Makefile.in
@@ -1009,6 +1009,8 @@
 		-cdl cells/*/*.cdl noconvert \
 		-liberty cells/*/*.lib \
 		-gds cells/*/*.gds \
+			options=custom/scripts/gds_import_sram.tcl \
+			filter=custom/scripts/fix_sram_gds.py \
 		-lef cells/*/*.lef \
 		-verilog cells/*/*.v \
 		-library general gf180mcu_fd_ip_sram 2>&1 | tee -a ${GF180MCU$*}_make.log
diff --git a/gf180mcu/custom/scripts/fix_sram_gds.py b/gf180mcu/custom/scripts/fix_sram_gds.py
new file mode 100755
index 0000000..d0e9940
--- /dev/null
+++ b/gf180mcu/custom/scripts/fix_sram_gds.py
@@ -0,0 +1,91 @@
+#!/usr/bin/env python3
+#
+# fix_sram_gds.py ---
+#
+# Special-purpose script that does the work of what ought to be a simple
+# binary diff and patch.  Except that no such thing exists as a standard
+# offering on most Linux systems, so instead of adding another OS
+# package requirement, I'm just writing a binary search-and-replace in
+# python.
+#
+# The purpose of the patch is to modify the PPLUS (31:0) layer in cell
+# ypass_gate_* to correctly surround the DIFF instead of being offset,
+# and to add the same layer to ypass_gate_a_* where it is missing
+# entirely (the SRAM was at some point modified by GF by incorrectly
+# patching the layer at the top level cell, which fixes the problem,
+# but not in a proper way, and not in a way that allows Magic to read
+# and extract the hierarchical layout).
+#
+# 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 gf180mcu Makefile.
+
+import os
+import sys
+
+def filter(inname, outname):
+
+    # Read input
+    try:
+        with open(inname, 'rb') as inFile:
+            data = inFile.read()
+    except:
+        print('fix_sram_gds.py: failed to open ' + inname + ' for reading.', file=sys.stderr)
+        return 1
+
+    # orig_data looks for the PPLUS layer in the existing ypass_gate_* cell
+
+    orig_data = b'\x00\x04\x08\x00\x00\x06\x0d\x02\x00\x1f\x00\x06\x0e\x02\x00\x00\x00\x2c\x10\x03\x00\x00\x00\x00\x00\x00\xa8\xac\x00\x00\x00\x00\x00\x00\xea\x83\x00\x00\x0e\x79\x00\x00\xea\x83\x00\x00\x0e\x79\x00\x00\xa8\xac\x00\x00\x00\x00\x00\x00\xa8\xac\x00\x04\x11\x00'
+
+    # replace_data modifies the layer position to surround the diffusion
+
+    replace_data = b'\x00\x04\x08\x00\x00\x06\x0d\x02\x00\x1f\x00\x06\x0e\x02\x00\x00\x00\x2c\x10\x03\xff\xff\xfc\xea\x00\x00\xc9\xa9\xff\xff\xfc\xea\x00\x00\xe9\xac\x00\x00\x0e\x79\x00\x00\xe9\xac\x00\x00\x0e\x79\x00\x00\xc9\xa9\xff\xff\xfc\xea\x00\x00\xc9\xa9\x00\x04\x11\x00'
+
+    # orig_data2 is the first occurrence of layer datatype 31:0 in ypass_gate_a*
+
+    orig_data2 = b'\x00\x04\x08\x00\x00\x06\x0d\x02\x00\x1f\x00\x06\x0e\x02\x00\x00\x00\x2c\x10\x03\x00\x00\x01\xe0\x00\x00\x63\x15\x00\x00\x01\xe0\x00\x00\x69\x7d\x00\x00\x09\x74\x00\x00\x69\x7d\x00\x00\x09\x74\x00\x00\x63\x15\x00\x00\x01\xe0\x00\x00\x63\x15\x00\x04\x11\x00'
+
+    # This is not efficient, but only needs to be done once.
+
+    data = data.replace(orig_data, replace_data)
+    data = data.replace(orig_data2, orig_data2 + replace_data)
+
+    # 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):
+        os.unlink(outname)
+
+    # Write output
+    try:
+        with open(outname, 'wb') as ofile:
+            ofile.write(data)
+    except:
+        print('fix_sram_gds.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/gf180mcu/custom/scripts/gds_import_sram.tcl b/gf180mcu/custom/scripts/gds_import_sram.tcl
new file mode 100644
index 0000000..bbb0f15
--- /dev/null
+++ b/gf180mcu/custom/scripts/gds_import_sram.tcl
@@ -0,0 +1,15 @@
+# Set GDS import styles as needed to deal with the SRAM layouts.
+gds flatten true
+gds flatglob *$$*
+gds flatglob M1_N*
+gds flatglob M1_P*
+gds flatglob M2_M1*
+gds flatglob M3_M2*
+gds flatglob nmos_5p0*
+gds flatglob nmos_1p2*
+gds flatglob pmos_5p0*
+gds flatglob pmos_1p2*
+gds flatglob via1_*
+gds flatglob ypass_gate*
+# Ensure unique cell names when reading multiple GDS files
+calma unique true
diff --git a/gf180mcu/gf180mcu.json b/gf180mcu/gf180mcu.json
index 32dfdc1..69b5568 100644
--- a/gf180mcu/gf180mcu.json
+++ b/gf180mcu/gf180mcu.json
@@ -84,13 +84,13 @@
         "magic": "MAGIC_COMMIT"
     },
     "reference": {
-        "open_pdks": "141eea4d1bb8c6d4dd85fcbf2c0bdface7df9cfc",
+        "open_pdks": "3b7c10b059e14066bef632f53ff0a00a4d5c9f4d",
         "magic": "fb091fa03f3646b0f90639a0798b711ca400941d",
         "gf180mcu_pdk": "a897aa30369d3bcec87d9d50ce9b01f320f854ef",
-        "gf180mcu_fd_pr": "132dc738056751efdea1cd437c26c45e49862b07",
-        "gf180mcu_fd_io": "bcaa40aaf6cf04d6e9cb143d0e5b0de9429e53ab",
-        "gf180mcu_fd_sc_mcu7t5v0": "05bdaa35c3e2f856b3f8240e079de41bf7de9e57",
-        "gf180mcu_fd_sc_mcu9t5v0": "604a2d52319350ff0a57715c143b7efa2e174b6e",
+        "gf180mcu_fd_pr": "6aa5432a368138e9e6b899daade4c666f5ec808a",
+        "gf180mcu_fd_io": "2aeec51ea2824b6cc0b396acfc39f4535f40b23a",
+        "gf180mcu_fd_sc_mcu7t5v0": "8743b6f9641eb8707179c4e51703380d4dc90f16",
+        "gf180mcu_fd_sc_mcu9t5v0": "ac89034a23595aea1e450374fe257102e5b172f1",
         "gf180mcu_fd_ip_sram": "9c411928870ce15226228fa52ddb6ecc0ea4ffbe"
     }
 }
diff --git a/gf180mcu/magic/gf180mcu.tech b/gf180mcu/magic/gf180mcu.tech
index 82f1e97..21817c7 100644
--- a/gf180mcu/magic/gf180mcu.tech
+++ b/gf180mcu/magic/gf180mcu.tech
@@ -747,7 +747,7 @@
 	grow 160
 
  layer NPLUS
-        bloat-or *ndif,*ndiode,*nndiode,ndiffres,*mvndif,*mvndiode,*mvnndiode,mvndiffres * 20 allpactivenonfet 0
+        bloat-or *ndif,*ndiode,*nndiode,ndiffres,*mvndif,*mvndiode,*mvnndiode,mvndiffres * 160 allpactivenonfet 0
         bloat-or *nsd,*mvnsd * 20 allpactivenonfet 0
 	bloat-or allnfets,var,mvvar * 230
 	or shortntap,shortdntap