Multiple changes to multiple PDKs:
1) Fixed the gf180mcu_fd_io GDS.  Previously the GDS was being
   updated with a modification after building the magic
   database files with GDS file pointers, rendering the file
   pointers incorrect.  The script has been moved to a filter
   so that it occurs before the magic database files are
   generated.
2) The gf180mcu device generator script updated mainly to remove
   the drain-extended and asymmetric devices from the device menu,
   since the drawing routines are unfinished (work in progress).
3) The sky130 tech file updated to add the extended drain layer,
   along with GDS generation rules and DRC rules.  The device
   generator for the extended drain devices is still a work in
   progress.
4) The gf180mcu "torture test" script corrected for device names
   and updated with additional devices.
5) The xschemrc file for gf180mcu updated to add the PDK path
   corresponding to the open_pdks installation location.
diff --git a/VERSION b/VERSION
index d99b186..d5d91cf 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.0.452
+1.0.453
diff --git a/gf180mcu/Makefile.in b/gf180mcu/Makefile.in
index 649665c..ac291f0 100644
--- a/gf180mcu/Makefile.in
+++ b/gf180mcu/Makefile.in
@@ -752,7 +752,9 @@
 	cp -rp ${GF180MCU_PR_PATH}/cells/xschem/symbols ${XSCHEM_STAGING_$*}
 	cp -rp ${GF180MCU_PR_PATH}/cells/xschem/tests ${XSCHEM_STAGING_$*}
 	cp -rp ${GF180MCU_PR_PATH}/cells/xschem/xschemrc ${XSCHEM_STAGING_$*}
-	cat ./custom/xschem/xschemrc_append >> ${XSCHEM_STAGING_$*}/xschemrc
+	# Make open_pdks-specific modifications to the xschemrc file
+	./custom/scripts/fix_xschemrc.py ${XSCHEM_STAGING_$*}/xschemrc \
+		${GF180MCU$*} 2>&1 | tee -a ${GF180MCU$*}_make.log || true
 
 openlane-%: openlane/config.tcl openlane/gf180mcu_fd_sc_mcu7t5v0/config.tcl openlane/gf180mcu_fd_sc_mcu9t5v0/config.tcl
 	mkdir -p ${OPENLANETOP_STAGING_$*}
@@ -1192,6 +1194,7 @@
 			filter=custom/scripts/convert_io_cdl.py \
 		-gds cells/*/*_${$*_STACK}.gds compile-only \
 			options=custom/scripts/gds_import_io.tcl \
+			filter=custom/scripts/fix_io_cor_gds.py \
 		-lef cells/*/*_${$*_STACK}.lef \
 			annotate lefopts=-hide compile-only \
 			filter=custom/scripts/fix_io_lef.py \
@@ -1201,10 +1204,6 @@
 	# in the corner clamp cell that contains the devices being isolated.
 	${ADDLAYER} ${STAGING_PATH}/${GF180MCU$*} gf180mcu_fd_io ESD_CLAMP_COR \
 		isosubstrate "-42 43458 56113 57130 40932 43016 57057 55812" -mag
-	# Permanent solution to the extraction issue---modify the GDS with the
-	# isolated substrate layer.
-	./custom/scripts/fix_io_cor_gds.py \
-		${STAGING_PATH}/${GF180MCU$*}/libs.ref/${IO_GDS}/gf180mcu_fd_io.gds
 
 sram-%:
 	# Install SRAM macros from vendor files
diff --git a/gf180mcu/custom/scripts/fix_io_cor_gds.py b/gf180mcu/custom/scripts/fix_io_cor_gds.py
index 397a7d3..aae539f 100755
--- a/gf180mcu/custom/scripts/fix_io_cor_gds.py
+++ b/gf180mcu/custom/scripts/fix_io_cor_gds.py
@@ -2,41 +2,75 @@
 #
 # fix_io_cor_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 add the isolated substrate layer
+# The purpose of this filter is to add the isolated substrate layer
 # (GDS layer 23:5) to the ESD_CLAMP_COR cell, which is the only way to
 # get the cell to be LVS-correct at that level of hierarchy.  The layer
 # is simply copied down from further up in the hierarchy.  There is no
 # mask change to the corner cell itself, but the change allows the corner
 # cell to be read back from GDS, extract, and pass LVS.
 
+import os
 import sys
 
-if len(sys.argv) != 2:
-    print('Usage:  fix_io_cor_gds.py <filename>')
-    sys.exit(1)
-else:
-    file_name = sys.argv[1]
+def filter(inname, outname):
 
-# orig_data is the STRNAME record for ESD_CLAMP_COR.  Insert the isosub layer
-# data after this record.
-orig_data = b'\x00\x12\x06\x06\x45\x53\x44\x5f\x43\x4c\x41\x4d\x50\x5f\x43\x4f\x52\x00'
+    # Read input
+    try:
+        with open(inname, 'rb') as inFile:
+            data = inFile.read()
+    except:
+        print('fix_io_cor_gds.py: failed to open ' + inname + ' for reading.', file=sys.stderr)
+        return 1
 
-append_data = b'\x00\x04\x08\x00\x00\x06\x0d\x02\x00\x17\x00\x06\x0e\x02\x00\x05\x00\x3c\x10\x03\xff\xff\xff\x2e\x00\x03\x48\x2d\xff\xff\xff\x2e\x00\x04\x5b\xd2\x00\x04\x47\xf5\x00\x04\x5b\xd2\x00\x04\x47\xf5\x00\x04\x42\x14\x00\x04\x5a\x65\x00\x04\x42\x14\x00\x04\x5a\x65\x00\x03\x48\x2d\xff\xff\xff\x2e\x00\x03\x48\x2d\x00\x04\x11\x00'
+    # orig_data is the STRNAME record for ESD_CLAMP_COR.  Insert the isosub layer
+    # data after this record.
+    orig_data = b'\x00\x12\x06\x06\x45\x53\x44\x5f\x43\x4c\x41\x4d\x50\x5f\x43\x4f\x52\x00'
 
-# This is not efficient, but only needs to be done once.
+    append_data = b'\x00\x04\x08\x00\x00\x06\x0d\x02\x00\x17\x00\x06\x0e\x02\x00\x05\x00\x3c\x10\x03\xff\xff\xff\x2e\x00\x03\x48\x2d\xff\xff\xff\x2e\x00\x04\x5b\xd2\x00\x04\x47\xf5\x00\x04\x5b\xd2\x00\x04\x47\xf5\x00\x04\x42\x14\x00\x04\x5a\x65\x00\x04\x42\x14\x00\x04\x5a\x65\x00\x03\x48\x2d\xff\xff\xff\x2e\x00\x03\x48\x2d\x00\x04\x11\x00'
 
-with open(file_name, 'rb') as ifile:
-    data = ifile.read()
-    data = data.replace(orig_data, orig_data + append_data)
+    # This is not efficient, but only needs to be done once.
+    # Avoid doing it to any file other than the corner I/O.
 
-# Write back into the same file
-with open(file_name, 'wb') as ofile:
-    ofile.write(data)
+    if '__cor' in inname:
+        data = data.replace(orig_data, orig_data + append_data)
 
