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 } }