/* * nextpnr -- Next Generation Place and Route * * Copyright (C) 2018 Clifford Wolf * * 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 "log.h" #include "nextpnr.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->getTileBelDimZ(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 usedz; for (int z = 0; z < ctx->getTileBelDimZ(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