diff options
author | David Shah <dave@ds0.me> | 2020-02-03 13:33:20 +0000 |
---|---|---|
committer | David Shah <dave@ds0.me> | 2020-02-03 13:33:20 +0000 |
commit | a8206ed170589dee3ae83cc6af0a8d936d7639b7 (patch) | |
tree | 3cf5bf4a4a01810e1d400d88271519454f9aae5b | |
parent | ce144addb3644dcb4790b5861bd028d40fc6f15d (diff) | |
download | nextpnr-a8206ed170589dee3ae83cc6af0a8d936d7639b7.tar.gz nextpnr-a8206ed170589dee3ae83cc6af0a8d936d7639b7.tar.bz2 nextpnr-a8206ed170589dee3ae83cc6af0a8d936d7639b7.zip |
router2: Add a simple timing heuristic
Signed-off-by: David Shah <dave@ds0.me>
-rw-r--r-- | common/router2.cc | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/common/router2.cc b/common/router2.cc index 5ed007c3..11fa2d68 100644 --- a/common/router2.cc +++ b/common/router2.cc @@ -36,6 +36,7 @@ #include <thread> #include "log.h" #include "nextpnr.h" +#include "timing.h" #include "util.h" NEXTPNR_NAMESPACE_BEGIN @@ -61,6 +62,7 @@ struct Router2 // Coordinates of the center of the net, used for the weight-to-average int cx, cy, hpwl; int total_route_us = 0; + float max_crit = 0; }; struct WireScore @@ -111,6 +113,10 @@ struct Router2 // Use 'udata' for fast net lookups and indexing std::vector<NetInfo *> nets_by_udata; std::vector<PerNetData> nets; + + // Criticality data from timing analysis + NetCriticalityMap net_crit; + void setup_nets() { // Populate per-net and per-arc structures at start of routing @@ -1024,8 +1030,29 @@ struct Router2 for (size_t i = 0; i < nets_by_udata.size(); i++) route_queue.push_back(i); + bool timing_driven = ctx->setting<bool>("timing_driven"); + do { ctx->sorted_shuffle(route_queue); + + 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 + get_criticalities(ctx, &net_crit); + for (auto n : route_queue) { + IdString name = nets_by_udata.at(n)->name; + auto fnd = net_crit.find(name); + auto &net = nets.at(n); + net.max_crit = 0; + if (fnd == net_crit.end()) + continue; + for (auto c : fnd->second.criticality) + net.max_crit = std::max(net.max_crit, c); + } + std::stable_sort(route_queue.begin(), route_queue.end(), + [&](int na, int nb) { return nets.at(na).max_crit > nets.at(nb).max_crit; }); + } + #if 0 for (size_t j = 0; j < route_queue.size(); j++) { route_net(st, nets_by_udata[route_queue[j]], false); |