-print("Done!")
+    # 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_io_cor_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/fix_xschemrc.py b/gf180mcu/custom/scripts/fix_xschemrc.py
new file mode 100755
index 0000000..41dd798
--- /dev/null
+++ b/gf180mcu/custom/scripts/fix_xschemrc.py
@@ -0,0 +1,51 @@
+#!/usr/bin/env python3
+#
+# fix_xschemrc.py ---
+#
+# Special-purpose script that does the work of modifying a few items in
+# the source xschemrc file to make it open_pdks-specific
+
+import sys
+
+if len(sys.argv) != 3:
+    print('Usage:  fix_xschemrc.py <filename> <techname>')
+    sys.exit(1)
+else:
+    file_name = sys.argv[1]
+    tech_name = sys.argv[2]
+
+with open(file_name, 'r') as ifile:
+    xlines = ifile.read().splitlines()
+
+# Replace lines which assume PDK is in the user directory above
+outlines = []
+skipnext = 0
+for line in xlines:
+    if skipnext == 0:
+        if 'trying to find' in line:
+            skipnext = 2
+        outlines.append(line)
+    else:
+        skipnext -= 1
+        if skipnext == 0:
+            outlines.append('  if {[file isdir /usr/share/pdk]} {set PDK_ROOT /usr/share/pdk')
+            outlines.append('  } elseif {[file isdir /usr/local/share/pdk]} {set PDK_ROOT /usr/local/share/pdk')
+            outlines.append('  } elseif {[file isdir $env(HOME)/share/pdk]} {set PDK_ROOT $env(HOME)/share/pdk')
+
+# Append these lines:
+outlines.append('')
+outlines.append('# open_pdks-specific')
+outlines.append('set XSCHEM_START_WINDOW ${PDK_ROOT}/' + tech_name + '/libs.tech/xschem/tests/0_top.sch')
+outlines.append('append XSCHEM_LIBRARY_PATH :${PDK_ROOT}/' + tech_name + '/libs.tech/xschem')
+outlines.append('')
+outlines.append('# allow a user-specific path add-on')
+outlines.append('if { [info exists ::env(XSCHEM_USER_LIBRARY_PATH) ] } {')
+outlines.append('    append XSCHEM_LIBRARY_PATH :$env(XSCHEM_USER_LIBRARY_PATH)')
+outlines.append('}')
+
+# Write back into the same file
+with open(file_name, 'w') as ofile:
+    for line in outlines:
+        print(line, file=ofile)
+
+print("Done!")
diff --git a/gf180mcu/custom/xschem/xschemrc_append b/gf180mcu/custom/xschem/xschemrc_append
deleted file mode 100644
index fa1b707..0000000
--- a/gf180mcu/custom/xschem/xschemrc_append
+++ /dev/null
@@ -1,5 +0,0 @@
-
-# allow a user-specific path add-on (https://github.com/iic-jku/iic-osic-tools/issues/7)
-if { [info exists ::env(XSCHEM_USER_LIBRARY_PATH) ] } {
-    append XSCHEM_LIBRARY_PATH :$env(XSCHEM_USER_LIBRARY_PATH)
-}
diff --git a/gf180mcu/magic/gf180mcu.tcl b/gf180mcu/magic/gf180mcu.tcl
index 6de2076..e3a28f9 100644
--- a/gf180mcu/magic/gf180mcu.tcl
+++ b/gf180mcu/magic/gf180mcu.tcl
@@ -71,9 +71,9 @@
     dict set ruleset diffres_spacing  0.40      ;# Diffusion resistor spacing rule
     dict set ruleset polyres_spacing  0.40      ;# Poly resistor spacing rule
     dict set ruleset diff_poly_space  0.10      ;# Diffusion to poly spacing rule
-    dict set ruleset diff_gate_space  0.10      ;# Diffusion to gate poly spacing rule
+    dict set ruleset diff_gate_space  0.11      ;# Diffusion to gate poly spacing rule
     dict set ruleset metal_spacing    0.23      ;# Metal1 spacing rule
-    dict set ruleset mmetal_spacing   0.23      ;# Metal spacing rule (above metal1)
+    dict set ruleset mmetal_spacing   0.38      ;# Metal spacing rule (above metal1)
     dict set ruleset sblk_to_cont     0.33      ;# resistor to contact center
     dict set ruleset sblk_diff_space  0.44      ;# resistor to guard ring
 }
@@ -98,15 +98,15 @@
    magic::add_toolkit_command $layoutframe "nmos - nMOSFET" "magic::gencell gf180mcu::nfet_03v3" pdk1
    magic::add_toolkit_command $layoutframe "pmos - pMOSFET" "magic::gencell gf180mcu::pfet_03v3" pdk1
 
-   magic::add_toolkit_separator	$layoutframe pdk1
-   magic::add_toolkit_command $layoutframe "nfet_03v3_dss - mosfet (unsalicided drain)" "magic::gencell gf180mcu::nfet_03v3_dss" pdk1
-   magic::add_toolkit_command $layoutframe "pfet_03v3_dss - mosfet (unsalicided drain)" "magic::gencell gf180mcu::pfet_03v3_dss" pdk1
-   magic::add_toolkit_command $layoutframe "nfet_06v0_dss - mosfet (unsalicided drain, thick oxide)" "magic::gencell gf180mcu::nfet_06v0_dss" pdk1
-   magic::add_toolkit_command $layoutframe "pfet_06v0_dss - mosfet (unsalicided drain, thick oxide)" "magic::gencell gf180mcu::pfet_06v0_dss" pdk1
+# (NOT ADDED YET---DRAW ROUTINE IS INCOMPLETE)
+#   magic::add_toolkit_separator	$layoutframe pdk1
+#   magic::add_toolkit_command $layoutframe "nfet_dss - mosfet (unsalicided drain)" "magic::gencell gf180mcu::nfet_03v3_dss" pdk1
+#   magic::add_toolkit_command $layoutframe "pfet_dss - mosfet (unsalicided drain)" "magic::gencell gf180mcu::pfet_03v3_dss" pdk1
 
- magic::add_toolkit_separator	$layoutframe pdk1
-   magic::add_toolkit_command $layoutframe "ldnmos - nMOSFET" "magic::gencell gf180mcu::nfet_10v0_asym" pdk1
-   magic::add_toolkit_command $layoutframe "ldpmos - nMOSFET" "magic::gencell gf180mcu::pfet_10v0_asym" pdk1
+# (NOT ADDED YET---DRAW ROUTINE IS INCOMPLETE)
+# magic::add_toolkit_separator	$layoutframe pdk1
+#   magic::add_toolkit_command $layoutframe "ldnmos - nMOSFET" "magic::gencell gf180mcu::nfet_10v0_asym" pdk1
+#   magic::add_toolkit_command $layoutframe "ldpmos - nMOSFET" "magic::gencell gf180mcu::pfet_10v0_asym" pdk1
 
    magic::add_toolkit_separator	$layoutframe pdk1
    magic::add_toolkit_command $layoutframe "diode_nd2ps_03v3 - n-diode" "magic::gencell gf180mcu::diode_nd2ps_03v3" pdk1
