def test_gen_netlist(): placement_verilog_d = { "global_signals": [], "modules": [{ "abstract_name": "top", "concrete_name": "top", "bbox": [0, 0, 100, 100], "parameters": [], "instances": [{ "abstract_template_name": "a", "concrete_template_name": "a", "instance_name": "u0", "transformation": { "oX": 0, "oY": 0, "sX": 1, "sY": 1 }, "fa_map": [{ "formal": "x", "actual": "y" }] }, { "abstract_template_name": "a", "concrete_template_name": "a", "instance_name": "u1", "transformation": { "oX": 0, "oY": 20, "sX": 1, "sY": 1 }, "fa_map": [{ "formal": "x", "actual": "y" }] }] }], "leaves": [{ "abstract_name": "a", "concrete_name": "a", "bbox": [0, 0, 10, 10], "terminals": [{ "name": "x", "rect": [4, 4, 6, 6] }] }] } nets_d = gen_netlist(placement_verilog_d, 'top') assert 24 == calculate_HPWL_from_placement_verilog_d( placement_verilog_d, 'top', nets_d)
def test_place_cmp_seed(seed): """ original comparator. Run this test with -v and -s""" name = f'ckt_{get_test_id()}' netlist = circuits.comparator(name) setup = textwrap.dedent(f"""\ POWER = vccx GND = vssx DONT_CONST = {name} """) constraints = [{ "constraint": "GroupBlocks", "instances": ["mn1", "mn2"], "name": "dp" }, { "constraint": "GroupBlocks", "instances": ["mn3", "mn4"], "name": "ccn" }, { "constraint": "GroupBlocks", "instances": ["mp5", "mp6"], "name": "ccp" }, { "constraint": "GroupBlocks", "instances": ["mn11", "mp13"], "name": "invp" }, { "constraint": "GroupBlocks", "instances": ["mn12", "mp14"], "name": "invn" }, { "constraint": "SameTemplate", "instances": ["mp7", "mp8"] }, { "constraint": "SameTemplate", "instances": ["mp9", "mp10"] }, { "constraint": "SameTemplate", "instances": ["invn", "invp"] }, { "constraint": "SymmetricBlocks", "direction": "V", "pairs": [["mn0"], ["dp"]] }, { "constraint": "SymmetricBlocks", "direction": "V", "pairs": [["ccp"], ["ccn"], ["invn", "invp"], ["mp9", "mp10"], ["mp7", "mp8"]] }, { "constraint": "Order", "direction": "top_to_bottom", "instances": ["mn0", "dp"] }, { "constraint": "AlignInOrder", "line": "bottom", "instances": ["dp", "ccn"] }, { "constraint": "MultiConnection", "nets": ["vcom"], "multiplier": 6 }, { "constraint": "AspectRatio", "subcircuit": name, "ratio_low": 0.01, "ratio_high": 100 }] example = build_example(name, netlist, setup, constraints) ckt_dir, run_dir = run_example(example, cleanup=cleanup, log_level='DEBUG', additional_args=[ '-e', '1', '--flow_stop', '3_pnr:route', '--router_mode', 'no_op', '--seed', str(seed) ]) cn = f'{name.upper()}_0' with (run_dir / '3_pnr' / 'Results' / f'{cn}.placement_verilog.json').open('rt') as fp: placement = json.load(fp) assert standalone_overlap_checker(placement, cn) nets = gen_netlist(placement, cn) hpwl_new = calculate_HPWL_from_placement_verilog_d(placement, cn, nets) x0, y0, x1, y1 = placement['modules'][0]['bbox'] area_new = (x1 - x0) * (y1 - y0) cn = 'CKT_PLACE_CMP_1_0' with (run_dir / '..' / f'_{cn}.placement_verilog.json').open('rt') as fp: placement = json.load(fp) assert standalone_overlap_checker(placement, cn) nets = gen_netlist(placement, cn) hpwl_best = calculate_HPWL_from_placement_verilog_d( placement, cn, nets) x0, y0, x1, y1 = placement['modules'][0]['bbox'] area_best = (x1 - x0) * (y1 - y0) hpwl_pct = round(100 * ((hpwl_new / hpwl_best) - 1)) area_pct = round(100 * ((area_new / area_best) - 1)) pct = (area_new * hpwl_new) / (area_best * hpwl_best) pct = round(100 * (pct - 1)) print( f'seed={seed} hpwl={hpwl_new} area={area_new} area*hpwl={area_new*hpwl_new} This placement is {hpwl_pct}% in hpwl, {area_pct}% in area, {pct}% in area*hpwl worse than the best known solution' ) plot_sa_cost(name.upper()) plot_sa_seq(name.upper())
def test_place_cmp_1(): """ original comparator. Run this test with -v and -s""" name = f'ckt_{get_test_id()}' netlist = circuits.comparator(name) setup = textwrap.dedent(f"""\ POWER = vccx GND = vssx DONT_CONST = {name} """) constraints = [{ "constraint": "GroupBlocks", "instances": ["mn1", "mn2"], "name": "dp" }, { "constraint": "GroupBlocks", "instances": ["mn3", "mn4"], "name": "ccn" }, { "constraint": "GroupBlocks", "instances": ["mp5", "mp6"], "name": "ccp" }, { "constraint": "GroupBlocks", "instances": ["mn11", "mp13"], "name": "invp" }, { "constraint": "GroupBlocks", "instances": ["mn12", "mp14"], "name": "invn" }, { "constraint": "SameTemplate", "instances": ["mp7", "mp8"] }, { "constraint": "SameTemplate", "instances": ["mp9", "mp10"] }, { "constraint": "SameTemplate", "instances": ["invn", "invp"] }, { "constraint": "SymmetricBlocks", "direction": "V", "pairs": [["mn0"], ["dp"]] }, { "constraint": "SymmetricBlocks", "direction": "V", "pairs": [["ccp"], ["ccn"], ["invn", "invp"], ["mp9", "mp10"], ["mp7", "mp8"]] }, { "constraint": "Order", "direction": "top_to_bottom", "instances": ["mn0", "dp"] }, { "constraint": "AlignInOrder", "line": "bottom", "instances": ["dp", "ccn"] }, { "constraint": "MultiConnection", "nets": ["vcom"], "multiplier": 6 }, { "constraint": "AspectRatio", "subcircuit": name, "ratio_low": 1, "ratio_high": 2 }] example = build_example(name, netlist, setup, constraints) ckt_dir, run_dir = run_example(example, cleanup=cleanup, log_level='DEBUG', additional_args=[ '-e', '4', '--flow_stop', '3_pnr:route', '--router_mode', 'no_op' ]) print(f'run_dir: {run_dir}') cn = f'{name.upper()}_0' with (run_dir / '3_pnr' / 'Results' / f'{cn}.placement_verilog.json').open('rt') as fp: placement = json.load(fp) assert standalone_overlap_checker(placement, cn) nets = gen_netlist(placement, cn) hpwl_new = calculate_HPWL_from_placement_verilog_d(placement, cn, nets) x0, y0, x1, y1 = placement['modules'][0]['bbox'] area_new = (x1 - x0) * (y1 - y0) print(f'hpwl_new={hpwl_new} area_new={area_new}') with (run_dir / '..' / f'_{cn}.placement_verilog.json').open('rt') as fp: placement = json.load(fp) assert standalone_overlap_checker(placement, cn) nets = gen_netlist(placement, cn) hpwl_best = calculate_HPWL_from_placement_verilog_d( placement, cn, nets) x0, y0, x1, y1 = placement['modules'][0]['bbox'] area_best = (x1 - x0) * (y1 - y0) print(f'hpwl_best={hpwl_best} area_best={area_best}') hpwl_pct = round(100 * ((hpwl_new / hpwl_best) - 1)) area_pct = round(100 * ((area_new / area_best) - 1)) print( f'Generated layout is {hpwl_pct}% worse in HPWL and {area_pct}% worse in AREA' ) if cleanup: shutil.rmtree(run_dir) shutil.rmtree(ckt_dir)
def test_place_cmp_2(): """ comparator with modified hierarchy """ name = f'ckt_{get_test_id()}' netlist = textwrap.dedent(f"""\ .subckt dptail clk vin vip vin_d vip_d vssx mn0 vcom clk vssx vssx n w=2.88e-6 m=1 nf=16 mn1 vin_d vin vcom vssx n w=360e-9 m=18 nf=2 mn2 vip_d vip vcom vssx n w=360e-9 m=18 nf=2 .ends dptail .subckt {name} clk vccx vin vip von vop vssx x0 clk vin vip vin_d vip_d vssx dptail mn3 vin_o vip_o vin_d vssx n w=360e-9 m=8 nf=2 mn4 vip_o vin_o vip_d vssx n w=360e-9 m=8 nf=2 mp5 vin_o vip_o vccx vccx p w=360e-9 m=6 nf=2 mp6 vip_o vin_o vccx vccx p w=360e-9 m=6 nf=2 mp7 vin_d clk vccx vccx p w=360e-9 m=1 nf=2 mp8 vip_d clk vccx vccx p w=360e-9 m=1 nf=2 mp9 vin_o clk vccx vccx p w=360e-9 m=2 nf=2 mp10 vip_o clk vccx vccx p w=360e-9 m=2 nf=2 mn11 von vin_o vssx vssx n w=360e-9 m=1 nf=2 mn12 vop vip_o vssx vssx n w=360e-9 m=1 nf=2 mp13 von vin_o vccx vccx p w=360e-9 m=1 nf=2 mp14 vop vip_o vccx vccx p w=360e-9 m=1 nf=2 .ends {name} """) setup = textwrap.dedent(f"""\ POWER = vccx GND = vssx DONT_CONST = {name} """) constraints = [{ "constraint": "GroupBlocks", "instances": ["mn3", "mn4"], "name": "ccn" }, { "constraint": "GroupBlocks", "instances": ["mp5", "mp6"], "name": "ccp" }, { "constraint": "GroupBlocks", "instances": ["mn11", "mp13"], "name": "invp" }, { "constraint": "GroupBlocks", "instances": ["mn12", "mp14"], "name": "invn" }, { "constraint": "SameTemplate", "instances": ["mp7", "mp8"] }, { "constraint": "SameTemplate", "instances": ["mp9", "mp10"] }, { "constraint": "SameTemplate", "instances": ["invn", "invp"] }, { "constraint": "SymmetricBlocks", "direction": "V", "pairs": [["ccp"], ["ccn"], ["invn", "invp"], ["mp9", "mp10"], ["mp7", "mp8"]] }, { "constraint": "AlignInOrder", "line": "bottom", "instances": ["x0", "ccn"] }, { "constraint": "AspectRatio", "subcircuit": name, "ratio_low": 1, "ratio_high": 2 }] example = build_example(name, netlist, setup, constraints) # TODO: Separate below to a separate PR to debug: Constraints for the subhierarchy not respected.. # setup = textwrap.dedent("""\ # GND = vssx # DONT_CONST = dptail # """) # with open(example / 'dptail.setup', 'w') as fp: # fp.write(setup) # constraints = [ # {"constraint": "GroupBlocks", "instances": ["mn1", "mn2"], "name": "dp"}, # {"constraint": "SymmetricBlocks", "direction": "V", "pairs": [["mn0"], ["dp"]]}, # {"constraint": "Order", "direction": "top_to_bottom", "instances": ["mn0", "dp"]} # ] # with open(example / 'dptail.const.json', 'w') as fp: # fp.write(json.dumps(constraints, indent=2)) ckt_dir, run_dir = run_example(example, cleanup=cleanup, area=4e10) cn = f'{name.upper()}_0' with (run_dir / '3_pnr' / 'Results' / f'{cn}.placement_verilog.json').open('rt') as fp: placement = json.load(fp) assert standalone_overlap_checker(placement, cn) nets = gen_netlist(placement, cn) hpwl_new = calculate_HPWL_from_placement_verilog_d(placement, cn, nets) x0, y0, x1, y1 = placement['modules'][0]['bbox'] area_new = (x1 - x0) * (y1 - y0) print(f'hpwl_new={hpwl_new} area_new={area_new}') if cleanup: shutil.rmtree(run_dir) shutil.rmtree(ckt_dir)
def test_gen_netlist_matrix(): txt = """{ "global_signals": [], "leaves": [ { "abstract_name": "slice", "bbox": [ 0, 0, 800, 840 ], "concrete_name": "slice_a", "terminal_centers": [ { "center": [ 400, 168 ], "name": "inp" }, { "center": [ 400, 672 ], "name": "out" } ], "terminals": [ { "name": "inp", "rect": [ 124, 152, 676, 184 ] }, { "name": "out", "rect": [ 124, 656, 676, 688 ] } ] } ], "modules": [ { "abstract_name": "matrix", "bbox": [ 0, 0, 2480, 3528 ], "concrete_name": "matrix_0", "constraints": [ { "abut": false, "constraint": "order", "direction": "top_to_bottom", "instances": [ "u0", "u1", "u2", "u3" ] }, { "constraint": "same_template", "instances": [ "u0", "u1", "u2", "u3" ] } ], "instances": [ { "abstract_template_name": "row", "concrete_template_name": "row_0", "fa_map": [ { "actual": "inp", "formal": "inp" }, { "actual": "x1", "formal": "out" } ], "instance_name": "u0", "transformation": { "oX": 0, "oY": 2688, "sX": 1, "sY": 1 } }, { "abstract_template_name": "row", "concrete_template_name": "row_0", "fa_map": [ { "actual": "x1", "formal": "inp" }, { "actual": "x2", "formal": "out" } ], "instance_name": "u1", "transformation": { "oX": 0, "oY": 1764, "sX": 1, "sY": 1 } }, { "abstract_template_name": "row", "concrete_template_name": "row_0", "fa_map": [ { "actual": "x2", "formal": "inp" }, { "actual": "x3", "formal": "out" } ], "instance_name": "u2", "transformation": { "oX": 0, "oY": 924, "sX": 1, "sY": 1 } }, { "abstract_template_name": "row", "concrete_template_name": "row_0", "fa_map": [ { "actual": "x3", "formal": "inp" }, { "actual": "out", "formal": "out" } ], "instance_name": "u3", "transformation": { "oX": 0, "oY": 0, "sX": 1, "sY": 1 } } ], "parameters": [ "inp", "out" ] }, { "abstract_name": "row", "bbox": [ 0, 0, 2480, 840 ], "concrete_name": "row_0", "constraints": [ { "abut": false, "constraint": "order", "direction": "left_to_right", "instances": [ "u0", "u1", "u2" ] }, { "constraint": "same_template", "instances": [ "u0", "u1", "u2" ] } ], "instances": [ { "abstract_template_name": "slice", "concrete_template_name": "slice_a", "fa_map": [ { "actual": "inp", "formal": "inp" }, { "actual": "x1", "formal": "out" } ], "instance_name": "u0", "transformation": { "oX": 0, "oY": 0, "sX": 1, "sY": 1 } }, { "abstract_template_name": "slice", "concrete_template_name": "slice_a", "fa_map": [ { "actual": "x1", "formal": "inp" }, { "actual": "x2", "formal": "out" } ], "instance_name": "u1", "transformation": { "oX": 880, "oY": 0, "sX": 1, "sY": 1 } }, { "abstract_template_name": "slice", "concrete_template_name": "slice_a", "fa_map": [ { "actual": "x2", "formal": "inp" }, { "actual": "out", "formal": "out" } ], "instance_name": "u2", "transformation": { "oX": 1680, "oY": 0, "sX": 1, "sY": 1 } } ], "parameters": [ "inp", "out" ] } ] } """ placement_verilog_d = json.loads(txt) cn = 'matrix_0' nets_d = gen_netlist(placement_verilog_d, cn) assert 27584 == calculate_HPWL_from_placement_verilog_d( placement_verilog_d, cn, nets_d) placement_verilog_d['modules'][1]['instances'][1]['transformation'][ "oY"] += 840 placement_verilog_d['modules'][1]['instances'][1]['transformation'][ "sY"] = -1 assert standalone_overlap_checker(placement_verilog_d, cn) hpwl = calculate_HPWL_from_placement_verilog_d(placement_verilog_d, cn, nets_d) print(hpwl) assert 27584 > hpwl placement_verilog_d['modules'][0]['instances'][1]['transformation'][ "oX"] += 2480 placement_verilog_d['modules'][0]['instances'][1]['transformation'][ "sX"] = -1 assert standalone_overlap_checker(placement_verilog_d, cn) hpwl2 = calculate_HPWL_from_placement_verilog_d(placement_verilog_d, cn, nets_d) print(hpwl2) assert hpwl > hpwl2 placement_verilog_d['modules'][0]['instances'][3]['transformation'][ "oX"] += 2480 placement_verilog_d['modules'][0]['instances'][3]['transformation'][ "sX"] = -1 assert standalone_overlap_checker(placement_verilog_d, cn) hpwl3 = calculate_HPWL_from_placement_verilog_d(placement_verilog_d, cn, nets_d) print(hpwl3) assert hpwl2 > hpwl3 placement_verilog_d['modules'][0]['instances'][0]['transformation'][ "oY"] += 840 placement_verilog_d['modules'][0]['instances'][0]['transformation'][ "sY"] = -1 placement_verilog_d['modules'][0]['instances'][1]['transformation'][ "oY"] += 840 placement_verilog_d['modules'][0]['instances'][1]['transformation'][ "sY"] = -1 placement_verilog_d['modules'][0]['instances'][2]['transformation'][ "oY"] += 840 placement_verilog_d['modules'][0]['instances'][2]['transformation'][ "sY"] = -1 placement_verilog_d['modules'][0]['instances'][3]['transformation'][ "oY"] += 840 placement_verilog_d['modules'][0]['instances'][3]['transformation'][ "sY"] = -1 assert standalone_overlap_checker(placement_verilog_d, cn) hpwl4 = calculate_HPWL_from_placement_verilog_d(placement_verilog_d, cn, nets_d) print(hpwl4) assert hpwl3 > hpwl4 placement_verilog_d['modules'][1]['instances'][1]['transformation'][ "oX"] -= 80 placement_verilog_d['modules'][1]['instances'][2]['transformation'][ "oX"] -= 80 assert standalone_overlap_checker(placement_verilog_d, cn) hpwl5 = calculate_HPWL_from_placement_verilog_d(placement_verilog_d, cn, nets_d) print(hpwl5) assert hpwl4 > hpwl5 placement_verilog_d['modules'][0]['instances'][0]['transformation'][ "oY"] -= 2 * 84 placement_verilog_d['modules'][0]['instances'][1]['transformation'][ "oY"] -= 84 placement_verilog_d['modules'][0]['instances'][2]['transformation'][ "oY"] -= 84 placement_verilog_d['modules'][0]['instances'][1]['transformation'][ "oX"] -= 80 placement_verilog_d['modules'][0]['instances'][3]['transformation'][ "oX"] -= 80 assert standalone_overlap_checker(placement_verilog_d, cn) hpwl6 = calculate_HPWL_from_placement_verilog_d(placement_verilog_d, cn, nets_d) print(hpwl6) assert hpwl5 > hpwl6 print(hpwl6 / 27584 - 1)