def main(): cunit_width = 16 cunit_height = 16 nx_cap = 12 ny_cap = 12 ctle_width = 192 ctle_height = 192 place = {} place['nm'] = "lane" place['bbox'] = [0, 0, ctle_width, ctle_height] place['leaves'] = [] assert place['bbox'][2] == cunit_width * nx_cap assert place['bbox'][3] == cunit_height * ny_cap place['leaves'].append({ "template_name": "cunit", "bbox": [0, 0, cunit_width, cunit_height], "terminals": [{ "net_name": "tp", "layer": "metal3", "rect": [1, 1, 1, cunit_height - 1] }, { "net_name": "tn", "layer": "metal3", "rect": [2, 1, 2, cunit_height - 1] }] }) place['instances'] = [] for ix in range(nx_cap): for iy in range(ny_cap): i_nm = "icap_%d_%d" % (ix, iy) ox = ix * cunit_width sx = 1 if ix < nx_cap // 2: ox += cunit_width sx = -1 place['instances'].append({ "instance_name": i_nm, "template_name": "cunit", "transformation": { "oX": ox, "oY": iy * cunit_height, "sX": sx, "sY": 1 }, "formal_actual_map": {} }) route = load("ctle_global_router_out.json") dump("ctle_placer_out_scaled.json", place)
def main(): nx_input_cap = 4 ny_input_cap = 8 place = {} place['nm'] = "diff" place['bbox'] = [0, 0, 0, 0] place['leaves'] = [] cunit_width = 16 cunit_height = 16 place['bbox'][2] = nx_input_cap * cunit_width place['bbox'][3] += cunit_height * ny_input_cap place['leaves'].append({ "template_name": "cunit", "bbox": [0, 0, cunit_width, cunit_height], "terminals": [{ "net_name": "tp", "layer": "metal3", "rect": [1, 1, 1, cunit_height - 1] }, { "net_name": "tn", "layer": "metal3", "rect": [2, 1, 2, cunit_height - 1] }] }) place['ports'] = [{ "net_name": "ina", "layer": "metal3", "rect": [1, 5 * cunit_height + 1, 1, 6 * cunit_height - 1] }, { "net_name": "inb", "layer": "metal3", "rect": [2, 5 * cunit_height + 1, 2, 6 * cunit_height - 1] }, { "net_name": "outa", "layer": "metal5", "rect": [31, 7 * cunit_height + 1, 31, 8 * cunit_height - 1] }, { "net_name": "outb", "layer": "metal5", "rect": [33, 7 * cunit_height + 1, 33, 8 * cunit_height - 1] }] place['instances'] = [] for ix in range(nx_input_cap): for iy in range(ny_input_cap): i_nm = "icap_%d_%d" % (ix, iy) ox = ix * cunit_width sx = 1 if ix < nx_input_cap // 2: ox += cunit_width sx = -1 place['instances'].append({ "instance_name": i_nm, "template_name": "cunit", "transformation": { "oX": ox, "oY": iy * cunit_height, "sX": sx, "sY": 1 }, "formal_actual_map": {} }) route = load("diff_global_router_out.json") dump("diff_placer_out_scaled.json", place)
def main(): lane_interface = load("lane_interface.json")['leaves'][0] n_lanes = 4 lane_width = lane_interface['bbox'][2] lane_height = lane_interface['bbox'][3] place = {} place['nm'] = "top" place['bbox'] = [0, 0, n_lanes * lane_width, lane_height] place['leaves'] = [lane_interface] place['instances'] = [] route = {"wires": []} for i in range(n_lanes): i_nm = "lane_%d" % i fa_map = { "sda_outa": "lane_%d_sda_outa" % i, "sda_outb": "lane_%d_sda_outb" % i } if i < n_lanes - 1: fa_map["diff_r_ina"] = "lane_%d_sda_outa" % (i + 1) fa_map["diff_r_inb"] = "lane_%d_sda_outb" % (i + 1) if i > 0: fa_map["diff_l_ina"] = "lane_%d_sda_outa" % (i - 1) fa_map["diff_l_inb"] = "lane_%d_sda_outb" % (i - 1) place['instances'].append({ "instance_name": i_nm, "template_name": "lane", "transformation": { "oX": lane_width * i, "oY": 0, "sX": 1, "sY": 1 }, "formal_actual_map": fa_map }) ry = 22 rx0 = (i * lane_width + lane_width // 2) // 4 rx1 = (i * lane_width + lane_width // 2) // 4 if i < n_lanes - 1: rx1 += 25 #lane_width // 8 ish else: rx1 += 2 if i > 0: rx0 -= 25 #lane_width // 8 ish else: rx0 -= 2 for net in ["outa", "outb"]: net_nm = "lane_%d_sda_%s" % (i, net) route['wires'].append({ "net_name": net_nm, "layer": "metal4", "width": 400, "rect": [rx0, ry, rx1, ry] }) dump("top_placer_out_scaled.json", place) dump("top_global_router_out.json", route)
def main(): s_place = load("stack_placer_out_scaled.json") s_route = load("stack_global_router_out.json") c_place = deepcopy(s_place) c_route = deepcopy(s_route) dp1x_interface = load("dp1x_interface.json")['leaves'][0] dp2x_interface = load("dp2x_interface.json")['leaves'][0] dp4x_interface = load("dp4x_interface.json")['leaves'][0] mirrors_interface = load("mirrors_interface.json")['leaves'][0] new_leaves = [ dp1x_interface, dp2x_interface, dp4x_interface, mirrors_interface ] c_place['nm'] = "wcap" c_place['leaves'] = new_leaves cunit_width = 16 cunit_height = 16 n_side_cols = 1 c_place['leaves'].append({ "template_name": "cunit", "bbox": [0, 0, cunit_width, cunit_height], "terminals": [{ "net_name": "tp", "layer": "metal3", "rect": [1, 1, 1, cunit_height - 1] }, { "net_name": "tn", "layer": "metal3", "rect": [2, 1, 2, cunit_height - 1] }] }) stack_x_offset = cunit_width * n_side_cols # bump bounding box: one col on both sides c_place['bbox'][2] += 2 * stack_x_offset metal2_kors = [] b = c_place['bbox'] print(b) for y in range(b[1] + 1, b[3]): x0 = b[0] + 1 x1 = b[2] - 1 metal2_kors.append({ 'net_name': '!kor', 'layer': 'metal2', 'rect': [x0, y, x1, y] }) # # Disable for now # # c_place['ports'] = metal2_kors c_place['ports'] = [] # shift stack for inst in c_place['instances']: inst['transformation']['oX'] += stack_x_offset y_offset = 8 + 16 def tup(ix, iy, side): assert side in ['l', 'r'], side idx = ix + iy i_nm = "cpl_%s_%d_%d" % (side, ix, iy) if side == 'r': idx = n_side_cols * 4 - 1 - idx # Make common centroid # bp 3 an 3 # ap 2 bn 2 # bn 1 ap 1 # an 0 bp 0 suffix = "_n" if idx % 4 in [0, 1] else "_p" if idx % 2 == 0: return (i_nm, "outa", "cpla" + suffix) else: return (i_nm, "outb", "cplb" + suffix) for (ix, iy) in ((x, y) for y in range(4) for x in range(n_side_cols)): (i_nm, tp, tn) = tup(ix, iy, 'l') c_place['instances'].append({ "instance_name": i_nm, "template_name": "cunit", "transformation": { "oX": cunit_width + ix * cunit_width, "oY": y_offset + iy * cunit_height, "sX": -1, "sY": 1 }, "formal_actual_map": { "tp": tp, "tn": tn } }) (i_nm, tp, tn) = tup(ix, iy, 'r') c_place['instances'].append({ "instance_name": i_nm, "template_name": "cunit", "transformation": { "oX": cunit_width * n_side_cols + s_place['bbox'][2] + ix * cunit_width, "oY": y_offset + iy * cunit_height, "sX": 1, "sY": 1 }, "formal_actual_map": { "tp": tp, "tn": tn } }) # routing grid is 4 placement pitches (poly pitches) assert cunit_width % 4 == 0 shift = (n_side_cols * cunit_width) // 4 for wire in c_route['wires']: wire['rect'][0] += shift wire['rect'][2] += shift tbin = (c_place['bbox'][3] - 1) // 4 xs = [4 * i + 3 for i in range(n_side_cols)] if xs: pair_sum = 2 * xs[-1] + 8 + 1 xs = xs + list(pair_sum - i for i in reversed(xs)) print("xs:", xs) for net in ["cpla_p", "cplb_p", "cpla_n", "cplb_n"]: for x in xs: c_route['wires'].append({ "layer": "metal5", "net_name": net, "width": 400, "rect": [x, 8, x, tbin] }) if xs: c_route['wires'].append({ "layer": "metal4", "net_name": net, "width": 400, "rect": [xs[0], tbin, xs[-1], tbin] }) # extend the metal4 and metal5 grs on "outa" and "outb" for wire in c_route['wires']: if wire['net_name'] in ["outa", "outb"]: if wire['layer'] == "metal4": if xs: wire['rect'][0] -= 4 * n_side_cols - 2 wire['rect'][2] += 4 * n_side_cols - 2 + 1 dump("wcap_placer_out_scaled.json", c_place) dump("wcap_global_router_out.json", c_route)
def main(): wcap_interface = load("wcap_interface.json")['leaves'][0] comp_interface = load("comp_interface.json")['leaves'][0] diff_interface = load("diff_interface.json")['leaves'][0] comp_and_diff_width = 64 comp_and_diff_height = 128 assert comp_interface['bbox'][2] == comp_and_diff_width assert diff_interface['bbox'][2] == comp_and_diff_width assert comp_interface['bbox'][3] == comp_and_diff_height assert diff_interface['bbox'][3] == comp_and_diff_height wcap_width = wcap_interface['bbox'][2] wcap_height = wcap_interface['bbox'][3] place = {} place['nm'] = "lane" place['bbox'] = [0, 0, 3 * wcap_width, wcap_height] place['leaves'] = [wcap_interface, comp_interface, diff_interface] assert place['bbox'][2] == 192 assert place['bbox'][3] == 88 place['bbox'][3] += comp_and_diff_height ctle_interface = load("ctle_interface.json")['leaves'][0] ctle_width = ctle_interface['bbox'][2] ctle_height = ctle_interface['bbox'][3] place['leaves'].append(ctle_interface) place['bbox'][3] += ctle_height adder_width = 64 adder_height = 32 place['bbox'][3] += adder_height pin_height = adder_height // 2 ts = [] fa_map = {} for p in [("l", 16), ("m", 32), ("r", 48)]: for ty in [("n", 0), ("p", 1)]: for net in [("ina", -1), ("inb", 1)]: net_name = "%s_%s_%s" % (p[0], ty[0], net[0]) x = p[1] + net[1] y0 = ty[1] * pin_height + 1 y1 = ty[1] * pin_height + pin_height - 1 ts.append({ "net_name": net_name, "layer": "metal3", "rect": [x, y0, x, y1] }) fa_map[net_name] = net_name adder_interface = { "template_name": "adder", "bbox": [0, 0, adder_width, adder_height], "terminals": ts } place['leaves'].append(adder_interface) place['instances'] = [] place['instances'].append({ "instance_name": "adder", "template_name": "adder", "transformation": { "oX": 64, "oY": comp_and_diff_height + wcap_height, "sX": 1, "sY": 1 }, "formal_actual_map": fa_map }) place['instances'].append({ "instance_name": "ctle", "template_name": "ctle", "transformation": { "oX": 0, "oY": comp_and_diff_height + wcap_height + adder_height, "sX": 1, "sY": 1 }, "formal_actual_map": {} }) pairs = [("l", 0), ("m", 64), ("r", 128)] for p in pairs: ox = p[1] sx = 1 if p[0] == "r": ox += comp_and_diff_width sx = -1 wcap_fa_map = {} for ty in ["p", "n"]: for net in ["a", "b"]: actual_name = "%s_%s_in%s" % (p[0], ty, net) formal_name = "cpl%s_%s" % (net, ty) wcap_fa_map[formal_name] = actual_name if p[0] == "m": wcap_fa_map["ina"] = "comp_outa" wcap_fa_map["inb"] = "comp_outb" else: wcap_fa_map["ina"] = "diff_%s_outa" % p[0] wcap_fa_map["inb"] = "diff_%s_outb" % p[0] place['instances'].append({ "instance_name": "wcap_%s" % p[0], "template_name": "wcap", "transformation": { "oX": ox, "oY": comp_and_diff_height, "sX": sx, "sY": 1 }, "formal_actual_map": wcap_fa_map }) t_nm = "comp" if p[0] in "m" else "diff" i_nm = "%s_%s" % (t_nm, p[0]) if t_nm == "comp": fa_map = { "sda_outa": "sda_outa", "sda_outb": "sda_outb", "outa": "comp_outa", "outb": "comp_outb" } else: fa_map = { "ina": "diff_%s_ina" % p[0], "inb": "diff_%s_inb" % p[0], "outa": "diff_%s_outa" % p[0], "outb": "diff_%s_outb" % p[0] } place['instances'].append({ "instance_name": i_nm, "template_name": t_nm, "transformation": { "oX": ox, "oY": 0, "sX": sx, "sY": 1 }, "formal_actual_map": fa_map }) def gen_terminal_tbl(interface): tbl = {} for p in interface['terminals']: layer = p['layer'] net_name = p['net_name'] if layer not in tbl: tbl[layer] = {} if net_name not in tbl[layer]: tbl[layer][net_name] = [] tbl[layer][net_name].append(p) return tbl wcap_terminal_tbl = gen_terminal_tbl(wcap_interface) adder_terminal_tbl = gen_terminal_tbl(adder_interface) print(adder_terminal_tbl) def find_routing_grids_covering_terminal(tbl, nm, layer): result = [] for p in tbl[layer][nm]: xs = [x // 4 for x in p['rect']] result.append(xs) return result route = {"wires": []} gr_y_offset = (16 * 8) // 4 for p in [("l", 0), ("m", 1), ("r", 2)]: for ty in [("n", 0), ("p", 1)]: for net in ["a", "b"]: cpl_nm = "cpl%s_%s" % (net, ty[0]) m5_rects = find_routing_grids_covering_terminal( wcap_terminal_tbl, cpl_nm, "metal5") assert len(m5_rects) == 2 xs = [r[0] for r in m5_rects] print(p, ty, net, m5_rects, xs) net_name = "%s_%s_in%s" % (p[0], ty[0], net) m3_rects = find_routing_grids_covering_terminal( adder_terminal_tbl, net_name, "metal3") print(net_name, m3_rects) assert len(m3_rects) y0 = gr_y_offset + m5_rects[0][3] y1 = gr_y_offset + 88 // 4 + (m3_rects[0][1] + m3_rects[0][3]) // 2 ox = p[1] * 64 // 4 print(ox, xs) for x in xs: assert 0 <= ox + x < 192 // 4, (ox, x, ox + x) route['wires'].append({ "layer": "metal5", "net_name": net_name, "width": 400, "rect": [ox + x, y0, ox + x, y1] }) other_x = m3_rects[0][0] + 64 // 4 assert 0 <= other_x < 192 // 4, other_x all_xs = [ox + x for x in xs] + [other_x] route['wires'].append({ "layer": "metal4", "net_name": net_name, "width": 400, "rect": [min(all_xs), y1, max(all_xs), y1] }) dump("lane_placer_out_scaled.json", place) dump("lane_global_router_out.json", route)