aboutsummaryrefslogtreecommitdiffstats
path: root/ecp5
diff options
context:
space:
mode:
authorDavid Shah <dave@ds0.me>2018-11-07 14:36:42 +0000
committerDavid Shah <dave@ds0.me>2018-11-15 11:30:27 +0000
commit4f8dfd8e1b5276337f46a1e21bc9b0075450d10b (patch)
treed6efaad5f80d93e9b12d1913d24de2558c5f6090 /ecp5
parentc5a3571a061b1340355bb758be71a86922ee863f (diff)
downloadnextpnr-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>
Diffstat (limited to 'ecp5')
-rw-r--r--ecp5/globals.cc43
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)
{