#!/usr/bin/env python3 import re import sys print("// auto-generated by timings.py from ../icefuzz/timings_*.txt") print("#include ") print("#include ") print("#include ") def timings_to_c(chip, f): print("") print("double get_delay_%s(std::string cell_type, std::string in_port, std::string out_port)" % chip) print("{") in_cell = False last_cell = "" for line in f: fields = line.split() if len(fields) == 0: continue if fields[0] == "CELL": if in_cell: if last_cell.startswith("SB_MAC16"): # DSPs have incomplete timing specification, as some paths # don't mathematically exist - e.g. there is no path from # A[1] to O[0] print(" if (in_port != \"*clkedge*\" && out_port != \"*setup*\") return 0.0;") print(" }") print(" if (cell_type == \"%s\") {" % fields[1]) last_cell = fields[1] in_cell = True if fields[0] == "SETUP": inport = fields[1].split(":")[1] delay = max([0 if s == "*" else float(s) / 1000 for s in fields[3].split(":")]) print(" if (in_port == \"%s\" && out_port == \"*setup*\") return %.5f;" % (inport, delay)) if fields[0] == "IOPATH": if fields[1].startswith("posedge:") or fields[1].startswith("negedge:"): fields[1] = "*clkedge*" delay = max([0 if s == "*" else float(s) / 1000 for s in fields[3].split(":") + fields[4].split(":")]) print(" if (in_port == \"%s\" && out_port == \"%s\") return %.5f;" % (fields[1], fields[2], delay)) if in_cell: print(" }") print(" if (in_port == \"*clkedge*\"|| out_port == \"*setup*\") return 0;") print(" fprintf(stderr, \"Unable to resolve delay for path %s -> %s in cell type %s!\\n\", in_port.c_str(), out_port.c_str(), cell_type.c_str());") print(" exit(1);") print("}") if len(sys.argv) >= 2: chips = sys.argv[1:] else: chips = "lp384 lp1k lp8k hx1k hx8k up5k".split() for db in chips: with open("../icefuzz/timings_%s.txt" % db, "r") as f: timings_to_c(db, f);