blob: e9c235af3bad64acb06ccfe6f696b8111d2f322d [file] [log] [blame]
#!/usr/bin/env python3
#
# This script traverses SPICE model files (e.g. from SKY130) and
# extracts only the wanted model section, removes all comments and
# empty lines, and resolves all includes so that a flat model file
# results. This should speed up ngspice starts.
#
# (c) 2021 Harald Pretl, Johannes Kepler University Linz
import sys,re,os
def process_file(file_in_name, top_file):
global is_warning
try:
f_in = open(file_in_name, 'r')
except FileNotFoundError:
print('Warning! File ' + file_in_name + ' not found.')
is_warning = True
return;
# process_file can be called recursively, so that nested include
# files can be traversed
# write_active indicates whether we are in the right model section; in
# include files, it is always true
if top_file == True:
write_active = False
else:
write_active = True
for line in f_in:
line_trim = (line.lower()).strip()
if top_file == True:
# we assume that .lib statements are only used in the main file
if '.lib' in line_trim:
if model_section in line_trim:
write_active = True
else:
write_active = False
if '.endl' == line_trim:
write_active = False
f_out.write(line)
if len(line_trim) > 0: # write no empty lines
if (line_trim[0] != '*'): # write no comments
if (write_active == True):
if '.include' in line_trim:
# need to save and restore working dir so that nested
# includes work
current_wd = os.getcwd()
newfile = re.findall(r'"(.*?)(?<!\\)"', line_trim)
print('Reading ',newfile[0])
# enter new working dir
new_wd = os.path.dirname(newfile[0])
if len(new_wd) > 0:
try:
os.chdir(new_wd)
except OSError:
print('Warning: Could not enter directory ' + new_wd)
is_warning = True
# traverse into new include file
new_file_name = os.path.basename(newfile[0])
process_file(new_file_name, False)
# restore old working dir after return
os.chdir(current_wd)
else:
f_out.write(line)
f_in.close()
return;
# main routine
if len(sys.argv) == 3:
model_section = sys.argv[2]
else:
model_section = 'tt'
if (len(sys.argv) == 2) or (len(sys.argv) == 3):
infile_name = sys.argv[1]
outfile_name = infile_name + '.' + model_section + '.red'
try:
f_out = open(outfile_name, 'w')
except OSError:
print('Error: Cannot write file ' + outfile_name + '.')
sys.exit(2)
is_warning = False
process_file(infile_name, True)
f_out.close()
print()
print('Model file ' + outfile_name + ' written.')
if is_warning == True:
print('There have been warnings! Please check output log.')
sys.exit(1)
else:
sys.exit(0)
else:
print()
print('spice_model_red.py SPICE model file reducer')
print(' (c) 2021 Harald Pretl, JKU')
print()
print('Usage: spice_model_red <inputfile> [corner] (default corner = tt)')
print()
print('Return codes for script automation:')
print(' 0 = all OK')
print(' 1 = warnings')
print(' 2 = errors')
print(' 3 = call of script w/o parameters (= showing this message)')
print()
sys.exit(3)