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 \