From a1103698328ada022b014bb7f8dbdb5d3e0bde1b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 27 Sep 2015 10:54:19 +0200 Subject: Added 1k timings --- icefuzz/timings.py | 297 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 297 insertions(+) create mode 100644 icefuzz/timings.py (limited to 'icefuzz/timings.py') diff --git a/icefuzz/timings.py b/icefuzz/timings.py new file mode 100644 index 0000000..d6440f8 --- /dev/null +++ b/icefuzz/timings.py @@ -0,0 +1,297 @@ +#!/usr/bin/env python3 + +import getopt, sys, re + +database = dict() +sdf_inputs = list() +txt_inputs = list() +output_sdf = False + + +def usage(): + print(""" +Usage: python3 timings.py [options] [sdf_file..] + + -t filename + read TXT file + + -s + output SDF (not TXT) format +""") + sys.exit(0) + + +try: + opts, args = getopt.getopt(sys.argv[1:], "t:s") +except: + usage() + +for o, a in opts: + if o == "-t": + txt_inputs.append(a) + elif o == "-s": + output_sdf = True + else: + usage() + +sdf_inputs += args + + +def skip_whitespace(text, cursor): + while cursor < len(text) and text[cursor] in [" ", "\t", "\r", "\n"]: + cursor += 1 + return cursor + + +def parse_sdf(text, cursor): + cursor = skip_whitespace(text, cursor) + + if cursor < len(text) and text[cursor] == "(": + expr = [] + cursor += 1 + while cursor < len(text) and text[cursor] != ")": + child, cursor = parse_sdf(text, cursor) + expr.append(child) + cursor = skip_whitespace(text, cursor) + return expr, cursor+1 + + if cursor < len(text) and text[cursor] == '"': + expr = '"' + cursor += 1 + while cursor < len(text) and text[cursor] != '"': + expr += text[cursor] + cursor += 1 + return expr + '"', cursor+1 + + expr = "" + while cursor < len(text) and text[cursor] not in [" ", "\t", "\r", "\n", "(", ")"]: + expr += text[cursor] + cursor += 1 + return expr, cursor + + +def sdf_to_string(expr): + if type(expr) is list: + tokens = [] + tokens.append("(") + first_child = True + for child in expr: + if not first_child: + tokens.append(" ") + tokens.append(sdf_to_string(child)) + first_child = False + tokens.append(")") + return "".join(tokens) + else: + return expr + + +def dump_sdf(expr, indent=""): + if type(expr) is list: + if len(expr) > 0 and expr[0] in ["IOPATH", "SETUP", "HOLD", "CELLTYPE", "INSTANCE", "SDFVERSION", + "DESIGN", "DATE", "VENDOR", "DIVIDER", "TIMESCALE", "RECOVERY", "REMOVAL"]: + print(indent + sdf_to_string(expr)) + else: + print("%s(%s" % (indent, expr[0] if len(expr) > 0 else "")) + for child in expr[1:]: + dump_sdf(child, indent + " ") + print("%s)" % indent) + else: + print("%s%s" % (indent, expr)) + + +def generalize_instances(expr): + if type(expr) is list: + if len(expr) == 2 and expr[0] == "INSTANCE": + expr[1] = "*" + for child in expr: + generalize_instances(child) + + +def list_to_tuple(expr): + if type(expr) is list: + tup = [] + for child in expr: + tup.append(list_to_tuple(child)) + return tuple(tup) + return expr + + +def uniquify_cells(expr): + cache = set() + filtered_expr = [] + + for child in expr: + t = list_to_tuple(child) + if t not in cache: + filtered_expr.append(child) + cache.add(t) + + return filtered_expr + + +########################################### +# Parse SDF input files + +for filename in sdf_inputs: + print("### reading SDF file %s" % filename, file=sys.stderr) + + intext = [] + with open(filename, "r") as f: + for line in f: + line = re.sub("//.*", "", line) + intext.append(line) + + sdfdata, _ = parse_sdf("".join(intext), 0) + generalize_instances(sdfdata) + sdfdata = uniquify_cells(sdfdata) + + for cell in sdfdata: + if cell[0] != "CELL": + continue + + celltype = None + + def add_entry(entry): + entry = sdf_to_string(entry) + entry = entry.replace("(posedge ", "posedge:") + entry = entry.replace("(negedge ", "negedge:") + entry = entry.replace("(", "") + entry = entry.replace(")", "") + entry = entry.split() + database[celltype].add(tuple(entry)) + + for stmt in cell: + if stmt[0] == "CELLTYPE": + celltype = stmt[1][1:-1] + + if celltype.startswith("PRE_IO_PIN_TYPE_"): + celltype = "PRE_IO_PIN_TYPE" + + if celltype.startswith("Span4Mux"): + if celltype == "Span4Mux": + celltype = "Span4Mux_v4" + elif celltype == "Span4Mux_v": + celltype = "Span4Mux_v4" + elif celltype == "Span4Mux_h": + celltype = "Span4Mux_h4" + else: + match = re.match("Span4Mux_s(.*)_(h|v)", celltype) + celltype = "Span4Mux_%c%d" % (match.group(2), int(match.group(1))) + + if celltype.startswith("Span12Mux"): + if celltype == "Span12Mux": + celltype = "Span12Mux_v12" + elif celltype == "Span12Mux_v": + celltype = "Span12Mux_v12" + elif celltype == "Span12Mux_h": + celltype = "Span12Mux_h12" + else: + match = re.match("Span12Mux_s(.*)_(h|v)", celltype) + celltype = "Span12Mux_%c%d" % (match.group(2), int(match.group(1))) + + database.setdefault(celltype, set()) + + if stmt[0] == "DELAY": + assert stmt[1][0] == "ABSOLUTE" + for entry in stmt[1][1:]: + assert entry[0] == "IOPATH" + add_entry(entry) + + if stmt[0] == "TIMINGCHECK": + for entry in stmt[1:]: + add_entry(entry) + + +########################################### +# Parse TXT input files + +for filename in txt_inputs: + print("### reading TXT file %s" % filename, file=sys.stderr) + with open(filename, "r") as f: + celltype = None + for line in f: + line = line.split() + if len(len) > 1: + if line[0] == "CELL": + celltype = line[1] + else: + database[celltype].add(tuple(line)) + + +########################################### +# Create SDF output + +convert = lambda text: int(text) if text.isdigit() else text.lower() +alphanum_key = lambda key: [ convert(c) for c in re.split('([0-9]+)', key) ] +alphanum_key_list = lambda l: [len(l)] + [ alphanum_key(s) for s in l ] + +if output_sdf: + print("(DELAYFILE") + print(" (SDFVERSION \"3.0\")") + print(" (TIMESCALE 1ps)") + + def format_entry(entry): + text = [] + for i in range(len(entry)): + if i > 2: + text.append("(%s)" % entry[i]) + elif entry[i].startswith("posedge:"): + text.append("(posedge %s)" % entry[i].replace("posedge:", "")) + elif entry[i].startswith("negedge:"): + text.append("(negedge %s)" % entry[i].replace("negedge:", "")) + else: + text.append(entry[i]) + return " ".join(text) + + for celltype in sorted(database, key=alphanum_key): + print(" (CELL") + print(" (CELLTYPE \"%s\")" % celltype) + print(" (INSTANCE *)") + + delay_abs_entries = list() + timingcheck_entries = list() + for entry in sorted(database[celltype], key=alphanum_key_list): + if entry[0] == "IOPATH": + delay_abs_entries.append(entry) + else: + timingcheck_entries.append(entry) + + if len(delay_abs_entries) != 0: + print(" (DELAY") + print(" (ABSOLUTE") + for entry in delay_abs_entries: + print(" (%s)" % format_entry(entry)) + print(" )") + print(" )") + + if len(timingcheck_entries) != 0: + print(" (TIMINGCHECK") + for entry in timingcheck_entries: + print(" (%s)" % format_entry(entry)) + print(" )") + + print(" )") + + print(")") + + +########################################### +# Create TXT output + +else: + for celltype in sorted(database, key=alphanum_key): + print("CELL %s" % celltype) + entries_lens = list() + for entry in database[celltype]: + for i in range(len(entry)): + if i < len(entries_lens): + entries_lens[i] = max(entries_lens[i], len(entry[i])) + else: + entries_lens.append(len(entry[i])) + for entry in sorted(database[celltype], key=alphanum_key_list): + for i in range(len(entry)): + print("%s%-*s" % (" " if i != 0 else "", entries_lens[i] if i != len(entry)-1 else 0, entry[i]), end="") + print() + print() + -- cgit v1.2.3