Add "checkPipAvailForNet" to Arch API.

This is important for distiguishing valid pseudo pips in the FPGA
interchange arch. This also avoids a double or triple lookup of
pip->net map.

Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com>
This commit is contained in:
Keith Rothman 2021-03-18 16:31:40 -07:00
parent 53ed6979a9
commit e7d81913a4
8 changed files with 30 additions and 16 deletions

View File

@ -93,6 +93,7 @@ template <typename R> struct ArchAPI : BaseCtx
virtual void bindPip(PipId pip, NetInfo *net, PlaceStrength strength) = 0; virtual void bindPip(PipId pip, NetInfo *net, PlaceStrength strength) = 0;
virtual void unbindPip(PipId pip) = 0; virtual void unbindPip(PipId pip) = 0;
virtual bool checkPipAvail(PipId pip) const = 0; virtual bool checkPipAvail(PipId pip) const = 0;
virtual bool checkPipAvailForNet(PipId pip, NetInfo *net) const = 0;
virtual NetInfo *getBoundPipNet(PipId pip) const = 0; virtual NetInfo *getBoundPipNet(PipId pip) const = 0;
virtual WireId getConflictingPipWire(PipId pip) const = 0; virtual WireId getConflictingPipWire(PipId pip) const = 0;
virtual NetInfo *getConflictingPipNet(PipId pip) const = 0; virtual NetInfo *getConflictingPipNet(PipId pip) const = 0;

View File

