Finished pass through the DRC rule templates and fixed all of them
that I could determine how to fix, leaving only a handful of errors
not handled correctly.
diff --git a/sky130/magic/sky130.tech b/sky130/magic/sky130.tech
index 5be057a..69faf54 100644
--- a/sky130/magic/sky130.tech
+++ b/sky130/magic/sky130.tech
@@ -367,6 +367,8 @@
   allnfets	   nfet,npass,npd,scnfet,mvnfet,mvnnfet,nfetlvt,nsonos
   allpfets	   pfet,ppu,scpfet,mvpfet,pfethvt,pfetlvt,pfetmvt
   allfets	   allnfets,allpfets,varactor,mvvaractor,varhvt
+  allfetsstd	   nfet,mvnfet,mvnnfet,nfetlvt,pfet,mvpfet,pfethvt,pfetlvt,pfetmvt
+  allfetsspecial   npass,npd,scnfet,nsonos,ppu,scpfet
 
   allnactivenonfet *ndiff,*nsd,*ndiode,*nndiode,*mvndiff,*mvnsd,*mvndiode,*ndiodelvt
   allnactive	   allnactivenonfet,allnfets
@@ -1313,6 +1315,19 @@
  templayer dnwell_missing nsonos
  and-not dnwell
 
+ # SONOS nFET devices must be in cell with abutment box
+ templayer abutment_box
+	boundary
+
+ templayer bbox_missing nsonos
+	and-not abutment_box
+
+ # Make sure nwell covers varactor poly
+ templayer var_poly_no_nwell
+	bloat-all *poly varactor,mvvaractor
+	grow 150
+	and-not nwell
+
  # Define MiM cap bottom plate for spacing rule
  templayer mim_bottom
  bloat-all *mimcap *metal3
@@ -1472,6 +1487,17 @@
  and-not dnwell
  and allpdifflv,allpdiffmv
 
+ templayer nwell_with_tap
+ bloat-all nsc,mvnsc nwell
+
+ templayer nwell_missing_tap nwell
+ and-not nwell_with_tap
+
+ # Make sure varactor nwell contains no P diffusion
+ templayer pdiff_in_varactor_well
+ bloat-all varactor,mvvaractor nwell
+ and allpactive
+
  templayer m1_small_hole allm1,obsm1,obslic
  close   140000
 
@@ -1484,6 +1510,42 @@
  templayer m2_hole_empty m2_small_hole
  and-not allm2,obsm2
 
+ templayer m1_huge allm1
+ shrink 1500
+ grow 1500
+
+ templayer m1_large_halo m1_huge
+ grow 280
+ and-not m1_huge
+ and allm1
+
+ templayer m2_huge allm2
+ shrink 1500
+ grow 1500
+
+ templayer m2_large_halo m2_huge
+ grow 280
+ and-not m2_huge
+ and allm2
+
+ templayer m3_huge allm3
+ shrink 1500
+ grow 1500
+
+ templayer m3_large_halo m3_huge
+ grow 400
+ and-not m3_huge
+ and allm3
+
+ templayer m4_huge allm4
+ shrink 1500
+ grow 1500
+
+ templayer m4_large_halo m4_huge
+ grow 400
+ and-not m4_huge
+ and allm4
+
 #ifdef EXPERIMENTAL
 #----------------------------------------------------------------
 style paint
@@ -4917,12 +4979,16 @@
  spacing dnwell dnwell 6300 touching_ok "Deep N-well spacing < %d (dnwell.3)"
  spacing dnwell allnwell 4500 surround_ok \
 	"Deep N-well spacing to N-well < %d (nwell.7)"
+
+ variants (full)
  cifmaxwidth nwell_missing 0 bend_illegal \
 	"N-well overlap of Deep N-well < 0.4um outside, 1.03um inside (nwell.5a, 7)"
  cifmaxwidth dnwell_missing 0 bend_illegal \
 	"SONOS nFET must be in Deep N-well (tunm.6a)"
