Created a new patch script that corrects the CDL netlists for four cells in the sky130_fd_sc_hd library that incorrectly tie together the midpoint of two sets of two series transistors in parallel.
diff --git a/VERSION b/VERSION index 819d259..5e952e4 100644 --- a/VERSION +++ b/VERSION
@@ -1 +1 @@ -1.0.346 +1.0.347
diff --git a/sky130/Makefile.in b/sky130/Makefile.in index 35dc218..1e0748c 100644 --- a/sky130/Makefile.in +++ b/sky130/Makefile.in
@@ -1356,6 +1356,7 @@ filter=custom/scripts/fix_device_models.py \ -cdl %l/latest/cells/*/*.cdl ignore=topography compile-only \ filter=custom/scripts/fix_sparecell_cdl.py \ + filter=custom/scripts/fix_serxtors_cdl.py \ sort=../common/sort_pdkfiles.py \ -lef %l/latest/cells/*/*.lef \ exclude=*.magic.lef,sky130_ef_sc_hd.lef lefopts=-toplayer \
diff --git a/sky130/custom/scripts/fix_serxtors_cdl.py b/sky130/custom/scripts/fix_serxtors_cdl.py new file mode 100755 index 0000000..62bf205 --- /dev/null +++ b/sky130/custom/scripts/fix_serxtors_cdl.py
@@ -0,0 +1,137 @@ +#!/usr/bin/env python3 +# +# fix_serxtors_cdl --- +# +# This script fixes problems in SkyWater HD library cells CDL netlists +# where transistor gates in series use M=2 incorrectly. +# The topology on the left is what is implemented in the CDL, while the +# topology on the right is what's actually in the layout: +# +# | | | | +# | | | | +# --- --- --- --- +# | | | | +# --| |-- --| |-- +# | | | | +# --- --- --- --- +# | | | | +# |---| | | +# | | | | +# --- --- --- --- +# | | | | +# --| |-- --| |-- +# | | | | +# --- --- --- --- +# | | | | +# | | | | +# +# The four (known) cells with this error are (sky130_fd_sc_hd__ +): +# a21o_4, o21a_4, a21bo_4, and a211o_4. + +# This script is a filter to be run by setting the name of this script as +# the value to "filter=" for the model install in the sky130 Makefile. + +import re +import os +import sys + +def filter(inname, outname): + + # Read input + try: + with open(inname, 'r') as inFile: + spitext = inFile.read() + # (Don't) unwrap continuation lines + # spilines = spitext.replace('\n+', ' ').splitlines() + spilines = spitext.splitlines() + except: + print('fix_serxtors_cdl.py: failed to open ' + inname + ' for reading.', file=sys.stderr) + return 1 + + errcells = [ + 'sky130_fd_sc_hd__a21o_4', + 'sky130_fd_sc_hd__o21a_4', + 'sky130_fd_sc_hd__a21bo_4', + 'sky130_fd_sc_hd__a211o_4'] + + fixedlines = [] + modified = False + inmacro = False + extor = False + + # NOTE: All occurrences of this error are at pin A1 + # and the node is always "sndA1" ("s" for "series") + + for line in spilines: + if inmacro == True: + if '.ENDS ' in line: + inmacro = False + fixedlines.append(line) + elif inmacro == True and 'sndA1' in line: + extor = True + fixedline = line.replace(' m=2', '') + fixedlines.append(fixedline) + saveline = fixedline.replace('sndA1', 'snd2A1') + modified = True + elif extor == True: + fixedlines.append(line) + fixedlines.append(saveline) + fixedlines.append(line) + extor = False + else: + fixedlines.append(line) + elif '.SUBCKT ' in line: + for cell in errcells: + if cell in line: + inmacro = True + fixedlines.append(line) + else: + fixedlines.append(line) + + # Write output + if outname == None: + for i in fixedlines: + print(i) + else: + # 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): + if not modified: + return 0 + else: + os.unlink(outname) + try: + with open(outname, 'w') as outFile: + for i in fixedlines: + print(i, file=outFile) + except: + print('fix_serxtors_cdl.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/sky130/sky130.json b/sky130/sky130.json index 5767096..8daa31f 100644 --- a/sky130/sky130.json +++ b/sky130/sky130.json
@@ -92,16 +92,16 @@ "magic": "MAGIC_COMMIT" }, "reference": { - "open_pdks": "82d61e2c9c265c0f0e994233cd2d024c90adb45f", - "magic": "7905e15ae3b66ed26349fb701b475ef93b566de5", + "open_pdks": "a56526bfe45971322526978132b059d43ddd3a02", + "magic": "eecdc3c6421d42a031e98023567a0f3694ba47f4", "skywater_pdk": "f70d8ca46961ff92719d8870a18a076370b85f6c", "sky130_osu_sc_t12": "ac90ef0c622a9377a16b5218d9da3ac4169eeaaf", "sky130_osu_sc_t15": "95d1c19abb47e1b2945847acb4e817b1b8417c43", "sky130_osu_sc_t18": "aa2b509f3c8f32ea94fdb55ac9768754667c1658", "sky130_sram_macros": "c2333394e0b0b9d9d71185678a8d8087715d5e3b", "sky130_ml_xx_hd": "6eb3b0718552b034f1bf1870285ff135e3fb2dcb", - "xschem_sky130": "5949895a0214f3471f16850297ea15e34a564edd", - "klayout_sky130": "85165d907f6b68e73bb25b9982cca20a87c98686", - "precheck_sky130": "07ace967fbe88e33844bf046bd9d30e1679580b7" + "xschem_sky130": "35af1ae750d109b78533399a3cb639be5a3f50e4", + "klayout_sky130": "40fe0f615dbc3f50aa394bd9ed7df3577e295b9d", + "precheck_sky130": "76cf0a9bb0407cae712b253f9dd291167568e712" } } \ No newline at end of file