diff options
author | David Shah <dave@ds0.me> | 2018-11-07 14:36:42 +0000 |
---|---|---|
committer | David Shah <dave@ds0.me> | 2018-11-15 11:30:27 +0000 |
commit | 4f8dfd8e1b5276337f46a1e21bc9b0075450d10b (patch) | |
tree | d6efaad5f80d93e9b12d1913d24de2558c5f6090 | |
parent | c5a3571a061b1340355bb758be71a86922ee863f (diff) | |
download | nextpnr-4f8dfd8e1b5276337f46a1e21bc9b0075450d10b.tar.gz nextpnr-4f8dfd8e1b5276337f46a1e21bc9b0075450d10b.tar.bz2 nextpnr-4f8dfd8e1b5276337f46a1e21bc9b0075450d10b.zip |
ecp5: Prefer DCCs with dedicated routing when placing DCCs
Signed-off-by: David Shah <dave@ds0.me>
-rw-r--r-- | ecp5/globals.cc | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/ecp5/globals.cc b/ecp5/globals.cc index 9b0928a4..f2a556fa 100644 --- a/ecp5/globals.cc +++ b/ecp5/globals.cc @@ -290,6 +290,10 @@ class Ecp5GlobalRouter float tns; return get_net_metric(ctx, clki, MetricType::WIRELENGTH, tns); } else { + // Check for dedicated routing + if (has_short_route(ctx->getBelPinWire(drv_bel, drv.port), ctx->getBelPinWire(dcc->bel, id_CLKI))) { + return 0; + } // Driver is locked Loc dcc_loc = ctx->getBelLocation(dcc->bel); Loc drv_loc = ctx->getBelLocation(drv_bel); @@ -297,6 +301,43 @@ class Ecp5GlobalRouter } } + // Return true if a short (<5) route exists between two wires + bool has_short_route(WireId src, WireId dst, int thresh = 5) { + std::queue<WireId> visit; + std::unordered_map<WireId, PipId> backtrace; + visit.push(src); + WireId cursor; + while (true) { + + if (visit.empty() || visit.size() > 1000) { + log_info ("dist %s -> %s = inf\n", ctx->getWireName(src).c_str(ctx), ctx->getWireName(dst).c_str(ctx)); + return false; + } + cursor = visit.front(); + visit.pop(); + + if (cursor == dst) + break; + for (auto dh : ctx->getPipsDownhill(cursor)) { + WireId pipDst = ctx->getPipDstWire(dh); + if (backtrace.count(pipDst)) + continue; + backtrace[pipDst] = dh; + visit.push(pipDst); + } + } + int length = 0; + while (true) { + auto fnd = backtrace.find(cursor); + if (fnd == backtrace.end()) + break; + cursor = ctx->getPipSrcWire(fnd->second); + length++; + } + log_info ("dist %s -> %s = %d\n", ctx->getWireName(src).c_str(ctx), ctx->getWireName(dst).c_str(ctx), length); + return length < thresh; + } + // Attempt to place a DCC void place_dcc(CellInfo *dcc) { @@ -319,6 +360,8 @@ class Ecp5GlobalRouter ctx->bindBel(best_bel, dcc, STRENGTH_LOCKED); } + + // Insert a DCC into a net to promote it to a global NetInfo *insert_dcc(NetInfo *net) { |