@@ -2780,10 +2780,10 @@
 	    plus_contact_type	psc \
 	    sub_type		pwell \
 	    end_surround	$diff_surround \
-	    end_spacing		1.2 \
+	    end_spacing		1.4 \
 	    overlap_compress	-0.84 \
-	    res_to_endcont	0.22 \
-	    res_spacing		1.2 \
+	    res_to_endcont	0.38 \
+	    res_spacing		1.4 \
 	    res_diff_spacing	0.28 \
 	    well_res_overlap	0.24 \
     ]
@@ -2954,7 +2954,7 @@
 	    end_type 		m5 \
 	    end_surround	0.0 \
 	    end_spacing		0.0 \
-	    res_to_endcont	0.2 \
+	    res_to_endcont	0.265 \
 	    res_spacing		$mmetal_spacing \
     ]
     set drawdict [dict merge $gf180mcu::ruleset $newdict $parameters]
@@ -3242,7 +3242,7 @@
 		guard 1 glc 1 grc 1 gtc 0 gbc 0 tbcov 100 rlcov 100 \
 		topc 1 botc 1 poverlap 0 doverlap 1 lmin 0.28 wmin 0.22 \
 		full_metal 1 \
-		compatible {pfet_03v3_dss}}
+		compatible {pfet_03v3_dss pfet_06v0_dss}}
 }
 
 proc gf180mcu::pfet_06v0_dss_defaults {} {
@@ -3250,7 +3250,7 @@
 		guard 1 glc 1 grc 1 gtc 0 gbc 0 tbcov 100 rlcov 100 \
 		topc 1 botc 1 poverlap 0 doverlap 1 lmin 0.5 wmin 0.3 \
 		full_metal 1 \
-		compatible {pfet_06v0_dss}}
+		compatible {pfet_03v3_dss pfet_06v0_dss}}
 }
 #----------------------------------------------------------------
 # nmos: Specify all user-editable default values and those
@@ -3282,16 +3282,16 @@
 }
 
 proc gf180mcu::nfet_10v0_asym_defaults {} {
-    return {w 1.0 l 1.0 m 1 nf 1 diffcov 100 polycov 100 \
+    return {w 4.0 l 0.6 m 1 nf 1 diffcov 100 polycov 100 \
 		guard 1 glc 1 grc 1 gtc 0 gbc 0 tbcov 100 rlcov 100 \
-		topc 1 botc 1 poverlap 0 doverlap 1 lmin 1.0 wmin 1.0 \
+		topc 1 botc 1 poverlap 0 doverlap 1 lmin 0.6 wmin 4.0 \
 		full_metal 1 }
 }
 
 proc gf180mcu::pfet_10v0_asym_defaults {} {
-    return {w 1.0 l 1.0 m 1 nf 1 diffcov 100 polycov 100 \
+    return {w 4.0 l 0.6 m 1 nf 1 diffcov 100 polycov 100 \
 		guard 1 glc 1 grc 1 gtc 0 gbc 0 tbcov 100 rlcov 100 \
-		topc 1 botc 1 poverlap 0 doverlap 1 lmin 1.0 wmin 1.0 \
+		topc 1 botc 1 poverlap 0 doverlap 1 lmin 0.6 wmin 4.0 \
 		full_metal 1 }
 }
 
@@ -3300,7 +3300,7 @@
 		guard 1 glc 1 grc 1 gtc 0 gbc 0 tbcov 100 rlcov 100 \
 		topc 1 botc 1 poverlap 0 doverlap 1 lmin 0.28 wmin 0.22 \
 		full_metal 1 \
-		compatible {nfet_03v3_dss}}
+		compatible {nfet_03v3_dss nfet_06v0_dss}}
 }
 
 proc gf180mcu::nfet_06v0_dss_defaults {} {
@@ -3308,7 +3308,7 @@
 		guard 1 glc 1 grc 1 gtc 0 gbc 0 tbcov 100 rlcov 100 \
 		topc 1 botc 1 poverlap 0 doverlap 1 lmin 0.6 wmin 0.3 \
 		full_metal 1 \
-		compatible {nfet_06v0_dss}}
+		compatible {nfet_03v3_dss nfet_06v0_dss}}
 }
 
 #----------------------------------------------------------------
@@ -3772,7 +3772,7 @@
 # MOSFET: Draw a single device
 #----------------------------------------------------------------
 
