diff options
Diffstat (limited to 'common')
-rw-r--r-- | common/archcheck.cc | 64 |
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 |