def main(): parser = argparse.ArgumentParser() parser.add_argument('--sdfs', nargs='+', type=str, help="List of sdf files to merge") parser.add_argument('--site', type=str, help="Site we want to merge") parser.add_argument('--json', type=str, help="Debug JSON") parser.add_argument('--out', type=str, help="Merged sdf name") args = parser.parse_args() timings_list = list() for sdf in args.sdfs: with open(sdf, 'r') as fp: timing = sdfparse.parse(fp.read()) timings_list.append(timing) merged_sdf = merge(timings_list, args.site) open(args.out, 'w').write(sdfparse.emit(merged_sdf, timescale='1ns')) if args.json is not None: with open(args.json, 'w') as fp: json.dump(merged_sdf, fp, indent=4, sort_keys=True)
def test_output_stability(): """ Checks if the generated SDF are identical with golden files""" parsed_sdfs_check = list() # read the golden files files = sorted(os.listdir(goldenfiles_path)) for f in sorted(files): if f.endswith('.sdf'): with open(os.path.join(goldenfiles_path, f)) as sdffile: parsed_sdfs_check.append(sdffile.read()) for s0, s1 in zip(parsed_sdfs, parsed_sdfs_check): sdf0 = sdfparse.emit(s0) assert sdf0 == s1
def generate_sdfs(timing_data, sdf_path): """ Builds and writes SDF files using the given timing data. """ def make_speed_model(data): """ Makes a speed model structure for the SDF writer """ model = dict() # Create entry for sdf writer iport = dict() iport['port'] = data["input"] iport['port_edge'] = None oport = dict() oport['port'] = data["output"] oport['port_edge'] = None paths = dict() paths = add_timing_paths_entry( paths, 'slow', [data['SLOW_MIN'], None, data['SLOW_MAX']]) paths = add_timing_paths_entry( paths, 'fast', [data['FAST_MIN'], None, data['FAST_MAX']]) # Net delay if data["is_net"]: model = utils.add_interconnect(iport, oport, paths) model["is_absolute"] = True # Routing bel delay else: model = utils.add_iopath(iport, oport, paths) model["is_absolute"] = True return model # Build SDF structures sdf_data = dict() for site_name, site_data in timing_data.items(): # New SDF if site_name not in sdf_data: sdf_data[site_name] = dict() sdf_data[site_name]["cells"] = dict() for cell_type, cell_data in site_data.items(): # New celltype if cell_type not in sdf_data[site_name]["cells"]: sdf_data[site_name]["cells"][cell_type] = dict() for instance, instance_data in cell_data.items(): # New cell instance if instance not in sdf_data[site_name]["cells"][cell_type]: sdf_data[site_name]["cells"][cell_type][instance] = dict() # Add speed models for speed_model, speed_data in instance_data.items(): sdf_data[site_name]["cells"][cell_type][instance][ speed_model] = make_speed_model(speed_data) # Emit SDFs for name, data in sdf_data.items(): fname = os.path.join(sdf_path, name.upper() + ".sdf") fdata = sdfparse.emit(data, timescale='1ns') with open(fname, "w") as fp: fp.write(fdata)
def generate_sdf(timings, sdffile): sdf_data = sdfparse.emit(timings, timescale='1ns') with open(sdffile, 'w') as fp: fp.write(sdf_data)
def test_emit(): for s in parsed_sdfs: generated_sdfs.append(sdfparse.emit(s))
def compute_delays(model, fin_name, fout_name): data = '' with open(fin_name, 'r') as f: data = f.read() sdf = sdfparse.parse(data) keys = sdf['cells'][model['type']].keys() if 'slicel'.upper() in keys: sl = 'L' elif 'slicem'.upper() in keys: sl = 'M' else: print("Unknown slice type!") return nsdf = dict() nsdf['header'] = sdf['header'] nsdf['cells'] = dict() nsdf['cells']['ROUTING_BEL'] = dict() for p in model['pins']: pin = model['pins'][p] outs = dict() for o in model['out']: outs[o] = [] res = [] cells = sdf['cells'] for src in model['srcs']: source = src.replace('?', pin['type']) _type = model['type'] + '_' + source if _type in cells.keys(): cell = cells[_type]["SLICE" + sl.upper()] for o in model['out']: iopath = 'iopath_' + p + '_' + o if iopath in cell.keys(): delay = cell[iopath]['delay_paths']['slow']['max'] outs[o].append(delay) for src in outs: s = sorted(outs[src]) for val in s: res.append(val - s[0]) delay = round(max(res), 3) muxname = str(model['mux'].replace('?', pin['type'])) rbel = nsdf['cells']['ROUTING_BEL']['SLICE' + sl.upper() + '/' + muxname] = dict() iname = 'interconnect_' + pin['type'].lower() + 'x_' + str(p).lower() rbel[iname] = dict() rbel[iname]['is_absolute'] = True rbel[iname]['to_pin_edge'] = None rbel[iname]['from_pin_edge'] = None rbel[iname]['from_pin'] = pin['type'].lower() + 'x' rbel[iname]['to_pin'] = str(p).lower() rbel[iname]['type'] = 'interconnect' rbel[iname]['is_timing_check'] = False rbel[iname]['is_timing_env'] = False paths = rbel[iname]['delay_paths'] = dict() paths['slow'] = dict() paths['slow']['min'] = delay paths['slow']['avg'] = None paths['slow']['max'] = delay paths['fast'] = dict() paths['fast']['min'] = delay paths['fast']['avg'] = None paths['fast']['max'] = delay # emit new sdfs with open(fout_name, 'w') as f: f.write(sdfparse.emit(nsdf))