+
  cifmaxwidth pdiff_crosses_dnwell 0 bend_illegal \
 	"P+ diff cannot straddle Deep N-well (dnwell.5)"
+ variants (fast),(full)
 
 #-----------------------------
 # NWELL
@@ -4931,6 +4997,11 @@
  width allnwell 840 "N-well width < %d (nwell.1)"
  spacing allnwell allnwell 1270 touching_ok "N-well spacing < %d (nwell.2a)"
 
+ variants (full)
+ cifmaxwidth nwell_missing_tap 0 bend_illegal \
+	"All nwells must contain metal-connected N+ taps (nwell.4)"
+ variants (fast),(full)
+
 #-----------------------------
 # DIFF
 #-----------------------------
@@ -4939,6 +5010,7 @@
 	150 "Diffusion width < %d (diff/tap.1)"
  width *mvndiff,mvnfet,mvnnfet,*mvndiode,*nndiode,mvndiffres,*mvpdiff,mvpfet,*mvpdiode 290 \
 	"MV Diffusion width < %d (diff/tap.14)"
+
  width *mvnsd,*mvpsd 150 "MV Tap width < %d (diff/tap.1)"
  extend *mvpsd *mvndiff 700 "MV Butting tap length < %d (diff/tap.16)"
  extend *mvnsd *mvpdiff 700 "MV Butting tap length < %d (diff/tap.16)"
@@ -4983,22 +5055,26 @@
 
  # Butting junction rules
  edge4way (*psd)/a ~(*ndiff,*psd)/a 125 ~(*ndiff)/a (*ndiff)/a 125 \
-	"N-Diffusion to P-tap spacing < %d across butted junction"
+	"N-Diffusion to P-tap spacing < %d across butted junction (psd.5b)"
  edge4way (*ndiff)/a ~(*ndiff,*psd)/a 125 ~(*psd)/a (*psd)/a 125 \
-	"N-Diffusion to P-tap spacing < %d across butted junction"
+	"N-Diffusion to P-tap spacing < %d across butted junction (psd.5a)"
  edge4way (*nsd)/a ~(*pdiff,*nsd)/a 125 ~(*pdiff)/a (*pdiff)/a 125 \
-	"P-Diffusion to N-tap spacing < %d across butted junction"
+	"P-Diffusion to N-tap spacing < %d across butted junction (nsd.5b)"
  edge4way (*pdiff)/a ~(*pdiff,*nsd)/a 125 ~(*nsd)/a (*nsd)/a 125 \
-	"P-Diffusion to N-tap spacing < %d across butted junction"
+	"P-Diffusion to N-tap spacing < %d across butted junction (nsd.5a)"
 
  edge4way (*mvpsd)/a ~(*mvndiff,*mvpsd)/a 125 ~(*mvndiff)/a (*mvndiff)/a 125 \
-	"MV N-Diffusion to MV P-tap spacing < %d across butted junction"
+	"MV N-Diffusion to MV P-tap spacing < %d across butted junction (psd.5b)"
  edge4way (*mvndiff)/a ~(*mvndiff,*mvpsd)/a 125 ~(*mvpsd)/a (*mvpsd)/a 125 \
-	"MV N-Diffusion to MV P-tap spacing < %d across butted junction"
+	"MV N-Diffusion to MV P-tap spacing < %d across butted junction (psd.5a)"
  edge4way (*mvnsd)/a ~(*mvpdiff,*mvnsd)/a 125 ~(*mvpdiff)/a (*mvpdiff)/a 125 \
-	"MV P-Diffusion to MV N-tap spacing < %d across butted junction"
+	"MV P-Diffusion to MV N-tap spacing < %d across butted junction (nsd.5b)"
  edge4way (*mvpdiff)/a ~(*mvpdiff,*mvnsd)/a 125 ~(*mvnsd)/a (*mvnsd)/a 125 \
