better inversion verification

This commit is contained in:
Hannah Ravensloft 2025-07-14 00:54:58 +01:00 committed by Lofty
parent f2c736ef81
commit 8047369347
2 changed files with 46 additions and 12 deletions

View File

@ -219,24 +219,52 @@ struct BitstreamBackend
void check_multipliers()
{
pool<IdString> 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));
}
}
}

View File

@ -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));
}
}
}