diff options
Diffstat (limited to 'common')
-rw-r--r-- | common/archcheck.cc | 30 | ||||
-rw-r--r-- | common/base_arch.h | 2 | ||||
-rw-r--r-- | common/idstringlist.cc | 19 | ||||
-rw-r--r-- | common/idstringlist.h | 3 | ||||
-rw-r--r-- | common/router2.cc | 9 |
5 files changed, 58 insertions, 5 deletions
diff --git a/common/archcheck.cc b/common/archcheck.cc index 6702032e..f46db95c 100644 --- a/common/archcheck.cc +++ b/common/archcheck.cc @@ -28,6 +28,12 @@ USING_NEXTPNR_NAMESPACE +#ifndef ARCH_MISTRAL +// The LRU cache to reduce memory usage during the connectivity check relies on getPips() having some spacial locality, +// which the current CycloneV arch impl doesn't have. This may be fixed in the future, though. +#define USING_LRU_CACHE +#endif + namespace { void archcheck_names(const Context *ctx) @@ -248,6 +254,11 @@ void archcheck_conn(const Context *ctx) log_info("Checking all wires...\n"); +#ifndef USING_LRU_CACHE + std::unordered_map<PipId, WireId> pips_downhill; + std::unordered_map<PipId, WireId> pips_uphill; +#endif + for (WireId wire : ctx->getWires()) { for (BelPin belpin : ctx->getWireBelPins(wire)) { WireId wire2 = ctx->getBelPinWire(belpin.bel, belpin.pin); @@ -257,11 +268,19 @@ void archcheck_conn(const Context *ctx) for (PipId pip : ctx->getPipsDownhill(wire)) { WireId wire2 = ctx->getPipSrcWire(pip); log_assert(wire == wire2); +#ifndef USING_LRU_CACHE + auto result = pips_downhill.emplace(pip, wire); + log_assert(result.second); +#endif } for (PipId pip : ctx->getPipsUphill(wire)) { WireId wire2 = ctx->getPipDstWire(pip); log_assert(wire == wire2); +#ifndef USING_LRU_CACHE + auto result = pips_uphill.emplace(pip, wire); + log_assert(result.second); +#endif } } @@ -285,7 +304,7 @@ void archcheck_conn(const Context *ctx) log_assert(found_belpin); } } - +#ifdef USING_LRU_CACHE // This cache is used to meet two goals: // - Avoid linear scan by invoking getPipsDownhill/getPipsUphill directly. // - Avoid having pip -> wire maps for the entire part. @@ -295,16 +314,25 @@ void archcheck_conn(const Context *ctx) // pip -> wire, assuming that pips are returned from getPips with some // chip locality. LruWireCacheMap pip_cache(ctx, /*cache_size=*/64 * 1024); +#endif log_info("Checking all PIPs...\n"); for (PipId pip : ctx->getPips()) { WireId src_wire = ctx->getPipSrcWire(pip); if (src_wire != WireId()) { +#ifdef USING_LRU_CACHE log_assert(pip_cache.isPipDownhill(pip, src_wire)); +#else + log_assert(pips_downhill.at(pip) == src_wire); +#endif } WireId dst_wire = ctx->getPipDstWire(pip); if (dst_wire != WireId()) { +#ifdef USING_LRU_CACHE log_assert(pip_cache.isPipUphill(pip, dst_wire)); +#else + log_assert(pips_uphill.at(pip) == dst_wire); +#endif } } } diff --git a/common/base_arch.h b/common/base_arch.h index e9cc8cf0..fbafee99 100644 --- a/common/base_arch.h +++ b/common/base_arch.h @@ -75,7 +75,7 @@ typename std::enable_if<std::is_same<Tret, Tc>::value, Tret>::type return_if_mat } template <typename Tret, typename Tc> -typename std::enable_if<!std::is_same<Tret, Tc>::value, Tret>::type return_if_match(Tret r) +typename std::enable_if<!std::is_same<Tret, Tc>::value, Tc>::type return_if_match(Tret r) { NPNR_ASSERT_FALSE("default implementations of cell type and bel bucket range functions only available when the " "respective range types are 'const std::vector&'"); diff --git a/common/idstringlist.cc b/common/idstringlist.cc index 9900f92a..6f6f8cd0 100644 --- a/common/idstringlist.cc +++ b/common/idstringlist.cc @@ -58,4 +58,23 @@ std::string IdStringList::str(const Context *ctx) const return s; } +IdStringList IdStringList::concat(IdStringList a, IdStringList b) +{ + IdStringList result(a.size() + b.size()); + for (size_t i = 0; i < a.size(); i++) + result.ids[i] = a[i]; + for (size_t i = 0; i < b.size(); i++) + result.ids[a.size() + i] = b[i]; + return result; +} + +IdStringList IdStringList::slice(size_t s, size_t e) const +{ + NPNR_ASSERT(e >= s); + IdStringList result(e - s); + for (size_t i = 0; i < result.size(); i++) + result.ids[i] = ids[s + i]; + return result; +} + NEXTPNR_NAMESPACE_END diff --git a/common/idstringlist.h b/common/idstringlist.h index 6a6a554d..24a46731 100644 --- a/common/idstringlist.h +++ b/common/idstringlist.h @@ -64,6 +64,9 @@ struct IdStringList } return false; } + + static IdStringList concat(IdStringList a, IdStringList b); + IdStringList slice(size_t s, size_t e) const; }; NEXTPNR_NAMESPACE_END diff --git a/common/router2.cc b/common/router2.cc index 59763f86..ebd4e390 100644 --- a/common/router2.cc +++ b/common/router2.cc @@ -710,10 +710,12 @@ struct Router2 if (is_bb && !hit_test_pip(nd.bb, ctx->getPipLocation(dh))) continue; if (!ctx->checkPipAvailForNet(dh, net)) { +#if 0 ROUTE_LOG_DBG("Skipping pip %s because it is bound to net '%s' not net '%s'\n", ctx->nameOfPip(dh), ctx->getBoundPipNet(dh) != nullptr ? ctx->getBoundPipNet(dh)->name.c_str(ctx) : "<not a net>", net->name.c_str(ctx)); +#endif continue; } #endif @@ -833,9 +835,6 @@ struct Router2 // Ripup failed arcs to start with // Check if arc is already legally routed if (check_arc_routing(net, i, j)) { -#if 0 - ROUTE_LOG_DBG("Arc '%s' (user %zu, arc %zu) already routed skipping.\n", ctx->nameOf(net), i, j); -#endif continue; } @@ -902,10 +901,14 @@ struct Router2 ++net_data.fail_count; if ((net_data.fail_count % 3) == 0) { // Every three times a net fails to route, expand the bounding box to increase the search space +#ifndef ARCH_MISTRAL + // This patch seems to make thing worse for CycloneV, as it slows down the resolution of TD congestion, + // disable it net_data.bb.x0 = std::max(net_data.bb.x0 - 1, 0); net_data.bb.y0 = std::max(net_data.bb.y0 - 1, 0); net_data.bb.x1 = std::min(net_data.bb.x1 + 1, ctx->getGridDimX()); net_data.bb.y1 = std::min(net_data.bb.y1 + 1, ctx->getGridDimY()); +#endif } } } |