Merge branch 'master' of 192.168.0.7:/home/tim/gitsrc/open_pdks/
diff --git a/VERSION b/VERSION
index c787b21..79728fe 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.0.22
+1.0.24
diff --git a/scripts/configure b/scripts/configure
index 536a041..62b4a34 100755
--- a/scripts/configure
+++ b/scripts/configure
@@ -1721,11 +1721,11 @@
     # --with-pdk-source=PDK_SOURCE_PATH
 
 
-        SKY130_SOURCE_PATH=""
+        SKY130_SOURCE_PATH_=""
 
 # Check whether --with-sky130-source was given.
 if test "${with_sky130_source+set}" = set; then :
-  withval=$with_sky130_source; SKY130_SOURCE_PATH=$withval
+  withval=$with_sky130_source; SKY130_SOURCE_PATH_=$withval
 
 fi
 
@@ -1733,11 +1733,11 @@
 	# Require this argument
         { $as_echo "$as_me:${as_lineno-$LINENO}: Checking whether source path is specified for 'sky130'" >&5
 $as_echo "$as_me: Checking whether source path is specified for 'sky130'" >&6;}
-        if test "x$SKY130_SOURCE_PATH" == "x" ; then
+        if test "x$SKY130_SOURCE_PATH_" == "x" ; then
 	   as_fn_error $? "Option --with-sky130-source=<path> not specified!" "$LINENO" 5
 	fi
 
