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