| #!/usr/bin/env python3 |
| # |
| #-------------------------------------------------------------------- |
| # Add a \"device\" property to the layout of specific PDK primitive |
| # devices that do not extract as intended. This includes, for |
| # example, RF devices (which extract as non-RF devices), vertical |
| # parallel plate capacitors (which extract as metal wires), and any |
| # other device that is not represented in magic's \"extract\" section. |
| # |
| # This uses the method introduced in magic version 8.3.298 using |
| # property "device" with value "primitive", so that the subcell is |
| # output to the netlist without a corresponding subcircuit entry or |
| # black box entry, as the device is assumed to be defined in the PDK. |
| # But it is necessary to make sure that the ports are in the correct |
| # order for the PDK device. |
| #-------------------------------------------------------------------- |
| |
| import os |
| import re |
| import sys |
| import subprocess |
| |
| options = [] |
| arguments = [] |
| for item in sys.argv[1:]: |
| if item.find('-', 0) == 0: |
| options.append(item[1:]) |
| else: |
| arguments.append(item) |
| |
| ef_format = False |
| variant = 'sky130A' |
| magpath = variant + '/libs.ref/sky130_fd_pr/mag' |
| maglefpath = variant + '/libs.ref/sky130_fd_pr/maglef' |
| spicepath = variant + '/libs.ref/sky130_fd_pr/spice' |
| |
| if len(options) > 0: |
| for option in options: |
| if option.startswith('variant'): |
| variant = option.split('=')[1] |
| magpath = variant + '/libs.ref/sky130_fd_pr/mag' |
| maglefpath = variant + '/libs.ref/sky130_fd_pr/maglef' |
| spicepath = variant + '/libs.ref/sky130_fd_pr/spice' |
| for option in options: |
| if option == 'ef_format': |
| ef_format = True |
| magpath = variant + '/libs.ref/mag/sky130_fd_pr' |
| maglefpath = variant + '/libs.ref/maglef/sky130_fd_pr' |
| spicepath = variant + '/libs.ref/spice/sky130_fd_pr' |
| elif len(arguments) > 0: |
| magpath = arguments[0] |
| maglefpath = magpath.replace('/mag/', '/maglef/') |
| spicepath = magpath.replace('/mag/', '/spice/') |
| |
| # \"devlist\" is an enumeration of all devices that have both a layout |
| # in libs.ref/sky130_fd_pr/mag and corresponding subcircuit models |
| # in libs.ref/sky130_fd_pr/spice, and for which extracting the layout |
| # in magic does not produce the intended SPICE model. |
| |
| devlist = ['sky130_fd_pr__cap_vpp_02p4x04p6_m1m2_noshield', |
| 'sky130_fd_pr__cap_vpp_02p7x06p1_m1m2m3m4_shieldl1_fingercap', |
| 'sky130_fd_pr__cap_vpp_02p7x11p1_m1m2m3m4_shieldl1_fingercap', |
| 'sky130_fd_pr__cap_vpp_02p7x21p1_m1m2m3m4_shieldl1_fingercap', |
| 'sky130_fd_pr__cap_vpp_02p7x41p1_m1m2m3m4_shieldl1_fingercap', |
| 'sky130_fd_pr__cap_vpp_02p9x06p1_m1m2m3m4_shieldl1_fingercap2', |
| 'sky130_fd_pr__cap_vpp_03p9x03p9_m1m2_shieldl1_floatm3', |
| 'sky130_fd_pr__cap_vpp_04p4x04p6_l1m1m2_noshield', |
| 'sky130_fd_pr__cap_vpp_04p4x04p6_l1m1m2_shieldpo_floatm3', |
| 'sky130_fd_pr__cap_vpp_04p4x04p6_m1m2_noshield', |
| 'sky130_fd_pr__cap_vpp_04p4x04p6_m1m2_noshield_o2', |
| 'sky130_fd_pr__cap_vpp_04p4x04p6_m1m2_noshield_o2', |
| 'sky130_fd_pr__cap_vpp_04p4x04p6_m1m2_shieldl1', |
| 'sky130_fd_pr__cap_vpp_04p4x04p6_m1m2m3_shieldl1', |
| 'sky130_fd_pr__cap_vpp_04p4x04p6_m1m2m3_shieldl1m5_floatm4', |
| 'sky130_fd_pr__cap_vpp_04p4x04p6_m1m2m3_shieldl1m5_floatm4', |
| 'sky130_fd_pr__cap_vpp_05p9x05p9_m1m2m3m4_shieldl1_wafflecap', |
| 'sky130_fd_pr__cap_vpp_06p8x06p1_l1m1m2m3_shieldpom4', |
| 'sky130_fd_pr__cap_vpp_06p8x06p1_m1m2m3_shieldl1m4', |
| 'sky130_fd_pr__cap_vpp_08p6x07p8_l1m1m2_noshield', |
| 'sky130_fd_pr__cap_vpp_08p6x07p8_l1m1m2_shieldpo_floatm3', |
| 'sky130_fd_pr__cap_vpp_08p6x07p8_m1m2_noshield', |
| 'sky130_fd_pr__cap_vpp_08p6x07p8_m1m2_shieldl1', |
| 'sky130_fd_pr__cap_vpp_08p6x07p8_m1m2m3_shieldl1', |
| 'sky130_fd_pr__cap_vpp_08p6x07p8_m1m2m3_shieldl1m5_floatm4', |
| 'sky130_fd_pr__cap_vpp_08p6x07p8_m1m2m3_shieldl1m5_floatm4', |
| 'sky130_fd_pr__cap_vpp_11p3x11p3_m1m2m3m4_shieldl1_wafflecap', |
| 'sky130_fd_pr__cap_vpp_11p3x11p8_l1m1m2m3m4_shieldm5_nhv', |
| 'sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2_noshield', |
| 'sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2_shieldpom3', |
| 'sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3_shieldm4', |
| 'sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3_shieldpom4', |
| 'sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldm5', |
| 'sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldpom5', |
| 'sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldpom5_x', |
| 'sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldpom5_x', |
| 'sky130_fd_pr__cap_vpp_11p5x11p7_m1m2_noshield', |
| 'sky130_fd_pr__cap_vpp_11p5x11p7_m1m2_shieldl1', |
| 'sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3_shieldl1', |
| 'sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3_shieldl1m5_floatm4', |
| 'sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3_shieldl1m5_floatm4', |
| 'sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3m4_shieldl1m5', |
| 'sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3m4_shieldm5', |
| 'sky130_fd_pr__cap_vpp_11p5x11p7_m1m4_noshield', |
| 'sky130_fd_pr__cap_vpp_44p7x23p1_pol1m1m2m3m4m5_noshield', |
| 'sky130_fd_pr__rf_nfet_01v8_bM02W1p65L0p15', |
| 'sky130_fd_pr__rf_nfet_01v8_bM02W1p65L0p18', |
| 'sky130_fd_pr__rf_nfet_01v8_bM02W1p65L0p25', |
| 'sky130_fd_pr__rf_nfet_01v8_bM02W3p00L0p15', |
| 'sky130_fd_pr__rf_nfet_01v8_bM02W3p00L0p18', |
| 'sky130_fd_pr__rf_nfet_01v8_bM02W3p00L0p25', |
| 'sky130_fd_pr__rf_nfet_01v8_bM02W5p00L0p15', |
| 'sky130_fd_pr__rf_nfet_01v8_bM02W5p00L0p18', |
| 'sky130_fd_pr__rf_nfet_01v8_bM02W5p00L0p25', |
| 'sky130_fd_pr__rf_nfet_01v8_bM04W1p65L0p15', |
| 'sky130_fd_pr__rf_nfet_01v8_bM04W1p65L0p18', |
| 'sky130_fd_pr__rf_nfet_01v8_bM04W1p65L0p25', |
| 'sky130_fd_pr__rf_nfet_01v8_bM04W3p00L0p15', |
| 'sky130_fd_pr__rf_nfet_01v8_bM04W3p00L0p18', |
| 'sky130_fd_pr__rf_nfet_01v8_bM04W3p00L0p25', |
| 'sky130_fd_pr__rf_nfet_01v8_bM04W5p00L0p15', |
| 'sky130_fd_pr__rf_nfet_01v8_bM04W5p00L0p18', |
| 'sky130_fd_pr__rf_nfet_01v8_bM04W5p00L0p25', |
| 'sky130_fd_pr__rf_nfet_01v8_lvt_aF02W0p42L0p15', |
| 'sky130_fd_pr__rf_nfet_01v8_lvt_aF02W0p84L0p15', |
| 'sky130_fd_pr__rf_nfet_01v8_lvt_aF02W3p00L0p15', |
| 'sky130_fd_pr__rf_nfet_01v8_lvt_aF04W0p84L0p15', |
| 'sky130_fd_pr__rf_nfet_01v8_lvt_aF04W3p00L0p15', |
| 'sky130_fd_pr__rf_nfet_01v8_lvt_aF08W0p84L0p15', |
| 'sky130_fd_pr__rf_nfet_01v8_lvt_aF08W3p00L0p15', |
| 'sky130_fd_pr__rf_nfet_01v8_lvt_bM02W5p00L0p18', |
| 'sky130_fd_pr__rf_nfet_01v8_lvt_bM02W5p00L0p25', |
| 'sky130_fd_pr__rf_nfet_01v8_lvt_bM04W5p00L0p18', |
| 'sky130_fd_pr__rf_nfet_01v8_lvt_bM04W5p00L0p25', |
| 'sky130_fd_pr__rf_nfet_g5v0d10v5_bM02W3p00L0p50', |
| 'sky130_fd_pr__rf_nfet_g5v0d10v5_bM02W5p00L0p50', |
| 'sky130_fd_pr__rf_nfet_g5v0d10v5_bM04W3p00L0p50', |
| 'sky130_fd_pr__rf_nfet_g5v0d10v5_bM04W5p00L0p50', |
| 'sky130_fd_pr__rf_nfet_g5v0d10v5_bM04W7p00L0p50', |
| 'sky130_fd_pr__rf_nfet_g5v0d10v5_bM10W3p00L0p50', |
| 'sky130_fd_pr__rf_nfet_g5v0d10v5_bM10W5p00L0p50', |
| 'sky130_fd_pr__rf_nfet_g5v0d10v5_bM10W7p00L0p50', |
| 'sky130_fd_pr__rf_pfet_01v8_aF02W0p84L0p15', |
| 'sky130_fd_pr__rf_pfet_01v8_aF02W1p68L0p15', |
| 'sky130_fd_pr__rf_pfet_01v8_aF02W3p00L0p15', |
| 'sky130_fd_pr__rf_pfet_01v8_aF02W5p00L0p15', |
| 'sky130_fd_pr__rf_pfet_01v8_aF04W1p68L0p15', |
| 'sky130_fd_pr__rf_pfet_01v8_bM02W1p65L0p15', |
| 'sky130_fd_pr__rf_pfet_01v8_bM02W1p65L0p18', |
| 'sky130_fd_pr__rf_pfet_01v8_bM02W1p65L0p25', |
| 'sky130_fd_pr__rf_pfet_01v8_bM02W3p00L0p15', |
| 'sky130_fd_pr__rf_pfet_01v8_bM02W3p00L0p18', |
| 'sky130_fd_pr__rf_pfet_01v8_bM02W3p00L0p25', |
| 'sky130_fd_pr__rf_pfet_01v8_bM02W5p00L0p15', |
| 'sky130_fd_pr__rf_pfet_01v8_bM02W5p00L0p18', |
| 'sky130_fd_pr__rf_pfet_01v8_bM02W5p00L0p25', |
| 'sky130_fd_pr__rf_pfet_01v8_bM04W1p65L0p15', |
| 'sky130_fd_pr__rf_pfet_01v8_bM04W1p65L0p18', |
| 'sky130_fd_pr__rf_pfet_01v8_bM04W1p65L0p25', |
| 'sky130_fd_pr__rf_pfet_01v8_bM04W3p00L0p15', |
| 'sky130_fd_pr__rf_pfet_01v8_bM04W3p00L0p18', |
| 'sky130_fd_pr__rf_pfet_01v8_bM04W3p00L0p25', |
| 'sky130_fd_pr__rf_pfet_01v8_bM04W5p00L0p15', |
| 'sky130_fd_pr__rf_pfet_01v8_bM04W5p00L0p18', |
| 'sky130_fd_pr__rf_pfet_01v8_bM04W5p00L0p25', |
| 'sky130_fd_pr__rf_pfet_01v8_mvt_aF02W0p84L0p15'] |
| |
| # The portlist array contains the names of the ports used in the layout in the order that |
| # they appear in the device subcircuit model. Note that none of the pin names match between |
| # the layout and device definition, so the usual annotation method in magic won't work. |
| |
| portlist = [ ['C0', 'C1', 'SUB'], |
| ['C0', 'C1', 'SUB'], |
| ['C0', 'C1', 'SUB'], |
| ['C0', 'C1', 'SUB'], |
| ['C0', 'C1', 'SUB'], |
| ['C0', 'C1', 'SUB'], |
| ['C0', 'C1', 'SUB', 'MET3'], |
| ['C0', 'C1', 'SUB'], |
| ['C0', 'C1', 'SUB', 'MET3'], |
| ['C0', 'C1', 'SUB'], |
| ['C0', 'C1', 'SUB'], |
| ['C0', 'C1', 'SUB'], |
| ['C0', 'C1', 'SUB'], |
| ['C0', 'C1', 'SUB'], |
| ['C0', 'C1', 'SUB', 'MET5'], |
| ['C0', 'C1', 'SUB', 'MET5'], |
| ['C0', 'C1', 'SUB'], |
| ['C0', 'C1', 'SUB', 'MET4'], |
| ['C0', 'C1', 'SUB', 'MET4'], |
| ['C0', 'C1', 'SUB'], |
| ['C0', 'C1', 'SUB', 'MET3'], |
| ['C0', 'C1', 'SUB'], |
| ['C0', 'C1', 'SUB'], |
| ['C0', 'C1', 'SUB'], |
| ['C0', 'C1', 'SUB', 'MET5'], |
| ['C0', 'C1', 'SUB', 'MET5'], |
| ['C0', 'C1', 'SUB'], |
| ['C0', 'C1', 'SUB', 'MET5'], |
| ['C0', 'C1', 'SUB'], |
| ['C0', 'C1', 'SUB', 'MET3'], |
| ['C0', 'C1', 'SUB', 'MET4'], |
| ['C0', 'C1', 'SUB', 'MET4'], |
| ['C0', 'C1', 'SUB', 'MET5'], |
| ['C0', 'C1', 'SUB', 'MET5'], |
| ['C0', 'C1', 'SUB', 'MET5'], |
| ['C0', 'C1', 'SUB', 'MET5'], |
| ['C0', 'C1', 'SUB'], |
| ['C0', 'C1', 'SUB'], |
| ['C0', 'C1', 'SUB'], |
| ['C0', 'C1', 'SUB', 'MET5'], |
| ['C0', 'C1', 'SUB', 'MET5'], |
| ['C0', 'C1', 'SUB', 'MET5'], |
| ['C0', 'C1', 'SUB', 'MET5'], |
| ['C0', 'C1', 'SUB'], |
| ['C0', 'C1', 'SUB'], |
| ['DRAIN', 'GATE', 'SOURCE', 'SUBSTRATE'], |
| ['DRAIN', 'GATE', 'SOURCE', 'SUBSTRATE'], |
| ['DRAIN', 'GATE', 'SOURCE', 'SUBSTRATE'], |
| ['DRAIN', 'GATE', 'SOURCE', 'SUBSTRATE'], |
| ['DRAIN', 'GATE', 'SOURCE', 'SUBSTRATE'], |
| ['DRAIN', 'GATE', 'SOURCE', 'SUBSTRATE'], |
| ['DRAIN', 'GATE', 'SOURCE', 'SUBSTRATE'], |
| ['DRAIN', 'GATE', 'SOURCE', 'SUBSTRATE'], |
| ['DRAIN', 'GATE', 'SOURCE', 'SUBSTRATE'], |
| ['DRAIN', 'GATE', 'SOURCE', 'SUBSTRATE'], |
| ['DRAIN', 'GATE', 'SOURCE', 'SUBSTRATE'], |
| ['DRAIN', 'GATE', 'SOURCE', 'SUBSTRATE'], |
| ['DRAIN', 'GATE', 'SOURCE', 'SUBSTRATE'], |
| ['DRAIN', 'GATE', 'SOURCE', 'SUBSTRATE'], |
| ['DRAIN', 'GATE', 'SOURCE', 'SUBSTRATE'], |
| ['DRAIN', 'GATE', 'SOURCE', 'SUBSTRATE'], |
| ['DRAIN', 'GATE', 'SOURCE', 'SUBSTRATE'], |
| ['DRAIN', 'GATE', 'SOURCE', 'SUBSTRATE'], |
| ['DRAIN', 'GATE', 'SOURCE', 'SUBSTRATE'], |
| ['DRAIN', 'GATE', 'SOURCE', 'SUBSTRATE'], |
| ['DRAIN', 'GATE', 'SOURCE', 'SUBSTRATE'], |
| ['DRAIN', 'GATE', 'SOURCE', 'SUBSTRATE'], |
| ['DRAIN', 'GATE', 'SOURCE', 'SUBSTRATE'], |
| ['DRAIN', 'GATE', 'SOURCE', 'SUBSTRATE'], |
| ['DRAIN', 'GATE', 'SOURCE', 'SUBSTRATE'], |
| ['DRAIN', 'GATE', 'SOURCE', 'SUBSTRATE'], |
| ['DRAIN', 'GATE', 'SOURCE', 'SUBSTRATE'], |
| ['DRAIN', 'GATE', 'SOURCE', 'SUBSTRATE'], |
| ['DRAIN', 'GATE', 'SOURCE', 'SUBSTRATE'], |
| ['DRAIN', 'GATE', 'SOURCE', 'SUBSTRATE'], |
| ['DRAIN', 'GATE', 'SOURCE', 'SUBSTRATE'], |
| ['DRAIN', 'GATE', 'SOURCE', 'SUBSTRATE'], |
| ['DRAIN', 'GATE', 'SOURCE', 'SUBSTRATE'], |
| ['DRAIN', 'GATE', 'SOURCE', 'SUBSTRATE'], |
| ['DRAIN', 'GATE', 'SOURCE', 'SUBSTRATE'], |
| ['DRAIN', 'GATE', 'SOURCE', 'SUBSTRATE'], |
| ['DRAIN', 'GATE', 'SOURCE', 'SUBSTRATE'], |
| ['DRAIN', 'GATE', 'SOURCE', 'BULK'], |
| ['DRAIN', 'GATE', 'SOURCE', 'BULK'], |
| ['DRAIN', 'GATE', 'SOURCE', 'BULK'], |
| ['DRAIN', 'GATE', 'SOURCE', 'BULK'], |
| ['DRAIN', 'GATE', 'SOURCE', 'BULK'], |
| ['DRAIN', 'GATE', 'SOURCE', 'BULK'], |
| ['DRAIN', 'GATE', 'SOURCE', 'BULK'], |
| ['DRAIN', 'GATE', 'SOURCE', 'BULK'], |
| ['DRAIN', 'GATE', 'SOURCE', 'BULK'], |
| ['DRAIN', 'GATE', 'SOURCE', 'BULK'], |
| ['DRAIN', 'GATE', 'SOURCE', 'BULK'], |
| ['DRAIN', 'GATE', 'SOURCE', 'BULK'], |
| ['DRAIN', 'GATE', 'SOURCE', 'BULK'], |
| ['DRAIN', 'GATE', 'SOURCE', 'BULK'], |
| ['DRAIN', 'GATE', 'SOURCE', 'BULK'], |
| ['DRAIN', 'GATE', 'SOURCE', 'BULK'], |
| ['DRAIN', 'GATE', 'SOURCE', 'BULK'], |
| ['DRAIN', 'GATE', 'SOURCE', 'BULK'], |
| ['DRAIN', 'GATE', 'SOURCE', 'BULK'], |
| ['DRAIN', 'GATE', 'SOURCE', 'BULK'], |
| ['DRAIN', 'GATE', 'SOURCE', 'BULK'], |
| ['DRAIN', 'GATE', 'SOURCE', 'BULK'], |
| ['DRAIN', 'GATE', 'SOURCE', 'BULK'], |
| ['DRAIN', 'GATE', 'SOURCE', 'BULK']] |
| |
| # List of devices which have a layout cell name that is different |
| # from the parameterized cell (gencell) and so must change the |
| # default "gencell" property. |
| |
| dev2list = ['sky130_fd_pr__rf_npn_05v5_W1p00L1p00', |
| 'sky130_fd_pr__rf_npn_05v5_W1p00L2p00', |
| 'sky130_fd_pr__rf_pnp_05v5_W0p68L0p68', |
| 'sky130_fd_pr__rf_pnp_05v5_W3p40L3p40', |
| 'sky130_fd_pr__rf_npn_11v0_W1p00L1p00']; |
| |
| |
| prop2list = ['sky130_fd_pr__npn_05v5_W1p00L1p00', |
| 'sky130_fd_pr__npn_05v5_W1p00L2p00', |
| 'sky130_fd_pr__pnp_05v5_W0p68L0p68', |
| 'sky130_fd_pr__pnp_05v5_W3p40L3p40', |
| 'sky130_fd_pr__npn_11v0_W1p00L1p00']; |
| |
| #-------------------------------------------------------------------- |
| # Do this for files both in mag/ and maglef/ . . . |
| |
| pathlist = [magpath, maglefpath] |
| |
| for idx, device in enumerate(devlist): |
| for path in pathlist: |
| infile_name = path + '/' + device + '.mag' |
| |
| if not os.path.exists(infile_name): |
| print('Error: Cannot find file ' + infile_name) |
| continue |
| |
| print('Adding special extraction property to device ' + device + ' layout') |
| |
| propcmd = ['../common/insert_property.py', variant, 'sky130_fd_pr', |
| device, 'device primitive'] |
| if ef_format: |
| propcmd.append('-ef_format') |
| |
| # Just call the insert_property.py script |
| subprocess.run(propcmd, stdout = subprocess.DEVNULL, stderr = subprocess.DEVNULL) |
| |
| # Now renumber the ports in the layout to match the PDK device. The port names in |
| # the layout generally don't match the port names in the PDK device definitions, |
| # so ports are handled by manually listing them all out. |
| |
| devports = portlist[idx] |
| modified = False |
| |
| with open(infile_name, 'r') as ifile: |
| magdata = ifile.read() |
| outlines = [] |
| for line in magdata.splitlines(): |
| if line.startswith('port'): |
| if lname and lname in devports: |
| tokens = line.split() |
| newindex = str(1 + devports.index(lname)) |
| if newindex != tokens[1]: |
| modified = True |
| tokens[1] = newindex |
| newline = ' '.join(tokens) |
| else: |
| newline = line |
| lname = None |
| elif line.startswith('flabel'): |
| lname = line.split()[-1] |
| newline = line |
| elif line.startswith('rlabel'): |
| lname = line.split()[-1] |
| newline = line |
| else: |
| lname = None |
| newline = line |
| outlines.append(newline) |
| |
| if modified: |
| print('Modifying port order in ' + infile_name) |
| with open(infile_name, 'w') as ofile: |
| ofile.write('\n'.join(outlines)) |
| |
| # Any SPICE netlist for this device that came from extraction in magic during the |
| # PDK build is invalid, and should be removed. |
| |
| infile_name = spicepath + '/' + device + '.spice' |
| if os.path.isfile(infile_name): |
| os.remove(infile_name) |
| |
| # Handle the gencell property changes |
| |
| for idx, device in enumerate(dev2list): |
| for path in pathlist: |
| infile_name = path + '/' + device + '.mag' |
| |
| if not os.path.exists(infile_name): |
| print('Error: Cannot find file ' + infile_name) |
| continue |
| |
| print('Altering gencell property in device ' + device + ' layout') |
| gencell = prop2list[idx] |
| |
| propcmd = ['../common/insert_property.py', variant, 'sky130_fd_pr', |
| device, 'gencell ' + gencell] |
| if ef_format: |
| propcmd.append('-ef_format') |
| |
| # Just call the insert_property.py script |
| subprocess.run(propcmd, stdout = subprocess.DEVNULL, stderr = subprocess.DEVNULL) |
| |