From 186c910d0685876f96256ce79d75850307631077 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Tue, 10 Feb 2026 11:55:42 +0100 Subject: [PATCH] handle inversion bits for pass signals --- himbaechel/uarch/gatemate/bitstream.cc | 10 ++++++---- himbaechel/uarch/gatemate/gatemate.cc | 17 ++++++++++------- himbaechel/uarch/gatemate/gatemate.h | 3 ++- 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/himbaechel/uarch/gatemate/bitstream.cc b/himbaechel/uarch/gatemate/bitstream.cc index 1f5595cb..d4c215f5 100644 --- a/himbaechel/uarch/gatemate/bitstream.cc +++ b/himbaechel/uarch/gatemate/bitstream.cc @@ -65,10 +65,12 @@ struct BitstreamBackend WireId cursor = dst_wire; bool invert = false; - if (net_info->driver.cell && net_info->driver.cell->type == id_CPE_BRIDGE && - net_info->driver.port == id_MUXOUT) { - int val = int_or_default(net_info->driver.cell->params, id_C_SN, 0) + 1; - invert ^= need_inversion(net_info->driver.cell, ctx->idf("IN%d", val)); + if (net_info->driver.cell && uarch->pass_backtrace.count(net_info->driver.cell->name)) { + auto &bt = uarch->pass_backtrace[net_info->driver.cell->name]; + if (bt.count(net_info->driver.port)) { + IdString src_port = bt[net_info->driver.port]; + invert ^= need_inversion(net_info->driver.cell, src_port); + } } while (cursor != WireId() && cursor != src_wire) { auto it = net_info->wires.find(cursor); diff --git a/himbaechel/uarch/gatemate/gatemate.cc b/himbaechel/uarch/gatemate/gatemate.cc index 381b82fe..361fe656 100644 --- a/himbaechel/uarch/gatemate/gatemate.cc +++ b/himbaechel/uarch/gatemate/gatemate.cc @@ -472,6 +472,7 @@ void GateMateImpl::reassign_bridges(NetInfo *ni, const dict &net cell->connectPort(in_port, ni); cell->connectPort(id_MUXOUT, new_net); + pass_backtrace[cell->name][id_MUXOUT] = in_port; num++; @@ -480,7 +481,7 @@ void GateMateImpl::reassign_bridges(NetInfo *ni, const dict &net } void GateMateImpl::reassign_cplines(NetInfo *ni, const dict &net_wires, WireId wire, - dict &wire_to_net, int &num) + dict &wire_to_net, int &num, IdString in_port) { wire_to_net.insert({wire, ni->name}); @@ -501,7 +502,7 @@ void GateMateImpl::reassign_cplines(NetInfo *ni, const dict &net const auto &extra_data = *pip_extra_data(pip); // If not a CP line pip, just recurse. if (extra_data.type != PipExtra::PIP_EXTRA_MUX || extra_data.resource == 0) { - reassign_cplines(ni, net_wires, dst, wire_to_net, num); + reassign_cplines(ni, net_wires, dst, wire_to_net, num, in_port); continue; } @@ -557,9 +558,10 @@ void GateMateImpl::reassign_cplines(NetInfo *ni, const dict &net auto input_port_name = input_port_map.find(ctx->getWireName(ctx->getPipSrcWire(pip))[1]); if (input_port_name != input_port_map.end()) { - if (cell->getPort(input_port_name->second) == nullptr) + if (cell->getPort(input_port_name->second) == nullptr) { cell->connectPort(input_port_name->second, ni); - else + in_port = input_port_name->second; + } else NPNR_ASSERT(cell->getPort(input_port_name->second) == ni); } @@ -575,13 +577,14 @@ void GateMateImpl::reassign_cplines(NetInfo *ni, const dict &net cell->addOutput(output_port_name->second); cell->connectPort(output_port_name->second, new_net); + pass_backtrace[cell->name][output_port_name->second] = in_port; num++; - reassign_cplines(new_net, net_wires, dst, wire_to_net, num); + reassign_cplines(new_net, net_wires, dst, wire_to_net, num, in_port); } else { // this is an internal resource pip; recurse anyway. - reassign_cplines(ni, net_wires, dst, wire_to_net, num); + reassign_cplines(ni, net_wires, dst, wire_to_net, num, in_port); } } } @@ -676,7 +679,7 @@ void GateMateImpl::postRoute() } // traverse the routing tree to assign bridge nets to wires. - reassign_cplines(ni, net_wires, ctx->getNetinfoSourceWire(ni), wire_to_net, num); + reassign_cplines(ni, net_wires, ctx->getNetinfoSourceWire(ni), wire_to_net, num, IdString()); for (auto &pair : net_wires) ctx->unbindWire(pair.first); diff --git a/himbaechel/uarch/gatemate/gatemate.h b/himbaechel/uarch/gatemate/gatemate.h index 1f497a41..2d2d55e6 100644 --- a/himbaechel/uarch/gatemate/gatemate.h +++ b/himbaechel/uarch/gatemate/gatemate.h @@ -114,6 +114,7 @@ struct GateMateImpl : HimbaechelAPI MultiDieStrategy strategy; dict index_to_die; dict die_to_index; + dict> pass_backtrace; private: bool getChildPlacement(const BaseClusterInfo *cluster, Loc root_loc, @@ -129,7 +130,7 @@ struct GateMateImpl : HimbaechelAPI void reassign_bridges(NetInfo *net, const dict &net_wires, WireId wire, dict &wire_to_net, int &num); void reassign_cplines(NetInfo *net, const dict &net_wires, WireId wire, - dict &wire_to_net, int &num); + dict &wire_to_net, int &num, IdString in_port); void repack(); bool get_delay_from_tmg_db(IdString id, DelayQuad &delay) const;