aboutsummaryrefslogtreecommitdiffstats
path: root/common/router2.cc
diff options
context:
space:
mode:
authorgatecat <gatecat@ds0.me>2021-07-28 11:46:08 +0100
committergatecat <gatecat@ds0.me>2021-07-28 12:15:36 +0100
commitce92cdf8e48eafa478ce644df2025722b74f472d (patch)
tree451a912f0731ba3c1e22e957943c150474726fc3 /common/router2.cc
parent14c676ab494e5a412fde9f6c303317df1d7e1b80 (diff)
downloadnextpnr-ce92cdf8e48eafa478ce644df2025722b74f472d.tar.gz
nextpnr-ce92cdf8e48eafa478ce644df2025722b74f472d.tar.bz2
nextpnr-ce92cdf8e48eafa478ce644df2025722b74f472d.zip
router2: Update route delays even when routes are congested
Signed-off-by: gatecat <gatecat@ds0.me>
Diffstat (limited to 'common/router2.cc')
-rw-r--r--common/router2.cc44
1 files changed, 43 insertions, 1 deletions
diff --git a/common/router2.cc b/common/router2.cc
index 7bffc089..eb889e12 100644
--- a/common/router2.cc
+++ b/common/router2.cc
@@ -1314,6 +1314,47 @@ struct Router2
#endif
}
+ delay_t get_route_delay(int net, int usr_idx, int phys_idx)
+ {
+ auto &nd = nets.at(net);
+ auto &ad = nd.arcs.at(usr_idx).at(phys_idx);
+ WireId cursor = ad.sink_wire;
+ if (cursor == WireId() || nd.src_wire == WireId())
+ return 0;
+ delay_t delay = 0;
+ while (true) {
+ delay += ctx->getWireDelay(cursor).maxDelay();
+ const auto &wd = wire_data(cursor);
+ if (!wd.bound_nets.count(net))
+ break;
+ auto &bound = wd.bound_nets.at(net);
+ if (bound.second == PipId())
+ break;
+ delay += ctx->getPipDelay(bound.second).maxDelay();
+ cursor = ctx->getPipSrcWire(bound.second);
+ }
+ NPNR_ASSERT(cursor == nd.src_wire);
+ return delay;
+ }
+
+ void update_route_delays()
+ {
+ for (int net : route_queue) {
+ NetInfo *ni = nets_by_udata.at(net);
+#ifdef ARCH_ECP5
+ if (ni->is_global)
+ continue;
+#endif
+ auto &nd = nets.at(net);
+ for (int i = 0; i < int(nd.arcs.size()); i++) {
+ delay_t arc_delay = 0;
+ for (int j = 0; j < int(nd.arcs.at(i).size()); j++)
+ arc_delay = std::max(arc_delay, get_route_delay(net, i, j));
+ tmg.set_route_delay(CellPortKey(ni->users.at(i)), DelayPair(arc_delay));
+ }
+ }
+ }
+
void operator()()
{
log_info("Running router2...\n");
@@ -1341,7 +1382,7 @@ struct Router2
if (timing_driven && (int(route_queue.size()) > (int(nets_by_udata.size()) / 50))) {
// Heuristic: reduce runtime by skipping STA in the case of a "long tail" of a few
// congested nodes
- tmg.run();
+ tmg.run(iter == 1);
for (auto n : route_queue) {
NetInfo *ni = nets_by_udata.at(n);
auto &net = nets.at(n);
@@ -1363,6 +1404,7 @@ struct Router2
}
#endif
do_route();
+ update_route_delays();
route_queue.clear();
update_congestion();
#if 0