blob: 23f1805a14392aec4a486c552aa1c721d3c05b34 [file] [log] [blame]
#!/usr/bin/env python3
#
# cleanup_unref.py: Look up all .mag files in the indicated path, and
# parse all files for "use" lines and make a list of all the cells being
# used. Next, check all files to determine which ones are parameterized
# PDK cells (those that have "string gencell" in the properties section).
# Finally, remove all the files which represent parametersized PDK cells
# that are not used anywhere by any other layout file.
#
# The purpose of this script is to reduce the number of cells scattered
# about the filesystem that come from parameterized cells being modified
# in place. Eventually, magic will be upgraded to have a way to indicate
# just the cell name and parameters in the .mag file so that all parameterized
# cells can be generated on-the-fly and do not need to be saved in .mag files.
#
# Note that this routine assumes that all files are local to a single project
# directory and are not being used by layout in some other directory. So use
# with caution.
#
# Usage, e.g.:
#
# cleanup_unref.py <path_to_layout>
import os
import re
import sys
import glob
def usage():
print("cleanup_unref.py [-remove] <path_to_layout>")
return 0
if __name__ == '__main__':
if len(sys.argv) == 1:
usage()
sys.exit(0)
optionlist = []
arguments = []
testmode = True
debugmode = False
for option in sys.argv[1:]:
if option.find('-', 0) == 0:
optionlist.append(option)
else:
arguments.append(option)
if len(arguments) != 1:
print("Wrong number of arguments given to cleanup_unref.py.")
usage()
sys.exit(0)
if '-remove' in optionlist or '-delete' in optionlist:
testmode = False
if '-debug' in optionlist:
debugmode = True
filepath = arguments[0]
magpath = filepath + '/*.mag'
sourcefiles = glob.glob(magpath)
if len(sourcefiles) == 0:
print("Warning: No files were found in the path " + filepath + ".")
usedfiles = []
pdkfiles = []
for file in sourcefiles:
if debugmode:
print("Checking file " + file)
fileroot = os.path.split(file)[1]
cellname = os.path.splitext(fileroot)[0]
proprex = re.compile('^string[ \t]+gencell[ \t]+([^ \t]+)')
userex = re.compile('^use[ \t]+([^ \t]+)')
with open(file, 'r') as ifile:
magtext = ifile.read().splitlines()
for line in magtext:
pmatch = proprex.match(line)
if pmatch:
pdkfiles.append(cellname)
umatch = userex.match(line)
if umatch:
cellname = umatch.group(1)
if cellname not in usedfiles:
usedfiles.append(cellname)
unusedfiles = list(item for item in pdkfiles if item not in usedfiles)
if debugmode:
print('')
print('Parameterized cells found:')
for cellname in sorted(pdkfiles):
print(cellname)
print('')
print('Used cells found:')
for cellname in sorted(usedfiles):
print(cellname)
if testmode:
# Just report on files that are unused
print('')
print('Parameterized cells not used by any layout:')
for cellname in sorted(unusedfiles):
print(cellname)
else:
# Remove files that are unused
for cellname in sorted(unusedfiles):
file = filepath + '/' + cellname + '.mag'
os.remove(file)
print('Removed unused parameterized cell ' + cellname)
print('')
print('Done!')