-	"MV P-Diffusion to MV N-tap spacing < %d across butted junction"
+	"MV P-Diffusion to MV N-tap spacing < %d across butted junction (nsd.5a)"
+
+ # Sandwiched butting junction restrictions
+ edge4way (*pdiff)/a (*nsd)/a 400 ~(*pdiff)/a 0 0 "NSDM width < %d (diff/tap.5)
+ edge4way (*ndiff)/a (*psd)/a 400 ~(*ndiff)/a 0 0 "PSDM width < %d (diff/tap.5)
 
  variants (full)
 
@@ -5010,7 +5086,7 @@
  cifmaxwidth ntap_missing 0 bend_illegal \
 	"P-diff distance to N-tap must be < 15.0um (LU.3)"
 
- variants *
+ variants (fast),(full)
 
 #-----------------------------
 # POLY
@@ -5018,8 +5094,11 @@
 
  width allpoly 150 "poly width < %d (poly.1a)"
  spacing allpoly allpoly 210 touching_ok "poly spacing < %d (poly.2)"
- spacing allpolynonfet alldifflvnonfet 75 corner_ok allfets \
-	"poly spacing to Diffusion < %d (poly.4a)"
+
+ spacing allpolynonfet \
+	*ndif,*ndiode,*nndiode,ndiffres,*ndiodelvt,*pdif,*pdiode,pdiffres,*pdiodelvt,*pdiodehvt \
+	75 corner_ok allfets \
+	"poly spacing to Diffusion < %d (poly.4)"
  spacing npres *nsd 480 touching_illegal \
 	"poly resistor spacing to N-tap < %d (poly.9)"
  overhang *ndiff,rndiff nfet,scnfet,npd,npass 250 "N-Diffusion overhang of nmos < %d (poly.7)"
@@ -5032,9 +5111,16 @@
  rect_only xhrpoly,uhrpoly "No bends in poly resistors (poly.11)"
  extend  xpc/a xhrpoly,uhrpoly 2160 \
  	"poly contact extends poly resistor by < %d (licon.1c + li.5)"
- spacing xhrpoly,uhrpoly xhrpoly,uhrpoly 1240 touching_illegal \
+ spacing xhrpoly,uhrpoly,xpc xhrpoly,uhrpoly,xpc 1240 touching_illegal \
 	"Distance between precision resistors < %d (rpm.2 + 2 * rpm.3)"
 
+ spacing xhrpoly,uhrpoly,xpc allndifflv,allndiffmv 780 touching_illegal \
+	"Distance from precision resistor to N+ diffusion < %d (rpm.3 + rpm.6 + nsd.5a)"
+ spacing xhrpoly,uhrpoly,xpc *poly 400 touching_illegal \
+	"Distance from precision resistor to unrelated poly < %d (rpm.3 + rpm.7)"
+ spacing xhrpoly,uhrpoly,xpc allndiffmvnontap 830 touching_illegal \
+	"Distance from precision resistor to MV N+ diffusion < %d (rpm.3 + rpm.9)"
+
 #--------------------------------------------------------------------
 # HVTP
 #--------------------------------------------------------------------
@@ -5043,6 +5129,9 @@
 		360 touching_illegal \
 		"Min. spacing between pFET and HVTP < %d (hvtp.4)"
 
+ spacing pmoshvt,pdiodehvt,varactorhvt varactor 360 touching_illegal \
+		"Min. spacing between varactor and HVTP < %d (hvtp.4 + varac.3)"
+
 #--------------------------------------------------------------------
 # LVTN
 #--------------------------------------------------------------------
@@ -5192,6 +5281,8 @@
 # LI - Local interconnect layer
 #-------------------------------------------------------------
 
+variants *
+
  width *li 170 "Local interconnect width < %d (li.1)"
  width rli 290 "Local interconnect width < %d (li.7)"
  width coreli 140 "Core local interconnect width < %d (li.c1)"
@@ -5231,13 +5322,16 @@
 
 variants (fast),(full)
  widespacing allm1 3000 allm1,*obsm1 280 touching_ok \
