blob: 2c746b503b3eb9dcce421c1026dc527c6db1af50 [file] [log] [blame]
Tim Edwards99a5cf92021-05-16 16:42:49 -04001#!/usr/bin/env python3
2#
3# fix_device_models ---
4#
5# This script fixes the issue where devices in the digital libraries did
6# not get the proper name conversion; specifically, the "conb" cell has
7# resistor type "short" which should be "sky130_fd_pr__res_generic_po",
8# and the pw2nd device model name is missing the suffix "_05v5".
9#
10# This script is a filter to be run by setting the name of this script as
11# the value to "filter=" for the model install in the sky130 Makefile.
12
13import re
14import os
15import sys
16
17def filter(inname, outname):
18
19 # Read input
20 try:
21 with open(inname, 'r') as inFile:
22 stext = inFile.read()
23 slines = stext.splitlines()
24 except:
25 print('fix_device_models.py: failed to open ' + fnmIn + ' for reading.', file=sys.stderr)
26 return 1
27
28 # Process input with regexp
29
30 fixedlines = []
31 modified = False
32
33 dioderex = re.compile('.*[ \t]+sky130_fd_pr__diode_pw2nd[ \t]+')
Tim Edwards8877f8f2021-06-10 21:35:36 -040034 ndioderex = re.compile('.*[ \t]+ndiode_h[ \t]+')
Tim Edwards99a5cf92021-05-16 16:42:49 -040035 shortrex = re.compile('.*[ \t]+short[ \t]+')
36
37 for line in slines:
38
39 # Check for incorrect diode reference
40 dmatch = dioderex.match(line)
Tim Edwards8877f8f2021-06-10 21:35:36 -040041 # Check for incorrect HVL diode ("ndiode_h") reference
42 nmatch = ndioderex.match(line)
Tim Edwards99a5cf92021-05-16 16:42:49 -040043 # Check for incorrect resistor reference
44 smatch = shortrex.match(line)
45 if dmatch:
Tim Edwards78ee6332021-05-17 16:31:05 -040046 fline = re.sub('pw2nd', 'pw2nd_05v5', line)
47 fline = re.sub('^X', 'D', fline)
48 fline = re.sub('a=', 'area=', fline)
49 fline = re.sub('p=', 'pj=', fline)
50 fixedlines.append(fline)
Tim Edwards99a5cf92021-05-16 16:42:49 -040051 modified = True
Tim Edwards8877f8f2021-06-10 21:35:36 -040052 elif nmatch:
53 fline = re.sub('ndiode_h', 'sky130_fd_pr__diode_pw2nd_11v0', line)
54 fline = re.sub('^X', 'D', fline)
55 fline = re.sub('a=', 'area=', fline)
56 fline = re.sub('p=', 'pj=', fline)
57 fixedlines.append(fline)
58 modified = True
Tim Edwards99a5cf92021-05-16 16:42:49 -040059 elif smatch:
Tim Edwards50161dc2021-08-31 09:51:38 -040060 fline = re.sub(' VNB short', ' sky130_fd_pr__res_generic_po', line)
61 fline = re.sub('short', 'sky130_fd_pr__res_generic_po', fline)
Tim Edwards78ee6332021-05-17 16:31:05 -040062 fline = re.sub('^X', 'R', fline)
63 fixedlines.append(fline)
Tim Edwards99a5cf92021-05-16 16:42:49 -040064 modified = True
65 else:
66 fixedlines.append(line)
67
68 # Write output
69 if outname == None:
70 for i in fixedlines:
71 print(i)
72 else:
73 # If the output is a symbolic link but no modifications have been made,
74 # then leave it alone. If it was modified, then remove the symbolic
75 # link before writing.
76 if os.path.islink(outname):
77 if not modified:
78 return 0
79 else:
80 os.unlink(outname)
81 try:
82 with open(outname, 'w') as outFile:
83 for i in fixedlines:
84 print(i, file=outFile)
85 except:
86 print('fix_device_models.py: failed to open ' + outname + ' for writing.', file=sys.stderr)
87 return 1
88
89
90if __name__ == '__main__':
91
92 # This script expects to get one or two arguments. One argument is
93 # mandatory and is the input file. The other argument is optional and
94 # is the output file. The output file and input file may be the same
95 # name, in which case the original input is overwritten.
96
97 options = []
98 arguments = []
99 for item in sys.argv[1:]:
100 if item.find('-', 0) == 0:
101 options.append(item[1:])
102 else:
103 arguments.append(item)
104
105 if len(arguments) > 0:
106 infilename = arguments[0]
107
108 if len(arguments) > 1:
109 outfilename = arguments[1]
110 else:
111 outfilename = None
112
113 result = filter(infilename, outfilename)
114 sys.exit(result)