blob: e50198cf698768bd623a0dda1c3116cbe1b029ce [file] [log] [blame]
#!/usr/bin/env python3
import parse_sdf
from os import path
import json
import sys
def include_cell(name, type):
return type.isupper() and "_" not in type
def rewrite_celltype(name, type):
return type
def rewrite_pin(name, type, pin):
return pin
def tupleise(x):
if type(x) is list:
return tuple(tupleise(_) for _ in x)
elif type(x) is tuple:
return tuple(tupleise(_) for _ in x)
elif type(x) is dict:
return "dict", tuple([(k, tupleise(v)) for k, v in sorted(x.items())])
else:
return x
def load_database(dbfile):
if not path.exists(dbfile):
database = {}
else:
database = {}
with open(dbfile, 'r') as dbf:
jsondb = json.load(dbf)
for cell, cdata in jsondb.items():
database[cell] = set()
for item in cdata:
database[cell].add(tupleise(item))
return database
def make_key(x):
if type(x) is tuple:
return ",".join(make_key(_) for _ in x)
else:
return str(x)
def save_database(dbfile, database):
jdb = {}
for cell, cdata in database.items():
jcdata = []
for dtype, dat in sorted(cdata, key=lambda x: make_key(x)):
assert dtype == "dict"
jcdata.append({k: v for k, v in dat})
jdb[cell] = jcdata
with open(dbfile, 'w') as dbf:
json.dump(jdb, dbf, indent=4, sort_keys=True)
def delay_tuple(delay):
return delay.minv, delay.typv, delay.maxv
def add_sdf_to_database(dbfile, sdffile, include_cell_predicate=include_cell, rewrite_cell_func=rewrite_celltype,
rewrite_pin_func=rewrite_pin):
db = load_database(dbfile)
sdf = parse_sdf.parse_sdf_file(sdffile)
for instname, cell in sdf.cells.items():
if not include_cell_predicate(cell.inst, cell.type):
continue
celltype = rewrite_cell_func(cell.inst, cell.type)
if celltype not in db:
db[celltype] = set()
for entry in cell.entries:
if type(entry) is parse_sdf.IOPath:
db[celltype].add(tupleise(
dict(type="IOPath", from_pin=rewrite_pin_func(cell.inst, cell.type, entry.from_pin),
to_pin=rewrite_pin_func(cell.inst, cell.type, entry.to_pin), rising=delay_tuple(entry.rising),
falling=delay_tuple(entry.falling))))
elif type(entry) is parse_sdf.SetupHoldCheck:
db[celltype].add(
tupleise(dict(type="SetupHold", pin=rewrite_pin_func(cell.inst, cell.type, entry.pin),
clock=rewrite_pin_func(cell.inst, cell.type, entry.clock),
setup=delay_tuple(entry.setup),
hold=delay_tuple(entry.hold))))
elif type(entry) is parse_sdf.WidthCheck:
db[celltype].add(tupleise(dict(type="Width", clock=rewrite_pin_func(cell.inst, cell.type, entry.clock),
width=delay_tuple(entry.width))))
else:
assert False
save_database(dbfile, db)
def main(argv):
if len(argv) < 3:
print("Usage: cell_timings.py database.json design.sdf")
return 2
add_sdf_to_database(argv[1], argv[2])
return 0
if __name__ == "__main__":
sys.exit(main(sys.argv))