1
0
mirror of https://github.com/YosysHQ/nextpnr.git synced 2026-01-11 23:53:21 +00:00

disable diagonal pips (with r2 debug code)

This commit is contained in:
Lofty 2025-09-09 12:14:22 +01:00
parent 8d99682f5e
commit f4f031bf16
4 changed files with 73 additions and 10 deletions

View File

@ -230,6 +230,8 @@ struct Router2
auto &ad = nd.arcs.at(usr.index.idx());
for (size_t phys_pin = 0; phys_pin < ad.size(); phys_pin++) {
if (check_arc_routing(net, usr.index, phys_pin)) {
if (ctx->debug)
log_info("prerouted arc: arc %d.%d of net '%s'\n", usr.index.idx(), phys_pin, net->name.c_str(ctx));
record_prerouted_net(net, usr.index, phys_pin);
}
}
@ -966,8 +968,10 @@ struct Router2
auto rstart = std::chrono::high_resolution_clock::now();
// Nothing to do if net is undriven
if (net->driver.cell == nullptr)
if (net->driver.cell == nullptr) {
ROUTE_LOG_DBG(" (net is undriven)\n");
return true;
}
bool have_failures = false;
t.processed_sinks.clear();
@ -984,6 +988,7 @@ struct Router2
// Ripup failed arcs to start with
// Check if arc is already legally routed
if (!failed_slack && check_arc_routing(net, usr.index, j)) {
ROUTE_LOG_DBG(" (arc %d.%d is already routed)\n", usr.index.idx(), j);
update_wire_by_loc(t, net, usr.index, j, true);
continue;
}
@ -1050,26 +1055,38 @@ struct Router2
overused_wires = 0;
total_wire_use = 0;
failed_nets.clear();
pool<WireId> already_updated;
dict<WireId, std::vector<IdString>> already_updated;
for (size_t i = 0; i < nets.size(); i++) {
auto &nd = nets.at(i);
for (const auto &w : nd.wires) {
++total_wire_use;
auto &wd = wire_data(w.first);
if (wd.curr_cong > 1) {
if (already_updated.count(w.first)) {
auto x = already_updated.find(w.first);
if (x != already_updated.end()) {
++total_overuse;
x->second.push_back(nets_by_udata.at(i)->name);
} else {
if (curr_cong_weight > 0)
wd.hist_cong_cost =
std::min(1e9, wd.hist_cong_cost + (wd.curr_cong - 1) * hist_cong_weight);
already_updated.insert(w.first);
already_updated.insert({w.first, std::vector<IdString>{nets_by_udata.at(i)->name}});
++overused_wires;
}
failed_nets.insert(i);
}
}
}
if (already_updated.size() <= 40) {
for (const auto& pair : already_updated) {
auto wire = pair.first;
auto& nets = pair.second;
log_info(" %s:\n", ctx->nameOfWire(wire));
for (auto net_name : nets) {
log_info(" %s\n", net_name.c_str(ctx));
}
}
}
for (int n : failed_nets) {
auto &net_data = nets.at(n);
++net_data.fail_count;

View File

@ -281,21 +281,66 @@ void GateMateImpl::postPlace()
repack();
ctx->assignArchInfo();
used_cpes.resize(ctx->getGridDimX() * ctx->getGridDimY());
for (auto &cell : ctx->cells) {
for (auto &cell_pair : ctx->cells) {
auto &cell = cell_pair.second;
// We need to skip CPE_MULT since using CP outputs is mandatory
// even if output is actually not connected
bool marked_used = cell.second.get()->type == id_CPE_MULT;
bool marked_used = cell->type == id_CPE_MULT;
// Can not use FF for OUT2 if CPE is used in bridge mode
if (cell.second.get()->type == id_CPE_FF && ctx->getBelLocation(cell.second.get()->bel).z == CPE_FF_U_Z)
if (cell->type == id_CPE_FF && ctx->getBelLocation(cell->bel).z == CPE_FF_U_Z)
marked_used = true;
if (marked_used)
used_cpes[cell.second.get()->bel.tile] = true;
used_cpes[cell->bel.tile] = true;
auto bel_z = ctx->getBelLocation(cell->bel).z;
if (bel_z != CPE_LT_L_Z && bel_z != CPE_LT_U_Z && bel_z != CPE_LT_FULL_Z)
continue;
IdString port_names[8] = {
id_IN1,
id_IN2,
id_IN3,
id_IN4,
id_IN5,
id_IN6,
id_IN7,
id_IN8
};
//log_info("disabling diagonals:\n");
for (auto cell_port_pin : port_names) {
if (!cell->ports.count(cell_port_pin))
continue;
auto cell_port_info = cell->ports.at(cell_port_pin);
bool used = cell_port_info.net != nullptr;
//log_info(" port %s.%s:\n", cell->name.c_str(ctx), cell_pin.c_str(ctx));
auto bel_pins = ctx->getBelPinsForCellPin(cell.get(), cell_port_pin);
for (auto bel_pin : bel_pins) {
auto bel_pin_wire = ctx->getBelPinWire(cell->bel, bel_pin);
if (bel_pin_wire == WireId())
continue;
//log_info(" wire %s\n", ctx->nameOfWire(bel_pin_wire));
for (auto uh : ctx->getPipsUphill(bel_pin_wire)) {
const auto &uh_extra_data = *pip_extra_data(uh);
if (!used && (uh_extra_data.flags & MUX_PERMUTATION) == MUX_PERMUTATION)
disabled_pips.insert(uh);
auto src = ctx->getPipSrcWire(uh);
for (auto dh : ctx->getPipsDownhill(src)) {
//log_info(" pip1 %s\n", ctx->nameOfPip(dh));
const auto &dh_extra_data = *pip_extra_data(dh);
if (used && (dh_extra_data.flags & MUX_DIAGONAL) == MUX_DIAGONAL)
disabled_pips.insert(dh);
}
}
}
}
}
}
bool GateMateImpl::checkPipAvail(PipId pip) const
{
const auto &extra_data = *pip_extra_data(pip);
if (extra_data.type == PipExtra::PIP_EXTRA_MUX && (extra_data.flags & MUX_DIAGONAL) == MUX_DIAGONAL) {
if (disabled_pips.count(pip)) {
//printf("pip :%s\n",ctx->getPipName(pip)[2].c_str(ctx));
return false;
}

View File

@ -90,6 +90,7 @@ struct GateMateImpl : HimbaechelAPI
dict<PipId, IdString> cpe_bridges;
int fpga_mode;
int timing_mode;
pool<PipId> disabled_pips;
private:
bool getChildPlacement(const BaseClusterInfo *cluster, Loc root_loc,

View File

@ -263,7 +263,7 @@ def main():
plane = int(mux.name[10:12])
if mux.name == "CPE.C_SN":
mux_flags |= MUX_ROUTING
if mux.name.startswith("CPE.IN") and mux.name.endswith("_int"):
if mux.name.startswith("CPE.IN") and mux.name.endswith("_int"):
mux_flags |= MUX_PERMUTATION
pp.extra_data = PipExtraData(PIP_EXTRA_MUX, ch.strs.id(mux.name), mux.bits, mux.value, mux_flags, plane)