ecp5: Prefer DCCs with dedicated routing when placing DCCs
Signed-off-by: David Shah <dave@ds0.me>
This commit is contained in:
parent
c5a3571a06
commit
4f8dfd8e1b
@ -290,6 +290,10 @@ class Ecp5GlobalRouter
|
|||||||
float tns;
|
float tns;
|
||||||
return get_net_metric(ctx, clki, MetricType::WIRELENGTH, tns);
|
return get_net_metric(ctx, clki, MetricType::WIRELENGTH, tns);
|
||||||
} else {
|
} 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
|
// Driver is locked
|
||||||
Loc dcc_loc = ctx->getBelLocation(dcc->bel);
|
Loc dcc_loc = ctx->getBelLocation(dcc->bel);
|
||||||
Loc drv_loc = ctx->getBelLocation(drv_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
|
// Attempt to place a DCC
|
||||||
void place_dcc(CellInfo *dcc)
|
void place_dcc(CellInfo *dcc)
|
||||||
{
|
{
|
||||||
@ -319,6 +360,8 @@ class Ecp5GlobalRouter
|
|||||||
ctx->bindBel(best_bel, dcc, STRENGTH_LOCKED);
|
ctx->bindBel(best_bel, dcc, STRENGTH_LOCKED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Insert a DCC into a net to promote it to a global
|
// Insert a DCC into a net to promote it to a global
|
||||||
NetInfo *insert_dcc(NetInfo *net)
|
NetInfo *insert_dcc(NetInfo *net)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user