diff options
author | gatecat <gatecat@ds0.me> | 2021-02-26 09:44:03 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-02-26 09:44:03 +0000 |
commit | 89928a0e6baf8b4ff39318c3655c7bd05df07057 (patch) | |
tree | fa7e840106221e28ded363fb4af557f38647d1ad | |
parent | 49fae990636b5b562355ffafdce7bc168bd1daf4 (diff) | |
parent | c64a9101512daf645d5244ffd737d2a0f162a9ba (diff) | |
download | nextpnr-89928a0e6baf8b4ff39318c3655c7bd05df07057.tar.gz nextpnr-89928a0e6baf8b4ff39318c3655c7bd05df07057.tar.bz2 nextpnr-89928a0e6baf8b4ff39318c3655c7bd05df07057.zip |
Merge pull request #599 from litghost/allow_router2_to_use_preroutes
Allow router2 to use routed but not fixed arcs.
-rw-r--r-- | common/router2.cc | 58 |
1 files changed, 54 insertions, 4 deletions
diff --git a/common/router2.cc b/common/router2.cc index f5779356..abe5f302 100644 --- a/common/router2.cc +++ b/common/router2.cc @@ -205,7 +205,7 @@ struct Router2 pwd.w = wire; NetInfo *bound = ctx->getBoundWireNet(wire); 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) pwd.unavailable = true; } @@ -217,6 +217,19 @@ struct Router2 wire_to_idx[wire] = int(flat_wires.size()); 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 @@ -393,6 +406,22 @@ struct Router2 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 bool is_wire_undriveable(WireId wire) { @@ -729,8 +758,10 @@ struct Router2 for (size_t j = 0; j < ad.size(); j++) { // Ripup failed arcs to start with // 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; + } auto &usr = net->users.at(i); WireId dst_wire = ctx->getNetinfoSinkWire(net, usr, j); // Case of arcs that were pre-routed strongly (e.g. clocks) @@ -812,12 +843,22 @@ struct Router2 return true; WireId dst = ctx->getNetinfoSinkWire(net, usr, phys_pin); // Skip routes where the destination is already bound - if (dst == WireId() || ctx->getBoundWireNet(dst) == net) + if (dst == WireId()) + 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) if (!ad.routed) { if ((src == dst) && ctx->getBoundWireNet(dst) != net) ctx->bindWire(src, net, STRENGTH_WEAK); + if (ctx->debug) { + log("Net %s not routed, not binding\n", ctx->nameOf(net)); + } return true; } @@ -875,11 +916,20 @@ struct Router2 // Ripup wires and pips used by the net in nextpnr's structures net_wires.clear(); for (auto &w : net->wires) { - if (w.second.strength <= STRENGTH_STRONG) + if (w.second.strength <= STRENGTH_STRONG) { 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) 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 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++) { |