def build_and_add(designs, density="45", inc_cell=cell_timings.include_cell, rw_cell_func=cell_timings.rewrite_celltype, rw_pin_func=cell_timings.rewrite_pin): jobs = [] sdfs = dict() for des in designs: jobs += timing_configs( path.basename(des).replace(".v", ""), des, density) for job in jobs: grade, cfg = job sdfs[grade] = [] def per_job(job): grade, cfg = job cfg.setup(skip_specimen=True) bitf = cfg.build_design(cfg.ncl, {}, backanno=True, substitute=False) sdf = bitf.replace(".bit", ".sdf") sdfs[grade].append(sdf) fuzzloops.parallel_foreach(jobs, per_job) for grade in sdfs.keys(): db = timing_dbs.cells_db_path("ECP5", grade) for sdf in sdfs[grade]: cell_timings.add_sdf_to_database(db, sdf, include_cell_predicate=inc_cell, rewrite_cell_func=rw_cell_func, rewrite_pin_func=rw_pin_func)
def process_timing_data(): for grade in speed_grade_names: with open(timing_dbs.cells_db_path("ECP5", grade)) as f: cell_data = json.load(f) cells = [] for cell, cdata in sorted(cell_data.items()): celltype = constids[cell.replace(":", "_").replace("=", "_").replace(",", "_")] delays = [] setupholds = [] for entry in cdata: if entry["type"] == "Width": continue elif entry["type"] == "IOPath": from_pin = entry["from_pin"][1] if type(entry["from_pin"]) is list else entry["from_pin"] if from_pin in timing_port_xform: from_pin = timing_port_xform[from_pin] to_pin = entry["to_pin"] if to_pin in timing_port_xform: to_pin = timing_port_xform[to_pin] min_delay = min(entry["rising"][0], entry["falling"][0]) max_delay = min(entry["rising"][2], entry["falling"][2]) delays.append((constids[from_pin], constids[to_pin], min_delay, max_delay)) elif entry["type"] == "SetupHold": if type(entry["pin"]) is list: continue pin = constids[entry["pin"]] clock = constids[entry["clock"][1]] min_setup = entry["setup"][0] max_setup = entry["setup"][2] min_hold = entry["hold"][0] max_hold = entry["hold"][2] setupholds.append((pin, clock, min_setup, max_setup, min_hold, max_hold)) else: assert False, entry["type"] cells.append((celltype, delays, setupholds)) pip_class_delays = [] for i in range(len(pip_class_to_idx)): pip_class_delays.append((50, 50, 0, 0)) pip_class_delays[pip_class_to_idx["zero"]] = (0, 0, 0, 0) with open(timing_dbs.interconnect_db_path("ECP5", grade)) as f: interconn_data = json.load(f) for pipclass, pipdata in sorted(interconn_data.items()): min_delay = pipdata["delay"][0] * 1.1 max_delay = pipdata["delay"][2] * 1.1 min_fanout = pipdata["fanout"][0] max_fanout = pipdata["fanout"][2] if grade == "6": pip_class_to_idx[pipclass] = len(pip_class_delays) pip_class_delays.append((min_delay, max_delay, min_fanout, max_fanout)) else: if pipclass in pip_class_to_idx: pip_class_delays[pip_class_to_idx[pipclass]] = (min_delay, max_delay, min_fanout, max_fanout) speed_grade_cells[grade] = cells speed_grade_pips[grade] = pip_class_delays
def main(argv): args = parser.parse_args(argv[1:]) if not path.exists(args.fld): os.mkdir(args.fld) commit_hash = database.get_db_commit() build_dt = time.strftime('%Y-%m-%d %H:%M:%S') docs_toc = "" pytrellis.load_database(database.get_db_root()) for fam, fam_data in sorted(database.get_devices()["families"].items()): if fam == "MachXO2": continue fdir = path.join(args.fld, fam) if not path.exists(fdir): os.mkdir(fdir) thdir = path.join(fdir, "tilehtml") if not path.exists(thdir): os.mkdir(thdir) docs_toc += "<h3>{} Family</h3>".format(fam) docs_toc += "<h4>Bitstream Documentation</h4>" docs_toc += "<ul>" tiles = get_device_tiles(fam, fam_data["devices"]) for dev, devdata in sorted(fam_data["devices"].items()): if devdata["fuzz"]: ddir = path.join(fdir, dev) if not path.exists(ddir): os.mkdir(ddir) print( "********* Generating documentation for device {}".format( dev)) generate_device_docs(fam, dev, ddir) if (fam, dev) in tiles: for tile in tiles[fam, dev]: print( "*** Generating documentation for tile {}".format( tile)) generate_tile_docs(fam, dev, tile, thdir) docs_toc += '<li><a href="{}">{} Documentation</a></li>'.format( '{}/{}/index.html'.format(fam, dev), dev) docs_toc += "</ul>" docs_toc += "<h4>Cell Timing Documentation</h4>" docs_toc += "<ul>" for spgrade in ["6", "7", "8", "8_5G"]: tdir = path.join(fdir, "timing") if not path.exists(tdir): os.mkdir(tdir) docs_toc += '<li><a href="{}">Speed Grade -{}</a></li>'.format( '{}/timing/cell_timing_{}.html'.format(fam, spgrade), spgrade) cell_html.make_cell_timing_html( timing_dbs.cells_db_path(fam, spgrade), fam, spgrade, path.join(tdir, 'cell_timing_{}.html'.format(spgrade))) docs_toc += "</ul>" docs_toc += "<h4>Interconnect Timing Documentation</h4>" docs_toc += "<ul>" for spgrade in ["6", "7", "8", "8_5G"]: tdir = path.join(fdir, "timing") if not path.exists(tdir): os.mkdir(tdir) docs_toc += '<li><a href="{}">Speed Grade -{}</a></li>'.format( '{}/timing/interconn_timing_{}.html'.format(fam, spgrade), spgrade) interconnect_html.make_interconn_timing_html( timing_dbs.interconnect_db_path(fam, spgrade), fam, spgrade, path.join(tdir, 'interconn_timing_{}.html'.format(spgrade))) docs_toc += "</ul>" index_html = Template(trellis_docs_index).substitute(datetime=build_dt, commit=commit_hash, docs_toc=docs_toc) with open(path.join(args.fld, "index.html"), 'w') as f: f.write(index_html)
def main(argv): if len(argv) < 3: print("./cell_html.py grade out.html") make_cell_timing_html(timing_dbs.cells_db_path("ECP5", argv[1]), "ECP5", argv[1], argv[2])