Additional work on the GF PDK. This includes updating the OSU
standard cells for changes made to the repository. Also:
SRAM now imported in such a way that the .mag view produced
can be extracted and passes LVS. For the SRAM and the standard
cells, switching from layout-extracted SPICE to converted CDL
from GF. Started a method for building open_pdks from commit
numbers pulled from the JSON file "reference" section; this
work is unfinished.
diff --git a/Makefile.in b/Makefile.in
index e63efb8..348ddd9 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -38,7 +38,9 @@
#
# annotate the technology JSON file with the current
# commit state of all repositories used by the PDK to
-# create a reference set of PDKs.
+# create a reference set of PDKs. Can be used with
+# the configure --with-reference option to compile
+# to sources from a specific set of commits.
#
#---------------------------------------------------
#
diff --git a/common/foundry_install.py b/common/foundry_install.py
index 969908f..bcb17e6 100755
--- a/common/foundry_install.py
+++ b/common/foundry_install.py
@@ -128,10 +128,13 @@
#
# rename : Followed by "=" and an alternative name. For any
# file that is a single entry, change the name of
-# the file in the target directory to this (To-do:
-# take regexps for multiple files). When used with
-# "compile" or "compile-only", this refers to the
-# name of the target compiled file.
+# the file in the target directory to this. If the
+# alternative name is a file extension (optionally
+# preceded by '*', as in "rename=*.spice", then all
+# input files are renamed with the indicated file
+# extension (To-do: take regexps for multiple files).
+# When used with "compile" or "compile-only", this
+# refers to the name of the target compiled file.
#
# filter: Followed by "=" and the name of a script.
# Each file is passed through the filter script
@@ -1008,6 +1011,10 @@
if len(liblist) == 1:
destfile = newname
+ elif newname.startswith('*.'):
+ destfile = os.path.splitext(libfile)[0] + newname[1:]
+ elif newname.startswith('.'):
+ destfile = os.path.splitext(libfile)[0] + newname
else:
if not do_compile and not do_compile_only:
print('Error: rename specified but more than one file found!')
diff --git a/gf180mcu/Makefile.in b/gf180mcu/Makefile.in
index 9741d6f..be9cf7b 100644
--- a/gf180mcu/Makefile.in
+++ b/gf180mcu/Makefile.in
@@ -157,6 +157,8 @@
GF180MCU_SRAM_PATH = @GF180MCU_FD_IP_SRAM_PATH@
GF180MCU_OSU_SC_PATH = @GF180MCU_OSU_SC_PATH@
+USE_REFERENCE = @USE_REFERENCE@
+
# Path to GF180MCU library sources
PDK_URL = https://github.com/google
OSU_URL = https://github.com/stineje
@@ -428,6 +430,8 @@
TOOLS += xcircuit
endif
+all: $(foreach var, ${VARIANTS}, all-$(var))
+
reference: ${TECH}.json
# Rewrite the ${TECH}.json file to change the commit values in
# "reference" to reflect the state of the system when "make
@@ -436,8 +440,6 @@
# tools.
../common/save_commit_refs.py ${COMMIT_DEFS} ${TECH}.json
-all: $(foreach var, ${VARIANTS}, all-$(var))
-
# Handle prerequisites
prerequisites: pr-repo io-repo sc-7t-repo sc-9t-repo sram-repo osu-sc-repo
@@ -821,6 +823,8 @@
filter=custom/scripts/fix_related_bias_pins.py \
header=liberty/gf180mcu_fd_sc_mcu9t5v0__tt_025C_5v00.lib \
rename=gf180mcu_fd_sc_mcu9t5v0__tt_025C_5v00 \
+ -spice cells/*/*.cdl compile-only \
+ filter=custom/scripts/convert_sc_cdl.py \
-gds cells/*/*.gds compile-only \
options=custom/scripts/gds_import_sc.tcl \
filter=custom/scripts/fix_stdcell_gds.py \
@@ -834,6 +838,7 @@
# Create minimum/maximum technology LEF files
./custom/scripts/make_minmax_techlef.py ${EF_FORMAT} -variant=${GF180MCU$*} \
-library=9t5v0 2>&1 | tee -a ${GF180MCU$*}_make.log || true
+
digital-7t5v0-%:
# Install 5V 7-track digital standard cells from vendor files
${STAGE} -source ${GF180MCU_SC_7T5V0_PATH} \
@@ -902,6 +907,8 @@
filter=custom/scripts/fix_related_bias_pins.py \
header=liberty/gf180mcu_fd_sc_mcu7t5v0__tt_025C_5v00.lib \
rename=gf180mcu_fd_sc_mcu7t5v0__tt_025C_5v00 \
+ -spice cells/*/*.cdl compile-only \
+ filter=custom/scripts/convert_sc_cdl.py \
-gds cells/*/*.gds compile-only \
options=custom/scripts/gds_import_sc.tcl \
filter=custom/scripts/fix_stdcell_gds.py \
@@ -919,34 +926,32 @@
digital-osu-%:
# Install OSU 3.3V digital standard cells from vendor files
# NOTE: Work in progress (to be completed)
- ${STAGE} -source ${GF180MCU_OSU_SC_PATH} \
+ ${STAGE} -source ${GF180MCU_OSU_SC_PATH}/gf180mcu_osu_sc_gp9t3v3 \
-target ${STAGING_PATH}/${GF180MCU$*} \
- -techlef lib/9T/tlef/gf180mcu_*_tech.lef \
- rename=gf180mcu_osu_sc_9T.tlef \
- -liberty lib/9T/lib/gf180mcu_9T_TT_3P3_25C*.lib \
- rename=gf180mcu_osu_sc_9T__tt_025C_3v30 \
- -verilog lib/9T/verilog/*.v \
- rename=gf180mcu_osu_sc_9T \
- -lef lib/9T/lef/*.lef \
- -gds lib/9T/*/*.gds compile-only \
- -spice lib/9T/*/*.spice compile-only \
- -xschem lib/9T/*/*.sch \
- -library digital gf180mcu_osu_sc_9T 2>&1 | \
+ -techlef ../tlef/gf180mcu_5LM_1TM_9K_9t.tlef \
+ rename=gf180mcu_fd_sc_mcu7t5v0__nom.tlef \
+ -liberty lib/gf180mcu_osu_sc_gp9t3v3_TT_3P3_25C.ccs.lib \
+ rename=gf180mcu_osu_sc_gp9t3v3__tt_025C_3v30 \
+ -verilog cells/*/*.v compile-only \
+ -lef cells/*/*.lef compile-only \
+ -gds cells/*/*.gds compile-only \
+ -spice cells/*/*.spice compile-only \
+ -xschem cells/*/*.sch \
+ -library digital gf180mcu_osu_sc_gp9t3v3 2>&1 | \
tee -a ${GF180MCU$*}_make.log
- ${STAGE} -source ${GF180MCU_OSU_SC_PATH} \
+ ${STAGE} -source ${GF180MCU_OSU_SC_PATH}/gf180mcu_osu_sc_gp12t3v3 \
-target ${STAGING_PATH}/${GF180MCU$*} \
- -techlef lib/12T/tlef/gf180mcu_*_tech.lef \
- rename=gf180mcu_osu_sc_12T.tlef \
- -liberty lib/12T/lib/gf180mcu_12T_TT_3P3_25C*.lib \
- rename=gf180mcu_osu_sc_12T__tt_025C_3v30 \
- -verilog lib/12T/verilog/*.v \
- rename=gf180mcu_osu_sc_12T \
- -lef lib/12T/lef/*.lef \
- -gds lib/12T/*/*.gds compile-only \
- -spice lib/12T/*/*.spice compile-only \
- -xschem lib/12T/*/*.sch \
- -library digital gf180mcu_osu_sc_12T 2>&1 | \
+ -techlef ../tlef/gf180mcu_5LM_1TM_9K_12t.tlef \
+ rename=gf180mcu_fd_sc_mcu7t5v0__nom.tlef \
+ -liberty lib/gf180mcu_osu_sc_gp12t3v3_TT_25C.ccs.lib \
+ rename=gf180mcu_osu_sc_gp12t3v3__tt_025C_3v30 \
+ -verilog cells/*/*.v compile-only \
+ -lef cells/*/*.lef compile-only \
+ -gds cells/*/*.gds compile-only \
+ -spice cells/*/*.spice compile-only \
+ -xschem cells/*/*.sch \
+ -library digital gf180mcu_osu_sc_gp12t3v3 2>&1 | \
tee -a ${GF180MCU$*}_make.log
io-%:
@@ -976,9 +981,9 @@
-liberty cells/*/*_ff_n40C_5v50.lib compile-only \
header=liberty/gf180mcu_fd_io__ff_n40C_5v50.lib \
rename=gf180mcu_fd_io__ff_n40C_5v50 \
- -liberty cells/*/*_ss_125C_2v50.lib compile-only \
- header=liberty/gf180mcu_fd_io__ss_125C_2v50.lib \
- rename=gf180mcu_fd_io__ss_125C_2v50 \
+ -liberty cells/*/*_ss_125C_2v25.lib compile-only \
+ header=liberty/gf180mcu_fd_io__ss_125C_2v25.lib \
+ rename=gf180mcu_fd_io__ss_125C_2v25 \
-liberty cells/*/*_ss_125C_2v97.lib compile-only \
header=liberty/gf180mcu_fd_io__ss_125C_2v97.lib \
rename=gf180mcu_fd_io__ss_125C_2v97 \
@@ -1010,6 +1015,9 @@
-target ${STAGING_PATH}/${GF180MCU$*} \
-cdl cells/*/*.cdl noconvert \
-liberty cells/*/*.lib \
+ -spice cells/*/*.cdl \
+ filter=custom/scripts/convert_sram_cdl.py \
+ rename=*.spice \
-gds cells/*/*.gds \
options=custom/scripts/gds_import_sram.tcl \
filter=custom/scripts/fix_sram_gds.py \
diff --git a/gf180mcu/custom/scripts/convert_sc_cdl.py b/gf180mcu/custom/scripts/convert_sc_cdl.py
new file mode 100755
index 0000000..8a9fcbd
--- /dev/null
+++ b/gf180mcu/custom/scripts/convert_sc_cdl.py
@@ -0,0 +1,95 @@
+#!/usr/bin/env python3
+#
+# convert_sc_cdl.py ---
+#
+# This script converts the GF CDL for the standard cells to turn them into
+# valid SPICE (ngspice) syntax, using regular expression parsing.
+
+# 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('convert_sc_cdl.py: failed to open ' + inname + ' for reading.', file=sys.stderr)
+ return 1
+
+ fixedlines = []
+ modified = False
+
+ for line in spilines:
+ fixedline = line
+
+ # 1) Lines starting with M --> change to X
+ fixedline = re.sub('^M', 'X', fixedline, flags=re.IGNORECASE)
+ # 2) 5V transistor models --> change to 6V
+ fixedline = re.sub('_05v0', '_06v0', fixedline, flags=re.IGNORECASE)
+ # 3) Uppercase diode "d" for consistency
+ fixedline = re.sub('^d', 'D', fixedline)
+ # 4) Convert $m to M
+ fixedline = re.sub('\$m=', 'M=', fixedline, flags=re.IGNORECASE)
+ # 5) Fix incorrect endcap (endcap does not have VNW VPW)
+ fixedline = re.sub('endcap VDD VNW VPW', 'endcap VDD', fixedline, flags=re.IGNORECASE)
+
+ if line != fixedline:
+ modified = True
+ fixedlines.append(fixedline)
+
+ # 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('convert_sc_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/gf180mcu/custom/scripts/convert_sram_cdl.py b/gf180mcu/custom/scripts/convert_sram_cdl.py
new file mode 100755
index 0000000..b07c09b
--- /dev/null
+++ b/gf180mcu/custom/scripts/convert_sram_cdl.py
@@ -0,0 +1,95 @@
+#!/usr/bin/env python3
+#
+# convert_sram_cdl.py ---
+#
+# This script converts the GF CDL for the SRAM macros to turn them into valid
+# SPICE syntax, using regular expression parsing.
+
+# 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('convert_sram_cdl.py: failed to open ' + inname + ' for reading.', file=sys.stderr)
+ return 1
+
+ fixedlines = []
+ modified = False
+
+ for line in spilines:
+ fixedline = line
+
+ # 1) Lines starting with M --> change to X
+ fixedline = re.sub('^M', 'X', fixedline, flags=re.IGNORECASE)
+ # 2) 5V transistor models --> change to 6V
+ fixedline = re.sub('_05v0', '_06v0', fixedline, flags=re.IGNORECASE)
+ # 3) Remove $X, $Y, $D, and $T parameters
+ fixedline = re.sub('\$X=-?[0-9]+', '', fixedline, flags=re.IGNORECASE)
+ fixedline = re.sub('\$Y=-?[0-9]+', '', fixedline, flags=re.IGNORECASE)
+ fixedline = re.sub('\$D=-?[0-9]+', '', fixedline, flags=re.IGNORECASE)
+ fixedline = re.sub('\$T=-?[0-9]+ -?[0-9]+ -?[0-9]+ -?[0-9]+', '',
+ fixedline, flags=re.IGNORECASE)
+
+ if line != fixedline:
+ modified = True
+ fixedlines.append(fixedline)
+
+ # 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('convert_sram_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/gf180mcu/custom/scripts/gds_import_sram.tcl b/gf180mcu/custom/scripts/gds_import_sram.tcl
index bbb0f15..26b625d 100644
--- a/gf180mcu/custom/scripts/gds_import_sram.tcl
+++ b/gf180mcu/custom/scripts/gds_import_sram.tcl
@@ -11,5 +11,18 @@
gds flatglob pmos_1p2*
gds flatglob via1_*
gds flatglob ypass_gate*
+# These additional cells must be flattened to get rid of 3.3V devices
+# (DUALGATE drawn into high-level cells)
+gds flatglob dcap_103*
+gds flatglob din_*
+gds flatglob mux821_*
+gds flatglob rdummy_*
+gds flatglob pmoscap_*
+gds flatglob xdec_*
+gds flatglob ypredec*
+gds flatglob xpredec*
+gds flatglob xdec8_*
+gds flatglob prexdec_*
+gds flatglob xdec32_*
# Ensure unique cell names when reading multiple GDS files
calma unique true
diff --git a/gf180mcu/magic/gf180mcu.tech b/gf180mcu/magic/gf180mcu.tech
index f437eb7..0de72ef 100644
--- a/gf180mcu/magic/gf180mcu.tech
+++ b/gf180mcu/magic/gf180mcu.tech
@@ -3429,18 +3429,18 @@
routing mtp MetalTop Metal6 METAL6 METTP mtp mettp MET6 m6 met6 metal6
#endif (METALS6)
- cut m2c Via1 VIA1 via1 cont2 via12
+ cut m2c Via1 VIA1 via1 cont2 via12 VIA12
#ifdef METALS3 || METALS4 || METALS5 || METALS6
- cut m3c Via2 VIA2 via2 cont3 via23
+ cut m3c Via2 VIA2 via2 cont3 via23 VIA23
#endif (METALS3 || METALS4 || METALS5 || METALS6)
#ifdef METALS4 || METALS5 || METALS6
- cut via3 Via3 VIA3 via3 cont4 via34
+ cut via3 Via3 VIA3 via3 cont4 via34 VIA34
#endif (METALS4 || METALS5 || METALS6)
#ifdef METALS5 || METALS6
- cut via4 Via4 VIA4 via4 cont5 via45
+ cut via4 Via4 VIA4 via4 cont5 via45 VIA45
#endif (METALS5 || METALS6)
#ifdef METALS6
- cut viatp Via5 viatp VIATP VIA5 vtp via5 cont6 via56
+ cut viatp Via5 viatp VIATP VIA5 vtp via5 cont6 via56 VIA56
#endif (METALS6)
obs obsm1 Metal1
diff --git a/scripts/configure.ac b/scripts/configure.ac
index ce8662a..f1852ff 100755
--- a/scripts/configure.ac
+++ b/scripts/configure.ac
@@ -275,6 +275,22 @@
AC_MSG_NOTICE([Tools enabled for PDK setup installation: M4_GET_TOOLS()])
+# Check for "--with-reference"
+USE_REFERENCE=0
+AC_ARG_WITH(
+ [reference],
+ AS_HELP_STRING(
+ [--with-reference],
+ [Use PDK JSON file reference commit values for sources @<:@default=no@:>@]
+ ), [
+ pdks_reference=$withval
+ if test "$withval" == "yes" -o "$withval" == "YES"; then
+ USE_REFERENCE=1
+ fi
+ ],
+)
+AC_SUBST(USE_REFERENCE)
+
# Check for "--with-ef-style"
EF_STYLE=0
AC_ARG_WITH(
@@ -289,8 +305,8 @@
fi
],
)
-
AC_SUBST(EF_STYLE)
+
# Export the list of enabled technologies to the Makefile
AC_SUBST(ENABLED_TECHS)
# Export the top level directory of open_pdks
diff --git a/scripts/download.sh b/scripts/download.sh
index 56af3ea..660c978 100755
--- a/scripts/download.sh
+++ b/scripts/download.sh
@@ -5,7 +5,7 @@
# directory, untar it, and remove the tarball file. If the URL is
# a repository and not a file, then clone it.
#
-# Usage: download.sh <url> <target_dir> [<strip>]
+# Usage: download.sh <url> <target_dir> [<strip>|<commit>|<tag>]
#
# where:
#
@@ -19,6 +19,8 @@
# <strip> is the number of directory levels to strip off the front of the
# tarball contents. Defaults to 1 if not specified (only
# applicable if <url> points to a tarball).
+# <commit> or <tag> is a specific reference commit to clone. If the
+# <url> is not a git repository, then this option has no effect.
#
# Check if <url> points to a tarball or a repository (note: this assumes
@@ -68,7 +70,14 @@
if type "git" > /dev/null; then
echo "Cloning $1 to $2"
- git clone --depth 1 $1 $2
+ if [ $# -gt 2 ]; then
+ # git clone $1 $2
+ # git checkout $3
+ git clone --branch $3 --single-branch $1 $2
+ else
+ git clone --depth 1 $1 $2
+ fi
+
else
echo "ERROR: \"git\" is required to automatically install tools."
exit 1
diff --git a/sky130/Makefile.in b/sky130/Makefile.in
index a0cfd35..d2336be 100644
--- a/sky130/Makefile.in
+++ b/sky130/Makefile.in
@@ -245,6 +245,8 @@
OSU_T15_URL = https://foss-eda-tools.googlesource.com/skywater-pdk/libs/sky130_osu_sc_t15
OSU_T18_URL = https://foss-eda-tools.googlesource.com/skywater-pdk/libs/sky130_osu_sc_t18
+USE_REFERENCE = @USE_REFERENCE@
+
# NOTE: Install destination is the git repository of the technology platform.
# Once updated in git, the git project can be distributed to all hosts.
#
@@ -589,6 +591,8 @@
SPIEXT = spice
endif
+all: $(foreach var, ${VARIANTS}, all-$(var))
+
reference: ${TECH}.json
# Rewrite the ${TECH}.json file to change the commit values in
# "reference" to reflect the state of the system when "make
@@ -597,8 +601,6 @@
# tools.
../common/save_commit_refs.py ${COMMIT_DEFS} ${TECH}.json
-all: $(foreach var, ${VARIANTS}, all-$(var))
-
# Handle prerequisites (fetch and install the PDK and requested libraries)
prerequisites: pdk-repo alpha-repo xschem-repo klayout-repo precheck-repo sram-repo osu-t12-repo osu-t15-repo osu-t18-repo