Various modifications to accommodate the somewhat complicated management of include statements in verilog files in order to build the compiled libraries.
diff --git a/VERSION b/VERSION index 42de374..7cb055c 100644 --- a/VERSION +++ b/VERSION
@@ -1 +1 @@ -1.0.40 +1.0.41
diff --git a/common/create_gds_library.py b/common/create_gds_library.py index 85380fe..34424fb 100755 --- a/common/create_gds_library.py +++ b/common/create_gds_library.py
@@ -38,7 +38,10 @@ def create_gds_library(destlibdir, destlib, startup_script, do_compile_only=False, excludelist=[], keep=False): - alllibname = destlibdir + '/' + destlib + '.gds' + # destlib should not have a file extension + destlibroot = os.path.splitext(destlib)[0] + + alllibname = destlibdir + '/' + destlibroot + '.gds' if os.path.isfile(alllibname): os.remove(alllibname) @@ -86,8 +89,8 @@ for gdsfile in glist: print('gds read ' + gdsfile, file=ofile) - print('puts stdout "Creating cell ' + destlib + '"', file=ofile) - print('load ' + destlib, file=ofile) + print('puts stdout "Creating cell ' + destlibroot + '"', file=ofile) + print('load ' + destlibroot, file=ofile) print('puts stdout "Adding cells to library"', file=ofile) print('box values 0 0 0 0', file=ofile) for gdsfile in glist: @@ -97,9 +100,9 @@ # Could properly make space for the cell here. . . print('box move e 200', file=ofile) - print('puts stdout "Writing GDS library ' + destlib + '"', file=ofile) + print('puts stdout "Writing GDS library ' + destlibroot + '"', file=ofile) print('gds library true', file=ofile) - print('gds write ' + destlib, file=ofile) + print('gds write ' + destlibroot, file=ofile) print('puts stdout "Done."', file=ofile) print('quit -noprompt', file=ofile)
diff --git a/common/create_lef_library.py b/common/create_lef_library.py index 4b8ecf3..8a922c8 100755 --- a/common/create_lef_library.py +++ b/common/create_lef_library.py
@@ -35,11 +35,14 @@ def create_lef_library(destlibdir, destlib, do_compile_only=False, excludelist=[]): - alllibname = destlibdir + '/' + destlib + '.lef' + # destlib should not have a file extension + destlibroot = os.path.splitext(destlib)[0] + + alllibname = destlibdir + '/' + destlibroot + '.lef' if os.path.isfile(alllibname): os.remove(alllibname) - print('Diagnostic: Creating consolidated LEF library ' + destlib + '.lef') + print('Diagnostic: Creating consolidated LEF library ' + destlibroot + '.lef') 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 7ee350c..bfa773d 100755 --- a/common/create_lib_library.py +++ b/common/create_lib_library.py
@@ -42,11 +42,14 @@ def create_lib_library(destlibdir, destlib, do_compile_only=False, excludelist=[]): - alllibname = destlibdir + '/' + destlib + '.lib' + # destlib should not have a file extension + destlibrooot = os.path.splitext(destlib)[0] + + alllibname = destlibdir + '/' + destlibroot + '.lib' if os.path.isfile(alllibname): os.remove(alllibname) - print('Diagnostic: Creating consolidated liberty library ' + destlib + '.lib') + print('Diagnostic: Creating consolidated liberty library ' + destlibroot + '.lib') # Create exclude list with glob-style matching using fnmatch if len(llist) > 0:
diff --git a/common/create_spice_library.py b/common/create_spice_library.py index a25ac34..ca95fa6 100755 --- a/common/create_spice_library.py +++ b/common/create_spice_library.py
@@ -38,10 +38,13 @@ def create_spice_library(destlibdir, destlib, spiext, do_compile_only=False, do_stub=False, excludelist=[]): + # destlib should not have a file extension + destlibroot = os.path.splitext(destlib)[0] + fformat = 'CDL' if spiext == '.cdl' else 'SPICE' allstubname = destlibdir + '/stub' + spiext - alllibname = destlibdir + '/' + destlib + spiext + alllibname = destlibdir + '/' + destlibroot + spiext if do_stub: outputname = allstubname else:
diff --git a/common/create_verilog_library.py b/common/create_verilog_library.py index fb530ab..32ce2c5 100755 --- a/common/create_verilog_library.py +++ b/common/create_verilog_library.py
@@ -37,11 +37,14 @@ def create_verilog_library(destlibdir, destlib, do_compile_only=False, do_stub=False, excludelist=[]): - alllibname = destlibdir + '/' + destlib + '.v' + # 'destlib' should not have an extension, because one will be generated. + destlibroot = os.path.splitext(destlib)[0] + + alllibname = destlibdir + '/' + destlibroot + '.v' if os.path.isfile(alllibname): os.remove(alllibname) - print('Diagnostic: Creating consolidated verilog library ' + destlib + '.v') + print('Diagnostic: Creating consolidated verilog library ' + destlibroot + '.v') 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 40782e0..7028956 100755 --- a/common/foundry_install.py +++ b/common/foundry_install.py
@@ -805,7 +805,23 @@ destpathcomp.reverse() destpath = ''.join(destpathcomp) + if option[0] == 'verilog': + fileext = '.v' + elif option[0] == 'gds': + fileext = '.gds' + elif option[0] == 'liberty' or option[0] == 'lib': + fileext = '.lib' + elif option[0] == 'spice' or option[0] == 'spi': + fileext = '.spice' if not ef_format else '.spi' + elif option[0] == 'cdl': + fileext = '.cdl' + elif option[0] == 'lef': + fileext = '.lef' + if newname: + if os.path.splitext(newname)[1] == '': + newname = newname + fileext + if len(liblist) == 1: destfile = newname else: @@ -864,7 +880,7 @@ 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 - # library into a compiled <destlib>.<ext> + # library into a compiled <destlib>.<ext> on another pass. compname = destlib @@ -877,11 +893,6 @@ create_verilog_library(destlibdir, compname, do_compile_only, do_stub, excludelist) - if do_compile_only == True: - if newname: - if os.path.isfile(newname): - os.remove(newname) - elif option[0] == 'gds' and have_mag_8_2: # If there is not a single file with all GDS cells in it, # then compile one. @@ -892,11 +903,6 @@ startup_script = targetdir + mag_current + pdkname + '.magicrc' create_gds_library(destlibdir, compname, startup_script, do_compile_only, excludelist) - if do_compile_only == True: - if newname: - if os.path.isfile(newname): - os.remove(newname) - elif option[0] == 'liberty' or option[0] == 'lib': # If there is not a single file with all liberty cells in it, # then compile one, because one does not want to have to have @@ -904,11 +910,6 @@ create_lib_library(destlibdir, compname, do_compile_only, excludelist) - if do_compile_only == True: - if newname: - if os.path.isfile(newname): - os.remove(newname) - elif option[0] == 'spice' or option[0] == 'spi': # If there is not a single file with all SPICE subcircuits in it, # then compile one, because one does not want to have to have @@ -916,10 +917,6 @@ spiext = '.spice' if not ef_format else '.spi' create_spice_library(destlibdir, compname, spiext, do_compile_only, do_stub, excludelist) - if do_compile_only == True: - if newname: - if os.path.isfile(newname): - os.remove(newname) elif option[0] == 'cdl': # If there is not a single file with all CDL subcircuits in it, @@ -927,10 +924,6 @@ # an include line for every single cell used in a design. create_spice_library(destlibdir, compname, '.cdl', do_compile_only, do_stub, excludelist) - if do_compile_only == True: - if newname: - if os.path.isfile(newname): - os.remove(newname) elif option[0] == 'lef': # If there is not a single file with all LEF cells in it, @@ -939,10 +932,20 @@ create_lef_library(destlibdir, compname, do_compile_only, excludelist) - if do_compile_only == True: - if newname: - if os.path.isfile(newname): - os.remove(newname) + if do_compile_only == True: + if newname: + if os.path.isfile(targname): + os.remove(targname) + + # "rename" with "compile" or "compile-only": Change the name + # of the compiled file. + + if newname: + print(' Renaming ' + compname + fileext + ' to ' + newname) + origname = destlibdir + '/' + compname + fileext + targrename = destlibdir + destpath + '/' + newname + if os.path.isfile(origname): + os.rename(origname, targrename) # Find any libraries/options marked as "privileged" (or "private") and # move the files from libs.tech or libs.ref to libs.priv, leaving a
diff --git a/sky130/Makefile.in b/sky130/Makefile.in index daa0808..2cfa21e 100644 --- a/sky130/Makefile.in +++ b/sky130/Makefile.in
@@ -385,7 +385,8 @@ -doc %l/latest/cells/*/*.pdf \ -lib %l/latest/timing/*.lib \ -gds %l/latest/cells/*/*.gds compile-only \ - -verilog %l/latest/cells/*/*.v compile-only \ + -verilog %l/latest/models/*/*.v exclude *.*.v compile-only rename test \ + -verilog %l/latest/cells/*/*.v exclude *.*.v,test,test.v compile-only \ -library digital sky130_fd_sc_hd \ -library digital sky130_fd_sc_hdll \ -library digital sky130_fd_sc_hvl \
diff --git a/sky130/custom/scripts/inc_verilog.py b/sky130/custom/scripts/inc_verilog.py new file mode 100755 index 0000000..d34129d --- /dev/null +++ b/sky130/custom/scripts/inc_verilog.py
@@ -0,0 +1,110 @@ +#!/bin/env python3 +# +# inc_verilog --- +# +# This script handles the verilog sources by removing `include statements +# for files that are already being added to the single consolidated +# verilog library file, and in-lining any other verilog files (namely +# the functional and behavioral sources). +# +# 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: + vtext = inFile.read() + vlines = vtext.splitlines() + except: + print('inc_verilog.py: failed to open ' + fnmIn + ' for reading.', file=sys.stderr) + return 1 + + # Process input with regexp + + fixedlines = [] + modified = False + increx = re.compile('[ \t]*`include[ \t]+"?([^ \t\n"]+)"?') + ddotrex = re.compile('[^\.]+\.[^\.]+\.v') + tdotrex = re.compile('[^\.]+\.[^\.]+\.[^\.]+\.v') + inpath = os.path.split(inname)[0] + + for line in vlines: + + # Check includes + imatch = increx.match(line) + if imatch: + incfilename = imatch.group(1) + dmatch = ddotrex.match(incfilename) + tmatch = tdotrex.match(incfilename) + if dmatch or tmatch: + # double-dot or triple-dot: Include this file in-line + # NOTE: These files are assumed not to need in-line + # includes, but includes of primitives need to be ignored. + + with open(inpath + '/' + incfilename, 'r') as incfile: + v2text = incfile.read() + v2lines = v2text.splitlines() + for line2 in v2lines: + i2match = imatch.match(line2) + if not i2match: + fixedlines.append(line2) + else: + # single-dot: Ignore this line + pass + modified = True + 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('inc_verilog.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)