blob: cff557683ef3191c0a9940d44b660a59732f361f [file] [log] [blame]
Tim Edwards33ce97a2021-05-24 20:51:28 -04001#!/usr/bin/env python3
2#
3#--------------------------------------------------------------------
4# Workaround for the problem that ngspice is unable to accept a
5# parameter name that shadows a device name. Parameters in the
6# files critical.spice and montecarlo.spice that shadow parameter
7# names have the leading sky130_fd_pr__ stripped off to prevent
8# this from being a problem.
9#--------------------------------------------------------------------
10
11import os
12import re
13import sys
14
Tim Edwards7325e442022-03-03 16:51:52 -050015options = []
16arguments = []
17for item in sys.argv[1:]:
18 if item.find('-', 0) == 0:
19 options.append(item[1:])
20 else:
21 arguments.append(item)
Tim Edwards33ce97a2021-05-24 20:51:28 -040022
Tim Edwards7325e442022-03-03 16:51:52 -050023variant = 'sky130A'
24
25if len(options) > 0:
26 for option in options:
27 if option.startswith('variant'):
28 variant = option.split('=')[1]
29 searchpath = [variant + '/libs.tech/ngspice/parameters/critical.spice',
30 variant + '/libs.tech/ngspice/parameters/montecarlo.spice']
31
32elif len(arguments) > 0:
Tim Edwards33ce97a2021-05-24 20:51:28 -040033 searchpath = sys.argv[1]
34
Tim Edwards7325e442022-03-03 16:51:52 -050035
Tim Edwards33ce97a2021-05-24 20:51:28 -040036# Flag all parameters that have the same name as devices.
37# These parameters are unused and must be deleted.
38
39excludelist = [
40 'sky130_fd_pr__nfet_20v0_nvt_iso',
41 'sky130_fd_pr__nfet_20v0_nvt',
42 'sky130_fd_pr__nfet_20v0_iso',
43 'sky130_fd_pr__nfet_20v0_zvt',
44 'sky130_fd_pr__nfet_20v0',
45 'sky130_fd_pr__pfet_20v0',
46 'sky130_fd_pr__nfet_01v8_lvt',
47 'sky130_fd_pr__pfet_01v8_mvt',
48 'sky130_fd_pr__pfet_01v8',
49 'sky130_fd_pr__nfet_g5v0d16v0',
50 'sky130_fd_pr__pfet_g5v0d16v0',
51 'sky130_fd_pr__special_nfet_pass_lvt',
52 'sky130_fd_pr__pnp_05v5_W0p68L0p68']
53
54# For each entry in the exclude list, create a regular expression
55# for detecting that entry and excluding other similar cases that
56# aren't the parameter. Items with preceding "/" are the device
57# filename, and items with additional text are other parameters.
58
59rexpat = {}
60rexdict = {}
61
62for item in excludelist:
63 rexpat[item] = '([^/])' + item + '(?=[^_])'
64 rexdict[item] = re.compile('([^/])' + item + '(?=[^_])')
65
66#--------------------------------------------------------------------
67
68for infile_name in searchpath:
69 filepath = os.path.split(infile_name)[0]
Tim Edwards477d9b72022-02-06 17:01:15 -050070 filename = os.path.split(infile_name)[1]
71 fileroot = os.path.splitext(filename)[0]
Tim Edwards7325e442022-03-03 16:51:52 -050072 outfile_name = os.path.join(filepath, fileroot + '_temp')
Tim Edwards33ce97a2021-05-24 20:51:28 -040073
74 infile = open(infile_name, 'r')
Tim Edwards7325e442022-03-03 16:51:52 -050075 outfile = open(outfile_name, 'w')
Tim Edwards33ce97a2021-05-24 20:51:28 -040076
77 line_number = 0
78 replaced_something = False
79 for line in infile:
80 line_number += 1
81
82 newline = line
83 for device in excludelist:
84 rmatch = rexdict[device].search(line)
85 if rmatch:
86 replacement = device[14:]
87 newline = re.sub(rexpat[device], '\g<1>' + replacement, newline)
88 replaced_something = True
89
90 outfile.write(newline)
91
92 infile.close()
93 outfile.close()
94 if replaced_something:
95 print("Something was replaced in '{}'".format(infile_name))
96 os.rename(outfile_name, infile_name)
97 else:
98 print("Nothing was replaced in '{}'.".format(infile_name))
99 os.remove(outfile_name)
100