-	"Metal1 > 3um spacing to unrelated m1 < %d (met1.3a)"
+	"Metal1 > 3um spacing to unrelated m1 < %d (met1.3b)"
  widespacing *obsm1 3000 allm1 280 touching_ok \
-	"Metal1 > 3um spacing to unrelated m1 < %d (met1.3a)"
+	"Metal1 > 3um spacing to unrelated m1 < %d (met1.3b)"
 
 variants (full)
  cifmaxwidth m1_hole_empty 0 bend_illegal \
 	"Min area of metal1 holes > 0.14um^2 (met1.7)"
+
+ cifspacing m1_large_halo m1_large_halo 280 touching_ok \
+	"Spacing of metal1 features attached to and within 0.28um of large metal1 < %d (met1.3a)"
 variants *
 
 #--------------------------------------------------
@@ -5263,13 +5357,16 @@
 
 variants (fast),(full)
  widespacing allm2 3000 allm2,obsm2  280 touching_ok \
-	"Metal2 > 3um spacing to unrelated m2 < %d (met2.3)"
+	"Metal2 > 3um spacing to unrelated m2 < %d (met2.3b)"
  widespacing obsm2 3000 allm2  280 touching_ok \
-	"Metal2 > 3um spacing to unrelated m2 < %d (met2.3)"
+	"Metal2 > 3um spacing to unrelated m2 < %d (met2.3b)"
 
 variants (full)
  cifmaxwidth m2_hole_empty 0 bend_illegal \
 	"Min area of metal2 holes > 0.14um^2 (met2.7)"
+
+ cifspacing m2_large_halo m2_large_halo 280 touching_ok \
+	"Spacing of metal2 features attached to and within 0.28um of large metal2 < %d (met2.3a)"
 variants *
 
 #--------------------------------------------------
@@ -5299,6 +5396,8 @@
 	"Metal3 > 3um spacing to unrelated m3 < %d (met3.3d)"
  widespacing obsm3 3000 allm3  400 touching_ok \
 	"Metal3 > 3um spacing to unrelated m3 < %d (met3.3d)"
+ cifspacing m3_large_halo m3_large_halo 400 touching_ok \
+	"Spacing of metal3 features attached to and within 0.40um of large metal3 < %d (met3.3c)"
 variants *
 
 
@@ -5332,6 +5431,8 @@
 	"Metal4 > 3um spacing to unrelated m4 < %d (met4.5b)"
  widespacing obsm4 3000 allm4  400 touching_ok \
 	"Metal4 > 3um spacing to unrelated m4 < %d (met4.5b)"
+ cifspacing m4_large_halo m4_large_halo 400 touching_ok \
+	"Spacing of metal4 features attached to and within 0.40um of large metal4 < %d (met4.5a)"
 variants *
 
 #--------------------------------------------------
@@ -5365,7 +5466,7 @@
  surround glass metrdl 10750 absence_ok "RDL must surround glass cut by %d (rdl.3)"
  spacing metrdl padl 19660 surround_ok "RDL spacing to unrelated pad < %d (rdl.6)"
 
-variants *
+variants (fast),(full)
 
 #endif (REDISTRIBUTION)
 
@@ -5373,14 +5474,18 @@
 # NMOS, PMOS
 #--------------------------------------------------
 
- extend allfets *poly 420 "Transistor width < %d (diff/tap.2)"
+ edge4way *poly allfetsstd 420 allfets 0 0 \
+	"Transistor width < %d (diff/tap.2)"
+ edge4way *poly allfetsspecial 360 allfets 0 0 \
+	"Transistor in standard cell width < %d (diff/tap.2)"
+
  # Except:  Note that standard cells allow transistor width minimum 0.36um
  width pfetlvt 350 "LVT PMOS gate length < %d (poly.1b)"
 
