Merge pull request #599 from litghost/allow_router2_to_use_preroutes
Allow router2 to use routed but not fixed arcs.
This commit is contained in:
commit
89928a0e6b
@ -205,7 +205,7 @@ struct Router2
|
|||||||
pwd.w = wire;
|
pwd.w = wire;
|
||||||
NetInfo *bound = ctx->getBoundWireNet(wire);
|
NetInfo *bound = ctx->getBoundWireNet(wire);
|
||||||
if (bound != nullptr) {
|
if (bound != nullptr) {
|
||||||
pwd.bound_nets[bound->udata] = std::make_pair(1, bound->wires.at(wire).pip);
|
pwd.bound_nets[bound->udata] = std::make_pair(0, bound->wires.at(wire).pip);
|
||||||
if (bound->wires.at(wire).strength > STRENGTH_STRONG)
|
if (bound->wires.at(wire).strength > STRENGTH_STRONG)
|
||||||
pwd.unavailable = true;
|
pwd.unavailable = true;
|
||||||
}
|
}
|
||||||
@ -217,6 +217,19 @@ struct Router2
|
|||||||
wire_to_idx[wire] = int(flat_wires.size());
|
wire_to_idx[wire] = int(flat_wires.size());
|
||||||
flat_wires.push_back(pwd);
|
flat_wires.push_back(pwd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto net_pair : sorted(ctx->nets)) {
|
||||||
|
auto *net = net_pair.second;
|
||||||
|
auto &nd = nets.at(net->udata);
|
||||||
|
for (size_t usr = 0; usr < net->users.size(); usr++) {
|
||||||
|
auto &ad = nd.arcs.at(usr);
|
||||||
|
for (size_t phys_pin = 0; phys_pin < ad.size(); phys_pin++) {
|
||||||
|
if (check_arc_routing(net, usr, phys_pin)) {
|
||||||
|
record_prerouted_net(net, usr, phys_pin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct QueuedWire
|
struct QueuedWire
|
||||||
@ -393,6 +406,22 @@ struct Router2
|
|||||||
return (cursor == src_wire);
|
return (cursor == src_wire);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void record_prerouted_net(NetInfo *net, size_t usr, size_t phys_pin)
|
||||||
|
{
|
||||||
|
auto &ad = nets.at(net->udata).arcs.at(usr).at(phys_pin);
|
||||||
|
ad.routed = true;
|
||||||
|
|
||||||
|
WireId src = nets.at(net->udata).src_wire;
|
||||||
|
WireId cursor = ad.sink_wire;
|
||||||
|
while (cursor != src) {
|
||||||
|
size_t wire_idx = wire_to_idx.at(cursor);
|
||||||
|
auto &wd = flat_wires.at(wire_idx);
|
||||||
|
PipId pip = wd.bound_nets.at(net->udata).second;
|
||||||
|
bind_pip_internal(net, usr, wire_idx, pip);
|
||||||
|
cursor = ctx->getPipSrcWire(pip);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Returns true if a wire contains no source ports or driving pips
|
// Returns true if a wire contains no source ports or driving pips
|
||||||
bool is_wire_undriveable(WireId wire)
|
bool is_wire_undriveable(WireId wire)
|
||||||
{
|
{
|
||||||
@ -729,8 +758,10 @@ struct Router2
|
|||||||
for (size_t j = 0; j < ad.size(); j++) {
|
for (size_t j = 0; j < ad.size(); j++) {
|
||||||
// Ripup failed arcs to start with
|
// Ripup failed arcs to start with
|
||||||
// Check if arc is already legally routed
|
// Check if arc is already legally routed
|
||||||
if (check_arc_routing(net, i, j))
|
if (check_arc_routing(net, i, j)) {
|
||||||
|
ROUTE_LOG_DBG("Arc '%s' (user %zu, arc %zu) already routed skipping.\n", ctx->nameOf(net), i, j);
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
auto &usr = net->users.at(i);
|
auto &usr = net->users.at(i);
|
||||||
WireId dst_wire = ctx->getNetinfoSinkWire(net, usr, j);
|
WireId dst_wire = ctx->getNetinfoSinkWire(net, usr, j);
|
||||||
// Case of arcs that were pre-routed strongly (e.g. clocks)
|
// Case of arcs that were pre-routed strongly (e.g. clocks)
|
||||||
@ -812,12 +843,22 @@ struct Router2
|
|||||||
return true;
|
return true;
|
||||||
WireId dst = ctx->getNetinfoSinkWire(net, usr, phys_pin);
|
WireId dst = ctx->getNetinfoSinkWire(net, usr, phys_pin);
|
||||||
// Skip routes where the destination is already bound
|
// Skip routes where the destination is already bound
|
||||||
if (dst == WireId() || ctx->getBoundWireNet(dst) == net)
|
if (dst == WireId())
|
||||||
return true;
|
return true;
|
||||||
|
if (ctx->getBoundWireNet(dst) == net) {
|
||||||
|
if (ctx->debug) {
|
||||||
|
log("Net %s already bound (because wire %s is part of net), not binding\n", ctx->nameOf(net),
|
||||||
|
ctx->nameOfWire(dst));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
// Skip routes where there is no routing (special cases)
|
// Skip routes where there is no routing (special cases)
|
||||||
if (!ad.routed) {
|
if (!ad.routed) {
|
||||||
if ((src == dst) && ctx->getBoundWireNet(dst) != net)
|
if ((src == dst) && ctx->getBoundWireNet(dst) != net)
|
||||||
ctx->bindWire(src, net, STRENGTH_WEAK);
|
ctx->bindWire(src, net, STRENGTH_WEAK);
|
||||||
|
if (ctx->debug) {
|
||||||
|
log("Net %s not routed, not binding\n", ctx->nameOf(net));
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -875,11 +916,20 @@ struct Router2
|
|||||||
// Ripup wires and pips used by the net in nextpnr's structures
|
// Ripup wires and pips used by the net in nextpnr's structures
|
||||||
net_wires.clear();
|
net_wires.clear();
|
||||||
for (auto &w : net->wires) {
|
for (auto &w : net->wires) {
|
||||||
if (w.second.strength <= STRENGTH_STRONG)
|
if (w.second.strength <= STRENGTH_STRONG) {
|
||||||
net_wires.push_back(w.first);
|
net_wires.push_back(w.first);
|
||||||
|
} else if (ctx->debug) {
|
||||||
|
log("Net %s didn't rip up wire %s because strength was %d\n", ctx->nameOf(net),
|
||||||
|
ctx->nameOfWire(w.first), w.second.strength);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for (auto w : net_wires)
|
for (auto w : net_wires)
|
||||||
ctx->unbindWire(w);
|
ctx->unbindWire(w);
|
||||||
|
|
||||||
|
if (ctx->debug) {
|
||||||
|
log("Ripped up %zu wires on net %s\n", net_wires.size(), ctx->nameOf(net));
|
||||||
|
}
|
||||||
|
|
||||||
// Bind the arcs using the routes we have discovered
|
// Bind the arcs using the routes we have discovered
|
||||||
for (size_t i = 0; i < net->users.size(); i++) {
|
for (size_t i = 0; i < net->users.size(); i++) {
|
||||||
for (size_t phys_pin = 0; phys_pin < nets.at(net->udata).arcs.at(i).size(); phys_pin++) {
|
for (size_t phys_pin = 0; phys_pin < nets.at(net->udata).arcs.at(i).size(); phys_pin++) {
|
||||||
|
Loading…
Reference in New Issue
Block a user