diff --git a/himbaechel/uarch/gatemate/delay.cc b/himbaechel/uarch/gatemate/delay.cc index 6b57f1d8..d6ce7275 100644 --- a/himbaechel/uarch/gatemate/delay.cc +++ b/himbaechel/uarch/gatemate/delay.cc @@ -157,6 +157,10 @@ bool GateMateImpl::getCellDelay(const CellInfo *cell, IdString fromPort, IdStrin return get_delay_from_tmg_db(ctx->idf("timing_glbout_%s_%s", fromPort.c_str(ctx), toPort.c_str(ctx)), delay); } else if (cell->type.in(id_RAM, id_RAM_HALF)) { return false; + } else if (cell->type.in(id_PLL)) { + if (fromPort.in(id_CLK_REF, id_USR_CLK_REF) && toPort.in(id_CLK0, id_CLK90, id_CLK180, id_CLK270)) + return get_delay_from_tmg_db(ctx->id("timing_pll_clk_ref_i_clk_core0_o"), delay); + return false; } return false; } diff --git a/himbaechel/uarch/gatemate/gen/arch_gen.py b/himbaechel/uarch/gatemate/gen/arch_gen.py index fc73585d..e4f1bbc5 100644 --- a/himbaechel/uarch/gatemate/gen/arch_gen.py +++ b/himbaechel/uarch/gatemate/gen/arch_gen.py @@ -44,7 +44,6 @@ import chip import die pip_tmg_names = set() -node_tmg_names = set() @dataclass class TileExtraData(BBAStruct): @@ -187,14 +186,11 @@ def set_timings(ch): continue name = "timing_" + re.sub(r"[-= >]", "_", rename_table.get(name, name)) tmg.get_speed_grade(speed).extra_data.add_timing(name=ch.strs.id(name), delay=convert_timing(val)) - #for k in node_tmg_names: - # assert k in timing, f"node class {k} not found in timing data" - # tmg.set_node_class(grade=speed, name=k, delay=convert_timing(timing[k])) - #for k in pip_tmg_names: - # assert k in timing, f"pip class {k} not found in timing data" - # tmg.set_pip_class(grade=speed, name=k, delay=convert_timing(timing[k])) + for k in pip_tmg_names: + assert k in timing, f"pip class {k} not found in timing data" + tmg.set_pip_class(grade=speed, name=k, delay=convert_timing(timing[k])) -EXPECTED_VERSION = 1.7 +EXPECTED_VERSION = 1.8 def main(): # Range needs to be +1, but we are adding +2 more to coordinates, since @@ -226,12 +222,29 @@ def main(): print("==============================================================================") os._exit(-1) + new_wires = dict() + wire_delay = dict() + for _,nodes in dev.get_connections(): + for conn in nodes: + if conn.endpoint: + t_name = dev.get_tile_type(conn.x,conn.y) + if t_name not in new_wires: + new_wires[t_name] = set() + new_wires[t_name].add(conn.name) + # Check to confirm no duplicates + if conn.name in wire_delay: + assert wire_delay[conn.name] == conn.delay, f"conflict delay {conn.name}" + wire_delay[conn.name] = conn.delay + for type_name in sorted(die.get_tile_type_list()): tt = ch.create_tile_type(type_name) for group in sorted(die.get_groups_for_type(type_name)): tt.create_group(group.name, group.type) for wire in sorted(die.get_endpoints_for_type(type_name)): tt.create_wire(wire.name, wire.type) + if type_name in new_wires: + for wire in sorted(new_wires[type_name]): + tt.create_wire(wire+"_n", "NODE_WIRE") for prim in sorted(die.get_primitives_for_type(type_name)): bel = tt.create_bel(prim.name, prim.type, prim.z) if (prim.name in ["CPE_LT_FULL", "CPE_BRIDGE"]): @@ -260,6 +273,20 @@ def main(): if mux.name == "CPE.C_SN": mux_flags |= MUX_ROUTING pp.extra_data = PipExtraData(PIP_EXTRA_MUX, ch.strs.id(mux.name), mux.bits, mux.value, mux_flags, plane) + if type_name in new_wires: + for wire in sorted(new_wires[type_name]): + delay = wire_delay[wire] + if len(delay)>0: + pip_tmg_names.add(delay) + pp = tt.create_pip(wire+"_n", wire, delay) + plane = 0 + if wire.startswith("IM"): + plane = int(wire[4:6]) + if wire.startswith("SB_SML") or wire.startswith("SB_BIG"): + plane = int(wire[8:10]) + if wire.startswith("SB_DRIVE"): + plane = int(wire[10:12]) + pp.extra_data = PipExtraData(PIP_EXTRA_MUX, ch.strs.id(""), 0, 0, 0, plane) # Setup tile grid for x in range(dev.max_col() + 3): @@ -271,14 +298,9 @@ def main(): # Create nodes between tiles for _,nodes in dev.get_connections(): node = [] - timing = "" for conn in sorted(nodes): - node.append(NodeWire(conn.x + 2, conn.y + 2, conn.name)) - # for now update to last one we have defined - if len(conn.delay)>0: - timing = conn.delay - node_tmg_names.add(conn.delay) - ch.add_node(node, timing) + node.append(NodeWire(conn.x + 2, conn.y + 2, (conn.name + "_n") if conn.endpoint else conn.name)) + ch.add_node(node) set_timings(ch) for package in dev.get_packages(): diff --git a/himbaechel/uarch/gatemate/pack_clocking.cc b/himbaechel/uarch/gatemate/pack_clocking.cc index 1639c835..dbe5f364 100644 --- a/himbaechel/uarch/gatemate/pack_clocking.cc +++ b/himbaechel/uarch/gatemate/pack_clocking.cc @@ -303,7 +303,7 @@ void GateMatePacker::remove_clocking() flush_cells(); } -static const char *fpga_mode_to_str(int mode) +static const char *timing_mode_to_str(int mode) { switch (mode) { case 1: @@ -444,9 +444,9 @@ void GateMatePacker::pack_pll() log_error("Unknown PERF_MD parameter value '%s' for cell %s.\n", mode.c_str(), ci.name.c_str(ctx)); } - if (perf_md != uarch->fpga_mode) - log_warning("PLL '%s' mode is '%s' but FPGA mode is '%s'.\n", ci.name.c_str(ctx), - fpga_mode_to_str(perf_md), fpga_mode_to_str(uarch->fpga_mode)); + if (perf_md != uarch->timing_mode) + log_warning("PLL '%s' timing mode is '%s' but FPGA timing mode is '%s'.\n", ci.name.c_str(ctx), + timing_mode_to_str(perf_md), timing_mode_to_str(uarch->timing_mode)); double ref_clk = double_or_default(ci.params, id_REF_CLK, 0.0); if (ref_clk <= 0 || ref_clk > 125) diff --git a/himbaechel/uarch/gatemate/route_clock.cc b/himbaechel/uarch/gatemate/route_clock.cc index 12ec6ce3..fd680cf5 100644 --- a/himbaechel/uarch/gatemate/route_clock.cc +++ b/himbaechel/uarch/gatemate/route_clock.cc @@ -33,10 +33,10 @@ namespace { struct QueuedWire { - explicit QueuedWire(WireId wire, float delay = 0.0) : wire{wire}, delay{delay} {}; + explicit QueuedWire(WireId wire, delay_t delay = 0) : wire{wire}, delay{delay} {}; WireId wire; - float delay; + delay_t delay; bool operator>(const QueuedWire &rhs) const { return this->delay > rhs.delay; } }; @@ -45,6 +45,9 @@ struct QueuedWire void GateMateImpl::route_clock() { + log_info("Routing clock nets...\n"); + auto rstart = std::chrono::high_resolution_clock::now(); + auto clk_nets = std::vector{}; auto reserved_wires = dict{}; @@ -64,6 +67,10 @@ void GateMateImpl::route_clock() }; auto reserve = [&](WireId wire, NetInfo *net) { + for (auto pip : ctx->getPipsUphill(wire)) { + wire = ctx->getPipSrcWire(pip); + break; + } if (ctx->debug) { auto wire_name = "(uninitialized)"; if (wire != WireId()) @@ -73,8 +80,6 @@ void GateMateImpl::route_clock() reserved_wires.insert({wire, net->name}); }; - log_info("Routing clock nets...\n"); - for (auto &net_pair : ctx->nets) { NetInfo *net = net_pair.second.get(); if (!net->driver.cell) @@ -107,37 +112,72 @@ void GateMateImpl::route_clock() } for (auto clk_net : clk_nets) { - log_info(" routing net '%s'\n", clk_net->name.c_str(ctx)); - ctx->bindWire(ctx->getNetinfoSourceWire(clk_net), clk_net, STRENGTH_LOCKED); - - auto clk_plane = 0; - switch (clk_net->driver.port.index) { - case id_GLB0.index: - clk_plane = 9; - break; - case id_GLB1.index: - clk_plane = 10; - break; - case id_GLB2.index: - clk_plane = 11; - break; - case id_GLB3.index: - clk_plane = 12; - break; - } + log_info(" routing net '%s' to %d users\n", clk_net->name.c_str(ctx), clk_net->users.entries()); + auto src_wire = ctx->getNetinfoSourceWire(clk_net); + ctx->bindWire(src_wire, clk_net, STRENGTH_LOCKED); + auto sink_wires = dict{}; + auto sink_wires_to_do = pool{}; for (auto &usr : clk_net->users) { - std::priority_queue, std::greater> visit; - dict backtrace; - WireId dest = WireId(); - if (!feeds_clk_port(usr) && !feeds_ddr_port(clk_net, usr)) continue; - auto cpe_loc = ctx->getBelLocation(usr.cell->bel); - auto is_glb_clk = clk_net->driver.cell->type == id_GLBOUT; - auto sink_wire = ctx->getNetinfoSinkWire(clk_net, usr, 0); + + sink_wires.insert({sink_wire, usr}); + sink_wires_to_do.insert(sink_wire); + } + + std::priority_queue, std::greater> visit; + dict backtrace; + dict delay_map; + + auto is_glb_clk = clk_net->driver.cell->type == id_GLBOUT; + + visit.push(QueuedWire(src_wire)); + while (!visit.empty()) { + QueuedWire curr = visit.top(); + visit.pop(); + if (sink_wires_to_do.count(curr.wire)) { + if (ctx->debug) { + auto sink_wire_name = "(uninitialized)"; + if (curr.wire != WireId()) + sink_wire_name = ctx->nameOfWire(curr.wire); + log_info(" -> %s (%.3fns)\n", sink_wire_name, ctx->getDelayNS(curr.delay)); + } + sink_wires_to_do.erase(curr.wire); + if (sink_wires_to_do.empty()) + break; + } + + for (auto dh : ctx->getPipsDownhill(curr.wire)) { + if (!ctx->checkPipAvailForNet(dh, clk_net)) + continue; + WireId dst = ctx->getPipDstWire(dh); + if (!ctx->checkWireAvail(dst) && ctx->getBoundWireNet(dst) != clk_net) + continue; + // Has this wire been reserved for another net? + auto reserved = reserved_wires.find(dst); + if (reserved != reserved_wires.end() && reserved->second != clk_net->name) + continue; + auto delay = curr.delay + ctx->getPipDelay(dh).maxDelay() + ctx->getWireDelay(dst).maxDelay() + + ctx->getDelayEpsilon(); + if (backtrace.count(dst) && delay_map.at(dst) <= delay) + continue; + delay_map[dst] = delay; + backtrace[dst] = dh; + visit.push(QueuedWire(dst, delay)); + } + } + for (auto sink_wire : sink_wires_to_do) { + log_info(" failed to find a route using dedicated resources. %s -> %s\n", + clk_net->driver.cell->name.c_str(ctx), ctx->nameOfWire(sink_wire)); + } + for (auto pair : sink_wires) { + auto sink_wire = pair.first; + auto usr = pair.second; + auto src = sink_wire; + if (ctx->debug) { auto sink_wire_name = "(uninitialized)"; if (sink_wire != WireId()) @@ -145,87 +185,30 @@ void GateMateImpl::route_clock() log_info(" routing arc to %s.%s (wire %s):\n", usr.cell->name.c_str(ctx), usr.port.c_str(ctx), sink_wire_name); } - visit.push(QueuedWire(sink_wire)); - while (!visit.empty()) { - QueuedWire curr = visit.top(); - visit.pop(); - if (curr.wire == ctx->getNetinfoSourceWire(clk_net)) { - if (ctx->debug) - log_info(" (%.3fns)\n", curr.delay); - dest = curr.wire; - break; - } - PipId bound_pip; - auto fnd_wire = clk_net->wires.find(curr.wire); - if (fnd_wire != clk_net->wires.end()) { - bound_pip = fnd_wire->second.pip; - } - - for (auto uh : ctx->getPipsUphill(curr.wire)) { - if (!ctx->checkPipAvailForNet(uh, clk_net)) - continue; - WireId src = ctx->getPipSrcWire(uh); - if (backtrace.count(src)) - continue; - if (!ctx->checkWireAvail(src) && ctx->getBoundWireNet(src) != clk_net) - continue; - if (bound_pip != PipId() && uh != bound_pip) - continue; - // Has this wire been reserved for another net? - auto reserved = reserved_wires.find(src); - if (reserved != reserved_wires.end() && reserved->second != clk_net->name) - continue; - auto pip_loc = ctx->getPipLocation(uh); - // Use only a specific plane to minimise congestion for global clocks. - if (is_glb_clk && (pip_loc.x != cpe_loc.x || pip_loc.y != cpe_loc.y)) { - // Plane 9 is the clock plane, so it should only ever use itself. - if (clk_plane == 9 && pip_plane(uh) != 9) - continue; - // Plane 10 is the enable plane. - // When there's a set/reset, we want to use the switchbox X23 pip to change directly to plane 9. - if (clk_plane == 10 && pip_plane(uh) != 9 && pip_plane(uh) != 10) - continue; - // Plane 11 is the set/reset plane; we want to use the switchbox X14 pip to go to plane 12, then - // use the IM to switch to plane 9. - if (clk_plane == 11 && pip_plane(uh) == 10) - continue; - // Plane 12 is the spare plane; we can use the IM to change directly to plane 9. - if (clk_plane == 12 && pip_plane(uh) != 9 && pip_plane(uh) != 12) - continue; - } - backtrace[src] = uh; - auto delay = ctx->getDelayNS(ctx->getPipDelay(uh).maxDelay() + ctx->getWireDelay(src).maxDelay() + - ctx->getDelayEpsilon()); - visit.push(QueuedWire(src, curr.delay + delay)); - } - } - if (dest == WireId()) { - log_info(" failed to find a route using dedicated resources. %s -> %s\n", - clk_net->driver.cell->name.c_str(ctx), usr.cell->name.c_str(ctx)); - } - while (backtrace.count(dest)) { - auto uh = backtrace[dest]; - dest = ctx->getPipDstWire(uh); - if (ctx->getBoundWireNet(dest) == clk_net) { - NPNR_ASSERT(clk_net->wires.at(dest).pip == uh); + while (backtrace.count(src)) { + auto uh = backtrace[src]; + if (ctx->getBoundWireNet(src) == clk_net) { if (ctx->debug) log_info(" pip %s --> %s (plane %hhd)\n", ctx->nameOfPip(uh), - ctx->nameOfWire(dest), pip_plane(uh)); - } else if (ctx->getBoundWireNet(dest) == nullptr) { - ctx->bindPip(uh, clk_net, STRENGTH_LOCKED); + ctx->nameOfWire(src), pip_plane(uh)); + } else if (ctx->getBoundWireNet(src) == nullptr) { if (ctx->debug) log_info(" bind pip %s --> %s (plane %hhd)\n", ctx->nameOfPip(uh), - ctx->nameOfWire(dest), pip_plane(uh)); + ctx->nameOfWire(src), pip_plane(uh)); + ctx->bindPip(uh, clk_net, is_glb_clk ? STRENGTH_LOCKED : STRENGTH_WEAK); } else { log_error("Can't bind pip %s because wire %s is already bound\n", ctx->nameOfPip(uh), - ctx->nameOfWire(dest)); + ctx->nameOfWire(src)); } - if (dest == sink_wire) + if (src == src_wire) break; + src = ctx->getPipSrcWire(uh); } } } + auto rend = std::chrono::high_resolution_clock::now(); + log_info("Clock router time %.02fs\n", std::chrono::duration(rend - rstart).count()); } NEXTPNR_NAMESPACE_END diff --git a/himbaechel/uarch/gatemate/route_mult.cc b/himbaechel/uarch/gatemate/route_mult.cc index a2bed912..856a7e52 100644 --- a/himbaechel/uarch/gatemate/route_mult.cc +++ b/himbaechel/uarch/gatemate/route_mult.cc @@ -64,15 +64,23 @@ void route_mult_diag(Context *ctx, NetInfo *net, Loc loc, WireId last_wire, int log_info(" routing diagonal: %d hops\n", hops); for (int i = 0; i < hops; i++) { + auto in_mux_y = ctx->getWireByName( + IdStringList::concat(ctx->idf("X%dY%d", loc.x + i, loc.y + i), ctx->idf("IM.P%02d.Y", plane))); + auto d4 = ctx->getWireByName( + IdStringList::concat(ctx->idf("X%dY%d", loc.x + i + 1, loc.y + i + 1), ctx->idf("IM.P%02d.D4", plane))); auto cpe_in = ctx->getWireByName( IdStringList::concat(ctx->idf("X%dY%d", loc.x + i, loc.y + i), ctx->idf("CPE.IN%d", plane))); auto cpe_in_int = ctx->getWireByName( IdStringList::concat(ctx->idf("X%dY%d", loc.x + i, loc.y + i), ctx->idf("CPE.IN%d_int", plane))); - find_and_bind_downhill_pip(ctx, last_wire, cpe_in, net); // inverting + find_and_bind_downhill_pip(ctx, last_wire, in_mux_y, net); + find_and_bind_downhill_pip(ctx, in_mux_y, cpe_in, net); find_and_bind_downhill_pip(ctx, cpe_in, cpe_in_int, net); - last_wire = cpe_in; + if (i != hops - 1) + find_and_bind_downhill_pip(ctx, in_mux_y, d4, net); + + last_wire = d4; } } @@ -86,23 +94,29 @@ void route_mult_x1y1_lower(Context *ctx, NetInfo *net, CellInfo *lower, Loc loc, auto cpe_combout1 = ctx->getBelPinWire(lower->bel, id_OUT); auto cpe_out1_int = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("CPE.OUT1_int"))); + auto cpe_out1 = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("CPE.OUT1"))); auto in_mux = ctx->getWireByName(IdStringList::concat(x2y1, ctx->idf("IM.P05.D0"))); ctx->bindWire(cpe_combout1, net, STRENGTH_LOCKED); find_and_bind_downhill_pip(ctx, cpe_combout1, cpe_out1_int, net); + find_and_bind_downhill_pip(ctx, cpe_out1_int, cpe_out1, net); if (is_fourgroup_a) { - auto sb_big = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_BIG.P05.D0"))); + auto sb_big_d0 = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_BIG.P05.D0"))); + auto sb_big_y1 = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_BIG.P05.Y1"))); - find_and_bind_downhill_pip(ctx, cpe_out1_int, sb_big, net); - find_and_bind_downhill_pip(ctx, sb_big, in_mux, net); // inverting + find_and_bind_downhill_pip(ctx, cpe_out1, sb_big_d0, net); + find_and_bind_downhill_pip(ctx, sb_big_d0, sb_big_y1, net); + find_and_bind_downhill_pip(ctx, sb_big_y1, in_mux, net); } else { auto sb_sml_d0 = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_SML.P05.D0"))); auto sb_sml_y1_int = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_SML.P05.Y1_int"))); + auto sb_sml_y1 = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_SML.P05.Y1"))); - find_and_bind_downhill_pip(ctx, cpe_out1_int, sb_sml_d0, net); + find_and_bind_downhill_pip(ctx, cpe_out1, sb_sml_d0, net); find_and_bind_downhill_pip(ctx, sb_sml_d0, sb_sml_y1_int, net); - find_and_bind_downhill_pip(ctx, sb_sml_y1_int, in_mux, net); // inverting + find_and_bind_downhill_pip(ctx, sb_sml_y1_int, sb_sml_y1, net); + find_and_bind_downhill_pip(ctx, sb_sml_y1, in_mux, net); // inverting } route_mult_diag(ctx, net, Loc{loc.x + 1, loc.y, 0}, in_mux, 5); @@ -118,23 +132,29 @@ void route_mult_x1y1_upper_in1(Context *ctx, NetInfo *net, CellInfo *upper, Loc auto cpe_combout2 = ctx->getBelPinWire(upper->bel, id_OUT); auto cpe_out2_int = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("CPE.OUT2_int"))); + auto cpe_out2 = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("CPE.OUT2"))); auto in_mux = ctx->getWireByName(IdStringList::concat(x2y1, ctx->idf("IM.P01.D0"))); ctx->bindWire(cpe_combout2, net, STRENGTH_LOCKED); find_and_bind_downhill_pip(ctx, cpe_combout2, cpe_out2_int, net); + find_and_bind_downhill_pip(ctx, cpe_out2_int, cpe_out2, net); if (is_fourgroup_a) { - auto sb_big = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_BIG.P01.D0"))); + auto sb_big_d0 = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_BIG.P01.D0"))); + auto sb_big_y1 = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_BIG.P01.Y1"))); - find_and_bind_downhill_pip(ctx, cpe_out2_int, sb_big, net); - find_and_bind_downhill_pip(ctx, sb_big, in_mux, net); // inverting + find_and_bind_downhill_pip(ctx, cpe_out2, sb_big_d0, net); + find_and_bind_downhill_pip(ctx, sb_big_d0, sb_big_y1, net); + find_and_bind_downhill_pip(ctx, sb_big_y1, in_mux, net); // inverting } else { auto sb_sml_d0 = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_SML.P01.D0"))); auto sb_sml_y1_int = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_SML.P01.Y1_int"))); + auto sb_sml_y1 = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_SML.P01.Y1"))); - find_and_bind_downhill_pip(ctx, cpe_out2_int, sb_sml_d0, net); + find_and_bind_downhill_pip(ctx, cpe_out2, sb_sml_d0, net); find_and_bind_downhill_pip(ctx, sb_sml_d0, sb_sml_y1_int, net); - find_and_bind_downhill_pip(ctx, sb_sml_y1_int, in_mux, net); // inverting + find_and_bind_downhill_pip(ctx, sb_sml_y1_int, sb_sml_y1, net); + find_and_bind_downhill_pip(ctx, sb_sml_y1, in_mux, net); } route_mult_diag(ctx, net, Loc{loc.x + 1, loc.y, 0}, in_mux, 1); @@ -152,6 +172,7 @@ void route_mult_x1y1_upper_in8(Context *ctx, NetInfo *net, CellInfo *upper, Loc auto cpe_combout2 = ctx->getBelPinWire(upper->bel, id_OUT); auto cpe_out2_int = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("CPE.OUT2_int"))); + auto cpe_out2 = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("CPE.OUT2"))); auto out_mux_d0 = ctx->getWireByName(IdStringList::concat(x2y2, ctx->idf("OM.P12.D0"))); auto out_mux_y = ctx->getWireByName(IdStringList::concat(x2y2, ctx->idf("OM.P12.Y"))); auto in_mux_p12 = ctx->getWireByName(IdStringList::concat(x2y2, ctx->idf("IM.P12.D2"))); @@ -159,41 +180,57 @@ void route_mult_x1y1_upper_in8(Context *ctx, NetInfo *net, CellInfo *upper, Loc if (bind_route_start) { ctx->bindWire(cpe_combout2, net, STRENGTH_LOCKED); find_and_bind_downhill_pip(ctx, cpe_combout2, cpe_out2_int, net); - find_and_bind_downhill_pip(ctx, cpe_out2_int, out_mux_d0, net); + find_and_bind_downhill_pip(ctx, cpe_out2_int, cpe_out2, net); } + find_and_bind_downhill_pip(ctx, cpe_out2, out_mux_d0, net); find_and_bind_downhill_pip(ctx, out_mux_d0, out_mux_y, net); // inverting if (is_fourgroup_a) { - auto sb_sml = ctx->getWireByName(IdStringList::concat(x2y2, ctx->idf("SB_SML.P12.Y1_int"))); + auto sb_sml_d0 = ctx->getWireByName(IdStringList::concat(x2y2, ctx->idf("SB_SML.P12.D0"))); + auto sb_sml_y1_int = ctx->getWireByName(IdStringList::concat(x2y2, ctx->idf("SB_SML.P12.Y1_int"))); + auto sb_sml_y1 = ctx->getWireByName(IdStringList::concat(x2y2, ctx->idf("SB_SML.P12.Y1"))); auto sb_big_d2_1 = ctx->getWireByName(IdStringList::concat(x4y2, ctx->idf("SB_BIG.P12.D2_1"))); auto sb_big_y1 = ctx->getWireByName(IdStringList::concat(x4y2, ctx->idf("SB_BIG.P12.Y1"))); auto sb_big_ydiag = ctx->getWireByName(IdStringList::concat(x4y2, ctx->idf("SB_BIG.P12.YDIAG"))); + auto sb_big_y3 = ctx->getWireByName(IdStringList::concat(x4y2, ctx->idf("SB_BIG.P12.Y3"))); - find_and_bind_downhill_pip(ctx, out_mux_y, sb_sml, net); - find_and_bind_downhill_pip(ctx, sb_sml, sb_big_d2_1, net); // inverting - find_and_bind_downhill_pip(ctx, sb_big_d2_1, sb_big_y1, net); // inverting - find_and_bind_downhill_pip(ctx, sb_big_y1, sb_big_ydiag, net); // inverting - find_and_bind_downhill_pip(ctx, sb_big_ydiag, in_mux_p12, net); // inverting + find_and_bind_downhill_pip(ctx, out_mux_y, sb_sml_d0, net); + find_and_bind_downhill_pip(ctx, sb_sml_d0, sb_sml_y1_int, net); + find_and_bind_downhill_pip(ctx, sb_sml_y1_int, sb_sml_y1, net); + find_and_bind_downhill_pip(ctx, sb_sml_y1, sb_big_d2_1, net); // inverting + find_and_bind_downhill_pip(ctx, sb_big_d2_1, sb_big_y1, net); // inverting + find_and_bind_downhill_pip(ctx, sb_big_y1, sb_big_ydiag, net); // inverting + find_and_bind_downhill_pip(ctx, sb_big_ydiag, sb_big_y3, net); // inverting + find_and_bind_downhill_pip(ctx, sb_big_y3, in_mux_p12, net); // inverting } else { - auto sb_big = - ctx->getWireByName(IdStringList::concat(x2y2, ctx->idf("SB_BIG.P12.Y1"))); // aka x4y2/SB_SML.P12.D2_1 + auto sb_big_d0 = ctx->getWireByName(IdStringList::concat(x2y2, ctx->idf("SB_BIG.P12.D0"))); + auto sb_big_y1 = ctx->getWireByName(IdStringList::concat(x2y2, ctx->idf("SB_BIG.P12.Y1"))); + auto sb_sml_d2_1 = ctx->getWireByName(IdStringList::concat(x4y2, ctx->idf("SB_SML.P12.D2_1"))); auto sb_sml_y1_int = ctx->getWireByName(IdStringList::concat(x4y2, ctx->idf("SB_SML.P12.Y1_int"))); auto sb_sml_ydiag_int = ctx->getWireByName(IdStringList::concat(x4y2, ctx->idf("SB_SML.P12.YDIAG_int"))); auto sb_sml_y3_int = ctx->getWireByName(IdStringList::concat(x4y2, ctx->idf("SB_SML.P12.Y3_int"))); + auto sb_sml_y3 = ctx->getWireByName(IdStringList::concat(x4y2, ctx->idf("SB_SML.P12.Y3"))); - find_and_bind_downhill_pip(ctx, out_mux_y, sb_big, net); // inverting - find_and_bind_downhill_pip(ctx, sb_big, sb_sml_y1_int, net); + find_and_bind_downhill_pip(ctx, out_mux_y, sb_big_d0, net); + find_and_bind_downhill_pip(ctx, sb_big_d0, sb_big_y1, net); + find_and_bind_downhill_pip(ctx, sb_big_y1, sb_sml_d2_1, net); + find_and_bind_downhill_pip(ctx, sb_sml_d2_1, sb_sml_y1_int, net); find_and_bind_downhill_pip(ctx, sb_sml_y1_int, sb_sml_ydiag_int, net); find_and_bind_downhill_pip(ctx, sb_sml_ydiag_int, sb_sml_y3_int, net); - find_and_bind_downhill_pip(ctx, sb_sml_y3_int, in_mux_p12, net); // inverting + find_and_bind_downhill_pip(ctx, sb_sml_y3_int, sb_sml_y3, net); + find_and_bind_downhill_pip(ctx, sb_sml_y3, in_mux_p12, net); } - auto in_mux_p04 = ctx->getWireByName(IdStringList::concat(x2y2, ctx->idf("IM.P04.D7"))); // aka IM.P12.Y - auto in_mux_p08 = ctx->getWireByName(IdStringList::concat(x2y2, ctx->idf("IM.P08.D6"))); // aka IM.P04.Y + auto in_mux_p12_y = ctx->getWireByName(IdStringList::concat(x2y2, ctx->idf("IM.P12.Y"))); + auto in_mux_p04 = ctx->getWireByName(IdStringList::concat(x2y2, ctx->idf("IM.P04.D7"))); + auto in_mux_p04_y = ctx->getWireByName(IdStringList::concat(x2y2, ctx->idf("IM.P04.Y"))); + auto in_mux_p08 = ctx->getWireByName(IdStringList::concat(x2y2, ctx->idf("IM.P08.D6"))); - find_and_bind_downhill_pip(ctx, in_mux_p12, in_mux_p04, net); // inverting - find_and_bind_downhill_pip(ctx, in_mux_p04, in_mux_p08, net); // inverting + find_and_bind_downhill_pip(ctx, in_mux_p12, in_mux_p12_y, net); + find_and_bind_downhill_pip(ctx, in_mux_p12_y, in_mux_p04, net); + find_and_bind_downhill_pip(ctx, in_mux_p04, in_mux_p04_y, net); + find_and_bind_downhill_pip(ctx, in_mux_p04_y, in_mux_p08, net); route_mult_diag(ctx, net, Loc{loc.x + 1, loc.y + 1, 0}, in_mux_p08, 8); } @@ -209,54 +246,65 @@ void route_mult_x1y2_lower(Context *ctx, NetInfo *net, CellInfo *lower, Loc loc, auto cpe_combout1 = ctx->getBelPinWire(lower->bel, id_OUT); auto cpe_out1_int = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("CPE.OUT1_int"))); + auto cpe_out1 = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("CPE.OUT1"))); auto in_mux = ctx->getWireByName(IdStringList::concat(x2y1, ctx->idf("IM.P05.D2"))); ctx->bindWire(cpe_combout1, net, STRENGTH_LOCKED); find_and_bind_downhill_pip(ctx, cpe_combout1, cpe_out1_int, net); + find_and_bind_downhill_pip(ctx, cpe_out1_int, cpe_out1, net); if (is_fourgroup_a) { auto sb_sml_p06_d0 = ctx->getWireByName(IdStringList::concat(x2y1, ctx->idf("SB_SML.P06.D0"))); auto sb_sml_p06_y1_int = ctx->getWireByName(IdStringList::concat(x2y1, ctx->idf("SB_SML.P06.Y1_int"))); auto sb_sml_p06_ydiag_int = ctx->getWireByName(IdStringList::concat(x2y1, ctx->idf("SB_SML.P06.YDIAG_int"))); - auto sb_sml_p06_ydiag = - ctx->getWireByName(IdStringList::concat(x2y1, ctx->idf("SB_SML.P06.YDIAG"))); // AKA SB_SML.P05.X23 + auto sb_sml_p06_ydiag = ctx->getWireByName(IdStringList::concat(x2y1, ctx->idf("SB_SML.P06.YDIAG"))); + auto sb_sml_p05_x23 = ctx->getWireByName(IdStringList::concat(x2y1, ctx->idf("SB_SML.P05.X23"))); auto sb_sml_p05_ydiag_int = ctx->getWireByName(IdStringList::concat(x2y1, ctx->idf("SB_SML.P05.YDIAG_int"))); auto sb_sml_p05_y1_int = ctx->getWireByName(IdStringList::concat(x2y1, ctx->idf("SB_SML.P05.Y1_int"))); auto sb_sml_p05_y1 = ctx->getWireByName(IdStringList::concat(x2y1, ctx->idf("SB_SML.P05.Y1"))); + auto sb_big_d2_1 = ctx->getWireByName(IdStringList::concat(x4y1, ctx->idf("SB_BIG.P05.D2_1"))); auto sb_big_y1 = ctx->getWireByName(IdStringList::concat(x4y1, ctx->idf("SB_BIG.P05.Y1"))); auto sb_big_ydiag = ctx->getWireByName(IdStringList::concat(x4y1, ctx->idf("SB_BIG.P05.YDIAG"))); - // x2y1/IM.P05.D2 is x4y1/SB_BIG.P05.Y3 + auto sb_big_y3 = ctx->getWireByName(IdStringList::concat(x4y1, ctx->idf("SB_BIG.P05.Y3"))); - find_and_bind_downhill_pip(ctx, cpe_out1_int, sb_sml_p06_d0, net); + find_and_bind_downhill_pip(ctx, cpe_out1, sb_sml_p06_d0, net); find_and_bind_downhill_pip(ctx, sb_sml_p06_d0, sb_sml_p06_y1_int, net); find_and_bind_downhill_pip(ctx, sb_sml_p06_y1_int, sb_sml_p06_ydiag_int, net); find_and_bind_downhill_pip(ctx, sb_sml_p06_ydiag_int, sb_sml_p06_ydiag, net); - find_and_bind_downhill_pip(ctx, sb_sml_p06_ydiag, sb_sml_p05_ydiag_int, net); + find_and_bind_downhill_pip(ctx, sb_sml_p06_ydiag, sb_sml_p05_x23, net); + find_and_bind_downhill_pip(ctx, sb_sml_p05_x23, sb_sml_p05_ydiag_int, net); find_and_bind_downhill_pip(ctx, sb_sml_p05_ydiag_int, sb_sml_p05_y1_int, net); find_and_bind_downhill_pip(ctx, sb_sml_p05_y1_int, sb_sml_p05_y1, net); - find_and_bind_downhill_pip(ctx, sb_sml_p05_y1, sb_big_y1, net); + find_and_bind_downhill_pip(ctx, sb_sml_p05_y1, sb_big_d2_1, net); + find_and_bind_downhill_pip(ctx, sb_big_d2_1, sb_big_y1, net); find_and_bind_downhill_pip(ctx, sb_big_y1, sb_big_ydiag, net); - find_and_bind_downhill_pip(ctx, sb_big_ydiag, in_mux, net); + find_and_bind_downhill_pip(ctx, sb_big_ydiag, sb_big_y3, net); + find_and_bind_downhill_pip(ctx, sb_big_y3, in_mux, net); } else { auto sb_big_p06_d0 = ctx->getWireByName(IdStringList::concat(x2y1, ctx->idf("SB_BIG.P06.D0"))); auto sb_big_p06_y1 = ctx->getWireByName(IdStringList::concat(x2y1, ctx->idf("SB_BIG.P06.Y1"))); - auto sb_big_p06_ydiag = - ctx->getWireByName(IdStringList::concat(x2y1, ctx->idf("SB_BIG.P06.YDIAG"))); // AKA SB_BIG.P05.X23 + auto sb_big_p06_ydiag = ctx->getWireByName(IdStringList::concat(x2y1, ctx->idf("SB_BIG.P06.YDIAG"))); + auto sb_big_p05_x23 = ctx->getWireByName(IdStringList::concat(x2y1, ctx->idf("SB_BIG.P05.X23"))); auto sb_big_p05_ydiag = ctx->getWireByName(IdStringList::concat(x2y1, ctx->idf("SB_BIG.P05.YDIAG"))); auto sb_big_p05_y1 = ctx->getWireByName(IdStringList::concat(x2y1, ctx->idf("SB_BIG.P05.Y1"))); + auto sb_sml_d2_1 = ctx->getWireByName(IdStringList::concat(x4y1, ctx->idf("SB_SML.P05.D2_1"))); auto sb_sml_y1_int = ctx->getWireByName(IdStringList::concat(x4y1, ctx->idf("SB_SML.P05.Y1_int"))); auto sb_sml_ydiag_int = ctx->getWireByName(IdStringList::concat(x4y1, ctx->idf("SB_SML.P05.YDIAG_int"))); auto sb_sml_y3_int = ctx->getWireByName(IdStringList::concat(x4y1, ctx->idf("SB_SML.P05.Y3_int"))); + auto sb_sml_y3 = ctx->getWireByName(IdStringList::concat(x4y1, ctx->idf("SB_SML.P05.Y3"))); - find_and_bind_downhill_pip(ctx, cpe_out1_int, sb_big_p06_d0, net); + find_and_bind_downhill_pip(ctx, cpe_out1, sb_big_p06_d0, net); find_and_bind_downhill_pip(ctx, sb_big_p06_d0, sb_big_p06_y1, net); find_and_bind_downhill_pip(ctx, sb_big_p06_y1, sb_big_p06_ydiag, net); - find_and_bind_downhill_pip(ctx, sb_big_p06_ydiag, sb_big_p05_ydiag, net); + find_and_bind_downhill_pip(ctx, sb_big_p06_ydiag, sb_big_p05_x23, net); + find_and_bind_downhill_pip(ctx, sb_big_p05_x23, sb_big_p05_ydiag, net); find_and_bind_downhill_pip(ctx, sb_big_p05_ydiag, sb_big_p05_y1, net); - find_and_bind_downhill_pip(ctx, sb_big_p05_y1, sb_sml_y1_int, net); + find_and_bind_downhill_pip(ctx, sb_big_p05_y1, sb_sml_d2_1, net); + find_and_bind_downhill_pip(ctx, sb_sml_d2_1, sb_sml_y1_int, net); find_and_bind_downhill_pip(ctx, sb_sml_y1_int, sb_sml_ydiag_int, net); find_and_bind_downhill_pip(ctx, sb_sml_ydiag_int, sb_sml_y3_int, net); - find_and_bind_downhill_pip(ctx, sb_sml_y3_int, in_mux, net); + find_and_bind_downhill_pip(ctx, sb_sml_y3_int, sb_sml_y3, net); + find_and_bind_downhill_pip(ctx, sb_sml_y3, in_mux, net); } route_mult_diag(ctx, net, Loc{loc.x + 1, loc.y, 0}, in_mux, 5); @@ -273,9 +321,11 @@ void route_mult_x1y2_upper_in1(Context *ctx, NetInfo *net, CellInfo *upper, Loc auto cpe_combout2 = ctx->getBelPinWire(upper->bel, id_OUT); auto cpe_out2_int = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("CPE.OUT2_int"))); + auto cpe_out2 = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("CPE.OUT2"))); ctx->bindWire(cpe_combout2, net, STRENGTH_LOCKED); find_and_bind_downhill_pip(ctx, cpe_combout2, cpe_out2_int, net); + find_and_bind_downhill_pip(ctx, cpe_out2_int, cpe_out2, net); auto in_mux = ctx->getWireByName(IdStringList::concat(x2y1, ctx->idf("IM.P01.D2"))); @@ -283,44 +333,53 @@ void route_mult_x1y2_upper_in1(Context *ctx, NetInfo *net, CellInfo *upper, Loc auto sb_sml_p02_d0 = ctx->getWireByName(IdStringList::concat(x2y1, ctx->idf("SB_SML.P02.D0"))); auto sb_sml_p02_y1 = ctx->getWireByName(IdStringList::concat(x2y1, ctx->idf("SB_SML.P02.Y1_int"))); auto sb_sml_p02_ydiag_int = ctx->getWireByName(IdStringList::concat(x2y1, ctx->idf("SB_SML.P02.YDIAG_int"))); - auto sb_sml_p02_ydiag = - ctx->getWireByName(IdStringList::concat(x2y1, ctx->idf("SB_SML.P02.YDIAG"))); // AKA SB_SML.P01.X23 + auto sb_sml_p02_ydiag = ctx->getWireByName(IdStringList::concat(x2y1, ctx->idf("SB_SML.P02.YDIAG"))); + auto sb_sml_p01_x23 = ctx->getWireByName(IdStringList::concat(x2y1, ctx->idf("SB_SML.P01.X23"))); auto sb_sml_p01_ydiag = ctx->getWireByName(IdStringList::concat(x2y1, ctx->idf("SB_SML.P01.YDIAG_int"))); - auto sb_sml_p01_y1 = ctx->getWireByName(IdStringList::concat(x2y1, ctx->idf("SB_SML.P01.Y1_int"))); + auto sb_sml_p01_y1_int = ctx->getWireByName(IdStringList::concat(x2y1, ctx->idf("SB_SML.P01.Y1_int"))); + auto sb_sml_p01_y1 = ctx->getWireByName(IdStringList::concat(x2y1, ctx->idf("SB_SML.P01.Y1"))); auto sb_big_d2_1 = ctx->getWireByName(IdStringList::concat(x4y1, ctx->idf("SB_BIG.P01.D2_1"))); auto sb_big_y1 = ctx->getWireByName(IdStringList::concat(x4y1, ctx->idf("SB_BIG.P01.Y1"))); auto sb_big_ydiag = ctx->getWireByName(IdStringList::concat(x4y1, ctx->idf("SB_BIG.P01.YDIAG"))); - // x2y1/IM.P01.D2 is x4y1/SB_BIG.P01.Y3 + auto sb_big_y3 = ctx->getWireByName(IdStringList::concat(x4y1, ctx->idf("SB_BIG.P01.Y3"))); - find_and_bind_downhill_pip(ctx, cpe_out2_int, sb_sml_p02_d0, net); + find_and_bind_downhill_pip(ctx, cpe_out2, sb_sml_p02_d0, net); find_and_bind_downhill_pip(ctx, sb_sml_p02_d0, sb_sml_p02_y1, net); find_and_bind_downhill_pip(ctx, sb_sml_p02_y1, sb_sml_p02_ydiag_int, net); find_and_bind_downhill_pip(ctx, sb_sml_p02_ydiag_int, sb_sml_p02_ydiag, net); - find_and_bind_downhill_pip(ctx, sb_sml_p02_ydiag, sb_sml_p01_ydiag, net); - find_and_bind_downhill_pip(ctx, sb_sml_p01_ydiag, sb_sml_p01_y1, net); + find_and_bind_downhill_pip(ctx, sb_sml_p02_ydiag, sb_sml_p01_x23, net); + find_and_bind_downhill_pip(ctx, sb_sml_p01_x23, sb_sml_p01_ydiag, net); + find_and_bind_downhill_pip(ctx, sb_sml_p01_ydiag, sb_sml_p01_y1_int, net); + find_and_bind_downhill_pip(ctx, sb_sml_p01_y1_int, sb_sml_p01_y1, net); find_and_bind_downhill_pip(ctx, sb_sml_p01_y1, sb_big_d2_1, net); find_and_bind_downhill_pip(ctx, sb_big_d2_1, sb_big_y1, net); find_and_bind_downhill_pip(ctx, sb_big_y1, sb_big_ydiag, net); - find_and_bind_downhill_pip(ctx, sb_big_ydiag, in_mux, net); + find_and_bind_downhill_pip(ctx, sb_big_ydiag, sb_big_y3, net); + find_and_bind_downhill_pip(ctx, sb_big_y3, in_mux, net); } else { auto sb_big_p02_d0 = ctx->getWireByName(IdStringList::concat(x2y1, ctx->idf("SB_BIG.P02.D0"))); auto sb_big_p02_y1 = ctx->getWireByName(IdStringList::concat(x2y1, ctx->idf("SB_BIG.P02.Y1"))); - auto sb_big_p02_ydiag = - ctx->getWireByName(IdStringList::concat(x2y1, ctx->idf("SB_BIG.P02.YDIAG"))); // AKA SB_BIG.P01.X23 + auto sb_big_p02_ydiag = ctx->getWireByName(IdStringList::concat(x2y1, ctx->idf("SB_BIG.P02.YDIAG"))); + auto sb_big_p01_x23 = ctx->getWireByName(IdStringList::concat(x2y1, ctx->idf("SB_BIG.P01.X23"))); auto sb_big_p01_ydiag = ctx->getWireByName(IdStringList::concat(x2y1, ctx->idf("SB_BIG.P01.YDIAG"))); auto sb_big_p01_y1 = ctx->getWireByName(IdStringList::concat(x2y1, ctx->idf("SB_BIG.P01.Y1"))); + auto sb_sml_d2_1 = ctx->getWireByName(IdStringList::concat(x4y1, ctx->idf("SB_SML.P01.D2_1"))); auto sb_sml_y1 = ctx->getWireByName(IdStringList::concat(x4y1, ctx->idf("SB_SML.P01.Y1_int"))); auto sb_sml_ydiag = ctx->getWireByName(IdStringList::concat(x4y1, ctx->idf("SB_SML.P01.YDIAG_int"))); - auto sb_sml_y3 = ctx->getWireByName(IdStringList::concat(x4y1, ctx->idf("SB_SML.P01.Y3_int"))); + auto sb_sml_y3_int = ctx->getWireByName(IdStringList::concat(x4y1, ctx->idf("SB_SML.P01.Y3_int"))); + auto sb_sml_y3 = ctx->getWireByName(IdStringList::concat(x4y1, ctx->idf("SB_SML.P01.Y3"))); - find_and_bind_downhill_pip(ctx, cpe_out2_int, sb_big_p02_d0, net); + find_and_bind_downhill_pip(ctx, cpe_out2, sb_big_p02_d0, net); find_and_bind_downhill_pip(ctx, sb_big_p02_d0, sb_big_p02_y1, net); find_and_bind_downhill_pip(ctx, sb_big_p02_y1, sb_big_p02_ydiag, net); - find_and_bind_downhill_pip(ctx, sb_big_p02_ydiag, sb_big_p01_ydiag, net); + find_and_bind_downhill_pip(ctx, sb_big_p02_ydiag, sb_big_p01_x23, net); + find_and_bind_downhill_pip(ctx, sb_big_p01_x23, sb_big_p01_ydiag, net); find_and_bind_downhill_pip(ctx, sb_big_p01_ydiag, sb_big_p01_y1, net); - find_and_bind_downhill_pip(ctx, sb_big_p01_y1, sb_sml_y1, net); + find_and_bind_downhill_pip(ctx, sb_big_p01_y1, sb_sml_d2_1, net); + find_and_bind_downhill_pip(ctx, sb_sml_d2_1, sb_sml_y1, net); find_and_bind_downhill_pip(ctx, sb_sml_y1, sb_sml_ydiag, net); - find_and_bind_downhill_pip(ctx, sb_sml_ydiag, sb_sml_y3, net); + find_and_bind_downhill_pip(ctx, sb_sml_ydiag, sb_sml_y3_int, net); + find_and_bind_downhill_pip(ctx, sb_sml_y3_int, sb_sml_y3, net); find_and_bind_downhill_pip(ctx, sb_sml_y3, in_mux, net); } @@ -339,6 +398,7 @@ void route_mult_x1y2_upper_in8(Context *ctx, NetInfo *net, CellInfo *upper, Loc auto cpe_combout2 = ctx->getBelPinWire(upper->bel, id_OUT); auto cpe_out2_int = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("CPE.OUT2_int"))); + auto cpe_out2 = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("CPE.OUT2"))); auto out_mux_d1 = ctx->getWireByName(IdStringList::concat(x2y1, ctx->idf("OM.P10.D1"))); auto out_mux_y = ctx->getWireByName(IdStringList::concat(x2y1, ctx->idf("OM.P10.Y"))); auto in_mux_p10 = ctx->getWireByName(IdStringList::concat(x2y2, ctx->idf("IM.P10.D1"))); @@ -346,30 +406,43 @@ void route_mult_x1y2_upper_in8(Context *ctx, NetInfo *net, CellInfo *upper, Loc if (bind_route_start) { ctx->bindWire(cpe_combout2, net, STRENGTH_LOCKED); find_and_bind_downhill_pip(ctx, cpe_combout2, cpe_out2_int, net); - find_and_bind_downhill_pip(ctx, cpe_out2_int, out_mux_d1, net); + find_and_bind_downhill_pip(ctx, cpe_out2_int, cpe_out2, net); } + find_and_bind_downhill_pip(ctx, cpe_out2, out_mux_d1, net); find_and_bind_downhill_pip(ctx, out_mux_d1, out_mux_y, net); // inverting if (is_fourgroup_a) { - auto sb_sml = ctx->getWireByName(IdStringList::concat(x2y1, ctx->idf("SB_SML.P10.Y2_int"))); + auto sb_sml_d0 = ctx->getWireByName(IdStringList::concat(x2y1, ctx->idf("SB_SML.P10.D0"))); + auto sb_sml_y2_int = ctx->getWireByName(IdStringList::concat(x2y1, ctx->idf("SB_SML.P10.Y2_int"))); + auto sb_sml_y2 = ctx->getWireByName(IdStringList::concat(x2y1, ctx->idf("SB_SML.P10.Y2"))); - find_and_bind_downhill_pip(ctx, out_mux_y, sb_sml, net); - find_and_bind_downhill_pip(ctx, sb_sml, in_mux_p10, net); // inverting + find_and_bind_downhill_pip(ctx, out_mux_y, sb_sml_d0, net); + find_and_bind_downhill_pip(ctx, sb_sml_d0, sb_sml_y2_int, net); + find_and_bind_downhill_pip(ctx, sb_sml_y2_int, sb_sml_y2, net); + find_and_bind_downhill_pip(ctx, sb_sml_y2, in_mux_p10, net); } else { - // x2y1/OM.P10.Y is x2y1/SB_BIG.P10.D0 - // x2y2/IM.P10.D1 is x2y1/SB_BIG.P10.Y2 + auto sb_big_d0 = ctx->getWireByName(IdStringList::concat(x2y1, ctx->idf("SB_BIG.P10.D0"))); + auto sb_big_y2 = ctx->getWireByName(IdStringList::concat(x2y1, ctx->idf("SB_BIG.P10.Y2"))); - find_and_bind_downhill_pip(ctx, out_mux_y, in_mux_p10, net); // inverting + find_and_bind_downhill_pip(ctx, out_mux_y, sb_big_d0, net); + find_and_bind_downhill_pip(ctx, sb_big_d0, sb_big_y2, net); + find_and_bind_downhill_pip(ctx, sb_big_y2, in_mux_p10, net); } - auto in_mux_p12 = ctx->getWireByName(IdStringList::concat(x2y2, ctx->idf("IM.P12.D6"))); // aka IM.P10.Y - auto in_mux_p04 = ctx->getWireByName(IdStringList::concat(x2y2, ctx->idf("IM.P04.D7"))); // aka IM.P12.Y - auto in_mux_p08 = ctx->getWireByName(IdStringList::concat(x2y2, ctx->idf("IM.P08.D6"))); // aka IM.P04.Y + auto in_mux_p10_y = ctx->getWireByName(IdStringList::concat(x2y2, ctx->idf("IM.P10.Y"))); + auto in_mux_p12 = ctx->getWireByName(IdStringList::concat(x2y2, ctx->idf("IM.P12.D6"))); + auto in_mux_p12_y = ctx->getWireByName(IdStringList::concat(x2y2, ctx->idf("IM.P12.Y"))); + auto in_mux_p04 = ctx->getWireByName(IdStringList::concat(x2y2, ctx->idf("IM.P04.D7"))); + auto in_mux_p04_y = ctx->getWireByName(IdStringList::concat(x2y2, ctx->idf("IM.P04.Y"))); + auto in_mux_p08 = ctx->getWireByName(IdStringList::concat(x2y2, ctx->idf("IM.P08.D6"))); - find_and_bind_downhill_pip(ctx, in_mux_p10, in_mux_p12, net); // inverting - find_and_bind_downhill_pip(ctx, in_mux_p12, in_mux_p04, net); // inverting - find_and_bind_downhill_pip(ctx, in_mux_p04, in_mux_p08, net); // inverting + find_and_bind_downhill_pip(ctx, in_mux_p10, in_mux_p10_y, net); + find_and_bind_downhill_pip(ctx, in_mux_p10_y, in_mux_p12, net); + find_and_bind_downhill_pip(ctx, in_mux_p12, in_mux_p12_y, net); + find_and_bind_downhill_pip(ctx, in_mux_p12_y, in_mux_p04, net); + find_and_bind_downhill_pip(ctx, in_mux_p04, in_mux_p04_y, net); + find_and_bind_downhill_pip(ctx, in_mux_p04_y, in_mux_p08, net); route_mult_diag(ctx, net, Loc{loc.x + 1, loc.y + 1, 0}, in_mux_p08, 8); } @@ -385,48 +458,57 @@ void route_mult_x2y1_lower(Context *ctx, NetInfo *net, CellInfo *lower, Loc loc, auto cpe_combout1 = ctx->getBelPinWire(lower->bel, id_OUT); auto cpe_out1_int = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("CPE.OUT1_int"))); + auto cpe_out1 = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("CPE.OUT1"))); auto in_mux = ctx->getWireByName(IdStringList::concat(x2y1, ctx->idf("IM.P05.D0"))); ctx->bindWire(cpe_combout1, net, STRENGTH_LOCKED); find_and_bind_downhill_pip(ctx, cpe_combout1, cpe_out1_int, net); + find_and_bind_downhill_pip(ctx, cpe_out1_int, cpe_out1, net); if (is_fourgroup_a) { auto sb_big_p07_d0 = ctx->getWireByName(IdStringList::concat(x0y1, ctx->idf("SB_BIG.P07.D0"))); auto sb_big_p07_y1 = ctx->getWireByName(IdStringList::concat(x0y1, ctx->idf("SB_BIG.P07.Y1"))); - auto sb_big_p07_ydiag = - ctx->getWireByName(IdStringList::concat(x0y1, ctx->idf("SB_BIG.P07.YDIAG"))); // AKA SB_BIG.P06.X23 - auto sb_big_p06_ydiag = - ctx->getWireByName(IdStringList::concat(x0y1, ctx->idf("SB_BIG.P06.YDIAG"))); // AKA SB_BIG.P05.X23 + auto sb_big_p07_ydiag = ctx->getWireByName(IdStringList::concat(x0y1, ctx->idf("SB_BIG.P07.YDIAG"))); + auto sb_big_p06_x23 = ctx->getWireByName(IdStringList::concat(x0y1, ctx->idf("SB_BIG.P06.X23"))); + auto sb_big_p06_ydiag = ctx->getWireByName(IdStringList::concat(x0y1, ctx->idf("SB_BIG.P06.YDIAG"))); + auto sb_big_p05_x23 = ctx->getWireByName(IdStringList::concat(x0y1, ctx->idf("SB_BIG.P05.X23"))); auto sb_big_p05_ydiag = ctx->getWireByName(IdStringList::concat(x0y1, ctx->idf("SB_BIG.P05.YDIAG"))); - // x2y1/IM.P05.D0 is x0y1/SB_BIG.P05.Y1 + auto sb_big_p05_y1 = ctx->getWireByName(IdStringList::concat(x0y1, ctx->idf("SB_BIG.P05.Y1"))); - find_and_bind_downhill_pip(ctx, cpe_out1_int, sb_big_p07_d0, net); + find_and_bind_downhill_pip(ctx, cpe_out1, sb_big_p07_d0, net); find_and_bind_downhill_pip(ctx, sb_big_p07_d0, sb_big_p07_y1, net); find_and_bind_downhill_pip(ctx, sb_big_p07_y1, sb_big_p07_ydiag, net); - find_and_bind_downhill_pip(ctx, sb_big_p07_ydiag, sb_big_p06_ydiag, net); - find_and_bind_downhill_pip(ctx, sb_big_p06_ydiag, sb_big_p05_ydiag, net); - find_and_bind_downhill_pip(ctx, sb_big_p05_ydiag, in_mux, net); + find_and_bind_downhill_pip(ctx, sb_big_p07_ydiag, sb_big_p06_x23, net); + find_and_bind_downhill_pip(ctx, sb_big_p06_x23, sb_big_p06_ydiag, net); + find_and_bind_downhill_pip(ctx, sb_big_p06_ydiag, sb_big_p05_x23, net); + find_and_bind_downhill_pip(ctx, sb_big_p05_x23, sb_big_p05_ydiag, net); + find_and_bind_downhill_pip(ctx, sb_big_p05_ydiag, sb_big_p05_y1, net); + find_and_bind_downhill_pip(ctx, sb_big_p05_y1, in_mux, net); } else { auto sb_sml_p07_d0 = ctx->getWireByName(IdStringList::concat(x0y1, ctx->idf("SB_SML.P07.D0"))); auto sb_sml_p07_y1_int = ctx->getWireByName(IdStringList::concat(x0y1, ctx->idf("SB_SML.P07.Y1_int"))); auto sb_sml_p07_ydiag_int = ctx->getWireByName(IdStringList::concat(x0y1, ctx->idf("SB_SML.P07.YDIAG_int"))); - auto sb_sml_p07_ydiag = - ctx->getWireByName(IdStringList::concat(x0y1, ctx->idf("SB_SML.P07.YDIAG"))); // AKA SB_SML.P06.X23 + auto sb_sml_p07_ydiag = ctx->getWireByName(IdStringList::concat(x0y1, ctx->idf("SB_SML.P07.YDIAG"))); + auto sb_sml_p06_x23 = ctx->getWireByName(IdStringList::concat(x0y1, ctx->idf("SB_SML.P06.X23"))); auto sb_sml_p06_ydiag_int = ctx->getWireByName(IdStringList::concat(x0y1, ctx->idf("SB_SML.P06.YDIAG_int"))); - auto sb_sml_p06_ydiag = - ctx->getWireByName(IdStringList::concat(x0y1, ctx->idf("SB_SML.P06.YDIAG"))); // AKA SB_SML.P05.X23 + auto sb_sml_p06_ydiag = ctx->getWireByName(IdStringList::concat(x0y1, ctx->idf("SB_SML.P06.YDIAG"))); + auto sb_sml_p05_x23 = ctx->getWireByName(IdStringList::concat(x0y1, ctx->idf("SB_SML.P05.X23"))); auto sb_sml_p05_ydiag_int = ctx->getWireByName(IdStringList::concat(x0y1, ctx->idf("SB_SML.P05.YDIAG_int"))); auto sb_sml_p05_y1_int = ctx->getWireByName(IdStringList::concat(x0y1, ctx->idf("SB_SML.P05.Y1_int"))); + auto sb_sml_p05_y1 = ctx->getWireByName(IdStringList::concat(x0y1, ctx->idf("SB_SML.P05.Y1"))); - find_and_bind_downhill_pip(ctx, cpe_out1_int, sb_sml_p07_d0, net); + find_and_bind_downhill_pip(ctx, cpe_out1, sb_sml_p07_d0, net); find_and_bind_downhill_pip(ctx, sb_sml_p07_d0, sb_sml_p07_y1_int, net); find_and_bind_downhill_pip(ctx, sb_sml_p07_y1_int, sb_sml_p07_ydiag_int, net); find_and_bind_downhill_pip(ctx, sb_sml_p07_ydiag_int, sb_sml_p07_ydiag, net); - find_and_bind_downhill_pip(ctx, sb_sml_p07_ydiag, sb_sml_p06_ydiag_int, net); + find_and_bind_downhill_pip(ctx, sb_sml_p07_ydiag, sb_sml_p06_x23, net); + find_and_bind_downhill_pip(ctx, sb_sml_p06_x23, sb_sml_p06_ydiag_int, net); find_and_bind_downhill_pip(ctx, sb_sml_p06_ydiag_int, sb_sml_p06_ydiag, net); - find_and_bind_downhill_pip(ctx, sb_sml_p06_ydiag, sb_sml_p05_ydiag_int, net); + find_and_bind_downhill_pip(ctx, sb_sml_p06_ydiag, sb_sml_p05_x23, net); + find_and_bind_downhill_pip(ctx, sb_sml_p05_x23, sb_sml_p05_ydiag_int, net); find_and_bind_downhill_pip(ctx, sb_sml_p05_ydiag_int, sb_sml_p05_y1_int, net); - find_and_bind_downhill_pip(ctx, sb_sml_p05_y1_int, in_mux, net); + find_and_bind_downhill_pip(ctx, sb_sml_p05_y1_int, sb_sml_p05_y1, net); + find_and_bind_downhill_pip(ctx, sb_sml_p05_y1, in_mux, net); } route_mult_diag(ctx, net, Loc{loc.x + 1, loc.y, 0}, in_mux, 5); @@ -443,48 +525,57 @@ void route_mult_x2y1_upper_in1(Context *ctx, NetInfo *net, CellInfo *upper, Loc auto cpe_combout2 = ctx->getBelPinWire(upper->bel, id_OUT); auto cpe_out2_int = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("CPE.OUT2_int"))); + auto cpe_out2 = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("CPE.OUT2"))); auto in_mux = ctx->getWireByName(IdStringList::concat(x2y1, ctx->idf("IM.P01.D0"))); ctx->bindWire(cpe_combout2, net, STRENGTH_LOCKED); find_and_bind_downhill_pip(ctx, cpe_combout2, cpe_out2_int, net); + find_and_bind_downhill_pip(ctx, cpe_out2_int, cpe_out2, net); if (is_fourgroup_a) { auto sb_big_p03_d0 = ctx->getWireByName(IdStringList::concat(x0y1, ctx->idf("SB_BIG.P03.D0"))); auto sb_big_p03_y1 = ctx->getWireByName(IdStringList::concat(x0y1, ctx->idf("SB_BIG.P03.Y1"))); - auto sb_big_p03_ydiag = - ctx->getWireByName(IdStringList::concat(x0y1, ctx->idf("SB_BIG.P03.YDIAG"))); // AKA SB_BIG.P02.X23 - auto sb_big_p02_ydiag = - ctx->getWireByName(IdStringList::concat(x0y1, ctx->idf("SB_BIG.P02.YDIAG"))); // AKA SB_BIG.P01.X23 + auto sb_big_p03_ydiag = ctx->getWireByName(IdStringList::concat(x0y1, ctx->idf("SB_BIG.P03.YDIAG"))); + auto sb_big_p02_x23 = ctx->getWireByName(IdStringList::concat(x0y1, ctx->idf("SB_BIG.P02.X23"))); + auto sb_big_p02_ydiag = ctx->getWireByName(IdStringList::concat(x0y1, ctx->idf("SB_BIG.P02.YDIAG"))); + auto sb_big_p01_x23 = ctx->getWireByName(IdStringList::concat(x0y1, ctx->idf("SB_BIG.P01.X23"))); auto sb_big_p01_ydiag = ctx->getWireByName(IdStringList::concat(x0y1, ctx->idf("SB_BIG.P01.YDIAG"))); - // x2y1/IM.P01.D0 is x0y1/SB_BIG.P01.Y1 + auto sb_big_p01_y1 = ctx->getWireByName(IdStringList::concat(x0y1, ctx->idf("SB_BIG.P01.Y1"))); - find_and_bind_downhill_pip(ctx, cpe_out2_int, sb_big_p03_d0, net); + find_and_bind_downhill_pip(ctx, cpe_out2, sb_big_p03_d0, net); find_and_bind_downhill_pip(ctx, sb_big_p03_d0, sb_big_p03_y1, net); find_and_bind_downhill_pip(ctx, sb_big_p03_y1, sb_big_p03_ydiag, net); - find_and_bind_downhill_pip(ctx, sb_big_p03_ydiag, sb_big_p02_ydiag, net); - find_and_bind_downhill_pip(ctx, sb_big_p02_ydiag, sb_big_p01_ydiag, net); - find_and_bind_downhill_pip(ctx, sb_big_p01_ydiag, in_mux, net); + find_and_bind_downhill_pip(ctx, sb_big_p03_ydiag, sb_big_p02_x23, net); + find_and_bind_downhill_pip(ctx, sb_big_p02_x23, sb_big_p02_ydiag, net); + find_and_bind_downhill_pip(ctx, sb_big_p02_ydiag, sb_big_p01_x23, net); + find_and_bind_downhill_pip(ctx, sb_big_p01_x23, sb_big_p01_ydiag, net); + find_and_bind_downhill_pip(ctx, sb_big_p01_ydiag, sb_big_p01_y1, net); + find_and_bind_downhill_pip(ctx, sb_big_p01_y1, in_mux, net); } else { auto sb_sml_p03_d0 = ctx->getWireByName(IdStringList::concat(x0y1, ctx->idf("SB_SML.P03.D0"))); auto sb_sml_p03_y1_int = ctx->getWireByName(IdStringList::concat(x0y1, ctx->idf("SB_SML.P03.Y1_int"))); auto sb_sml_p03_ydiag_int = ctx->getWireByName(IdStringList::concat(x0y1, ctx->idf("SB_SML.P03.YDIAG_int"))); - auto sb_sml_p03_ydiag = - ctx->getWireByName(IdStringList::concat(x0y1, ctx->idf("SB_SML.P03.YDIAG"))); // AKA SB_SML.P02.X23 + auto sb_sml_p03_ydiag = ctx->getWireByName(IdStringList::concat(x0y1, ctx->idf("SB_SML.P03.YDIAG"))); + auto sb_sml_p02_x23 = ctx->getWireByName(IdStringList::concat(x0y1, ctx->idf("SB_SML.P02.X23"))); auto sb_sml_p02_ydiag_int = ctx->getWireByName(IdStringList::concat(x0y1, ctx->idf("SB_SML.P02.YDIAG_int"))); - auto sb_sml_p02_ydiag = - ctx->getWireByName(IdStringList::concat(x0y1, ctx->idf("SB_SML.P02.YDIAG"))); // AKA SB_SML.P01.X23 + auto sb_sml_p02_ydiag = ctx->getWireByName(IdStringList::concat(x0y1, ctx->idf("SB_SML.P02.YDIAG"))); + auto sb_sml_p01_x23 = ctx->getWireByName(IdStringList::concat(x0y1, ctx->idf("SB_SML.P01.X23"))); auto sb_sml_p01_ydiag_int = ctx->getWireByName(IdStringList::concat(x0y1, ctx->idf("SB_SML.P01.YDIAG_int"))); auto sb_sml_p01_y1_int = ctx->getWireByName(IdStringList::concat(x0y1, ctx->idf("SB_SML.P01.Y1_int"))); + auto sb_sml_p01_y1 = ctx->getWireByName(IdStringList::concat(x0y1, ctx->idf("SB_SML.P01.Y1"))); - find_and_bind_downhill_pip(ctx, cpe_out2_int, sb_sml_p03_d0, net); + find_and_bind_downhill_pip(ctx, cpe_out2, sb_sml_p03_d0, net); find_and_bind_downhill_pip(ctx, sb_sml_p03_d0, sb_sml_p03_y1_int, net); find_and_bind_downhill_pip(ctx, sb_sml_p03_y1_int, sb_sml_p03_ydiag_int, net); find_and_bind_downhill_pip(ctx, sb_sml_p03_ydiag_int, sb_sml_p03_ydiag, net); - find_and_bind_downhill_pip(ctx, sb_sml_p03_ydiag, sb_sml_p02_ydiag_int, net); + find_and_bind_downhill_pip(ctx, sb_sml_p03_ydiag, sb_sml_p02_x23, net); + find_and_bind_downhill_pip(ctx, sb_sml_p02_x23, sb_sml_p02_ydiag_int, net); find_and_bind_downhill_pip(ctx, sb_sml_p02_ydiag_int, sb_sml_p02_ydiag, net); - find_and_bind_downhill_pip(ctx, sb_sml_p02_ydiag, sb_sml_p01_ydiag_int, net); + find_and_bind_downhill_pip(ctx, sb_sml_p02_ydiag, sb_sml_p01_x23, net); + find_and_bind_downhill_pip(ctx, sb_sml_p01_x23, sb_sml_p01_ydiag_int, net); find_and_bind_downhill_pip(ctx, sb_sml_p01_ydiag_int, sb_sml_p01_y1_int, net); - find_and_bind_downhill_pip(ctx, sb_sml_p01_y1_int, in_mux, net); + find_and_bind_downhill_pip(ctx, sb_sml_p01_y1_int, sb_sml_p01_y1, net); + find_and_bind_downhill_pip(ctx, sb_sml_p01_y1, in_mux, net); } route_mult_diag(ctx, net, Loc{loc.x + 1, loc.y, 0}, in_mux, 1); @@ -502,6 +593,7 @@ void route_mult_x2y1_upper_in8(Context *ctx, NetInfo *net, CellInfo *upper, Loc auto cpe_combout2 = ctx->getBelPinWire(upper->bel, id_OUT); auto cpe_out2_int = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("CPE.OUT2_int"))); + auto cpe_out2 = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("CPE.OUT2"))); auto out_mux_d2 = ctx->getWireByName(IdStringList::concat(x1y2, ctx->idf("OM.P09.D2"))); auto out_mux_y = ctx->getWireByName(IdStringList::concat(x1y2, ctx->idf("OM.P09.Y"))); auto in_mux_p09 = ctx->getWireByName(IdStringList::concat(x2y2, ctx->idf("IM.P09.D0"))); @@ -509,30 +601,43 @@ void route_mult_x2y1_upper_in8(Context *ctx, NetInfo *net, CellInfo *upper, Loc if (bind_route_start) { ctx->bindWire(cpe_combout2, net, STRENGTH_LOCKED); find_and_bind_downhill_pip(ctx, cpe_combout2, cpe_out2_int, net); - find_and_bind_downhill_pip(ctx, cpe_out2_int, out_mux_d2, net); + find_and_bind_downhill_pip(ctx, cpe_out2_int, cpe_out2, net); } + find_and_bind_downhill_pip(ctx, cpe_out2, out_mux_d2, net); find_and_bind_downhill_pip(ctx, out_mux_d2, out_mux_y, net); // inverting if (is_fourgroup_a) { - auto sb_sml = ctx->getWireByName(IdStringList::concat(x1y2, ctx->idf("SB_SML.P09.Y1_int"))); + auto sb_sml_d0 = ctx->getWireByName(IdStringList::concat(x1y2, ctx->idf("SB_SML.P09.D0"))); + auto sb_sml_y1_int = ctx->getWireByName(IdStringList::concat(x1y2, ctx->idf("SB_SML.P09.Y1_int"))); + auto sb_sml_y1 = ctx->getWireByName(IdStringList::concat(x1y2, ctx->idf("SB_SML.P09.Y1"))); - find_and_bind_downhill_pip(ctx, out_mux_y, sb_sml, net); - find_and_bind_downhill_pip(ctx, sb_sml, in_mux_p09, net); // inverting + find_and_bind_downhill_pip(ctx, out_mux_y, sb_sml_d0, net); + find_and_bind_downhill_pip(ctx, sb_sml_d0, sb_sml_y1_int, net); + find_and_bind_downhill_pip(ctx, sb_sml_y1_int, sb_sml_y1, net); + find_and_bind_downhill_pip(ctx, sb_sml_y1, in_mux_p09, net); // inverting } else { - // x1y2/OM.P09.Y is x1y2/SB_BIG.P09.D0 - // x2y2/IM.P09.D0 is x2y1/SB_BIG.P09.Y1 + auto sb_big_d0 = ctx->getWireByName(IdStringList::concat(x1y2, ctx->idf("SB_BIG.P09.D0"))); + auto sb_big_y1 = ctx->getWireByName(IdStringList::concat(x1y2, ctx->idf("SB_BIG.P09.Y1"))); - find_and_bind_downhill_pip(ctx, out_mux_y, in_mux_p09, net); // inverting + find_and_bind_downhill_pip(ctx, out_mux_y, sb_big_d0, net); + find_and_bind_downhill_pip(ctx, sb_big_d0, sb_big_y1, net); + find_and_bind_downhill_pip(ctx, sb_big_y1, in_mux_p09, net); } - auto in_mux_p12 = ctx->getWireByName(IdStringList::concat(x2y2, ctx->idf("IM.P12.D7"))); // aka IM.P09.Y - auto in_mux_p04 = ctx->getWireByName(IdStringList::concat(x2y2, ctx->idf("IM.P04.D7"))); // aka IM.P12.Y - auto in_mux_p08 = ctx->getWireByName(IdStringList::concat(x2y2, ctx->idf("IM.P08.D6"))); // aka IM.P04.Y + auto in_mux_p09_y = ctx->getWireByName(IdStringList::concat(x2y2, ctx->idf("IM.P09.Y"))); + auto in_mux_p12 = ctx->getWireByName(IdStringList::concat(x2y2, ctx->idf("IM.P12.D7"))); + auto in_mux_p12_y = ctx->getWireByName(IdStringList::concat(x2y2, ctx->idf("IM.P12.Y"))); + auto in_mux_p04 = ctx->getWireByName(IdStringList::concat(x2y2, ctx->idf("IM.P04.D7"))); + auto in_mux_p04_y = ctx->getWireByName(IdStringList::concat(x2y2, ctx->idf("IM.P04.Y"))); + auto in_mux_p08 = ctx->getWireByName(IdStringList::concat(x2y2, ctx->idf("IM.P08.D6"))); - find_and_bind_downhill_pip(ctx, in_mux_p09, in_mux_p12, net); // inverting - find_and_bind_downhill_pip(ctx, in_mux_p12, in_mux_p04, net); // inverting - find_and_bind_downhill_pip(ctx, in_mux_p04, in_mux_p08, net); // inverting + find_and_bind_downhill_pip(ctx, in_mux_p09, in_mux_p09_y, net); + find_and_bind_downhill_pip(ctx, in_mux_p09_y, in_mux_p12, net); + find_and_bind_downhill_pip(ctx, in_mux_p12, in_mux_p12_y, net); + find_and_bind_downhill_pip(ctx, in_mux_p12_y, in_mux_p04, net); + find_and_bind_downhill_pip(ctx, in_mux_p04, in_mux_p04_y, net); + find_and_bind_downhill_pip(ctx, in_mux_p04_y, in_mux_p08, net); route_mult_diag(ctx, net, Loc{loc.x + 1, loc.y + 1, 0}, in_mux_p08, 8); } @@ -547,56 +652,67 @@ void route_mult_x2y2_lower(Context *ctx, NetInfo *net, CellInfo *lower, Loc loc, auto cpe_combout1 = ctx->getBelPinWire(lower->bel, id_OUT); auto cpe_out1_int = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("CPE.OUT1_int"))); + auto cpe_out1 = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("CPE.OUT1"))); auto in_mux = ctx->getWireByName(IdStringList::concat(x2y1, ctx->idf("IM.P05.D0"))); ctx->bindWire(cpe_combout1, net, STRENGTH_LOCKED); find_and_bind_downhill_pip(ctx, cpe_combout1, cpe_out1_int, net); + find_and_bind_downhill_pip(ctx, cpe_out1_int, cpe_out1, net); if (is_fourgroup_a) { auto sb_sml_p08_d0 = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_SML.P08.D0"))); auto sb_sml_p08_y1_int = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_SML.P08.Y1_int"))); auto sb_sml_p08_ydiag_int = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_SML.P08.YDIAG_int"))); - auto sb_sml_p08_ydiag = - ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_SML.P08.YDIAG"))); // AKA SB_SML.P07.X23 + auto sb_sml_p08_ydiag = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_SML.P08.YDIAG"))); + auto sb_sml_p07_x23 = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_SML.P07.X23"))); auto sb_sml_p07_ydiag_int = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_SML.P07.YDIAG_int"))); - auto sb_sml_p07_ydiag = - ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_SML.P07.YDIAG"))); // AKA SB_SML.P06.X23 + auto sb_sml_p07_ydiag = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_SML.P07.YDIAG"))); + auto sb_sml_p06_x23 = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_SML.P06.X23"))); auto sb_sml_p06_ydiag_int = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_SML.P06.YDIAG_int"))); - auto sb_sml_p06_ydiag = - ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_SML.P06.YDIAG"))); // AKA SB_SML.P05.X23 + auto sb_sml_p06_ydiag = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_SML.P06.YDIAG"))); + auto sb_sml_p05_x23 = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_SML.P05.X23"))); auto sb_sml_p05_ydiag_int = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_SML.P05.YDIAG_int"))); auto sb_sml_p05_y1_int = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_SML.P05.Y1_int"))); + auto sb_sml_p05_y1 = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_SML.P05.Y1"))); - find_and_bind_downhill_pip(ctx, cpe_out1_int, sb_sml_p08_d0, net); + find_and_bind_downhill_pip(ctx, cpe_out1, sb_sml_p08_d0, net); find_and_bind_downhill_pip(ctx, sb_sml_p08_d0, sb_sml_p08_y1_int, net); find_and_bind_downhill_pip(ctx, sb_sml_p08_y1_int, sb_sml_p08_ydiag_int, net); find_and_bind_downhill_pip(ctx, sb_sml_p08_ydiag_int, sb_sml_p08_ydiag, net); // inverting - find_and_bind_downhill_pip(ctx, sb_sml_p08_ydiag, sb_sml_p07_ydiag_int, net); + find_and_bind_downhill_pip(ctx, sb_sml_p08_ydiag, sb_sml_p07_x23, net); + find_and_bind_downhill_pip(ctx, sb_sml_p07_x23, sb_sml_p07_ydiag_int, net); find_and_bind_downhill_pip(ctx, sb_sml_p07_ydiag_int, sb_sml_p07_ydiag, net); // inverting - find_and_bind_downhill_pip(ctx, sb_sml_p07_ydiag, sb_sml_p06_ydiag_int, net); + find_and_bind_downhill_pip(ctx, sb_sml_p07_ydiag, sb_sml_p06_x23, net); + find_and_bind_downhill_pip(ctx, sb_sml_p06_x23, sb_sml_p06_ydiag_int, net); find_and_bind_downhill_pip(ctx, sb_sml_p06_ydiag_int, sb_sml_p06_ydiag, net); // inverting - find_and_bind_downhill_pip(ctx, sb_sml_p06_ydiag, sb_sml_p05_ydiag_int, net); + find_and_bind_downhill_pip(ctx, sb_sml_p06_ydiag, sb_sml_p05_x23, net); + find_and_bind_downhill_pip(ctx, sb_sml_p05_x23, sb_sml_p05_ydiag_int, net); find_and_bind_downhill_pip(ctx, sb_sml_p05_ydiag_int, sb_sml_p05_y1_int, net); - find_and_bind_downhill_pip(ctx, sb_sml_p05_y1_int, in_mux, net); // inverting + find_and_bind_downhill_pip(ctx, sb_sml_p05_y1_int, sb_sml_p05_y1, net); + find_and_bind_downhill_pip(ctx, sb_sml_p05_y1, in_mux, net); } else { auto sb_big_p08_d0 = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_BIG.P08.D0"))); auto sb_big_p08_y1 = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_BIG.P08.Y1"))); - auto sb_big_p08_ydiag = - ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_BIG.P08.YDIAG"))); // AKA SB_BIG.P07.X23 - auto sb_big_p07_ydiag = - ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_BIG.P07.YDIAG"))); // AKA SB_BIG.P06.X23 - auto sb_big_p06_ydiag = - ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_BIG.P06.YDIAG"))); // AKA SB_BIG.P05.X23 + auto sb_big_p08_ydiag = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_BIG.P08.YDIAG"))); + auto sb_big_p07_x23 = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_BIG.P07.X23"))); + auto sb_big_p07_ydiag = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_BIG.P07.YDIAG"))); + auto sb_big_p06_x23 = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_BIG.P06.X23"))); + auto sb_big_p06_ydiag = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_BIG.P06.YDIAG"))); + auto sb_big_p05_x23 = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_BIG.P05.X23"))); auto sb_big_p05_ydiag = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_BIG.P05.YDIAG"))); - // x2y1/IM.P05.D0 is x1y1/SB_BIG.P05.Y1 + auto sb_big_p05_y1 = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_BIG.P05.Y1"))); - find_and_bind_downhill_pip(ctx, cpe_out1_int, sb_big_p08_d0, net); + find_and_bind_downhill_pip(ctx, cpe_out1, sb_big_p08_d0, net); find_and_bind_downhill_pip(ctx, sb_big_p08_d0, sb_big_p08_y1, net); find_and_bind_downhill_pip(ctx, sb_big_p08_y1, sb_big_p08_ydiag, net); - find_and_bind_downhill_pip(ctx, sb_big_p08_ydiag, sb_big_p07_ydiag, net); - find_and_bind_downhill_pip(ctx, sb_big_p07_ydiag, sb_big_p06_ydiag, net); - find_and_bind_downhill_pip(ctx, sb_big_p06_ydiag, sb_big_p05_ydiag, net); - find_and_bind_downhill_pip(ctx, sb_big_p05_ydiag, in_mux, net); + find_and_bind_downhill_pip(ctx, sb_big_p08_ydiag, sb_big_p07_x23, net); + find_and_bind_downhill_pip(ctx, sb_big_p07_x23, sb_big_p07_ydiag, net); + find_and_bind_downhill_pip(ctx, sb_big_p07_ydiag, sb_big_p06_x23, net); + find_and_bind_downhill_pip(ctx, sb_big_p06_x23, sb_big_p06_ydiag, net); + find_and_bind_downhill_pip(ctx, sb_big_p06_ydiag, sb_big_p05_x23, net); + find_and_bind_downhill_pip(ctx, sb_big_p05_x23, sb_big_p05_ydiag, net); + find_and_bind_downhill_pip(ctx, sb_big_p05_ydiag, sb_big_p05_y1, net); + find_and_bind_downhill_pip(ctx, sb_big_p05_y1, in_mux, net); } route_mult_diag(ctx, net, Loc{loc.x + 1, loc.y, 0}, in_mux, 5); @@ -612,56 +728,67 @@ void route_mult_x2y2_upper_in1(Context *ctx, NetInfo *net, CellInfo *upper, Loc auto cpe_combout2 = ctx->getBelPinWire(upper->bel, id_OUT); auto cpe_out2_int = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("CPE.OUT2_int"))); + auto cpe_out2 = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("CPE.OUT2"))); auto in_mux = ctx->getWireByName(IdStringList::concat(x2y1, ctx->idf("IM.P01.D0"))); ctx->bindWire(cpe_combout2, net, STRENGTH_LOCKED); find_and_bind_downhill_pip(ctx, cpe_combout2, cpe_out2_int, net); + find_and_bind_downhill_pip(ctx, cpe_out2_int, cpe_out2, net); if (is_fourgroup_a) { auto sb_sml_p04_d0 = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_SML.P04.D0"))); auto sb_sml_p04_y1_int = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_SML.P04.Y1_int"))); auto sb_sml_p04_ydiag_int = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_SML.P04.YDIAG_int"))); - auto sb_sml_p04_ydiag = - ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_SML.P04.YDIAG"))); // AKA SB_SML.P03.X23 + auto sb_sml_p04_ydiag = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_SML.P04.YDIAG"))); + auto sb_sml_p03_x23 = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_SML.P03.X23"))); auto sb_sml_p03_ydiag_int = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_SML.P03.YDIAG_int"))); - auto sb_sml_p03_ydiag = - ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_SML.P03.YDIAG"))); // AKA SB_SML.P02.X23 + auto sb_sml_p03_ydiag = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_SML.P03.YDIAG"))); + auto sb_sml_p02_x23 = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_SML.P02.X23"))); auto sb_sml_p02_ydiag_int = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_SML.P02.YDIAG_int"))); - auto sb_sml_p02_ydiag = - ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_SML.P02.YDIAG"))); // AKA SB_SML.P01.X23 + auto sb_sml_p02_ydiag = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_SML.P02.YDIAG"))); + auto sb_sml_p01_x23 = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_SML.P01.X23"))); auto sb_sml_p01_ydiag_int = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_SML.P01.YDIAG_int"))); auto sb_sml_p01_y1_int = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_SML.P01.Y1_int"))); + auto sb_sml_p01_y1 = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_SML.P01.Y1"))); - find_and_bind_downhill_pip(ctx, cpe_out2_int, sb_sml_p04_d0, net); + find_and_bind_downhill_pip(ctx, cpe_out2, sb_sml_p04_d0, net); find_and_bind_downhill_pip(ctx, sb_sml_p04_d0, sb_sml_p04_y1_int, net); find_and_bind_downhill_pip(ctx, sb_sml_p04_y1_int, sb_sml_p04_ydiag_int, net); find_and_bind_downhill_pip(ctx, sb_sml_p04_ydiag_int, sb_sml_p04_ydiag, net); - find_and_bind_downhill_pip(ctx, sb_sml_p04_ydiag, sb_sml_p03_ydiag_int, net); + find_and_bind_downhill_pip(ctx, sb_sml_p04_ydiag, sb_sml_p03_x23, net); + find_and_bind_downhill_pip(ctx, sb_sml_p03_x23, sb_sml_p03_ydiag_int, net); find_and_bind_downhill_pip(ctx, sb_sml_p03_ydiag_int, sb_sml_p03_ydiag, net); - find_and_bind_downhill_pip(ctx, sb_sml_p03_ydiag, sb_sml_p02_ydiag_int, net); + find_and_bind_downhill_pip(ctx, sb_sml_p03_ydiag, sb_sml_p02_x23, net); + find_and_bind_downhill_pip(ctx, sb_sml_p02_x23, sb_sml_p02_ydiag_int, net); find_and_bind_downhill_pip(ctx, sb_sml_p02_ydiag_int, sb_sml_p02_ydiag, net); - find_and_bind_downhill_pip(ctx, sb_sml_p02_ydiag, sb_sml_p01_ydiag_int, net); + find_and_bind_downhill_pip(ctx, sb_sml_p02_ydiag, sb_sml_p01_x23, net); + find_and_bind_downhill_pip(ctx, sb_sml_p01_x23, sb_sml_p01_ydiag_int, net); find_and_bind_downhill_pip(ctx, sb_sml_p01_ydiag_int, sb_sml_p01_y1_int, net); - find_and_bind_downhill_pip(ctx, sb_sml_p01_y1_int, in_mux, net); + find_and_bind_downhill_pip(ctx, sb_sml_p01_y1_int, sb_sml_p01_y1, net); + find_and_bind_downhill_pip(ctx, sb_sml_p01_y1, in_mux, net); } else { auto sb_big_p04_d0 = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_BIG.P04.D0"))); auto sb_big_p04_y1 = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_BIG.P04.Y1"))); - auto sb_big_p04_ydiag = - ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_BIG.P04.YDIAG"))); // AKA SB_BIG.P07.X23 - auto sb_big_p03_ydiag = - ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_BIG.P03.YDIAG"))); // AKA SB_BIG.P05.X23 - auto sb_big_p02_ydiag = - ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_BIG.P02.YDIAG"))); // AKA SB_BIG.P05.X23 + auto sb_big_p04_ydiag = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_BIG.P04.YDIAG"))); + auto sb_big_p03_x23 = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_BIG.P03.X23"))); + auto sb_big_p03_ydiag = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_BIG.P03.YDIAG"))); + auto sb_big_p02_x23 = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_BIG.P02.X23"))); + auto sb_big_p02_ydiag = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_BIG.P02.YDIAG"))); + auto sb_big_p01_x23 = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_BIG.P01.X23"))); auto sb_big_p01_ydiag = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_BIG.P01.YDIAG"))); - // x2y1/IM.P05.D0 is x1y1/SB_BIG.P05.Y1 + auto sb_big_p01_y1 = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("SB_BIG.P01.Y1"))); - find_and_bind_downhill_pip(ctx, cpe_out2_int, sb_big_p04_d0, net); + find_and_bind_downhill_pip(ctx, cpe_out2, sb_big_p04_d0, net); find_and_bind_downhill_pip(ctx, sb_big_p04_d0, sb_big_p04_y1, net); find_and_bind_downhill_pip(ctx, sb_big_p04_y1, sb_big_p04_ydiag, net); - find_and_bind_downhill_pip(ctx, sb_big_p04_ydiag, sb_big_p03_ydiag, net); - find_and_bind_downhill_pip(ctx, sb_big_p03_ydiag, sb_big_p02_ydiag, net); - find_and_bind_downhill_pip(ctx, sb_big_p02_ydiag, sb_big_p01_ydiag, net); - find_and_bind_downhill_pip(ctx, sb_big_p01_ydiag, in_mux, net); + find_and_bind_downhill_pip(ctx, sb_big_p04_ydiag, sb_big_p03_x23, net); + find_and_bind_downhill_pip(ctx, sb_big_p03_x23, sb_big_p03_ydiag, net); + find_and_bind_downhill_pip(ctx, sb_big_p03_ydiag, sb_big_p02_x23, net); + find_and_bind_downhill_pip(ctx, sb_big_p02_x23, sb_big_p02_ydiag, net); + find_and_bind_downhill_pip(ctx, sb_big_p02_ydiag, sb_big_p01_x23, net); + find_and_bind_downhill_pip(ctx, sb_big_p01_x23, sb_big_p01_ydiag, net); + find_and_bind_downhill_pip(ctx, sb_big_p01_ydiag, sb_big_p01_y1, net); + find_and_bind_downhill_pip(ctx, sb_big_p01_y1, in_mux, net); } route_mult_diag(ctx, net, Loc{loc.x + 1, loc.y, 0}, in_mux, 1); @@ -680,45 +807,49 @@ void route_mult_x2y2_upper_in8(Context *ctx, NetInfo *net, CellInfo *upper, Loc auto cpe_combout2 = ctx->getBelPinWire(upper->bel, id_OUT); auto cpe_out2_int = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("CPE.OUT2_int"))); + auto cpe_out2 = ctx->getWireByName(IdStringList::concat(x1y1, ctx->idf("CPE.OUT2"))); auto in_mux = ctx->getWireByName(IdStringList::concat(x2y2, ctx->idf("IM.P08.D1"))); if (bind_route_start) { ctx->bindWire(cpe_combout2, net, STRENGTH_LOCKED); find_and_bind_downhill_pip(ctx, cpe_combout2, cpe_out2_int, net); - if (is_fourgroup_a) { - auto sb_big_d0 = ctx->getWireByName(IdStringList::concat(x0y0, ctx->idf("SB_BIG.P08.D0"))); - find_and_bind_downhill_pip(ctx, cpe_out2_int, sb_big_d0, net); - } else { - auto sb_sml_d0 = ctx->getWireByName(IdStringList::concat(x0y0, ctx->idf("SB_SML.P08.D0"))); - find_and_bind_downhill_pip(ctx, cpe_out2_int, sb_sml_d0, net); - } + find_and_bind_downhill_pip(ctx, cpe_out2_int, cpe_out2, net); } if (is_fourgroup_a) { auto sb_big_d0 = ctx->getWireByName(IdStringList::concat(x0y0, ctx->idf("SB_BIG.P08.D0"))); auto sb_big_y1 = ctx->getWireByName(IdStringList::concat(x0y0, ctx->idf("SB_BIG.P08.Y1"))); + auto sb_sml_d2_1 = ctx->getWireByName(IdStringList::concat(x2y0, ctx->idf("SB_SML.P08.D2_1"))); auto sb_sml_y1_int = ctx->getWireByName(IdStringList::concat(x2y0, ctx->idf("SB_SML.P08.Y1_int"))); auto sb_sml_ydiag_int = ctx->getWireByName(IdStringList::concat(x2y0, ctx->idf("SB_SML.P08.YDIAG_int"))); auto sb_sml_y2_int = ctx->getWireByName(IdStringList::concat(x2y0, ctx->idf("SB_SML.P08.Y2_int"))); + auto sb_sml_y2 = ctx->getWireByName(IdStringList::concat(x2y0, ctx->idf("SB_SML.P08.Y2"))); + find_and_bind_downhill_pip(ctx, cpe_out2, sb_big_d0, net); find_and_bind_downhill_pip(ctx, sb_big_d0, sb_big_y1, net); - find_and_bind_downhill_pip(ctx, sb_big_y1, sb_sml_y1_int, net); + find_and_bind_downhill_pip(ctx, sb_big_y1, sb_sml_d2_1, net); + find_and_bind_downhill_pip(ctx, sb_sml_d2_1, sb_sml_y1_int, net); find_and_bind_downhill_pip(ctx, sb_sml_y1_int, sb_sml_ydiag_int, net); find_and_bind_downhill_pip(ctx, sb_sml_ydiag_int, sb_sml_y2_int, net); - find_and_bind_downhill_pip(ctx, sb_sml_y2_int, in_mux, net); + find_and_bind_downhill_pip(ctx, sb_sml_y2_int, sb_sml_y2, net); + find_and_bind_downhill_pip(ctx, sb_sml_y2, in_mux, net); } else { auto sb_sml_d0 = ctx->getWireByName(IdStringList::concat(x0y0, ctx->idf("SB_SML.P08.D0"))); auto sb_sml_y1_int = ctx->getWireByName(IdStringList::concat(x0y0, ctx->idf("SB_SML.P08.Y1_int"))); auto sb_sml_y1 = ctx->getWireByName(IdStringList::concat(x0y0, ctx->idf("SB_SML.P08.Y1"))); + auto sb_big_d2_1 = ctx->getWireByName(IdStringList::concat(x2y0, ctx->idf("SB_BIG.P08.D2_1"))); auto sb_big_y1 = ctx->getWireByName(IdStringList::concat(x2y0, ctx->idf("SB_BIG.P08.Y1"))); auto sb_big_ydiag = ctx->getWireByName(IdStringList::concat(x2y0, ctx->idf("SB_BIG.P08.YDIAG"))); - // x2y2/IM.P08.D0 is x2y0/SB_BIG.P08.Y2 + auto sb_big_y2 = ctx->getWireByName(IdStringList::concat(x2y0, ctx->idf("SB_BIG.P08.Y2"))); + find_and_bind_downhill_pip(ctx, cpe_out2, sb_sml_d0, net); find_and_bind_downhill_pip(ctx, sb_sml_d0, sb_sml_y1_int, net); find_and_bind_downhill_pip(ctx, sb_sml_y1_int, sb_sml_y1, net); - find_and_bind_downhill_pip(ctx, sb_sml_y1, sb_big_y1, net); + find_and_bind_downhill_pip(ctx, sb_sml_y1, sb_big_d2_1, net); + find_and_bind_downhill_pip(ctx, sb_big_d2_1, sb_big_y1, net); find_and_bind_downhill_pip(ctx, sb_big_y1, sb_big_ydiag, net); - find_and_bind_downhill_pip(ctx, sb_big_ydiag, in_mux, net); + find_and_bind_downhill_pip(ctx, sb_big_ydiag, sb_big_y2, net); + find_and_bind_downhill_pip(ctx, sb_big_y2, in_mux, net); } route_mult_diag(ctx, net, Loc{loc.x + 1, loc.y + 1, 0}, in_mux, 8);