mirror of
https://github.com/YosysHQ/nextpnr.git
synced 2026-01-11 23:53:21 +00:00
gatemate: Include and use connection timing data (#1559)
* convert nodes to pips * add plane info for node pips * a few multiplier router fixes * do not need node delay * add pip delays * cleanup * tried fixing clock router * add PLL delays * fix clock routing * Do not use actual pip delay, determine best by number of passed pips * optimize * proper parameter check * more multiplier fixes * another mult fix * another multiplier fix * another multiplier fix * another multiplier fix * another multiplier fix * another multiplier fix * another multiplier fix * another multiplier fix * another multiplier fix * another multiplier fix * another multiplier fix * another multiplier fix * another multiplier fix * another multiplier fix * another multiplier fix * another multiplier fix * another multiplier fix * another multiplier fix * another multiplier fix * another multiplier fix * another multiplier fix * log number of clock net users * Revert "Do not use actual pip delay, determine best by number of passed pips" This reverts commit c66e422dd0814edfbfb81fdd6f9dcaaea9cece0d. We want to guarantee minimum clock skew, so we need pip delay. * route clocks from source to sink * add time spent to route_clock * weakly-bind non-global clocks * clangformat * remove dead code * Require version 1.8 * change to assert * add revisits in clock router --------- Co-authored-by: Lofty <dan.ravensloft@gmail.com>
This commit is contained in:
parent
8f8181c717
commit
8381827fa5
@ -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;
|
||||
}
|
||||
|
||||
@ -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():
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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<NetInfo *>{};
|
||||
auto reserved_wires = dict<WireId, IdString>{};
|
||||
|
||||
@ -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<WireId, PortRef>{};
|
||||
auto sink_wires_to_do = pool<WireId>{};
|
||||
for (auto &usr : clk_net->users) {
|
||||
std::priority_queue<QueuedWire, std::vector<QueuedWire>, std::greater<QueuedWire>> visit;
|
||||
dict<WireId, PipId> 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<QueuedWire, std::vector<QueuedWire>, std::greater<QueuedWire>> visit;
|
||||
dict<WireId, PipId> backtrace;
|
||||
dict<WireId, delay_t> 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<float>(rend - rstart).count());
|
||||
}
|
||||
|
||||
NEXTPNR_NAMESPACE_END
|
||||
|
||||
@ -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);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user