aboutsummaryrefslogtreecommitdiffstats
path: root/common/archcheck.cc
diff options
context:
space:
mode:
Diffstat (limited to 'common/archcheck.cc')
-rw-r--r--common/archcheck.cc64
1 files changed, 64 insertions, 0 deletions
diff --git a/common/archcheck.cc b/common/archcheck.cc
index 3c4c3133..1c5d57a0 100644
--- a/common/archcheck.cc
+++ b/common/archcheck.cc
@@ -51,6 +51,16 @@ void archcheck_names(const Context *ctx)
log_error("wire != wire2, name = %s\n", name.c_str(ctx));
}
}
+
+ log_info("Checking partition names..\n");
+ for(PartitionId partition : ctx->getPartitions()) {
+ IdString name = ctx->getPartitionName(partition);
+ PartitionId partition2 = ctx->getPartitionByName(name);
+ if (partition != partition2) {
+ log_error("partition != partition2, name = %s\n", name.c_str(ctx));
+ }
+ }
+
#ifndef ARCH_ECP5
log_info("Checking pip names..\n");
for (PipId pip : ctx->getPips()) {
@@ -187,6 +197,59 @@ void archcheck_conn(const Context *ctx)
}
}
+void archcheck_partitions(const Context *ctx)
+{
+ log_info("Checking partition data.\n");
+
+ // Partitions should be subsets of BELs that form an exact cover.
+ // In particular that means cell types in a partition should only be
+ // placable in that partition.
+ for(PartitionId partition : ctx->getPartitions()) {
+
+ // Find out which cell types are in this partition.
+ std::unordered_set<IdString> cell_types_in_partition;
+ for(IdString cell_type : ctx->getCellTypes()) {
+ if(ctx->getPartitionForCellType(cell_type) == partition) {
+ cell_types_in_partition.insert(cell_type);
+ }
+ }
+
+ // Make sure that all cell types in this partition have at least one
+ // BelId they can be placed at.
+ std::unordered_set<IdString> cell_types_unused;
+
+ std::unordered_set<BelId> bels_in_partition;
+ for(BelId bel : ctx->getBelsForPartition(partition)) {
+ PartitionId partition2 = ctx->getPartitionForBel(bel);
+ log_assert(partition == partition2);
+
+ bels_in_partition.insert(bel);
+
+ // Check to see if a cell type not in this partition can be
+ // placed at a BEL in this partition.
+ for(IdString cell_type : ctx->getCellTypes()) {
+ if(ctx->getPartitionForCellType(cell_type) == partition) {
+ if(ctx->isValidBelForCellType(cell_type, bel)) {
+ cell_types_unused.erase(cell_type);
+ }
+ } else {
+ log_assert(!ctx->isValidBelForCellType(cell_type, bel));
+ }
+ }
+ }
+
+ // Verify that any BEL not in this partition reports a different
+ // partition.
+ for(BelId bel : ctx->getBels()) {
+ if(ctx->getPartitionForBel(bel) != partition) {
+ log_assert(bels_in_partition.count(bel) == 0);
+ }
+ }
+
+ log_assert(cell_types_unused.empty());
+ }
+}
+
} // namespace
NEXTPNR_NAMESPACE_BEGIN
@@ -199,6 +262,7 @@ void Context::archcheck() const
archcheck_names(this);
archcheck_locs(this);
archcheck_conn(this);
+ archcheck_partitions(this);
}
NEXTPNR_NAMESPACE_END