-proc gf180mcu::mos_device {xcount parameters} {
+proc gf180mcu::mos_device {parameters} {
 
     # Epsilon for avoiding round-off errors
     set eps  0.0005
@@ -3783,6 +3783,7 @@
     set topc 1		;# draw top poly contact
     set botc 1		;# draw bottom poly contact
     set dev_sub_type ""	;# device substrate type (if different from guard ring)
+    set evens 1		;# even or odd (evens = 1 means drain is on left)
 
     # Set a local variable for each parameter (e.g., $l, $w, etc.)
     foreach key [dict keys $parameters] {
@@ -3812,8 +3813,8 @@
     box grow s ${hw}um
     box grow e ${hl}um
     box grow w ${hl}um
-    # Set drain and source sides based on xcount.
-    if {[% $xcount 2] == 1} {
+    # Set drain and source sides based on "evens".
+    if {$evens == 0} {
 	set dside e
 	set sside w
     } else {
@@ -4032,7 +4033,7 @@
     # to duplicate it here with calculations.
 
     tech lock *
-    set bbox [gf180mcu::mos_device 0 $parameters]
+    set bbox [gf180mcu::mos_device $parameters]
     # puts stdout "Diagnostic: Device bounding box e $bbox (um)"
     tech unlock *
 
@@ -4123,10 +4124,13 @@
     pushbox
     box move w ${corellx}um
     box move s ${corelly}um
+    set evens 1
     for {set xp 0} {$xp < $nf} {incr xp} {
+	dict set parameters evens $evens
+	set evens [- 1 $evens]
         pushbox
         for {set yp 0} {$yp < $m} {incr yp} {
-            gf180mcu::mos_device $xp $parameters
+            gf180mcu::mos_device $parameters
             box move n ${dy}um
         }
         popbox
diff --git a/gf180mcu/magic/gf180mcu.tech b/gf180mcu/magic/gf180mcu.tech
index b8ce0fd..30c5604 100644
--- a/gf180mcu/magic/gf180mcu.tech
+++ b/gf180mcu/magic/gf180mcu.tech
@@ -1550,7 +1550,7 @@
  templayer pohmic_missing_pwell *psd
  grow 120
  and dnwell
- and-not pwell
+ and-not pwell,pbase
 
  templayer mvpohmic_missing_pwell *mvpsd,mvpvaractor
  grow 160
@@ -1707,7 +1707,7 @@
  scalefactor 50 nanometers
  gridlimit 5
 
- options ignore-unknown-layer-labels options no-reconnect-labels 
+ options ignore-unknown-layer-labels
 
  ignore SRAMDEF
  ignore FET5VDEF
@@ -1774,7 +1774,6 @@
  copyup mvndifcheck
 
  layer mvndiff mvndiffarea
- labels DIFF
 
  # Copy mvndiff areas up for contact checks
  templayer mvxndifcheck mvndifcheck
@@ -1795,7 +1794,6 @@
  grow 140
  shrink 140
  and-not sccathode
- labels DIFF
 
  # Schottky contact
  layer schottkyc SCHOTTKY
@@ -1814,7 +1812,6 @@
  and-not PPLUS
  and-not DUALGATE
  and-not NAT
- labels DIFF
 
  layer nndiode DIFF
  and NPLUS
@@ -1824,7 +1821,6 @@
  and-not PPLUS
  and-not DUALGATE
  and NAT
- labels DIFF
 
  templayer ndiodearea DIODE
  and NPLUS
@@ -1837,7 +1833,6 @@
  and SBLK
  and NPLUS
  and-not DUALGATE
- labels DIFF
 
  templayer pdiffarea DIFF
  and-not POLY
@@ -1850,7 +1845,6 @@
  copyup pdifcheck
 
  layer pdiff pdiffarea
- labels DIFF
 
  layer mvndiode DIFF
  and NPLUS
@@ -1859,7 +1853,6 @@
  and-not PPLUS
  and DUALGATE
  and-not NAT
- labels DIFF
 
  layer mvnndiode DIFF
  and NPLUS
@@ -1868,7 +1861,6 @@
  and-not PPLUS
  and DUALGATE
  and NAT
- labels DIFF
 
  templayer mvndiodearea DIODE
  and NPLUS
@@ -1881,7 +1873,6 @@
  and SBLK
  and NPLUS
  and DUALGATE
- labels DIFF
 
  templayer mvpdiffarea DIFF
  and-not POLY
@@ -1894,7 +1885,6 @@
  copyup mvpdifcheck
 
  layer mvpdiff mvpdiffarea
- labels DIFF
 
  # Copy pdiff areas up for contact checks
  templayer xpdifcheck pdifcheck
@@ -1906,7 +1896,6 @@
  and-not NPLUS
  and-not DUALGATE
  and DIODE
- labels DIFF
 
  templayer pdiodearea DIODE
  and PPLUS
@@ -1923,11 +1912,9 @@
 
  layer pfet pfetarea
  and-not MOSCAP
- labels DIFF
 
  layer pcap pfetarea
  and MOSCAP
- labels DIFF
 
  templayer pfetexpand pfetarea
  grow 530
@@ -1947,7 +1934,6 @@
  and-not RESDEF
  and DUALGATE
  and DIODE
- labels DIFF
 
  templayer mvpdiodearea DIODE
  and PPLUS
@@ -1964,11 +1950,9 @@
 
  layer mvpfet mvpfetarea
  and-not MOSCAP
- labels DIFF
 
  layer mvpcap mvpfetarea
  and MOSCAP
- labels DIFF
 
  templayer mvpfetexpand mvpfetarea
  grow 530
@@ -1979,14 +1963,12 @@
  and-not POLY
  and nwelldef
  and pfetexpand
- labels DIFF
 
  layer pdiffres DIFF
  and-not POLY
  and PPLUS
  and nwelldef
  and SBLK
- labels DIFF
 
  layer nfet DIFF
  and POLY
@@ -1996,7 +1978,6 @@
  and NPLUS
  and-not NAT
  and-not MOSCAP
- labels DIFF
 
  layer ncap DIFF
  and POLY
@@ -2006,7 +1987,6 @@
  and NPLUS
  and-not NAT
  and MOSCAP
- labels DIFF
 
  layer nnfet DIFF
  and POLY
@@ -2015,7 +1995,6 @@
  and-not nwelldef
  and NPLUS
  and NAT
- labels DIFF
 
  templayer nsdarea DIFF
  and NPLUS
@@ -2025,7 +2004,6 @@
  and-not DUALGATE
 
  layer nsd nsdarea
- labels DIFF
 
  templayer nsdexpand nsdarea
  grow 500
@@ -2044,7 +2022,6 @@
  copyup psubcheck
 
  layer psd psdarea
- labels DIFF
 
  templayer psdexpand psdarea
  grow 500
@@ -2055,14 +2032,12 @@
  and nwelldef
  and DUALGATE
  and mvpfetexpand
- labels DIFF
 
  layer mvpdiffres DIFF
  and-not POLY
  and PPLUS
  and SBLK
  and DUALGATE
- labels DIFF
 
  layer mvnfet DIFF
  and POLY
@@ -2072,7 +2047,6 @@
  and-not nwelldef
  and DUALGATE
  and-not MOSCAP
- labels DIFF
 
  layer mvncap DIFF
  and POLY
@@ -2082,7 +2056,6 @@
  and-not nwelldef
  and DUALGATE
  and MOSCAP
- labels DIFF
 
  layer mvnnfet DIFF
  and POLY
@@ -2091,7 +2064,6 @@
  and NAT
  and-not nwelldef
  and DUALGATE
- labels DIFF
 
  templayer mvnsdarea DIFF
  and NPLUS
@@ -2102,7 +2074,6 @@
  copyup mvnsubcheck
 
  layer mvnsd mvnsdarea
- labels DIFF
 
  templayer mvnsdexpand mvnsdarea
  grow 500
@@ -2121,7 +2092,6 @@
  copyup mvpsubcheck
 
  layer mvpsd mvpsdarea
- labels DIFF
 
  templayer mvpsdexpand mvpsdarea
  grow 500
@@ -2191,13 +2161,11 @@
  and-not SBLK
  and PPLUS
  and RESDEF
- labels POLY
 
  layer rnps POLY
  and-not SBLK
  and NPLUS
  and RESDEF
- labels POLY
 
  layer rpp POLY
  and SBLK
@@ -2206,7 +2174,6 @@
  and-not HRES
 #endif (HRPOLY1K)
  and RESDEF
- labels POLY
 
  # POLY + SBLK without RESDEF may be a salicide-blocked transistor.
  # The SBLK will be regenerated on GDS output and the poly should be
@@ -2215,12 +2182,10 @@
  and-not DIFF
  and SBLK
  and-not RESDEF
- labels POLY
 
  layer efuse POLY
  and-not DIFF
  and PLFUSE
- labels POLY
 
  layer rnp POLY
  and SBLK
@@ -2229,7 +2194,6 @@
 #ifdef HRPOLY1K
  and-not HRES
 #endif (HRPOLY1K)
- labels POLY
 
 #ifdef HRPOLY1K
  layer hires POLY
@@ -2237,14 +2201,12 @@
  and HRES
  and RESDEF
  and-not DUALGATE
- labels POLY
 
  layer mvhires POLY
  and SBLK
  and HRES
  and RESDEF
  and DUALGATE
- labels POLY
 
  # We define poly under HRES but not under SBLK to be plain poly
  layer poly POLY
@@ -2778,28 +2740,24 @@
  and NPLUS
  and nwelldef
  and-not DUALGATE
- labels POLY
 
  layer mvnvar POLY
  and DIFF
  and NPLUS
  and nwelldef
  and DUALGATE
- labels POLY
 
  layer pvar POLY
  and DIFF
  and PPLUS
  and-not nwelldef
  and-not DUALGATE
- labels POLY
 
  layer mvpvar POLY
  and DIFF
  and PPLUS
  and-not nwelldef
  and DUALGATE
- labels POLY
 
  calma DNWELL 12 0
  calma NWELL 21 0
diff --git a/gf180mcu/magic/gf180mcu_make_torture.tcl b/gf180mcu/magic/gf180mcu_make_torture.tcl
index dc1d3aa..3a84bf7 100644
--- a/gf180mcu/magic/gf180mcu_make_torture.tcl
+++ b/gf180mcu/magic/gf180mcu_make_torture.tcl
@@ -46,7 +46,7 @@
          magic::gencell gf180mcu::${devname} ${devname}_$i w $w l $l m $m nf $nf diffcov $dcov polycov $pcov rlcov $rlcov poverlap $pov doverlap $dov topc $tc botc $bc full_metal $fm glc $gl grc $gr gbc $gb gtc $gt
          select cell ${devname}_$i
          set bh [box height]
-         set bh [+ $bh 124]
+         set bh [+ $bh 200]
          box move n $bh
          incr i
       }
@@ -88,7 +88,7 @@
          magic::gencell gf180mcu::${devname} ${devname}_$i w $w l $l m $m nx $nx endcov $ecov roverlap $rov snake $sn full_metal $fm glc $gl grc $gr gbc $gb gtc $gt
          select cell ${devname}_$i
          set bh [box height]
-         set bh [+ $bh 124]
+         set bh [+ $bh 200]
          box move n $bh
          incr i
       }
@@ -130,7 +130,7 @@
          magic::gencell gf180mcu::${devname} ${devname}_$i w $w l $l nx $nx ny $ny doverlap $dov full_metal $fm elc $el erc $er etc $et ebc $eb glc $gl grc $gr gbc $gb gtc $gt
          select cell ${devname}_$i
          set bh [box height]
-         set bh [+ $bh 124]
+         set bh [+ $bh 200]
          box move n $bh
          incr i
       }
@@ -213,60 +213,69 @@
 snap int
 box size 0 0
  
-# Layout:
-#                                                       apmom_bb
-#  pmos_3p3                                             mim_sm_bb
-#            pplus_u  ppolyf_s   ppolyf_u  pplus_u_3p3
-#  nmos_3p3                                pn_3p3
-#                                          np_3p3
-#  pmos_1p2                                
-#            nplus_u  nwell_1p2  npolyf_u  nplus_u_3p3  pn_1p2
-#  pmos_1p2                                             np_1p2 
+#
+# Generate device arrays
 #
 
+mos_array 6 nfet_03v3 	   0      0
+mos_array 6 pfet_03v3 	   0  75000
+mos_array 6 nfet_06v0 	   0 150000 
+mos_array 6 pfet_06v0 	   0 225000
+mos_array 6 nfet_03v3_nvt  0 300000
+mos_array 6 nfet_03v3_dss  0 375000
+mos_array 6 pfet_03v3_dss  0 450000
+mos_array 6 nfet_06v0_dss  0 525000
+mos_array 6 nfet_06v0_dss  0 600000
+mos_array 6 pfet_06v0_nat  0 675000
+mos_array 6 nfet_10v0_asym 0 675000
+mos_array 6 pfet_10v0_asym 0 725000
 
-mos_array 6 nmos_3p3 0 0
-mos_array 6 pmos_3p3 0 75000
-mos_array 6 nmos_6p0 0 150000 
-mos_array 6 pmos_6p0 0 225000
-mos_array 6 pmos_3p3_lvt 0 300000
-mos_array 6 pmos_3p3_hvt 0 375000
-mos_array 6 nmos_3p3_lvt 0 450000
-mos_array 6 nmos_3p3_hvt 0 525000
-mos_array 6 nmos_3p3_nat 0 600000
-mos_array 6 nmos_6p0_nat 0 675000
+res_array 6 npolyf_u 	100000      0 
+res_array 6 ppolyf_u 	100000 180000
 
-res_array 6 nplus_u 100000 0 
-res_array 6 pplus_u 100000 180000
+res_array 6 ppolyf_u_1k	    200000      0
+res_array 6 ppolyf_u_1k_6p0 200000 180000
 
-res_array 6 nwell_1p2 200000 0
-res_array 6 ppolyf_s 200000 180000
+res_array 6 nplus_u 	300000      0
+res_array 6 pplus_u 	300000 180000
 
-res_array 6 npolyf_u 300000 0
-res_array 6 ppolyf_u 300000 180000
-
-res_array 6 nplus_u_3p3 400000 0
-res_array 6 pplus_u_3p3 400000 180000
+res_array 6 npolyf_s 	400000      0
+res_array 6 ppolyf_s 	400000 180000
  
-diode_array 6 np_1p2 500000 0
-diode_array 6 pn_1p2 500000 30000 
-diode_array 6 np_3p3 500000 60000
-diode_array 6 pn_3p3 500000 90000 
-diode_array 6 np_1p2_lvt 500000 120000
-diode_array 6 np_1p2_hvt 500000 150000
-diode_array 6 np_1p2_nat 500000 180000
-diode_array 6 pn_1p2_lvt 500000 210000 
-diode_array 6 pn_1p2_hvt 500000 240000 
-diode_array 6 np_3p3_nat 500000 270000
+res_array 6 nwell 	500000      0
+res_array 6 rm1   	500000 180000
+res_array 6 rm2   	500000 360000
+res_array 6 rm3   	500000 540000
+res_array 6 rm4   	500000 720000
+res_array 6 rm5   	500000 900000
+
+diode_array 6 diode_nd2ps_03v3 	   600000      0
+diode_array 6 diode_pd2nw_03v3 	   600000  30000 
+diode_array 6 diode_nd2ps_06v0 	   600000  60000
+diode_array 6 diode_pd2nw_06v0 	   600000  90000 
+diode_array 6 diode_nw2pw_03v3 	   600000 120000
+diode_array 6 diode_nw2pw_06v0 	   600000 150000
+diode_array 6 diode_dnw2pw     	   600000 180000
+diode_array 6 diode_dnw2ps     	   600000 210000 
+diode_array 6 sc_diode 		   600000 240000 
+diode_array 6 diode_nd2ps_06v0_nvt 600000 270000
+
+cap_array 6 cap_mim_2p0fF	700000      0
+cap_array 6 nmoscap_3p3   	700000 100000 
+cap_array 6 nmoscap_6p0   	700000 200000 
 
 # Add individual devices from primdev, check GDS pointers
-fixed_array 2 vnpn_2x2 600000 0
-fixed_array 2 vnpn_5x0p42 600000 50000
-fixed_array 2 vnpn_5x5 600000 100000
-fixed_array 2 vnpn_10x0p42 600000 150000
+fixed_array 2 efuse_cell      800000      0
+fixed_array 2 npn_00p54x02p00 800000  50000
+fixed_array 2 npn_00p54x04p00 800000 100000
+fixed_array 2 npn_00p54x08p00 800000 150000
+fixed_array 2 npn_00p54x16p00 800000 200000
+fixed_array 2 npn_05p00x05p00 800000 250000
+fixed_array 2 npn_10p00x10p00 800000 300000
+fixed_array 2 pnp_05p00x00p42 800000 350000
+fixed_array 2 pnp_05p00x05p00 800000 400000
+fixed_array 2 pnp_10p00x00p42 800000 450000
+fixed_array 2 pnp_10p00x10p00 800000 500000
 
-cap_array 6  mim_sm_bb 600000 200000 
-# cap_array 6 apmom_bb 600000 250000 
-
-save torture_test_gf013
-gds write torture_test_gf013
+save torture_test_gf180mcu
+gds write torture_test_gf180mcu
diff --git a/sky130/magic/sky130.tcl b/sky130/magic/sky130.tcl
index 4dba385..48367fa 100644
--- a/sky130/magic/sky130.tcl
+++ b/sky130/magic/sky130.tcl
@@ -98,6 +98,12 @@
    magic::add_toolkit_command $layoutframe "pmos (MOSFET)" \
 	    "magic::gencell sky130::sky130_fd_pr__pfet_01v8" pdk1
 
+   # magic::add_toolkit_separator	$layoutframe pdk1
+   # magic::add_toolkit_command $layoutframe "LDNMOS (extended drain)" \
+   #	    "magic::gencell sky130::sky130_fd_pr__nfet_g5v0d16v0" pdk1
+   # magic::add_toolkit_command $layoutframe "LDPMOS (extended drain)" \
+   #	    "magic::gencell sky130::sky130_fd_pr__pfet_g5v0d16v0" pdk1
+
    magic::add_toolkit_separator	$layoutframe pdk1
    magic::add_toolkit_command $layoutframe "n-diode" \
 	    "magic::gencell sky130::sky130_fd_pr__diode_pw2nd_05v5" pdk1
@@ -4986,6 +4992,13 @@
 		viagb 0 viagr 0 viagl 0 viagt 0}
 }
 
+proc sky130::sky130_fd_pr__pfet_g5v0d16v0_defaults {} {
+    return {w 5.00 l 1.050 m 1 nf 1 diffcov 100 polycov 100 \
+		tbcov 100 rlcov 100 topc 1 botc 1 \
+		poverlap 0 doverlap 0 lmin 1.050 wmin 5.00 \
+		viasrc 100 viadrn 100 viagate 100 }
+}
+
 #----------------------------------------------------------------
 # nmos: Specify all user-editable default values and those
 # needed by mos_check
@@ -5063,6 +5076,13 @@
 		viagb 0 viagr 0 viagl 0 viagt 0}
 }
 
