aboutsummaryrefslogtreecommitdiffstats
path: root/common/archcheck.cc
diff options
context:
space:
mode:
authorClifford Wolf <clifford@clifford.at>2018-07-23 14:03:23 +0200
committerClifford Wolf <clifford@clifford.at>2018-07-23 14:03:23 +0200
commite647604e2a584917ad2fc9acfe838a1395c613c2 (patch)
tree79af7f375362eeae2a0d9ee96c1bc6f09ab8fcce /common/archcheck.cc
parent90fe002a36a9b90cd6d003d34398242a5d5affb6 (diff)
downloadnextpnr-e647604e2a584917ad2fc9acfe838a1395c613c2.tar.gz
nextpnr-e647604e2a584917ad2fc9acfe838a1395c613c2.tar.bz2
nextpnr-e647604e2a584917ad2fc9acfe838a1395c613c2.zip
Add Context::archcheck() and "nextpnr-ice40 --test"
Signed-off-by: Clifford Wolf <clifford@clifford.at>
Diffstat (limited to 'common/archcheck.cc')
-rw-r--r--common/archcheck.cc146
1 files changed, 146 insertions, 0 deletions
diff --git a/common/archcheck.cc b/common/archcheck.cc
new file mode 100644
index 00000000..5c4ef26c
--- /dev/null
+++ b/common/archcheck.cc
@@ -0,0 +1,146 @@
+/*
+ * nextpnr -- Next Generation Place and Route
+ *
+ * Copyright (C) 2018 Clifford Wolf <clifford@symbioticeda.com>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+#include "nextpnr.h"
+#include "log.h"
+
+#if 0
+#define dbg(...) log(__VA_ARGS__)
+#else
+#define dbg(...)
+#endif
+
+USING_NEXTPNR_NAMESPACE
+
+namespace {
+
+void archcheck_names(const Context *ctx)
+{
+ log_info("Checking entity names.\n");
+
+ log_info("Checking bel names..\n");
+ for (BelId bel : ctx->getBels()) {
+ IdString name = ctx->getBelName(bel);
+ BelId bel2 = ctx->getBelByName(name);
+ log_assert(bel == bel2);
+ }
+
+ log_info("Checking wire names..\n");
+ for (WireId wire : ctx->getWires()) {
+ IdString name = ctx->getWireName(wire);
+ WireId wire2 = ctx->getWireByName(name);
+ log_assert(wire == wire2);
+ }
+
+ log_info("Checking pip names..\n");
+ for (PipId pip : ctx->getPips()) {
+ IdString name = ctx->getPipName(pip);
+ PipId pip2 = ctx->getPipByName(name);
+ log_assert(pip == pip2);
+ }
+
+ log_break();
+}
+
+void archcheck_locs(const Context *ctx)
+{
+ log_info("Checking location data.\n");
+
+ log_info("Checking all bels..\n");
+ for (BelId bel : ctx->getBels()) {
+ log_assert(bel != BelId());
+ dbg("> %s\n", ctx->getBelName(bel).c_str(ctx));
+
+ Loc loc = ctx->getBelLocation(bel);
+ dbg(" ... %d %d %d\n", loc.x, loc.y, loc.z);
+
+ log_assert(0 <= loc.x);
+ log_assert(0 <= loc.y);
+ log_assert(0 <= loc.z);
+ log_assert(loc.x < ctx->getGridDimX());
+ log_assert(loc.y < ctx->getGridDimY());
+ log_assert(loc.z < ctx->getTileDimZ(loc.x, loc.y));
+
+ BelId bel2 = ctx->getBelByLocation(loc);
+ dbg(" ... %s\n", ctx->getBelName(bel2).c_str(ctx));
+ log_assert(bel == bel2);
+ }
+
+ log_info("Checking all locations..\n");
+ for (int x = 0; x < ctx->getGridDimX(); x++)
+ for (int y = 0; y < ctx->getGridDimY(); y++)
+ {
+ dbg("> %d %d\n", x, y);
+ std::unordered_set<int> usedz;
+
+ for (int z = 0; z < ctx->getTileDimZ(x, y); z++) {
+ BelId bel = ctx->getBelByLocation(Loc(x, y, z));
+ if (bel == BelId())
+ continue;
+ Loc loc = ctx->getBelLocation(bel);
+ dbg(" + %d %s\n", z, ctx->getBelName(bel).c_str(ctx));
+ log_assert(x == loc.x);
+ log_assert(y == loc.y);
+ log_assert(z == loc.z);
+ usedz.insert(z);
+ }
+
+ for (BelId bel : ctx->getBelsByTile(x, y)) {
+ Loc loc = ctx->getBelLocation(bel);
+ dbg(" - %d %s\n", loc.z, ctx->getBelName(bel).c_str(ctx));
+ log_assert(x == loc.x);
+ log_assert(y == loc.y);
+ log_assert(usedz.count(loc.z));
+ usedz.erase(loc.z);
+ }
+
+ log_assert(usedz.empty());
+ }
+
+ log_break();
+}
+
+void archcheck_conn(const Context *ctx)
+{
+#if 0
+ log_info("Checking connectivity data.\n");
+
+ log_info("Checking all wires..\n");
+ for (WireId wire : ctx->getWires())
+ {
+ ...
+ }
+#endif
+}
+
+} // namespace
+
+NEXTPNR_NAMESPACE_BEGIN
+
+void Context::archcheck() const
+{
+ log_info("Running architecture database integrity check.\n");
+ log_break();
+
+ archcheck_names(this);
+ archcheck_locs(this);
+ archcheck_conn(this);
+}
+
+NEXTPNR_NAMESPACE_END