ecp5: Prefer DCCs with dedicated routing when placing DCCs

Signed-off-by: David Shah <dave@ds0.me>
This commit is contained in:
David Shah 2018-11-07 14:36:42 +00:00
parent c5a3571a06
commit 4f8dfd8e1b

View File

@ -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)
{