Added additional option "sort" to supply a sorting script to specify
the order of files when compiled into a library; this allows the
Makefile to enforce natural sort order and/or put dependent entries
at the top. Also added a custom script for sky130 to handle the
assortment of "include" statements in the standard cell verilog
before generating the library files.
diff --git a/common/create_gds_library.py b/common/create_gds_library.py
index 34424fb..b02535f 100755
--- a/common/create_gds_library.py
+++ b/common/create_gds_library.py
@@ -45,9 +45,18 @@
if os.path.isfile(alllibname):
os.remove(alllibname)
- glist = glob.glob(destlibdir + '/*.gds')
- glist.extend(glob.glob(destlibdir + '/*.gdsii'))
- glist.extend(glob.glob(destlibdir + '/*.gds2'))
+ # If file "filelist.txt" exists in the directory, get the list of files from it
+ if os.path.exists(destlibdir + '/filelist.txt'):
+ with open(destlibdir + '/filelist.txt', 'r') as ifile:
+ rlist = ifile.read().splitlines()
+ glist = []
+ for rfile in rlist:
+ glist.append(destlibdir + '/' + rfile)
+ else:
+ glist = glob.glob(destlibdir + '/*.gds')
+ glist.extend(glob.glob(destlibdir + '/*.gdsii'))
+ glist.extend(glob.glob(destlibdir + '/*.gds2'))
+
if alllibname in glist:
glist.remove(alllibname)
diff --git a/common/create_lef_library.py b/common/create_lef_library.py
index 8a922c8..4a46e5f 100755
--- a/common/create_lef_library.py
+++ b/common/create_lef_library.py
@@ -43,7 +43,17 @@
os.remove(alllibname)
print('Diagnostic: Creating consolidated LEF library ' + destlibroot + '.lef')
- llist = glob.glob(destlibdir + '/*.lef')
+
+ # If file "filelist.txt" exists in the directory, get the list of files from it
+ if os.path.exists(destlibdir + '/filelist.txt'):
+ with open(destlibdir + '/filelist.txt', 'r') as ifile:
+ rlist = ifile.read().splitlines()
+ llist = []
+ for rfile in rlist:
+ llist.append(destlibdir + '/' + rfile)
+ else:
+ llist = glob.glob(destlibdir + '/*.lef')
+
if alllibname in llist:
llist.remove(alllibname)
diff --git a/common/create_lib_library.py b/common/create_lib_library.py
index bfa773d..1f058c7 100755
--- a/common/create_lib_library.py
+++ b/common/create_lib_library.py
@@ -51,6 +51,16 @@
print('Diagnostic: Creating consolidated liberty library ' + destlibroot + '.lib')
+ # If file "filelist.txt" exists in the directory, get the list of files from it
+ if os.path.exists(destlibdir + '/filelist.txt'):
+ with open(destlibdir + '/filelist.txt', 'r') as ifile:
+ rlist = ifile.read().splitlines()
+ llist = []
+ for rfile in rlist:
+ llist.append(destlibdir + '/' + rfile)
+ else:
+ llist = glob.glob(destlibdir + '/*.lib')
+
# Create exclude list with glob-style matching using fnmatch
if len(llist) > 0:
llistnames = list(os.path.split(item)[1] for item in llist)
diff --git a/common/create_spice_library.py b/common/create_spice_library.py
index ca95fa6..90d4e65 100755
--- a/common/create_spice_library.py
+++ b/common/create_spice_library.py
@@ -55,16 +55,24 @@
if os.path.isfile(outputname):
os.remove(outputname)
- if fformat == 'CDL':
- slist = glob.glob(destlibdir + '/*.cdl')
+ # If file "filelist.txt" exists in the directory, get the list of files from it
+ if os.path.exists(destlibdir + '/filelist.txt'):
+ with open(destlibdir + '/filelist.txt', 'r') as ifile:
+ rlist = ifile.read().splitlines()
+ slist = []
+ for rfile in rlist:
+ slist.append(destlibdir + '/' + rfile)
else:
- # Sadly, there is no consensus on what a SPICE file extension should be.
- slist = glob.glob(destlibdir + '/*.spc')
- slist.extend(glob.glob(destlibdir + '/*.spice'))
- slist.extend(glob.glob(destlibdir + '/*.spi'))
- slist.extend(glob.glob(destlibdir + '/*.ckt'))
- slist.extend(glob.glob(destlibdir + '/*.cir'))
- slist.extend(glob.glob(destlibdir + '/*' + spiext))
+ if fformat == 'CDL':
+ slist = glob.glob(destlibdir + '/*.cdl')
+ else:
+ # Sadly, there is no consensus on what a SPICE file extension should be.
+ slist = glob.glob(destlibdir + '/*.spc')
+ slist.extend(glob.glob(destlibdir + '/*.spice'))
+ slist.extend(glob.glob(destlibdir + '/*.spi'))
+ slist.extend(glob.glob(destlibdir + '/*.ckt'))
+ slist.extend(glob.glob(destlibdir + '/*.cir'))
+ slist.extend(glob.glob(destlibdir + '/*' + spiext))
if alllibname in slist:
slist.remove(alllibname)
diff --git a/common/create_verilog_library.py b/common/create_verilog_library.py
index 32ce2c5..55e1c76 100755
--- a/common/create_verilog_library.py
+++ b/common/create_verilog_library.py
@@ -45,7 +45,18 @@
os.remove(alllibname)
print('Diagnostic: Creating consolidated verilog library ' + destlibroot + '.v')
- vlist = glob.glob(destlibdir + '/*.v')
+
+ # If file "filelist.txt" exists in the directory, get the list of files from it
+ if os.path.exists(destlibdir + '/filelist.txt'):
+ print('Diagnostic: Reading sorted verilog file list.')
+ with open(destlibdir + '/filelist.txt', 'r') as ifile:
+ rlist = ifile.read().splitlines()
+ vlist = []
+ for rfile in rlist:
+ vlist.append(destlibdir + '/' + rfile)
+ else:
+ vlist = glob.glob(destlibdir + '/*.v')
+
if alllibname in vlist:
vlist.remove(alllibname)
diff --git a/common/foundry_install.py b/common/foundry_install.py
index 7028956..3fa7f1c 100755
--- a/common/foundry_install.py
+++ b/common/foundry_install.py
@@ -79,6 +79,10 @@
# when a foundry library has inconveniently split
# an IP library (LEF, CDL, verilog, etc.) into
# individual files.
+# compile-only: Like "compile" except that the individual
+# files are removed after the library file has been
+# created.
+#
# stub : Remove contents of subcircuits from CDL or SPICE
# netlist files.
#
@@ -98,6 +102,20 @@
# "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
+# before writing into the staging area.
+#
+# sort: Optionally followed by "=" and the name of a script.
+# The list of files to process (after applying items
+# from "exclude") will be written to a file
+# "filelist.txt", which will be used by the
+# library compile routines, if present. If a script
+# name is specified, then the sort script will rewrite
+# the file with the order in which entries should
+# appear in the compiled library. Only useful when
+# used with "compile" or "compile-only".
+#
# noconvert : Install only; do not attempt to convert to other
# formats (applies only to GDS, CDL, and LEF).
#
@@ -669,16 +687,11 @@
# the source should be copied (or linked) from <number> levels up
# in the hierarchy (see below).
- if 'up' in option:
- uparg = option.index('up')
- try:
- hier_up = int(option[uparg + 1])
- except:
- print("Non-numeric option to 'up': " + option[uparg + 1])
- print("Ignoring 'up' option.")
- hier_up = 0
- else:
- hier_up = 0
+ hier_up = 0
+ for item in option:
+ if item.split('=')[0] == 'up':
+ hier_up = int(item.split('=')[1])
+ break
filter_scripts = []
for item in option:
@@ -713,6 +726,17 @@
else:
print('Renaming file to: ' + newname)
+ # Option 'sort' may have an argument. . .
+ try:
+ sortscript = list(item.split('=')[1] for item in option if item.startswith('sort'))[0]
+ except IndexError:
+ sortscript = None
+ else:
+ print('Sorting files with script ' + sortscript)
+ # . . . or not.
+ if 'sort' in option:
+ sortscript = True
+
# 'anno' may be specified for LEF, in which case the LEF is used only
# to annotate GDS and is not itself installed; this allows LEF to
# be generated from Magic and avoids quirky use of obstruction layers.
@@ -791,6 +815,7 @@
print(' ' + item)
print('(' + str(len(liblist)) + ' files total)')
+ destfilelist = []
for libname in liblist:
# Note that there may be a hierarchy to the files in option[1],
# say for liberty timing files under different conditions, so
@@ -877,6 +902,19 @@
# Apply filter script to all files in the target directory
tfilter(targname, filter_script)
+ destfilelist.append(os.path.split(targname)[1])
+
+ if sortscript:
+ print('Diagnostic: Sorting files to compile.')
+ with open(destlibdir + '/filelist.txt', 'w') as ofile:
+ for destfile in destfilelist:
+ print(destfile, file=ofile)
+ if os.path.isfile(sortscript):
+ print('Diagnostic: Sorting files with ' + sortscript)
+ subprocess.run([sortscript, destlibdir],
+ stdout = subprocess.DEVNULL,
+ stderr = subprocess.DEVNULL)
+
if do_compile == True or do_compile_only == True:
# NOTE: The purpose of "rename" is to put a destlib-named
# library elsewhere so that it can be merged with another
@@ -946,6 +984,11 @@
targrename = destlibdir + destpath + '/' + newname
if os.path.isfile(origname):
os.rename(origname, targrename)
+
+ # If "filelist.txt" was created, remove it
+ if sortscript:
+ if os.path.isfile(destlibdir + '/filelist.txt'):
+ os.remove(destlibdir + '/filelist.txt')
# Find any libraries/options marked as "privileged" (or "private") and
# move the files from libs.tech or libs.ref to libs.priv, leaving a