+proc sky130::sky130_fd_pr__nfet_g5v0d16v0_defaults {} {
+    return {w 5.00 l 1.055 m 1 nf 1 diffcov 100 polycov 100 \
+		tbcov 100 rlcov 100 topc 1 botc 1 \
+		poverlap 0 doverlap 0 lmin 1.055 wmin 5.00 \
+		viasrc 100 viadrn 100 viagate 100 }
+}
+
 #----------------------------------------------------------------
 # mos varactor: Specify all user-editable default values and those
 # needed by mosvc_check
@@ -5158,6 +5178,10 @@
     return [sky130::mos_convert $parameters]
 }
 
+proc sky130::sky130_fd_pr__nfet_g5v0d16v0_convert {parameters} {
+    return [sky130::mos_convert $parameters]
+}
+
 proc sky130::sky130_fd_pr__nfet_05v0_nvt_convert {parameters} {
     return [sky130::mos_convert $parameters]
 }
@@ -5182,6 +5206,10 @@
     return [sky130::mos_convert $parameters]
 }
 
+proc sky130::sky130_fd_pr__pfet_g5v0d16v0_convert {parameters} {
+    return [sky130::mos_convert $parameters]
+}
+
 proc sky130::sky130_fd_pr__cap_var_lvt_convert {parameters} {
     return [sky130::mos_convert $parameters]
 }