@ -243,6 +243,11 @@ template <typename R> struct BaseArch : ArchAPI<R>
p2n_entry = nullptr; p2n_entry = nullptr;
} }
virtual bool checkPipAvail(PipId pip) const override { return getBoundPipNet(pip) == nullptr; } virtual bool checkPipAvail(PipId pip) const override { return getBoundPipNet(pip) == nullptr; }
virtual bool checkPipAvailForNet(PipId pip, NetInfo *net) const override
{
NetInfo *bound_net = getBoundPipNet(pip);
return bound_net == nullptr || bound_net == net;
}
virtual NetInfo *getBoundPipNet(PipId pip) const override virtual NetInfo *getBoundPipNet(PipId pip) const override
{ {
auto fnd = base_pip2net.find(pip); auto fnd = base_pip2net.find(pip);

View File

@ -588,7 +588,7 @@ struct Router2
bool did_something = false; bool did_something = false;
for (auto uh : ctx->getPipsUphill(flat_wires[cursor].w)) { for (auto uh : ctx->getPipsUphill(flat_wires[cursor].w)) {
did_something = true; did_something = true;
if (!ctx->checkPipAvail(uh) && ctx->getBoundPipNet(uh) != net) if (!ctx->checkPipAvailForNet(uh, net))
continue; continue;
if (cpip != PipId() && cpip != uh) if (cpip != PipId() && cpip != uh)
continue; // don't allow multiple pips driving a wire with a net continue; // don't allow multiple pips driving a wire with a net
@ -675,19 +675,13 @@ struct Router2
#else #else
if (is_bb && !hit_test_pip(ad.bb, ctx->getPipLocation(dh))) if (is_bb && !hit_test_pip(ad.bb, ctx->getPipLocation(dh)))
continue; continue;
if (!ctx->checkPipAvail(dh)) { if (!ctx->checkPipAvailForNet(dh, net)) {
NetInfo *bound_net = ctx->getBoundPipNet(dh); ROUTE_LOG_DBG("Skipping pip %s because it is bound to net '%s' not net '%s'\n", ctx->nameOfPip(dh),
if (bound_net != net) { ctx->getBoundPipNet(dh) != nullptr ? ctx->getBoundPipNet(dh)->name.c_str(ctx)
if (bound_net != nullptr) { : "<not a net>",
ROUTE_LOG_DBG("Skipping pip %s because it is bound to net '%s' not net '%s'\n", net->name.c_str(ctx));
ctx->nameOfPip(dh), bound_net->name.c_str(ctx), net->name.c_str(ctx));
} else {
ROUTE_LOG_DBG("Skipping pip %s because it is reported not available\n", ctx->nameOfPip(dh));
}
continue; continue;
} }
}
#endif #endif
// Evaluate score of next wire // Evaluate score of next wire
WireId next = ctx->getPipDstWire(dh); WireId next = ctx->getPipDstWire(dh);

View File

@ -398,6 +398,13 @@ pip to a net.
*BaseArch default: returns `getBoundPipNet(pip) == nullptr`* *BaseArch default: returns `getBoundPipNet(pip) == nullptr`*
### bool checkPipAvailForNet(PipId pip, NetInfo *net) const
Returns true if the given pip is available to be bound to a net, or if the
pip is already bound to that net.
*BaseArch default: returns `getBoundPipNet(pip) == nullptr || getBoundPipNet(pip) == net`*
### NetInfo \*getBoundPipNet(PipId pip) const ### NetInfo \*getBoundPipNet(PipId pip) const
Return the net this pip is bound to. Return the net this pip is bound to.

View File

@ -1587,7 +1587,7 @@ void Arch::bindWire(WireId wire, NetInfo *net, PlaceStrength strength)
refreshUiWire(wire); refreshUiWire(wire);
} }
bool Arch::check_pip_avail_for_net(PipId pip, NetInfo *net) const bool Arch::checkPipAvailForNet(PipId pip, NetInfo *net) const
{ {
NPNR_ASSERT(pip != PipId()); NPNR_ASSERT(pip != PipId());
auto pip_iter = pip_to_net.find(pip); auto pip_iter = pip_to_net.find(pip);
@ -1725,7 +1725,7 @@ bool Arch::check_pip_avail_for_net(PipId pip, NetInfo *net) const
return true; return true;
} }
bool Arch::checkPipAvail(PipId pip) const { return check_pip_avail_for_net(pip, nullptr); } bool Arch::checkPipAvail(PipId pip) const { return checkPipAvailForNet(pip, nullptr); }
Arch::~Arch() {} Arch::~Arch() {}

View File

@ -536,7 +536,7 @@ struct Arch : ArchAPI<ArchRanges>
void unbindPip(PipId pip) final; void unbindPip(PipId pip) final;
bool checkPipAvail(PipId pip) const final; bool checkPipAvail(PipId pip) const final;
bool check_pip_avail_for_net(PipId pip, NetInfo *) const; bool checkPipAvailForNet(PipId pip, NetInfo *net) const final;
NetInfo *getBoundPipNet(PipId pip) const final NetInfo *getBoundPipNet(PipId pip) const final
{ {

View File

@ -450,6 +450,12 @@ void Arch::unbindPip(PipId pip)
bool Arch::checkPipAvail(PipId pip) const { return pips.at(pip).bound_net == nullptr; } bool Arch::checkPipAvail(PipId pip) const { return pips.at(pip).bound_net == nullptr; }
bool Arch::checkPipAvailForNet(PipId pip, NetInfo *net) const
{
NetInfo *bound_net = pips.at(pip).bound_net;
return bound_net == nullptr || bound_net == net;
}
NetInfo *Arch::getBoundPipNet(PipId pip) const { return pips.at(pip).bound_net; } NetInfo *Arch::getBoundPipNet(PipId pip) const { return pips.at(pip).bound_net; }
NetInfo *Arch::getConflictingPipNet(PipId pip) const { return pips.at(pip).bound_net; } NetInfo *Arch::getConflictingPipNet(PipId pip) const { return pips.at(pip).bound_net; }

View File

@ -279,6 +279,7 @@ struct Arch : ArchAPI<ArchRanges>
void bindPip(PipId pip, NetInfo *net, PlaceStrength strength) override; void bindPip(PipId pip, NetInfo *net, PlaceStrength strength) override;
void unbindPip(PipId pip) override; void unbindPip(PipId pip) override;
bool checkPipAvail(PipId pip) const override; bool checkPipAvail(PipId pip) const override;
bool checkPipAvailForNet(PipId pip, NetInfo *net) const override;
NetInfo *getBoundPipNet(PipId pip) const override; NetInfo *getBoundPipNet(PipId pip) const override;
WireId getConflictingPipWire(PipId pip) const override; WireId getConflictingPipWire(PipId pip) const override;
NetInfo *getConflictingPipNet(PipId pip) const override; NetInfo *getConflictingPipNet(PipId pip) const override;