Made a change to the PNP transistor layouts in sky130_fd_pr so that the layouts have an _rf_ in the name (which they did, originally, except not consistently). This keeps the layout cell from having the same name as the wrapper subcircuit, which would otherwise cause an invalid loop of a subcircuit apparently calling itself. The magic .mag view of this device layout is modified to contain the ID layer specific to the 0p68 or 3p40 devices, so that when extracted from magic, the device has the correct extracted name for the device model's subcircuit wrapper. This should be correct now for the four devices that can be instantiated from magic's device generator.
diff --git a/sky130/Makefile.in b/sky130/Makefile.in index 9bc14de..818071c 100644 --- a/sky130/Makefile.in +++ b/sky130/Makefile.in
@@ -821,6 +821,10 @@ custom/models/sky130.lib.spice.extra > \ ${STAGING_PATH}/${SKY130A}/libs.tech/ngspice/sky130.lib.spice rm ${STAGING_PATH}/${SKY130A}/libs.tech/ngspice/sky130.lib.spice.head + # Custom: Add special device ID layers to bipolar layouts in magic + # to make the extraction models correct. + ./custom/scripts/add_bipolar_ids.py \ + 2>&1 | tee -a ${SKY130A}_make.log || true # Custom: Add "spinit" file cat ./custom/models/spinit >> \
diff --git a/sky130/custom/scripts/add_bipolar_ids.py b/sky130/custom/scripts/add_bipolar_ids.py new file mode 100755 index 0000000..1668ef4 --- /dev/null +++ b/sky130/custom/scripts/add_bipolar_ids.py
@@ -0,0 +1,84 @@ +#!/usr/bin/env python3 +# +#-------------------------------------------------------------------- +# Add the special ID layers for the bipolar transistors which tell +# the extraction engine in magic to extract the device model that +# is specific to the device size. There is no such GDS layer, so it +# can only be added after the fact. +#-------------------------------------------------------------------- + +import os +import re +import sys + +magpath = 'sky130A/libs.ref/sky130_fd_pr/mag' + +if len(sys.argv) > 1: + magpath = sys.argv[1] + +baserex = re.compile('<< [np]base >>') + +# Note that the list of NPNs is not comprehensive. However, at the +# moment only 5 special layers and 5 special models are defined in +# the magic techfile and in the device generator. Adding more must +# start with the magic techfile, as the layers must be defined before +# this script can be run. + +devlist = ['sky130_fd_pr__rf_pnp_05v5_W0p68L0p68', + 'sky130_fd_pr__rf_pnp_05v5_W3p40L3p40', + 'sky130_fd_pr__rf_npn_11v0_W1p00L1p00', + 'sky130_fd_pr__rf_npn_05v5_W1p00L1p00', + 'sky130_fd_pr__rf_npn_05v5_W1p00L2p00'] + +typelist = ['pnp0p68', + 'pnp3p40', + 'npn11p0', + 'npn1p00', + 'npn2p00'] + +#-------------------------------------------------------------------- + +for idx, device in enumerate(devlist): + infile_name = magpath + '/' + device + '.mag' + outfile_name = magpath + '/temp.mag' + + if not os.path.exists(infile_name): + print('Error: Cannot find file ' + infile_name) + continue + + print('Adding special ID layer to device ' + device + ' layout') + + type = typelist[idx] + is_baserect = False + infile = open(infile_name, 'r') + outfile = open(outfile_name, 'w') + line_number = 0 + replaced_something = False + + for line in infile: + line_number += 1 + + if is_baserect: + # Repeat the same rectangle as for the bipolar base layer, + # using the ID type layer + outfile.write(line) + outfile.write('<< ' + type + ' >>\n') + replaced_something = True + is_baserect = False + else: + bmatch = baserex.match(line) + if bmatch: + is_baserect = True + + outfile.write(line) + + infile.close() + outfile.close() + + if replaced_something: + print("Something was replaced in '{}'".format(infile_name)) + os.rename(outfile_name, infile_name) + else: + print("Nothing was replaced in '{}'.".format(infile_name)) + os.remove(outfile_name) +
diff --git a/sky130/custom/sky130_fd_pr/sky130_fd_pr__pnp_05v5_W0p68L0p68.gds b/sky130/custom/sky130_fd_pr/sky130_fd_pr__rf_pnp_05v5_W0p68L0p68.gds similarity index 97% rename from sky130/custom/sky130_fd_pr/sky130_fd_pr__pnp_05v5_W0p68L0p68.gds rename to sky130/custom/sky130_fd_pr/sky130_fd_pr__rf_pnp_05v5_W0p68L0p68.gds index ed066be..92cd525 100644 --- a/sky130/custom/sky130_fd_pr/sky130_fd_pr__pnp_05v5_W0p68L0p68.gds +++ b/sky130/custom/sky130_fd_pr/sky130_fd_pr__rf_pnp_05v5_W0p68L0p68.gds Binary files differ
diff --git a/sky130/custom/sky130_fd_pr/sky130_fd_pr__pnp_05v5_W3p40L3p40.gds b/sky130/custom/sky130_fd_pr/sky130_fd_pr__rf_pnp_05v5_W3p40L3p40.gds similarity index 98% rename from sky130/custom/sky130_fd_pr/sky130_fd_pr__pnp_05v5_W3p40L3p40.gds rename to sky130/custom/sky130_fd_pr/sky130_fd_pr__rf_pnp_05v5_W3p40L3p40.gds index 1e0a117..13e2a20 100644 --- a/sky130/custom/sky130_fd_pr/sky130_fd_pr__pnp_05v5_W3p40L3p40.gds +++ b/sky130/custom/sky130_fd_pr/sky130_fd_pr__rf_pnp_05v5_W3p40L3p40.gds Binary files differ
diff --git a/sky130/magic/sky130.tcl b/sky130/magic/sky130.tcl index 69250f2..bcf4df5 100644 --- a/sky130/magic/sky130.tcl +++ b/sky130/magic/sky130.tcl
@@ -112,9 +112,9 @@ magic::add_toolkit_command $layoutframe "NPN 1.0 x 2.0" \ "magic::gencell sky130::sky130_fd_pr__rf_npn_05v5_W1p00L2p00" pdk1 magic::add_toolkit_command $layoutframe "PNP 0.68 x 0.68" \ - "magic::gencell sky130::sky130_fd_pr__pnp_05v5_W0p68L0p68" pdk1 + "magic::gencell sky130::sky130_fd_pr__rf_pnp_05v5_W0p68L0p68" pdk1 magic::add_toolkit_command $layoutframe "PNP 3.4 x 3.4" \ - "magic::gencell sky130::sky130_fd_pr__pnp_05v5_W3p40L3p40" pdk1 + "magic::gencell sky130::sky130_fd_pr__rf_pnp_05v5_W3p40L3p40" pdk1 magic::add_toolkit_separator $layoutframe pdk1 @@ -6392,8 +6392,8 @@ # # sky130_fd_pr__rf_npn_05v5_W1p00L1p00 # sky130_fd_pr__rf_npn_05v5_W1p00L2p00 -# sky130_fd_pr__pnp_05v5_W3p40L3p40 -# sky130_fd_pr__pnp_05v5_W0p68L0p68 +# sky130_fd_pr__rf_pnp_05v5_W3p40L3p40 +# sky130_fd_pr__rf_pnp_05v5_W0p68L0p68 # # Parallel Plate Capacitors: # @@ -6415,11 +6415,11 @@ return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 7.03 ystep 8.03} } -proc sky130::sky130_fd_pr__pnp_05v5_W0p68L0p68_defaults {} { +proc sky130::sky130_fd_pr__rf_pnp_05v5_W0p68L0p68_defaults {} { return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 3.72 ystep 3.72} } -proc sky130::sky130_fd_pr__pnp_05v5_W3p40L3p40_defaults {} { +proc sky130::sky130_fd_pr__rf_pnp_05v5_W3p40L3p40_defaults {} { return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 6.44 ystep 6.44} } @@ -6472,11 +6472,11 @@ return [sky130::fixed_convert $parameters] } -proc sky130::sky130_fd_pr__pnp_05v5_W0p68L0p68_convert {parameters} { +proc sky130::sky130_fd_pr__rf_pnp_05v5_W0p68L0p68_convert {parameters} { return [sky130::fixed_convert $parameters] } -proc sky130::sky130_fd_pr__pnp_05v5_W3p40L3p40_convert {parameters} { +proc sky130::sky130_fd_pr__rf_pnp_05v5_W3p40L3p40_convert {parameters} { return [sky130::fixed_convert $parameters] } @@ -6556,11 +6556,11 @@ sky130::fixed_dialog $parameters } -proc sky130::sky130_fd_pr__pnp_05v5_W0p68L0p68_dialog {parameters} { +proc sky130::sky130_fd_pr__rf_pnp_05v5_W0p68L0p68_dialog {parameters} { sky130::fixed_dialog $parameters } -proc sky130::sky130_fd_pr__pnp_05v5_W3p40L3p40_dialog {parameters} { +proc sky130::sky130_fd_pr__rf_pnp_05v5_W3p40L3p40_dialog {parameters} { sky130::fixed_dialog $parameters } @@ -6635,12 +6635,12 @@ return [sky130::fixed_draw sky130_fd_pr__rf_npn_05v5_W1p00L2p00 $parameters] } -proc sky130::sky130_fd_pr__pnp_05v5_W0p68L0p68_draw {parameters} { - return [sky130::fixed_draw sky130_fd_pr__pnp_05v5_W0p68L0p68 $parameters] +proc sky130::sky130_fd_pr__rf_pnp_05v5_W0p68L0p68_draw {parameters} { + return [sky130::fixed_draw sky130_fd_pr__rf_pnp_05v5_W0p68L0p68 $parameters] } -proc sky130::sky130_fd_pr__pnp_05v5_W3p40L3p40_draw {parameters} { - return [sky130::fixed_draw sky130_fd_pr__pnp_05v5_W3p40L3p40 $parameters] +proc sky130::sky130_fd_pr__rf_pnp_05v5_W3p40L3p40_draw {parameters} { + return [sky130::fixed_draw sky130_fd_pr__rf_pnp_05v5_W3p40L3p40 $parameters] } proc sky130::sky130_fd_pr__rf_test_coil1 {parameters} { @@ -6726,11 +6726,11 @@ return [sky130::fixed_check $parameters] } -proc sky130::sky130_fd_pr__pnp_05v5_W0p68L0p68_check {parameters} { +proc sky130::sky130_fd_pr__rf_pnp_05v5_W0p68L0p68_check {parameters} { return [sky130::fixed_check $parameters] } -proc sky130::sky130_fd_pr__pnp_05v5_W3p40L3p40_check {parameters} { +proc sky130::sky130_fd_pr__rf_pnp_05v5_W3p40L3p40_check {parameters} { return [sky130::fixed_check $parameters] }