@@ -5270,6 +5298,10 @@
     sky130::mos_dialog sky130_fd_pr__nfet_g5v0d10v5 $parameters
 }
 
+proc sky130::sky130_fd_pr__nfet_g5v0d16v0_dialog {parameters} {
+    sky130::mos_dialog sky130_fd_pr__nfet_g5v0d16v0 $parameters
+}
+
 proc sky130::sky130_fd_pr__nfet_05v0_nvt_dialog {parameters} {
     sky130::mos_dialog sky130_fd_pr__nfet_05v0_nvt $parameters
 }
@@ -5294,6 +5326,10 @@
     sky130::mos_dialog sky130_fd_pr__pfet_g5v0d10v5 $parameters
 }
 
+proc sky130::sky130_fd_pr__pfet_g5v0d16v0_dialog {parameters} {
+    sky130::mos_dialog sky130_fd_pr__pfet_g5v0d16v0 $parameters
+}
+
 proc sky130::sky130_fd_pr__cap_var_lvt_dialog {parameters} {
     sky130::mos_dialog sky130_fd_pr__cap_var_lvt $parameters
 }
@@ -5709,6 +5745,20 @@
 }
 
 #----------------------------------------------------------------
+# LDNMOS:  Sub-procedure to draw the extended drain
+#----------------------------------------------------------------
+
+proc sky130::draw_ldnmos_drain {parameters} {
+}
+
+#----------------------------------------------------------------
+# LDPMOS:  Sub-procedure to draw the extended drain
+#----------------------------------------------------------------
+
+proc sky130::draw_ldpmos_drain {parameters} {
+}
+
+#----------------------------------------------------------------
 # MOSFET: Draw a single device
 #----------------------------------------------------------------
 
@@ -5725,12 +5775,13 @@
     set viasrc 100	;# draw source vias
     set viadrn 100	;# draw drain vias
     set viagate 100	;# draw gate vias
-    set evens 1		;# even or odd numbered device finger, in X
+    set evens 1		;# even or odd (evens = 1 means drain is on the left)
     set dev_sub_type ""	;# device substrate type (if different from guard ring)
     set dev_sub_dist 0	;# device substrate distance (if nondefault dev_sub_type)
     set min_effl 0	;# gate length below which finger pitch must be stretched
     set diff_overlap_cont 0	;# extra overlap of end contact by diffusion
     set gshield 0	;# no metal shield over gate (used for varactors)
+    set drain_proc {}	;# no special procedure to draw the drain
 
     # Set a local variable for each parameter (e.g., $l, $w, etc.)
     foreach key [dict keys $parameters] {
@@ -5749,13 +5800,23 @@
     box grow s ${hw}um
     box grow e ${hl}um
     box grow w ${hl}um
+
+    # Set drain and source sides based on "evens".
+    if {$evens == 0} {
+	set dside e
+	set sside w
+    } else {
+	set dside w
+	set sside e
+    }
+
     pushbox
     if {${diff_extension} > ${gate_to_diffcont}} {
-        box grow e ${diff_extension}um
-        box grow w ${diff_extension}um
+        box grow $dside ${diff_extension}um
+        box grow $sside ${diff_extension}um
     } else {
-        box grow e ${gate_to_diffcont}um
-        box grow w ${gate_to_diffcont}um
+        box grow $dside ${gate_to_diffcont}um
+        box grow $sside ${gate_to_diffcont}um
     }
     paint ${diff_type}
     popbox
@@ -5853,52 +5914,57 @@
 	set cpl [* ${cpl} [/ ${polycov} 100.0]]
     }
 
