blob: e9c235af3bad64acb06ccfe6f696b8111d2f322d [file] [log] [blame]
Tim Edwards5cad4f82021-10-04 12:31:36 -04001#!/usr/bin/env python3
2#
3# This script traverses SPICE model files (e.g. from SKY130) and
4# extracts only the wanted model section, removes all comments and
5# empty lines, and resolves all includes so that a flat model file
6# results. This should speed up ngspice starts.
7#
8# (c) 2021 Harald Pretl, Johannes Kepler University Linz
9
10import sys,re,os
11
12def process_file(file_in_name, top_file):
13 global is_warning
14 try:
15 f_in = open(file_in_name, 'r')
16 except FileNotFoundError:
17 print('Warning! File ' + file_in_name + ' not found.')
18 is_warning = True
19 return;
20
21 # process_file can be called recursively, so that nested include
22 # files can be traversed
23
24 # write_active indicates whether we are in the right model section; in
25 # include files, it is always true
26
27 if top_file == True:
28 write_active = False
29 else:
30 write_active = True
31
32 for line in f_in:
33 line_trim = (line.lower()).strip()
34
35 if top_file == True:
36 # we assume that .lib statements are only used in the main file
37 if '.lib' in line_trim:
38 if model_section in line_trim:
39 write_active = True
40 else:
41 write_active = False
42
43 if '.endl' == line_trim:
44 write_active = False
45 f_out.write(line)
46
47 if len(line_trim) > 0: # write no empty lines
48 if (line_trim[0] != '*'): # write no comments
49 if (write_active == True):
50 if '.include' in line_trim:
51 # need to save and restore working dir so that nested
52 # includes work
53 current_wd = os.getcwd()
54 newfile = re.findall(r'"(.*?)(?<!\\)"', line_trim)
55 print('Reading ',newfile[0])
56
57 # enter new working dir
58 new_wd = os.path.dirname(newfile[0])
59 if len(new_wd) > 0:
60 try:
61 os.chdir(new_wd)
62 except OSError:
63 print('Warning: Could not enter directory ' + new_wd)
64 is_warning = True
65
66 # traverse into new include file
67 new_file_name = os.path.basename(newfile[0])
68 process_file(new_file_name, False)
69
70 # restore old working dir after return
71 os.chdir(current_wd)
72 else:
73 f_out.write(line)
74
75 f_in.close()
76 return;
77
78# main routine
79
80if len(sys.argv) == 3:
81 model_section = sys.argv[2]
82else:
83 model_section = 'tt'
84
85if (len(sys.argv) == 2) or (len(sys.argv) == 3):
86 infile_name = sys.argv[1]
87 outfile_name = infile_name + '.' + model_section + '.red'
88
89 try:
90 f_out = open(outfile_name, 'w')
91 except OSError:
92 print('Error: Cannot write file ' + outfile_name + '.')
93 sys.exit(2)
94
95 is_warning = False
96 process_file(infile_name, True)
97 f_out.close()
98
99 print()
100 print('Model file ' + outfile_name + ' written.')
101 if is_warning == True:
102 print('There have been warnings! Please check output log.')
103 sys.exit(1)
104 else:
105 sys.exit(0)
106else:
107 print()
108 print('spice_model_red.py SPICE model file reducer')
109 print(' (c) 2021 Harald Pretl, JKU')
110 print()
111 print('Usage: spice_model_red <inputfile> [corner] (default corner = tt)')
112 print()
113 print('Return codes for script automation:')
114 print(' 0 = all OK')
115 print(' 1 = warnings')
116 print(' 2 = errors')
117 print(' 3 = call of script w/o parameters (= showing this message)')
118 print()
119 sys.exit(3)