- spacing *nsd,*mvnsd allpolynonfet 55 touching_illegal \
-	"N-tap spacing to field poly < %d (poly.5)"
- spacing *psd,*mvpsd allpolynonfet 55 touching_illegal \
-	"P-tap spacing to field poly < %d (poly.5)"
+ spacing allpolynonfet *nsd 55 corner_ok varactor \
+	"poly spacing to diffusion tap < %d (poly.5)"
+ spacing allpolynonfet *mvnsd 55 corner_ok mvvaractor \
+	"poly spacing to diffusion tap < %d (poly.5)"
 
  # Full edge rule required to describe FET to butted tap distance
  edge4way *psd *ndiff 300 *ndiff *psd 300 \
@@ -5426,19 +5531,31 @@
 
 #--------------------------------------------------
 # xhrpoly (P+ poly resistor)
-#--------------------------------------------------
-
-  width xhrpoly 350 "xhrpoly resistor width < %d (P+ poly.1a)"
-  # NOTE: xhrpoly resistor requires choice of discrete widths 0.35, 0.69, ... up to 1.27.
-
-#--------------------------------------------------
 # uhrpoly (P+ poly resistor, 2kOhm/sq)
 #--------------------------------------------------
 
-  width uhrpoly 350 "uhrpoly resistor width < %d"
+  # NOTE: u/xhrpoly resistor requires discrete widths 0.35, 0.69, ... up to 1.27.
+  width xhrpoly 350 "xhrpoly resistor width < %d (P+ poly.1a)"
+  width uhrpoly 350 "uhrpoly resistor width < %d (P+ poly.1a)"
+
   spacing xhrpoly,uhrpoly,xpc alldiff 480 touching_illegal \
 	"xhrpoly/uhrpoly resistor spacing to diffusion < %d (poly.9)"
 
+  spacing allpolyres,xpc *poly,allfets 480 touching_illegal \
+	"Poly resistor spacing to poly < %d (poly.9)"
+
+  spacing allpolyres,xpc alldiff 480 touching_illegal \
+	"Poly resistor spacing to diffusion < %d (poly.9)"
+
+#------------------------------------
+# nsonos
+#------------------------------------
+
+variants (full)
+  cifmaxwidth bbox_missing 0 bend_illegal \
+	"SONOS transistor must be in cell with abutment box (tunm.8)"
+variants (fast),(full)
+
 #------------------------------------
 # MOS Varactor device rules
 #------------------------------------
@@ -5452,6 +5569,14 @@
  width var,varhvt,mvvar 180 "Varactor length < %d (var.1)"
  extend var,varhvt,mvvar *poly 1000 "Varactor width < %d (var.2)"
 
+variants (full)
+ cifmaxwidth var_poly_no_nwell 0 bend_illegal \
+	"N-well overlap of varactor poly < 0.15um (varac.5)"
+
+ cifmaxwidth pdiff_in_varactor_well 0 bend_illegal \
+	"Varactor N-well must not contain P+ diffusion (varac.7)"
+variants (fast),(full)
+
 #ifdef MIM
 #-----------------------------------------------------------
 # MiM CAP (CAPM) - 
@@ -5471,8 +5596,11 @@
  spacing via3 *mimcap 140 touching_illegal "MiM cap spacing to via3 < %d (capm.8)"
  spacing *mimcap *metal3/m3 500 surround_ok \
 	"MiM cap spacing to unrelated metal3 < %d (capm.11)"
+
+variants (full)
  cifspacing mim_bottom mim_bottom 1200 touching_ok \
 	 "MiM cap bottom plate spacing < %d (capm.2b)"
+variants (fast),(full)
 
  # MiM cap contact rules (VIA3)
 
@@ -5496,8 +5624,11 @@
  spacing via4 *mimcap2 140 touching_illegal "MiM cap spacing to via4 < %d (cap2m.8)"
  spacing *mimcap *metal4/m4 500 surround_ok \
 	"MiM cap spacing to unrelated metal4 < %d (cap2m.11)"
+
+variants (full)
  cifspacing mim2_bottom mim2_bottom 1200 touching_ok \
  	"MiM2 cap bottom plate spacing < %d (cap2m.2b)"
+variants (fast),(full)
 
  # MiM cap contact rules (VIA4)