aboutsummaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/archcheck.cc30
-rw-r--r--common/base_arch.h2
-rw-r--r--common/idstringlist.cc19
-rw-r--r--common/idstringlist.h3
-rw-r--r--common/router2.cc9
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
}
}
}