-	SKY130_SOURCE_PATH=$(readlink -f $SKY130_SOURCE_PATH)
+	SKY130_SOURCE_PATH=`readlink -f $SKY130_SOURCE_PATH_`
 
         # basic check that the PDK exists there (the path must exist in any case)
         { $as_echo "$as_me:${as_lineno-$LINENO}: Checking specified path for 'sky130' at $SKY130_SOURCE_PATH" >&5
diff --git a/scripts/configure.ac b/scripts/configure.ac
index 362d3d2..a596202 100755
--- a/scripts/configure.ac
+++ b/scripts/configure.ac
@@ -9,19 +9,19 @@
     # --with-pdk-source=PDK_SOURCE_PATH
     m4_foreach_w(pdk, $1, [
 	m4_define([pdkvar], [m4_normalize(m4_esyscmd(echo pdk | tr "a-z" "A-Z"))])
-        pdkvar[]_SOURCE_PATH=""
+        pdkvar[]_SOURCE_PATH_=""
         AC_ARG_WITH(pdk-source,
               [AS_HELP_STRING([--with-pdk-source=/path/to/pdk/source], "location of the source files for pdk")],
-              [pdkvar[]_SOURCE_PATH=$withval]
+              [pdkvar[]_SOURCE_PATH_=$withval]
         )
 
 	# Require this argument
         AC_MSG_NOTICE([Checking whether source path is specified for 'pdk'])
-        if test "x$[]pdkvar[]_SOURCE_PATH" == "x" ; then
+        if test "x$[]pdkvar[]_SOURCE_PATH_" == "x" ; then
 	   AC_MSG_ERROR([Option --with-pdk-source=<path> not specified!])
 	fi
 
-	pdkvar[]_SOURCE_PATH=$(readlink -f $[]pdkvar[]_SOURCE_PATH)
+	pdkvar[]_SOURCE_PATH=`readlink -f $[]pdkvar[]_SOURCE_PATH_`
 
         # basic check that the PDK exists there (the path must exist in any case)
         AC_MSG_NOTICE([Checking specified path for 'pdk' at $[]pdkvar[]_SOURCE_PATH])
diff --git a/sky130/Makefile.in b/sky130/Makefile.in
index 8485deb..cc337dd 100644
--- a/sky130/Makefile.in
+++ b/sky130/Makefile.in
@@ -428,10 +428,10 @@
 	# 	"FIXED_BBOX 0 407 15000 40000"
 
 install:
-	if test "x${DIST_PATH}" == "x" ; then
-	    ${MAKE} install-local
-	else
-	    ${MAKE} install-dist
+	if test "x${DIST_PATH}" == "x" ; then \
+	    ${MAKE} install-local ; \
+	else \
+	    ${MAKE} install-dist; \
 	fi
 
 install-local: install-local-a
diff --git a/sky130/magic/sky130.tcl b/sky130/magic/sky130.tcl
index 684aee5..c97d9a9 100644
--- a/sky130/magic/sky130.tcl
+++ b/sky130/magic/sky130.tcl
@@ -175,9 +175,9 @@
 
    magic::add_toolkit_command $layoutframe "mrp1 - 48.2 Ohm/sq" \
 	    "magic::gencell sky130::mrp1" pdk2
-   magic::add_toolkit_command $layoutframe "xhrpoly - 319.8 Ohm/sq" \
+   magic::add_toolkit_command $layoutframe "xhrpoly_0p35 - 319.8 Ohm/sq" \
 	    "magic::gencell sky130::xhrpoly" pdk2
-   magic::add_toolkit_command $layoutframe "uhrpoly - 2000 Ohm/sq" \
+   magic::add_toolkit_command $layoutframe "uhrpoly_0p35 - 2000 Ohm/sq" \
 	    "magic::gencell sky130::uhrpoly" pdk2
    magic::add_toolkit_command $layoutframe "xpwres - 3050 Ohm/sq" \
 	    "magic::gencell sky130::xpwres" pdk2
@@ -2077,7 +2077,7 @@
 proc sky130::xpwres_defaults {} {
     return {w 2.650 l 26.50 m 1 nx 1 wmin 2.650 lmin 26.50 \
 	 	rho 975 val 4875 dummy 0 dw 0.25 term 1.0 \
-		endcov 100 full_metal 1}
+		guard 1 endcov 100 full_metal 1}
 }
 
 #----------------------------------------------------------------
@@ -2088,25 +2088,93 @@
 proc sky130::mrp1_defaults {} {
     return {w 0.330 l 1.650 m 1 nx 1 wmin 0.330 lmin 1.650 \
 		rho 48.2 val 241 dummy 0 dw 0.0 term 0.0 \
-		sterm 0.0 caplen 0.4 snake 0 \
+		sterm 0.0 caplen 0.4 snake 0 guard 1 \
 		glc 1 grc 1 gtc 1 gbc 1 roverlap 0 endcov 100 \
 		full_metal 1}
 }
 
 # "term" is rho * 0.06, the distance between xpc edge and CONT.
-proc sky130::xhrpoly_defaults {} {
+proc sky130::xhrpoly_0p35_defaults {} {
     return {w 0.350 l 0.50 m 1 nx 1 wmin 0.350 lmin 0.50 \
 		rho 319.8 val 456.857 dummy 0 dw 0.0 term 19.188 \
-		sterm 0.0 caplen 0 glc 1 grc 1 gtc 1 gbc 1 \
-		full_metal 1}
+		sterm 0.0 caplen 0 guard 1 glc 1 grc 1 gtc 1 gbc 1 \
+		compatible {xhrpoly_0p35 xhrpoly_0p69 xhrpoly_1p41 \
+		xhrpoly_2p85 xhrpoly_5p73} \
+		full_metal 1 wmax 0.350}
+}
+proc sky130::xhrpoly_0p69_defaults {} {
+    return {w 0.690 l 1.00 m 1 nx 1 wmin 0.690 lmin 0.50 \
+		rho 319.8 val 463.480 dummy 0 dw 0.0 term 19.188 \
+		sterm 0.0 caplen 0 guard 1 glc 1 grc 1 gtc 1 gbc 1 \
+		compatible {xhrpoly_0p35 xhrpoly_0p69 xhrpoly_1p41 \
+		xhrpoly_2p85 xhrpoly_5p73} \
+		full_metal 1 wmax 0.690}
+}
+proc sky130::xhrpoly_1p41_defaults {} {
+    return {w 1.410 l 2.00 m 1 nx 1 wmin 1.410 lmin 0.50 \
+		rho 319.8 val 453.620 dummy 0 dw 0.0 term 19.188 \
+		sterm 0.0 caplen 0 guard 1 glc 1 grc 1 gtc 1 gbc 1 \
+		compatible {xhrpoly_0p35 xhrpoly_0p69 xhrpoly_1p41 \
+		xhrpoly_2p85 xhrpoly_5p73} \
+		full_metal 1 wmax 1.410}
+}
+proc sky130::xhrpoly_2p85_defaults {} {
+    return {w 2.850 l 3.00 m 1 nx 1 wmin 2.850 lmin 0.50 \
+		rho 319.8 val 336.630 dummy 0 dw 0.0 term 19.188 \
+		sterm 0.0 caplen 0 guard 1 glc 1 grc 1 gtc 1 gbc 1 \
+		compatible {xhrpoly_0p35 xhrpoly_0p69 xhrpoly_1p41 \
+		xhrpoly_2p85 xhrpoly_5p73} \
+		full_metal 1 wmax 2.850}
+}
+proc sky130::xhrpoly_5p73_defaults {} {
+    return {w 5.730 l 6.00 m 1 nx 1 wmin 5.730 lmin 0.50 \
+		rho 319.8 val 334.870 dummy 0 dw 0.0 term 19.188 \
+		sterm 0.0 caplen 0 guard 1 glc 1 grc 1 gtc 1 gbc 1 \
+		compatible {xhrpoly_0p35 xhrpoly_0p69 xhrpoly_1p41 \
+		xhrpoly_2p85 xhrpoly_5p73} \
+		full_metal 1 wmax 5.730}
 }
 
 # "term" is rho * 0.06, the distance between xpc edge and CONT.
-proc sky130::uhrpoly_defaults {} {
+proc sky130::uhrpoly_0p35_defaults {} {
     return {w 0.350 l 0.50 m 1 nx 1 wmin 0.350 lmin 0.50 \
 		rho 2000 val 2875.143 dummy 0 dw 0.0 term 120 \
-		sterm 0.0 caplen 0 \
-		glc 1 grc 1 gtc 1 gbc 1 full_metal 1}
+		sterm 0.0 caplen 0 wmax 0.350 \
+		guard 1 glc 1 grc 1 gtc 1 gbc 1 \
+		compatible {uhrpoly_0p35 uhrpoly_0p69 uhrpoly_1p41 \
+		uhrpoly_2p85 uhrpoly_5p73} full_metal 1}
+}
+proc sky130::uhrpoly_0p69_defaults {} {
+    return {w 0.690 l 1.00 m 1 nx 1 wmin 0.690 lmin 0.50 \
+		rho 2000 val 2898.600 dummy 0 dw 0.0 term 120 \
+		sterm 0.0 caplen 0 wmax 0.690 \
+		guard 1 glc 1 grc 1 gtc 1 gbc 1 \
+		compatible {uhrpoly_0p35 uhrpoly_0p69 uhrpoly_1p41 \
+		uhrpoly_2p85 uhrpoly_5p73} full_metal 1}
+}
+proc sky130::uhrpoly_1p41_defaults {} {
+    return {w 1.410 l 2.00 m 1 nx 1 wmin 1.410 lmin 0.50 \
+		rho 2000 val 2836.900 dummy 0 dw 0.0 term 120 \
+		sterm 0.0 caplen 0 wmax 1.410 \
+		guard 1 glc 1 grc 1 gtc 1 gbc 1 \
+		compatible {uhrpoly_0p35 uhrpoly_0p69 uhrpoly_1p41 \
+		uhrpoly_2p85 uhrpoly_5p73} full_metal 1}
+}
+proc sky130::uhrpoly_2p85_defaults {} {
+    return {w 2.850 l 3.00 m 1 nx 1 wmin 2.850 lmin 0.50 \
+		rho 2000 val 2105.300 dummy 0 dw 0.0 term 120 \
+		sterm 0.0 caplen 0 wmax 2.850 \
+		guard 1 glc 1 grc 1 gtc 1 gbc 1 \
+		compatible {uhrpoly_0p35 uhrpoly_0p69 uhrpoly_1p41 \
+		uhrpoly_2p85 uhrpoly_5p73} full_metal 1}
+}
+proc sky130::uhrpoly_5p73_defaults {} {
+    return {w 5.730 l 6.00 m 1 nx 1 wmin 5.730 lmin 0.50 \
+		rho 2000 val 2094.200 dummy 0 dw 0.0 term 120 \
+		sterm 0.0 caplen 0 wmax 5.730 \
+		guard 1 glc 1 grc 1 gtc 1 gbc 1 \
+		compatible {uhrpoly_0p35 uhrpoly_0p69 uhrpoly_1p41 \
+		uhrpoly_2p85 uhrpoly_5p73} full_metal 1}
 }
 
 #----------------------------------------------------------------
@@ -2117,7 +2185,7 @@
 proc sky130::mrdn_defaults {} {
     return {w 0.420 l 2.100 m 1 nx 1 wmin 0.42 lmin 2.10 \
 		rho 120 val 600.0 dummy 0 dw 0.05 term 0.0 \
-		sterm 0.0 caplen 0.4 snake 0 \
+		sterm 0.0 caplen 0.4 snake 0 guard 1 \
 		glc 1 grc 1 gtc 1 gbc 1 roverlap 0 endcov 100 \
 		full_metal 1}
 }
@@ -2125,7 +2193,7 @@
 proc sky130::mrdn_hv_defaults {} {
     return {w 0.420 l 2.100 m 1 nx 1 wmin 0.42 lmin 2.10 \
 		rho 120 val 600.0 dummy 0 dw 0.02 term 0.0 \
-		sterm 0.0 caplen 0.4 snake 0 \
+		sterm 0.0 caplen 0.4 snake 0 guard 1 \
 		glc 1 grc 1 gtc 1 gbc 1 roverlap 0 endcov 100 \
 		full_metal 1}
 }
@@ -2138,7 +2206,7 @@
 proc sky130::mrdp_defaults {} {
     return {w 0.420 l 2.100 m 1 nx 1 wmin 0.42 lmin 2.10 \
 		rho 197 val 985.0 dummy 0 dw 0.02 term 0.0 \
-		sterm 0.0 caplen 0.60 snake 0 \
+		sterm 0.0 caplen 0.60 snake 0 guard 1 \
 		glc 1 grc 1 gtc 1 gbc 1 roverlap 0 endcov 100 \
 		full_metal 1}
 }
@@ -2146,7 +2214,7 @@
 proc sky130::mrdp_hv_defaults {} {
     return {w 0.420 l 2.100 m 1 nx 1 wmin 0.42 lmin 2.10 \
 		rho 197 val 985.0 dummy 0 dw 0.02 term 0.0 \
-		sterm 0.0 caplen 0.60 snake 0 \
+		sterm 0.0 caplen 0.60 snake 0 guard 1 \
 		glc 1 grc 1 gtc 1 gbc 1 roverlap 0 endcov 100 \
 		full_metal 1}
 }
@@ -2244,11 +2312,35 @@
     return [sky130::res_convert $parameters]
 }
 
-proc sky130::xhrpoly_convert {parameters} {
+proc sky130::xhrpoly_0p35_convert {parameters} {
+    return [sky130::res_convert $parameters]
+}
+proc sky130::xhrpoly_0p69_convert {parameters} {
+    return [sky130::res_convert $parameters]
+}
+proc sky130::xhrpoly_1p41_convert {parameters} {
+    return [sky130::res_convert $parameters]
+}
+proc sky130::xhrpoly_2p85_convert {parameters} {
+    return [sky130::res_convert $parameters]
+}
+proc sky130::xhrpoly_5p73_convert {parameters} {
     return [sky130::res_convert $parameters]
 }
 
-proc sky130::uhrpoly_convert {parameters} {
+proc sky130::uhrpoly_0p35_convert {parameters} {
+    return [sky130::res_convert $parameters]
+}
+proc sky130::uhrpoly_0p69_convert {parameters} {
+    return [sky130::res_convert $parameters]
+}
+proc sky130::uhrpoly_1p41_convert {parameters} {
+    return [sky130::res_convert $parameters]
+}
+proc sky130::uhrpoly_2p85_convert {parameters} {
+    return [sky130::res_convert $parameters]
+}
+proc sky130::uhrpoly_5p73_convert {parameters} {
     return [sky130::res_convert $parameters]
 }
 
@@ -2314,6 +2406,11 @@
 	magic::add_entry endcov "End contact coverage (%)" $parameters
     }
 
+    if {[dict exists $parameters compatible]} {
+	set sellist [dict get $parameters compatible]
+	magic::add_selectlist gencell "Device type" $sellist $parameters $device
+    }
+
     # magic::add_checkbox dummy "Add dummy" $parameters
 
     if {[dict exists $parameters snake]} {
@@ -2326,22 +2423,24 @@
             magic::add_checkbox roverlap "Overlap at ends" $parameters
 	}
     }
-    magic::add_checkbox guard "Add guard ring" $parameters
+    if {[dict exists $parameters guard]} {
+	magic::add_checkbox guard "Add guard ring" $parameters
 
-    if {[dict exists $parameters full_metal]} {
-	magic::add_checkbox full_metal "Full metal guard ring" $parameters
-    }
-    if {[dict exists $parameters glc]} {
-	magic::add_checkbox glc "Add left guard ring contact" $parameters
-    }
-    if {[dict exists $parameters grc]} {
-	magic::add_checkbox grc "Add right guard ring contact" $parameters
-    }
-    if {[dict exists $parameters gtc]} {
-	magic::add_checkbox gtc "Add top guard ring contact" $parameters
-    }
-    if {[dict exists $parameters gbc]} {
-	magic::add_checkbox gbc "Add bottom guard ring contact" $parameters
+	if {[dict exists $parameters full_metal]} {
+	    magic::add_checkbox full_metal "Full metal guard ring" $parameters
+	}
+	if {[dict exists $parameters glc]} {
+	    magic::add_checkbox glc "Add left guard ring contact" $parameters
+	}
+	if {[dict exists $parameters grc]} {
+	    magic::add_checkbox grc "Add right guard ring contact" $parameters
+	}
+	if {[dict exists $parameters gtc]} {
+	    magic::add_checkbox gtc "Add top guard ring contact" $parameters
+	}
+	if {[dict exists $parameters gbc]} {
+	    magic::add_checkbox gbc "Add bottom guard ring contact" $parameters
+	}
     }
 
     if {[dict exists $parameters snake]} {
@@ -2361,12 +2460,36 @@
     sky130::res_dialog mrp1 $parameters
 }
 
-proc sky130::xhrpoly_dialog {parameters} {
-    sky130::res_dialog xhrpoly $parameters
+proc sky130::xhrpoly_0p35_dialog {parameters} {
+    sky130::res_dialog xhrpoly_0p35 $parameters
+}
+proc sky130::xhrpoly_0p69_dialog {parameters} {
+    sky130::res_dialog xhrpoly_0p69 $parameters
+}
+proc sky130::xhrpoly_1p41_dialog {parameters} {
+    sky130::res_dialog xhrpoly_1p41 $parameters
+}
+proc sky130::xhrpoly_2p85_dialog {parameters} {
+    sky130::res_dialog xhrpoly_2p85 $parameters
+}
+proc sky130::xhrpoly_5p73_dialog {parameters} {
+    sky130::res_dialog xhrpoly_5p73 $parameters
 }
 
-proc sky130::uhrpoly_dialog {parameters} {
-    sky130::res_dialog uhrpoly $parameters
+proc sky130::uhrpoly_0p35_dialog {parameters} {
+    sky130::res_dialog uhrpoly_0p35 $parameters
+}
+proc sky130::uhrpoly_0p69_dialog {parameters} {
+    sky130::res_dialog uhrpoly_0p69 $parameters
+}
+proc sky130::uhrpoly_1p41_dialog {parameters} {
+    sky130::res_dialog uhrpoly_1p41 $parameters
+}
+proc sky130::uhrpoly_2p85_dialog {parameters} {
+    sky130::res_dialog uhrpoly_2p85 $parameters
+}
+proc sky130::uhrpoly_5p73_dialog {parameters} {
+    sky130::res_dialog uhrpoly_5p73 $parameters
 }
 
 proc sky130::mrdn_dialog {parameters} {
@@ -2424,6 +2547,7 @@
     set well_res_overlap 0 	;# not a well resistor
     set end_contact_type ""	;# no contacts for metal resistors
     set end_overlap_cont 0	;# additional end overlap on sides
+    set res_idtype none
 
     # Set a local variable for each parameter (e.g., $l, $w, etc.)
     foreach key [dict keys $parameters] {
@@ -2465,6 +2589,10 @@
 	erase ${end_type}
     }
     paint ${res_type}
+    if {"$res_idtype" != "none"} {
+	box grow c 2
+	paint ${res_idtype}
+    }
     popbox
 
     # Reduce contact sizes by (end type) surround so that
@@ -2740,10 +2868,12 @@
     # Set defaults if they are not in parameters
     set snake 0		;# some resistors don't allow snake geometry
     set roverlap 0	;# overlap resistors at contacts
-    set guard 1		;# draw a guard ring
+    set guard 0		;# draw a guard ring
     set plus_diff_type   nsd	;# guard ring diffusion type
     set overlap_compress 0	;# special Y distance compression
     set well_res_overlap 0	;# additional well extension behind contact
+    set res_diff_spacing 0	;# spacing from resistor to diffusion
+    set res_idtype  none
 
     # Set a local variable for each parameter (e.g., $l, $w, etc.)
     foreach key [dict keys $parameters] {
@@ -2880,7 +3010,7 @@
 
 #----------------------------------------------------------------
 
-proc sky130::xhrpoly_draw {parameters} {
+proc sky130::xhrpoly_0p35_draw {parameters} {
 
     # Set a local variable for each rule in ruleset
     foreach key [dict keys $sky130::ruleset] {
@@ -2889,6 +3019,127 @@
 
     set newdict [dict create \
 	    res_type		ppres \
+	    res_idtype		res0p35 \
+	    end_type 		xpc \
+	    end_contact_type	xpc \
+	    end_contact_size	0 \
+	    plus_diff_type	psd \
+	    plus_contact_type	psc \
+	    sub_type		psub \
+	    end_surround	$poly_surround \
+	    end_spacing		0.48 \
+	    end_to_end_space	0.52 \
+	    end_contact_size	0.19 \
+	    res_to_endcont	1.985 \
+	    res_spacing		1.24 \
+	    res_diff_spacing	0.48 \
+	    mask_clearance	0.52 \
+	    overlap_compress	0.36 \
+    ]
+    set drawdict [dict merge $sky130::ruleset $newdict $parameters]
+    return [sky130::res_draw $drawdict]
+}
+
+proc sky130::xhrpoly_0p69_draw {parameters} {
+
+    # Set a local variable for each rule in ruleset
+    foreach key [dict keys $sky130::ruleset] {
+        set $key [dict get $sky130::ruleset $key]
+    }
+
+    set newdict [dict create \
+	    res_type		ppres \
+	    res_idtype		res0p69 \
+	    end_type 		xpc \
+	    end_contact_type	xpc \
+	    end_contact_size	0 \
+	    plus_diff_type	psd \
+	    plus_contact_type	psc \
+	    sub_type		psub \
+	    end_surround	$poly_surround \
+	    end_spacing		0.48 \
+	    end_to_end_space	0.52 \
+	    end_contact_size	0.19 \
+	    res_to_endcont	1.985 \
+	    res_spacing		1.24 \
+	    res_diff_spacing	0.48 \
+	    mask_clearance	0.52 \
+	    overlap_compress	0.36 \
+    ]
+    set drawdict [dict merge $sky130::ruleset $newdict $parameters]
+    return [sky130::res_draw $drawdict]
+}
+
+proc sky130::xhrpoly_1p41_draw {parameters} {
+
+    # Set a local variable for each rule in ruleset
+    foreach key [dict keys $sky130::ruleset] {
+        set $key [dict get $sky130::ruleset $key]
+    }
+
+    set newdict [dict create \
+	    res_type		ppres \
+	    res_idtype		res1p41 \
+	    end_type 		xpc \
+	    end_contact_type	xpc \
+	    end_contact_size	0 \
+	    plus_diff_type	psd \
+	    plus_contact_type	psc \
+	    sub_type		psub \
+	    end_surround	$poly_surround \
+	    end_spacing		0.48 \
+	    end_to_end_space	0.52 \
+	    end_contact_size	0.19 \
+	    res_to_endcont	1.985 \
+	    res_spacing		1.24 \
+	    res_diff_spacing	0.48 \
+	    mask_clearance	0.52 \
+	    overlap_compress	0.36 \
+    ]
+    set drawdict [dict merge $sky130::ruleset $newdict $parameters]
+    return [sky130::res_draw $drawdict]
+}
+
+proc sky130::xhrpoly_2p85_draw {parameters} {
+
+    # Set a local variable for each rule in ruleset
+    foreach key [dict keys $sky130::ruleset] {
+        set $key [dict get $sky130::ruleset $key]
+    }
+
+    set newdict [dict create \
+	    res_type		ppres \
+	    res_idtype		res2p85 \
+	    end_type 		xpc \
+	    end_contact_type	xpc \
+	    end_contact_size	0 \
+	    plus_diff_type	psd \
+	    plus_contact_type	psc \
+	    sub_type		psub \
+	    end_surround	$poly_surround \
+	    end_spacing		0.48 \
+	    end_to_end_space	0.52 \
+	    end_contact_size	0.19 \
+	    res_to_endcont	1.985 \
+	    res_spacing		1.24 \
+	    res_diff_spacing	0.48 \
+	    mask_clearance	0.52 \
+	    overlap_compress	0.36 \
+    ]
+    set drawdict [dict merge $sky130::ruleset $newdict $parameters]
+    return [sky130::res_draw $drawdict]
+}
+
+proc sky130::xhrpoly_5p73_draw {parameters} {
+
+    # Set a local variable for each rule in ruleset
+    foreach key [dict keys $sky130::ruleset] {
+        set $key [dict get $sky130::ruleset $key]
+    }
+
+    set newdict [dict create \
+	    res_type		ppres \
+	    res_idtype		res5p73 \
 	    end_type 		xpc \
 	    end_contact_type	xpc \
 	    end_contact_size	0 \
@@ -2911,7 +3162,7 @@
 
 #----------------------------------------------------------------
 
-proc sky130::uhrpoly_draw {parameters} {
+proc sky130::uhrpoly_0p35_draw {parameters} {
 
     # Set a local variable for each rule in ruleset
     foreach key [dict keys $sky130::ruleset] {
@@ -2920,6 +3171,127 @@
 
     set newdict [dict create \
 	    res_type		xpres \
+	    res_idtype		res0p35 \
+	    end_type 		xpc \
+	    end_contact_type	xpc \
+	    end_contact_size	0 \
+	    plus_diff_type	psd \
+	    plus_contact_type	psc \
+	    sub_type		psub \
+	    end_surround	$poly_surround \
+	    end_spacing		0.48 \
+	    end_to_end_space	0.52 \
+	    end_contact_size	0.19 \
+	    res_to_endcont	1.985 \
+	    res_spacing		1.24 \
+	    res_diff_spacing	0.48 \
+	    mask_clearance	0.52 \
+	    overlap_compress	0.36 \
+    ]
+    set drawdict [dict merge $sky130::ruleset $newdict $parameters]
+    return [sky130::res_draw $drawdict]
+}
+
+proc sky130::uhrpoly_0p69_draw {parameters} {
+
+    # Set a local variable for each rule in ruleset
+    foreach key [dict keys $sky130::ruleset] {
+        set $key [dict get $sky130::ruleset $key]
+    }
+
+    set newdict [dict create \
+	    res_type		xpres \
+	    res_idtype		res0p69 \
+	    end_type 		xpc \
+	    end_contact_type	xpc \
+	    end_contact_size	0 \
+	    plus_diff_type	psd \
+	    plus_contact_type	psc \
+	    sub_type		psub \
+	    end_surround	$poly_surround \
+	    end_spacing		0.48 \
+	    end_to_end_space	0.52 \
+	    end_contact_size	0.19 \
+	    res_to_endcont	1.985 \
+	    res_spacing		1.24 \
+	    res_diff_spacing	0.48 \
+	    mask_clearance	0.52 \
+	    overlap_compress	0.36 \
+    ]
+    set drawdict [dict merge $sky130::ruleset $newdict $parameters]
+    return [sky130::res_draw $drawdict]
+}
+
+proc sky130::uhrpoly_1p41_draw {parameters} {
+
+    # Set a local variable for each rule in ruleset
+    foreach key [dict keys $sky130::ruleset] {
+        set $key [dict get $sky130::ruleset $key]
+    }
+
+    set newdict [dict create \
+	    res_type		xpres \
+	    res_idtype		res1p41 \
+	    end_type 		xpc \
+	    end_contact_type	xpc \
+	    end_contact_size	0 \
+	    plus_diff_type	psd \
+	    plus_contact_type	psc \
+	    sub_type		psub \
+	    end_surround	$poly_surround \
+	    end_spacing		0.48 \
+	    end_to_end_space	0.52 \
+	    end_contact_size	0.19 \
+	    res_to_endcont	1.985 \
+	    res_spacing		1.24 \
+	    res_diff_spacing	0.48 \
+	    mask_clearance	0.52 \
+	    overlap_compress	0.36 \
+    ]
+    set drawdict [dict merge $sky130::ruleset $newdict $parameters]
+    return [sky130::res_draw $drawdict]
+}
+
+proc sky130::uhrpoly_2p85_draw {parameters} {
+
+    # Set a local variable for each rule in ruleset
+    foreach key [dict keys $sky130::ruleset] {
+        set $key [dict get $sky130::ruleset $key]
+    }
+
+    set newdict [dict create \
+	    res_type		xpres \
+	    res_idtype		res2p85 \
+	    end_type 		xpc \
+	    end_contact_type	xpc \
+	    end_contact_size	0 \
+	    plus_diff_type	psd \
+	    plus_contact_type	psc \
+	    sub_type		psub \
+	    end_surround	$poly_surround \
+	    end_spacing		0.48 \
+	    end_to_end_space	0.52 \
+	    end_contact_size	0.19 \
+	    res_to_endcont	1.985 \
+	    res_spacing		1.24 \
+	    res_diff_spacing	0.48 \
+	    mask_clearance	0.52 \
+	    overlap_compress	0.36 \
+    ]
+    set drawdict [dict merge $sky130::ruleset $newdict $parameters]
+    return [sky130::res_draw $drawdict]
+}
+
+proc sky130::uhrpoly_5p73_draw {parameters} {
+
+    # Set a local variable for each rule in ruleset
+    foreach key [dict keys $sky130::ruleset] {
+        set $key [dict get $sky130::ruleset $key]
+    }
+
+    set newdict [dict create \
+	    res_type		xpres \
+	    res_idtype		res5p73 \
 	    end_type 		xpc \
 	    end_contact_type	xpc \
 	    end_contact_size	0 \
@@ -3259,6 +3631,7 @@
     set snake 0
     set sterm 0.0
     set caplen 0
+    set wmax 0
 
     foreach key [dict keys $parameters] {
         set $key [dict get $parameters $key]
@@ -3288,6 +3661,11 @@
 	puts stderr "Resistor width must be >= $wmin um"
 	dict set parameters w $wmin
     } 
+    if {$wmax > 0 && $w > $wmax} {
+	puts stderr "Resistor width must be <= $wmax um"
+	dict set parameters w $wmax
+    }
+    
     # Val and W specified - no L
     if {$l == 0}  {
    	set l [expr ($w - $dw) * $val / $rho]
@@ -3380,12 +3758,36 @@
     return [sky130::res_check mrp1 $parameters]
 }
 
-proc sky130::xhrpoly_check {parameters} {
-    return [sky130::res_check xhrpoly $parameters]
+proc sky130::xhrpoly_0p35_check {parameters} {
+    return [sky130::res_check xhrpoly_0p35 $parameters]
+}
+proc sky130::xhrpoly_0p69_check {parameters} {
+    return [sky130::res_check xhrpoly_0p69 $parameters]
+}
+proc sky130::xhrpoly_1p41_check {parameters} {
+    return [sky130::res_check xhrpoly_1p41 $parameters]
+}
+proc sky130::xhrpoly_2p85_check {parameters} {
+    return [sky130::res_check xhrpoly_2p85 $parameters]
+}
+proc sky130::xhrpoly_5p73_check {parameters} {
+    return [sky130::res_check xhrpoly_5p73 $parameters]
 }
 
-proc sky130::uhrpoly_check {parameters} {
-    return [sky130::res_check uhrpoly $parameters]
+proc sky130::uhrpoly_0p35_check {parameters} {
+    return [sky130::res_check uhrpoly_0p35 $parameters]
+}
+proc sky130::uhrpoly_0p69_check {parameters} {
+    return [sky130::res_check uhrpoly_0p69 $parameters]
+}
+proc sky130::uhrpoly_1p41_check {parameters} {
+    return [sky130::res_check uhrpoly_1p41 $parameters]
+}
+proc sky130::uhrpoly_2p85_check {parameters} {
+    return [sky130::res_check uhrpoly_2p85 $parameters]
+}
+proc sky130::uhrpoly_5p73_check {parameters} {
+    return [sky130::res_check uhrpoly_5p73 $parameters]
 }
 
 proc sky130::mrdn_check {parameters} {
@@ -3564,17 +3966,28 @@
 		dict set pdkparams [string tolower $key] $value
 	    }
 	    m {
-		# M value in an expression like '1*1' convert to
-		# M and NF
-		if {[regexp {\'([0-9]+)\*([0-9]+)\'} $value valid m nf]} {
-		    dict set pdkparams [string tolower $key] $m
-		    dict set pdkparams nf $nf
-		} else {
-		    dict set pdkparams [string tolower $key] $value
-		}
+		dict set pdkparams [string tolower $key] $value
+	    }
+	    nf {
+		# Adjustment ot W will be handled below
+		dict set pdkparams [string tolower $key] $value
 	    }
 	}
     }
+
+    # Magic does not understand "nf" as a parameter, but expands to
+    # "nf" number of devices connected horizontally.  The "w" value
+    # must be divided down accordingly, as the "nf" parameter implies
+    # that the total width "w" is divided into "nf" fingers.
+
+    catch {
+	set w [dict get $pdkparams w]
+	set nf [dict get $pdkparams nf]
+	if {$nf > 1} {
+	    dict set pdkparams w [expr $w / $nf]
+	}
+    }
+
     return $pdkparams
 }
 
diff --git a/sky130/magic/sky130.tech b/sky130/magic/sky130.tech
index 1e2861d..ee75912 100644
--- a/sky130/magic/sky130.tech
+++ b/sky130/magic/sky130.tech
@@ -303,6 +303,12 @@
  -block  fillblock
  -comment comment
  -comment obscomment
+# fixed resistor width identifiers
+ -comment res0p35
+ -comment res0p69
+ -comment res1p41
+ -comment res2p85
+ -comment res5p73
 
 end
 
@@ -354,6 +360,12 @@
   padl m1 m2 m3 glass
 #endif  (!METAL5)
 
+  res0p35   implant1
+  res0p69   implant1
+  res1p41   implant1
+  res2p85   implant1
+  res5p73   implant1
+
 #ifdef REDISTRIBUTION
   mrdlc metal5 mrdl
 #endif (REDISTRIBUTION)
@@ -4333,8 +4345,19 @@
  device rsubcircuit short rm5 *m5 space/w,pwell,nwell error l=l w=w
 #endif (METAL5)
 
+ device rsubcircuit xhrpoly_0p35  xhrpoly xpc pwell,space/w error +res0p35 l=l w=w
+ device rsubcircuit xhrpoly_0p69  xhrpoly xpc pwell,space/w error +res0p69 l=l w=w
+ device rsubcircuit xhrpoly_1p41  xhrpoly xpc pwell,space/w error +res1p41 l=l w=w
+ device rsubcircuit xhrpoly_2p85  xhrpoly xpc pwell,space/w error +res2p85 l=l w=w
+ device rsubcircuit xhrpoly_5p73  xhrpoly xpc pwell,space/w error +res5p73 l=l w=w
  device rsubcircuit xhrpoly  xhrpoly xpc pwell,space/w error l=l w=w
+ device rsubcircuit uhrpoly_0p35  uhrpoly xpc pwell,space/w error +res0p35 l=l w=w
+ device rsubcircuit uhrpoly_0p69  uhrpoly xpc pwell,space/w error +res0p69 l=l w=w
+ device rsubcircuit uhrpoly_1p41  uhrpoly xpc pwell,space/w error +res1p41 l=l w=w
+ device rsubcircuit uhrpoly_2p85  uhrpoly xpc pwell,space/w error +res2p85 l=l w=w
+ device rsubcircuit uhrpoly_5p73  uhrpoly xpc pwell,space/w error +res5p73 l=l w=w
  device rsubcircuit uhrpoly  uhrpoly xpc pwell,space/w error l=l w=w
+
  device rsubcircuit mrp1     mrp1    *poly pwell,space/w error 	l=l w=w
 
  device rsubcircuit mrdn     ndiffres *ndiff pwell,space/w  error l=l w=w
@@ -4390,7 +4413,17 @@
  device resistor short rm5 *m5
 #endif (METAL5)
 
+ device resistor xhrpoly_0p35 xhrpoly xpc +res0p35
+ device resistor xhrpoly_0p69 xhrpoly xpc +res0p69
+ device resistor xhrpoly_1p41 xhrpoly xpc +res1p41
+ device resistor xhrpoly_2p85 xhrpoly xpc +res2p85
+ device resistor xhrpoly_5p73 xhrpoly xpc +res5p73
  device resistor xhrpoly xhrpoly xpc 
+ device resistor uhrpoly_0p35 uhrpoly xpc +res0p35
+ device resistor uhrpoly_0p69 uhrpoly xpc +res0p69
+ device resistor uhrpoly_1p41 uhrpoly xpc +res1p41
+ device resistor uhrpoly_2p85 uhrpoly xpc +res2p85
+ device resistor uhrpoly_5p73 uhrpoly xpc +res5p73
  device resistor uhrpoly uhrpoly xpc 
  device resistor mrp1 mrp1       *poly 
  device resistor mrdn  ndiffres *ndiff 
@@ -4430,11 +4463,11 @@
  scalefactor 10
 
  contact lic 170 li 0  0 m1 30 60
- contact v1  260 m1 0 30 m2  0 30  
+ contact v1  260 m1 0 30 m2  0 30
  contact v2  280 m2 0 45 m3 25  0
 #ifdef METAL5
  contact v3  320 m3 0 30 m4  5  5
- contact v4 1180 m4 0    m5 120 
+ contact v4 1180 m4 0    m5 120
 #endif (METAL5)
 
  contact pc  170  poly 50 80 li 0 80
diff --git a/sky130/netgen/sky130_setup.tcl b/sky130/netgen/sky130_setup.tcl
index 7669f39..66d40ee 100644
--- a/sky130/netgen/sky130_setup.tcl
+++ b/sky130/netgen/sky130_setup.tcl
@@ -40,7 +40,7 @@
 	property "-circuit1 $dev" parallel {value par}
 	property "-circuit1 $dev" tolerance {l 0.01} {w 0.01}
 	# Ignore these properties
-	property "-circuit2 $dev" delete par1 pm
+	property "-circuit2 $dev" delete mult
     }
     if {[lsearch $cells2 $dev] >= 0} {
 	permute "-circuit2 $dev" 1 2
@@ -53,7 +53,7 @@
 	property "-circuit1 $dev" parallel {value par}
 	property "-circuit1 $dev" tolerance {l 0.01} {w 0.01}
 	# Ignore these properties
-	property "-circuit2 $dev" delete par1 pm
+	property "-circuit2 $dev" delete mult
     }
 }
 
@@ -78,7 +78,7 @@
 	property "-circuit1 $dev" parallel {value par}
 	property "-circuit1 $dev" tolerance {l 0.01} {w 0.01}
 	# Ignore these properties
-	property "-circuit2 $dev" delete par1 pm
+	property "-circuit2 $dev" delete mult
     }
     if {[lsearch $cells2 $dev] >= 0} {
 	permute "-circuit2 $dev" 1 2
@@ -91,7 +91,7 @@
 	property "-circuit1 $dev" parallel {value par}
 	property "-circuit1 $dev" tolerance {l 0.01} {w 0.01}
 	# Ignore these properties
-	property "-circuit2 $dev" delete par1 pm
+	property "-circuit2 $dev" delete mult
     }
 }
 
@@ -111,7 +111,7 @@
 	property "-circuit1 $dev" parallel {w add}
 	property "-circuit1 $dev" tolerance {w 0.01} {l 0.01}
 	# Ignore these properties
-	property "-circuit2 $dev" delete par1 NRD NRS
+	property "-circuit2 $dev" delete as ad ps pd mult sa sb sd
     }
     if {[lsearch $cells2 $dev] >= 0} {
 	permute "-circuit2 $dev" 1 3
@@ -120,7 +120,7 @@
 	property "-circuit1 $dev" parallel {w add}
 	property "-circuit2 $dev" tolerance {w 0.01} {l 0.01}
 	# Ignore these properties
-	property "-circuit2 $dev" delete par1 NRD NRS
+	property "-circuit2 $dev" delete as ad ps pd mult sa sb sd
     }
 }
 
@@ -138,7 +138,7 @@
 	property "-circuit1 $dev" parallel {value add}
 	property "-circuit1 $dev" tolerance {area 0.02}
 	# Ignore these properties
-	property "-circuit2 $dev" delete par1 peri
+	property "-circuit2 $dev" delete mult perim
     }
     if {[lsearch $cells2 $dev] >= 0} {
 	property "-circuit2 $dev" parallel enable
@@ -146,7 +146,7 @@
 	property "-circuit1 $dev" parallel {value add}
 	property "-circuit2 $dev" tolerance {area 0.02}
 	# Ignore these properties
-	property "-circuit2 $dev" delete par1 peri
+	property "-circuit2 $dev" delete mult perim
     }
 }
 
@@ -164,7 +164,7 @@
 	property "-circuit1 $dev" parallel {value add}
 	property "-circuit1 $dev" tolerance {l 0.01} {w 0.01}
 	# Ignore these properties
-	property "-circuit2 $dev" delete par1 pm
+	property "-circuit2 $dev" delete mult perim
     }
     if {[lsearch $cells2 $dev] >= 0} {
 	property "-circuit1 $dev" parallel enable
@@ -172,7 +172,7 @@
 	property "-circuit1 $dev" parallel {value add}
 	property "-circuit1 $dev" tolerance {l 0.01} {w 0.01}
 	# Ignore these properties
-	property "-circuit2 $dev" delete par1 pm
+	property "-circuit2 $dev" delete mult perim
     }
 }
 
@@ -211,12 +211,12 @@
     if {[lsearch $cells1 $dev] >= 0} {
 	property "-circuit1 $dev" parallel enable
 	# Ignore these properties
-	property "-circuit2 $dev" delete par1
+	property "-circuit2 $dev" delete mult
     }
     if {[lsearch $cells2 $dev] >= 0} {
 	property "-circuit2 $dev" parallel enable
 	# Ignore these properties
-	property "-circuit2 $dev" delete par1
+	property "-circuit2 $dev" delete mult
     }
 }