blob: aebce3ea7fc97f759f8fc79cb665051891db42fe [file] [log] [blame]
Tim Edwards9d3debb2020-10-20 20:52:18 -04001#!/usr/bin/env python3
Tim Edwards05e66eb2020-09-24 13:11:59 -04002#
3# inc_verilog ---
4#
5# This script handles the verilog sources by removing `include statements
6# for files that are already being added to the single consolidated
7# verilog library file, and in-lining any other verilog files (namely
8# the functional and behavioral sources).
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 vtext = inFile.read()
23 vlines = vtext.splitlines()
24 except:
25 print('inc_verilog.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 increx = re.compile('[ \t]*`include[ \t]+"?([^ \t\n"]+)"?')
33 ddotrex = re.compile('[^\.]+\.[^\.]+\.v')
34 tdotrex = re.compile('[^\.]+\.[^\.]+\.[^\.]+\.v')
35 inpath = os.path.split(inname)[0]
36
37 for line in vlines:
38
39 # Check includes
40 imatch = increx.match(line)
41 if imatch:
42 incfilename = imatch.group(1)
43 dmatch = ddotrex.match(incfilename)
44 tmatch = tdotrex.match(incfilename)
45 if dmatch or tmatch:
46 # double-dot or triple-dot: Include this file in-line
47 # NOTE: These files are assumed not to need in-line
48 # includes, but includes of primitives need to be ignored.
49
Tim Edwards995c1332020-09-25 15:33:58 -040050 # Quick hack: Remove this when the filenames are corrected
51 if not os.path.exists(inpath + '/' + incfilename):
52 print('Detected incorrect filename')
53 print(' Old filename was: ' + incfilename)
54 dlist = incfilename.split('.')
55 ilist = dlist[0:-3]
56 ilist.append(dlist[-2])
57 ilist.append(dlist[-3])
58 ilist.append(dlist[-1])
59 print(' New filename is: ' + incfilename)
60 incfilename = '.'.join(ilist)
61
Tim Edwards05e66eb2020-09-24 13:11:59 -040062 with open(inpath + '/' + incfilename, 'r') as incfile:
63 v2text = incfile.read()
64 v2lines = v2text.splitlines()
65 for line2 in v2lines:
Tim Edwards995c1332020-09-25 15:33:58 -040066 i2match = increx.match(line2)
Tim Edwards05e66eb2020-09-24 13:11:59 -040067 if not i2match:
68 fixedlines.append(line2)
69 else:
70 # single-dot: Ignore this line
71 pass
72 modified = True
73 else:
74 fixedlines.append(line)
75
76 # Write output
77 if outname == None:
78 for i in fixedlines:
79 print(i)
80 else:
81 # If the output is a symbolic link but no modifications have been made,
82 # then leave it alone. If it was modified, then remove the symbolic
83 # link before writing.
84 if os.path.islink(outname):
85 if not modified:
86 return 0
87 else:
88 os.unlink(outname)
89 try:
90 with open(outname, 'w') as outFile:
91 for i in fixedlines:
92 print(i, file=outFile)
93 except:
94 print('inc_verilog.py: failed to open ' + outname + ' for writing.', file=sys.stderr)
95 return 1
96
97
98if __name__ == '__main__':
99
100 # This script expects to get one or two arguments. One argument is
101 # mandatory and is the input file. The other argument is optional and
102 # is the output file. The output file and input file may be the same
103 # name, in which case the original input is overwritten.
104
105 options = []
106 arguments = []
107 for item in sys.argv[1:]:
108 if item.find('-', 0) == 0:
109 options.append(item[1:])
110 else:
111 arguments.append(item)
112
113 if len(arguments) > 0:
114 infilename = arguments[0]
115
116 if len(arguments) > 1:
117 outfilename = arguments[1]
118 else:
119 outfilename = None
120
121 result = filter(infilename, outfilename)
122 sys.exit(result)