A number of updates to the magic tech file for GF180MCU in
concert with changes to the gf180mcu_ocd_io library to resolve
various DRC issues.
diff --git a/VERSION b/VERSION
index 04e9b00..79de682 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.0.561
+1.0.562
diff --git a/gf180mcu/gf180mcu.json b/gf180mcu/gf180mcu.json
index 24a143e..85d8312 100644
--- a/gf180mcu/gf180mcu.json
+++ b/gf180mcu/gf180mcu.json
@@ -95,8 +95,8 @@
         "magic": "MAGIC_COMMIT"
     },
     "reference": {
-        "open_pdks": "d2752164328c3ca94490405be0db932da62a390c",
-        "magic": "441d93314836f2443e9d5786912b6f3e2a2a705a",
+        "open_pdks": "2873ebc687189850c9b754bb762fe8a35c917815",
+        "magic": "98aa2f760a8e8d51a83e85802077abf6d0e9587b",
         "gf180mcu_pdk": "a897aa30369d3bcec87d9d50ce9b01f320f854ef",
         "gf180mcu_fd_pr": "739f508876db86bd7d3403f1fe056dedfeaabdab",
         "gf180mcu_fd_pv": "50cc2fe338c81925e24a6ac4907ddaab534c1312",
@@ -105,7 +105,7 @@
         "gf180mcu_fd_sc_mcu9t5v0": "e0e80f5a6522f10b82165d3aeab9b8ee28e89849",
         "gf180mcu_fd_ip_sram": "9c411928870ce15226228fa52ddb6ecc0ea4ffbe",
         "gf180mcu_as_sc_mcu7t3v3": "51f4e2a6d9692f3f8982dffaf7c012272a4b4ca3",
-        "gf180mcu_ocd_io": "634ba381118fcaba02f4a944cfeb126f082afce5",
+        "gf180mcu_ocd_io": "2fa4cdcd8c88c29590572a1b6750912a21413da9",
         "gf180mcu_ocd_alpha": "076bab7ac11118e1aa810ccf75e5c297b5501fcc",
         "gf180mcu_ocd_ip_sram": "f91d74cc332f2947b7da10c96baab1b41d8529ae",
         "gf180mcu_osu_sc_gf12t3v3": "aa2fa8cd1bcb8fe98669acd05c0b0c65879268b3",
diff --git a/gf180mcu/magic/gf180mcu.tech b/gf180mcu/magic/gf180mcu.tech
index e0b5df0..e5938a8 100644
--- a/gf180mcu/magic/gf180mcu.tech
+++ b/gf180mcu/magic/gf180mcu.tech
@@ -970,8 +970,10 @@
 # DUALGATE (thickox)
 #-----------------------------------------------------
 
- layer DUALGATE allfetsmv
-	bloat-all mvhires *poly
+ layer DUALGATE
+	# NOTE:  This rule requires satisfying PL.19;  poly cannot
+	# cross a DUALGATE boundary.
+	bloat-all mvhires,allfetsmv *poly
 	# Rule DV.8 (DUALGATE around poly)
 	grow 400
 	# Rule DV.6 (DUALGATE around diff, LV substrate tap excepted)
@@ -1011,7 +1013,8 @@
  # flagged for DRC errors.
 
  layer FET5VDEF
-	bloat-all mvnfet,mvpfet,srammvnfet,srammvpfet *mvndiff,*mvpdiff
+	bloat-all mvnfet,mvpfet,srammvnfet,srammvpfet \
+		*mvndiff,*mvpdiff,mvndiffres,mvpdiffres
 	grow 100
 	calma 112 1
 
@@ -1355,8 +1358,15 @@
 #-----------------------------------------------------
 # RESDEF MARK
 #-----------------------------------------------------
+# Identify unsalicided drain areas in I/O ESD structures.
+# These are not marked with RESDEF.
+ templayer esd_io
+	bloat-all mvndiffres *mvndiff,hvnfet,mvnfet
+	bloat-all mvpdiffres *mvpdiff,hvpfet,mvpfet
+
  layer RESDEF allres
- calma 110 5
+	and-not esd_io
+	calma 110 5
 
 #-----------------------------------------------------
 # METAL RESISTOR IDs
@@ -1428,6 +1438,17 @@
  mask-hints SRAMDEF
  calma 108 5
 
+# I/O pads should have latchup and ESD markers;  these are not
+# recognized layers and must be handled with mask hints.
+
+ layer LATCHUP_ID esd_io
+ mask-hints LATCHUP_ID
+ calma 137 5
+
+ layer ESD_ID esd_io
+ mask-hints ESD_ID
+ calma 24 5
+
 #------------------------------------------------------------------------
 # FILLBLOCK (NOTE: two layers define this on active, then poly & metal)
 #------------------------------------------------------------------------
@@ -3170,11 +3191,15 @@
 	"Diffusion spacing < %d (DF.3a)"
  spacing alldiffmv,mvnvar,mvpvar alldiffmv,mvnvar,mvpvar 360 touching_ok \
 	"Diffusion spacing < %d (DF.3a)"
- # Low voltage tap cannot abut high voltage source/drain
- spacing *mvpdiff,mvpvar,*srammvpdiff *nsd 360 touching_illegal \
+ spacing *mvpdiff,mvpvar,*srammvpdiff *mvnsd 360 touching_illegal \
 	"Diffusion spacing to tap < %d (DF.3a)"
- spacing *mvndiff,mvnvar,*srammvndiff *psd 360 touching_illegal \
+ spacing *mvndiff,mvnvar,*srammvndiff *mvpsd 360 touching_illegal \
 	 "Diffusion spacing to tap < %d (DF.3a)"
+ # Low voltage tap to high voltage diffusion has to clear DUALGATE-to-COMP spacing
+ spacing *mvpdiff,mvpvar,*srammvpdiff *nsd 480 touching_illegal \
+	"5/6V Diffusion spacing to 3.3V tap < %d (DV.6 + DV.3)"
+ spacing *mvndiff,mvnvar,*srammvndiff *psd 480 touching_illegal \
+	 "5/6V Diffusion spacing to 3.3V tap < %d (DV.6 + DV.3)"
 
  spacing (*ndiff,*ndiode,nfet,nnfet,ncap)/a allnwell 430 touching_illegal \
 	"N-Diffusion spacing to N-well < %d (DF.8)"
@@ -5241,8 +5266,8 @@
  device rsubcircuit nwell rnw   nwell allpsub error l=r_length w=r_width
 
  # The following absorbs the source/drain resistor into a *_dss FET device
- device subcircuit Short mvndiffres *mvndiff hvnfet allpsub error
- device subcircuit Short mvpdiffres *mvpdiff hvpfet allnwell error
+ device subcircuit Short mvndiffres *mvndiff hvnfet,mvnfet allpsub error
+ device subcircuit Short mvpdiffres *mvpdiff hvpfet,mvpfet allnwell error
  device subcircuit Short ndiffres *ndiff nfet allpsub error
  device subcircuit Short pdiffres *pdiff pfet allnwell error
 
diff --git a/sky130/sky130.json b/sky130/sky130.json
index f95b44e..e4b3b90 100644
--- a/sky130/sky130.json
+++ b/sky130/sky130.json
@@ -94,8 +94,8 @@
         "magic": "MAGIC_COMMIT"
     },
     "reference": {
-        "open_pdks": "d2752164328c3ca94490405be0db932da62a390c",
-        "magic": "441d93314836f2443e9d5786912b6f3e2a2a705a",
+        "open_pdks": "2873ebc687189850c9b754bb762fe8a35c917815",
+        "magic": "98aa2f760a8e8d51a83e85802077abf6d0e9587b",
         "sky130_fd_pr": "c996d0e7417d7574714079050e2768da70f7fdca",
         "sky130_fd_io": "e60737bf624df95c211fe99c007ddec78e3e081d",
         "sky130_fd_sc_hs": "c4cfcd760f1964f1670a1ed99c71c7c12b7ad49f",