blob: 23f1805a14392aec4a486c552aa1c721d3c05b34 [file] [log] [blame]
Tim Edwards02c01932020-11-22 10:45:37 -05001#!/usr/bin/env python3
2#
3# cleanup_unref.py: Look up all .mag files in the indicated path, and
4# parse all files for "use" lines and make a list of all the cells being
5# used. Next, check all files to determine which ones are parameterized
6# PDK cells (those that have "string gencell" in the properties section).
7# Finally, remove all the files which represent parametersized PDK cells
8# that are not used anywhere by any other layout file.
9#
10# The purpose of this script is to reduce the number of cells scattered
11# about the filesystem that come from parameterized cells being modified
12# in place. Eventually, magic will be upgraded to have a way to indicate
13# just the cell name and parameters in the .mag file so that all parameterized
14# cells can be generated on-the-fly and do not need to be saved in .mag files.
15#
16# Note that this routine assumes that all files are local to a single project
17# directory and are not being used by layout in some other directory. So use
18# with caution.
19#
20# Usage, e.g.:
21#
22# cleanup_unref.py <path_to_layout>
23
24import os
25import re
26import sys
27import glob
28
29def usage():
30 print("cleanup_unref.py [-remove] <path_to_layout>")
31 return 0
32
33if __name__ == '__main__':
34
35 if len(sys.argv) == 1:
36 usage()
37 sys.exit(0)
38
39 optionlist = []
40 arguments = []
41
42 testmode = True
43 debugmode = False
44
45 for option in sys.argv[1:]:
46 if option.find('-', 0) == 0:
47 optionlist.append(option)
48 else:
49 arguments.append(option)
50
51 if len(arguments) != 1:
52 print("Wrong number of arguments given to cleanup_unref.py.")
53 usage()
54 sys.exit(0)
55
56 if '-remove' in optionlist or '-delete' in optionlist:
57 testmode = False
58 if '-debug' in optionlist:
59 debugmode = True
60
61 filepath = arguments[0]
62
63 magpath = filepath + '/*.mag'
64 sourcefiles = glob.glob(magpath)
65
66 if len(sourcefiles) == 0:
67 print("Warning: No files were found in the path " + filepath + ".")
68
69 usedfiles = []
70 pdkfiles = []
71
72 for file in sourcefiles:
73 if debugmode:
74 print("Checking file " + file)
75 fileroot = os.path.split(file)[1]
76 cellname = os.path.splitext(fileroot)[0]
77
78 proprex = re.compile('^string[ \t]+gencell[ \t]+([^ \t]+)')
79 userex = re.compile('^use[ \t]+([^ \t]+)')
80
81 with open(file, 'r') as ifile:
82 magtext = ifile.read().splitlines()
83 for line in magtext:
84 pmatch = proprex.match(line)
85 if pmatch:
86 pdkfiles.append(cellname)
87 umatch = userex.match(line)
88 if umatch:
89 cellname = umatch.group(1)
90 if cellname not in usedfiles:
91 usedfiles.append(cellname)
92
93 unusedfiles = list(item for item in pdkfiles if item not in usedfiles)
94
95 if debugmode:
96 print('')
97 print('Parameterized cells found:')
98 for cellname in sorted(pdkfiles):
99 print(cellname)
100
101 print('')
102 print('Used cells found:')
103 for cellname in sorted(usedfiles):
104 print(cellname)
105
106 if testmode:
107 # Just report on files that are unused
108 print('')
109 print('Parameterized cells not used by any layout:')
110 for cellname in sorted(unusedfiles):
111 print(cellname)
112 else:
113 # Remove files that are unused
114 for cellname in sorted(unusedfiles):
115 file = filepath + '/' + cellname + '.mag'
116 os.remove(file)
117 print('Removed unused parameterized cell ' + cellname)
118
119 print('')
120 print('Done!')