-    # Right diffusion contact
-    pushbox
-    box move e ${he}um
-    box move e ${gate_to_diffcont}um
+    if {$drain_proc != {}} {
+	set cext [sky130::unionbox $cext [eval $drain_proc parameters]]
+    } else {
+	# Drain diffusion contact
+	pushbox
+	box move $dside ${he}um
+	box move $dside ${gate_to_diffcont}um
 
-    # Source via on top of contact
-    if {$evens == 1} {set viatype $viasrc} else {set viatype $viadrn}
-    if {$viatype != 0} {
-        pushbox
-        set cw $via_size
-    	set ch [* $cdwfull [/ [expr abs($viatype)] 100.0]]
-    	if {$ch < $via_size} {set ch $via_size}
-	box grow e [/ $cw 2]um
-	box grow w [/ $cw 2]um
-        set anchor [string index $viatype 0]
-	if {$anchor == "+"} {
-            box move s [/ [- $cdwfull $via_size] 2]um
-	    box grow n ${ch}um
-	} elseif {$anchor == "-"} {
-            box move n [/ [- $cdwfull $via_size] 2]um
-	    box grow s ${ch}um
-	} else {
-	    box grow n [/ $ch 2]um
-	    box grow s [/ $ch 2]um
+	# Drain via on top of contact
+	set viatype $viadrn
+	if {$viatype != 0} {
+            pushbox
+            set cw $via_size
+    	    set ch [* $cdwfull [/ [expr abs($viatype)] 100.0]]
+    	    if {$ch < $via_size} {set ch $via_size}
+	    box grow $dside [/ $cw 2]um
+	    box grow $sside [/ $cw 2]um
+            set anchor [string index $viatype 0]
+	    if {$anchor == "+"} {
+        	box move s [/ [- $cdwfull $via_size] 2]um
+		box grow n ${ch}um
+	    } elseif {$anchor == "-"} {
+        	box move n [/ [- $cdwfull $via_size] 2]um
+		box grow s ${ch}um
+	    } else {
+		box grow n [/ $ch 2]um
+		box grow s [/ $ch 2]um
+	    }
+	    sky130::mcon_draw vert
+	    popbox
 	}
-        sky130::mcon_draw vert
-        popbox
-    }
-    set cext [sky130::unionbox $cext [sky130::draw_contact 0 ${cdw} \
+	set cext [sky130::unionbox $cext [sky130::draw_contact 0 ${cdw} \
 		${diff_surround} ${metal_surround} ${contact_size}\
 		${diff_type} ${diff_contact_type} li vert]]
-    popbox
-    # Left diffusion contact
-    pushbox
-    box move w ${he}um
-    box move w ${gate_to_diffcont}um
+	popbox
+    }
 
-    # Drain via on top of contact
-    if {$evens == 1} {set viatype $viadrn} else {set viatype $viasrc}
+    # Source diffusion contact
+    pushbox
+    box move $sside ${he}um
+    box move $sside ${gate_to_diffcont}um
+
+    # Source via on top of contact
+    set viatype $viasrc
     if {$viatype != 0} {
         pushbox
         set cw $via_size
     	set ch [* $cdwfull [/ [expr abs($viatype)] 100.0]]
     	if {$ch < $via_size} {set ch $via_size}
-	box grow e [/ $cw 2]um
-	box grow w [/ $cw 2]um
+	box grow $sside [/ $cw 2]um
+	box grow $dside [/ $cw 2]um
         set anchor [string index $viatype 0]
 	if {$anchor == "+"} {
             box move s [/ [- $cdwfull $via_size] 2]um
@@ -6540,6 +6606,48 @@
 }
 
 #----------------------------------------------------------------
+# 16V extended-drain devices LDNMOS and LDPMOS
+#----------------------------------------------------------------
+
+proc sky130::sky130_fd_pr__nfet_g5v0d16v0_draw {parameters} {
+    set newdict [dict create \
+	    gate_type		mvnfet \
+	    diff_type 		mvndiff \
+	    diff_contact_type	mvndc \
+	    plus_diff_type	mvpsd \
+	    plus_contact_type	mvpsc \
+	    poly_type		poly \
+	    poly_contact_type	pc \
+	    sub_type		psub \
+	    diff_spacing	0.31 \
+	    diff_tap_space	0.38 \
+	    diff_gate_space	0.38 \
+	    drain_proc		sky130::draw_ldnmos_drain \
+    ]
+    set drawdict [dict merge $sky130::ruleset $newdict $parameters]
+    return [sky130::mos_draw $drawdict]
+}
+
+proc sky130::sky130_fd_pr__pfet_g5v0d16v0_draw {parameters} {
+    set newdict [dict create \
+	    gate_type		mvpfet \
+	    diff_type 		mvpdiff \
+	    diff_contact_type	mvpdc \
+	    plus_diff_type	mvnsd \
+	    plus_contact_type	mvnsc \
+	    poly_type		poly \
+	    poly_contact_type	pc \
+	    sub_type		nwell \
+	    diff_spacing	0.31 \
+	    diff_tap_space	0.38 \
+	    diff_gate_space	0.38 \
+	    drain_proc		sky130::draw_ldpmos_drain \
+    ]
+    set drawdict [dict merge $sky130::ruleset $newdict $parameters]
+    return [sky130::mos_draw $drawdict]
+}
+
+#----------------------------------------------------------------
 # MOSFET: Check device parameters for out-of-bounds values
 #----------------------------------------------------------------
 
@@ -6724,6 +6832,10 @@
    return [sky130::mos_check sky130_fd_pr__nfet_g5v0d10v5 $parameters]
 }
 
+proc sky130::sky130_fd_pr__nfet_g5v0d16v0_check {parameters} {
+   return [sky130::mos_check sky130_fd_pr__nfet_g5v0d16v0 $parameters]
+}
+
 proc sky130::sky130_fd_pr__nfet_05v0_nvt_check {parameters} {
    return [sky130::mos_check sky130_fd_pr__nfet_05v0_nvt $parameters]
 }
@@ -6748,6 +6860,10 @@
    return [sky130::mos_check sky130_fd_pr__pfet_g5v0d10v5 $parameters]
 }
 
+proc sky130::sky130_fd_pr__pfet_g5v0d16v0_check {parameters} {
+   return [sky130::mos_check sky130_fd_pr__pfet_g5v0d16v0 $parameters]
+}
+
 proc sky130::sky130_fd_pr__cap_var_lvt_check {parameters} {
    return [sky130::mos_check sky130_fd_pr__cap_var_lvt $parameters]
 }
diff --git a/sky130/magic/sky130.tech b/sky130/magic/sky130.tech
index 8d4ad2f..9cde973 100644
--- a/sky130/magic/sky130.tech
+++ b/sky130/magic/sky130.tech
@@ -58,6 +58,8 @@
 # sky130_fd_pr__pfet_g5v0d10v5	mvpfet		thickox pFET
 # sky130_fd_pr__nfet_g5v0d10v5	mvnfet		thickox nFET
 # sky130_fd_pr__nfet_01v8_nvt	mvnnfet		thickox native nFET
+# sky130_fd_pr__nfet_g5v0d16v0	mvnfet		extended-drain nFET***
+# sky130_fd_pr__pfet_g5v0d16v0	mvpfet		extended-drain pFET***
 # sky130_fd_pr__diode_pw2nd_05v5 ndiode		n+ diff diode
 # sky130_fd_pr__diode_pw2nd_05v5_lvt ndiodelvt	low Vt n+ diff diode
 # sky130_fd_pr__diode_pw2nd_05v5_nvt nndiode	diode with nndiff
@@ -95,6 +97,10 @@
 # outside of the standard cell except for the DRC rule for
 # FET to diffusion contact spacing (which is 0.05um, not 0.055um)
 #
+# (***) The extended-drain devices have the same identifying
+# FET type as the thick oxide devices, but the drain side of the
+# device is represented by layer extdrain extending to nsd or psd.
+#
 #-------------------------------------------------------------
 # The following devices are not extracted but are represented
 # only by script-generated subcells in the PDK.
@@ -201,6 +207,7 @@
   active nsubdiffcont,nsubstratencontact,nsc,ntapc
   active mvpsubdiffcont,mvpsubstratepcontact,mvpsc,mvptapc
   active mvnsubdiffcont,mvnsubstratencontact,mvnsc,mvntapc
+  active extdrain,ed
  -active obsactive
  -active mvobsactive
 
@@ -522,6 +529,8 @@
   mvnsc     ndiff_in_nwell metal1  contact_X'es hvndiff_mask
   mvpsc     pdiff_in_pwell metal1  contact_X'es hvpdiff_mask
 
+  extdrain  nselect pselect
+
   poly      polysilicon 
   polyfill  polysilicon
   pc        polysilicon    metal1  contact_X'es
@@ -721,8 +730,8 @@
 #-----------------------------------------------------
 
 connect
-  *nwell,*nsd,*mvnsd,dnwell,pnp,photo *nwell,*nsd,*mvnsd,dnwell,pnp,photo
-  pwell,*psd,*mvpsd,npn,isosub  pwell,*psd,*mvpsd,npn,isosub
+  *nwell,*nsd,*mvnsd,dnwell,pnp,photo,ed *nwell,*nsd,*mvnsd,dnwell,pnp,photo,ed
+  pwell,*psd,*mvpsd,npn,isosub,ed  pwell,*psd,*mvpsd,npn,isosub,ed
   *li,coreli,lifill	*li,coreli,lifill
   *m1,m1fill,obsmcon	*m1,m1fill,obsmcon
 #ifdef RERAM
@@ -801,9 +810,21 @@
 # NWELL
 #----------------------------------------------------------------
 
- layer NWELL 	allnwell
+ # Generate n-well under extended-drain nFET
+ templayer extnwell
+	bloat-or *mvnsd * 0 extdrain 1150
+	and-not *mvnsd
+	grow 660
+
+ # Erase n-well under extended-drain pFET
+ templayer extpwell
+	bloat-or *mvpsd * 0 extdrain 590
+	and-not *mvpsd
+	grow 860
+
+ layer NWELL 	allnwell,extnwell
 	bloat-all rpw dnwell
-	and-not rpw,pwell
+	and-not rpw,pwell,extpwell
  	calma 	64 20
 
  layer WELLTXT
@@ -830,7 +851,13 @@
 # DIFF
 #----------------------------------------------------------------
 
+ # Extended-drain FETs cut the diffusion under the gate
+ templayer ldbreak
+	bloat-or *mvnsd * 0 extdrain 1585
+	bloat-or *mvpsd * 0 extdrain 1190
+
  layer DIFF 	allnactivenontap,allpactivenontap,allactiveres
+	and-not	ldbreak
  	calma 	65 20
 
  layer DIFFTXT
@@ -900,6 +927,15 @@
  	calma	93 44
 
 #----------------------------------------------------------------
+# EDID (Extended drain identifier)
+#----------------------------------------------------------------
+
+ layer EDID
+	bloat-all extdrain *mvnsd,*mvpsd,mvnfet,mvpfet,*mvndiff,*mvpdiff
+	labels	extdrain
+	calma	81 57
+
+#----------------------------------------------------------------
 # LVID
 #----------------------------------------------------------------
 
@@ -2362,7 +2398,7 @@
  scalefactor 10 nanometers
  gridlimit 5
 
- options ignore-unknown-layer-labels no-reconnect-labels
+ options ignore-unknown-layer-labels
 
 #ifndef MIM
  ignore CAPM
@@ -2380,6 +2416,7 @@
  ignore POLYMOD
  ignore LOWTAPDENSITY
  ignore FILLOBSPOLY
+ ignore FILLOBSFOM
  ignore MET5BLOCK
  ignore OUTLINE
  ignore POLYCUT
@@ -3878,8 +3915,6 @@
  and-not FILLOBSM5
  labels FILLOBSM1,FILLOBSM2,FILLOBSM3,FILLOBSM4
 
- layer obsactive  FILLOBSFOM
-
 # MOS Varactor
 
  layer var POLY
@@ -4256,6 +4291,15 @@
  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)"
 
+ # Extended drain rules
+ edge4way space/a ed/a 5000 ~(space)/a 0 0 "LDNFET/LDPFET width < %d (denmos/depmos.2)"
+ edge4way (*mvndiff)/a mvnfet 1055 ~(ed)/a 0 0 "LDNFET length < %d (denmos.1)"
+ edge4way (*mvnsd)/a ed/a 2510 ~(*mvndiff)/a 0 0 \
+	"LDNFET drain to source < %d (denmos.6 + denmos.3)"
+ edge4way (*mvpdiff)/a mvpfet 1050 ~(ed)/a 0 0 "LDPFET length < %d (depmos.1)"
+ edge4way (*mvpsd)/a ed/a 2510 ~(*mvpdiff)/a 0 0 \
+	"LDPFET drain to source < %d (depmos.6 + depmos.3)"
+
  area  *nsd,*mvnsd 70110 150 "N-tap minimum area < 0.07011um^2 (nsd.10b)"
  area  *psd,*mvpsd 70110 150 "P-tap minimum area < 0.07011um^2 (psd.10b)"
 
@@ -6392,6 +6436,10 @@
  device msubcircuit Ignore mvpfet *mvpdiff,mvpdiffres pwell,space/w nwell error +npn,pnp
 
  # Extended drain devices (must appear before the regular devices)
+ device msubcircuit sky130_fd_pr__nfet_g5v0d16v0 mvnfet *mvndiff \
+	extdrain,*mvnsd pwell,space/w error l=l w=w a1=as p1=ps a2=ad p2=pd
+ device msubcircuit sky130_fd_pr__pfet_g5v0d16v0 mvpfet *mvpdiff \
+	extdrain,*mvpsd nwell error l=l w=w a1=as p1=ps a2=ad p2=pd
  device msubcircuit sky130_fd_pr__nfet_20v0_nvt mvnnfet *mvndiff,mvndiffres \
 	dnwell pwell,space/w error l=l w=w a1=as a2=ad p1=ps p2=pd
  device msubcircuit sky130_fd_pr__nfet_20v0 mvnfet *mvndiff,mvndiffres \