From 8047369347b3540f1c5535b8791a547f2bf8f971 Mon Sep 17 00:00:00 2001 From: Hannah Ravensloft Date: Mon, 14 Jul 2025 00:54:58 +0100 Subject: [PATCH] better inversion verification --- himbaechel/uarch/gatemate/bitstream.cc | 50 ++++++++++++++++++++------ himbaechel/uarch/gatemate/gatemate.cc | 8 ++++- 2 files changed, 46 insertions(+), 12 deletions(-) diff --git a/himbaechel/uarch/gatemate/bitstream.cc b/himbaechel/uarch/gatemate/bitstream.cc index a6c70a5b..ed63bfe2 100644 --- a/himbaechel/uarch/gatemate/bitstream.cc +++ b/himbaechel/uarch/gatemate/bitstream.cc @@ -219,24 +219,52 @@ struct BitstreamBackend void check_multipliers() { + pool multiplier_nets; + for (auto *mult : uarch->multipliers) { NPNR_ASSERT(mult != nullptr); - auto should_be_inverted = mult->constr_x % 2 == 1; + multiplier_nets.insert(mult->ports.at(id_IN8).net->name); + multiplier_nets.insert(mult->ports.at(id_IN5).net->name); + multiplier_nets.insert(mult->ports.at(id_IN1).net->name); + } - // TODO: these are errors, but downgraded to allow providing *some* output. + for (auto net_name : multiplier_nets) { + auto *net = ctx->nets.at(net_name).get(); - // IN8 - if (need_inversion(mult, id_IN8) != should_be_inverted) - log_warning("%s.IN8 has wrong inversion state\n", mult->name.c_str(ctx)); + bool all_correct = true; + bool all_inverted = true; - // IN5 - if (need_inversion(mult, id_IN5) != should_be_inverted) - log_warning("%s.IN5 has wrong inversion state\n", mult->name.c_str(ctx)); + for (PortRef user : net->users) { + auto should_be_inverted = user.cell->constr_x % 2 == 1; + auto inversion = need_inversion(user.cell, user.port); + all_correct &= (inversion == should_be_inverted); + all_inverted &= (inversion != should_be_inverted); + } - // IN1 - if (need_inversion(mult, id_IN1) != should_be_inverted) - log_warning("%s.IN1 has wrong inversion state\n", mult->name.c_str(ctx)); + NPNR_ASSERT(!(all_correct && all_inverted) && "net doesn't drive any ports?"); + + if (!all_correct && !all_inverted) { + log_warning("multiplier net '%s' has inconsistent inversion\n", net_name.c_str(ctx)); + + log_warning(" these ports are not inverted:\n"); + for (PortRef user : net->users) { + auto should_be_inverted = user.cell->constr_x % 2 == 1; + auto inversion = need_inversion(user.cell, user.port); + if (inversion == should_be_inverted) + log_warning(" %s.%s\n", user.cell->name.c_str(ctx), user.port.c_str(ctx)); + } + + log_warning(" these ports are inverted:\n"); + for (PortRef user : net->users) { + auto should_be_inverted = user.cell->constr_x % 2 == 1; + auto inversion = need_inversion(user.cell, user.port); + if (inversion != should_be_inverted) + log_warning(" %s.%s\n", user.cell->name.c_str(ctx), user.port.c_str(ctx)); + } + } else if (all_inverted) { + log_info("multiplier net '%s' has fixable inversion (but I haven't implemented it yet)\n", net_name.c_str(ctx)); + } } } diff --git a/himbaechel/uarch/gatemate/gatemate.cc b/himbaechel/uarch/gatemate/gatemate.cc index b77872c2..78f03bf8 100644 --- a/himbaechel/uarch/gatemate/gatemate.cc +++ b/himbaechel/uarch/gatemate/gatemate.cc @@ -212,8 +212,11 @@ void GateMateImpl::preRoute() NPNR_ASSERT(from != WireId()); NPNR_ASSERT(to != WireId()); for (auto pip : ctx->getPipsDownhill(from)) { - if (ctx->getPipDstWire(pip) == to) + if (ctx->getPipDstWire(pip) == to) { + log_info(" pip %s\n", ctx->nameOfPip(pip)); + return pip; + } } log_error("Couldn't find pip from %s to %s\n", ctx->nameOfWire(from), ctx->nameOfWire(to)); }; @@ -276,6 +279,9 @@ void GateMateImpl::preRoute() ctx->bindPip(find_downhill_pip(in_mux_p04, in_mux_p08), upper_out, STRENGTH_USER); ctx->bindPip(find_downhill_pip(in_mux_p08, cpe_in8_int), upper_out, STRENGTH_USER); } + } else { + log_info(" don't know how to route net '%s'\n", lower_out->name.c_str(ctx)); + log_info(" don't know how to route net '%s'\n", upper_out->name.c_str(ctx)); } } }