aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeith Rothman <537074+litghost@users.noreply.github.com>2021-01-28 16:48:22 -0800
committerKeith Rothman <537074+litghost@users.noreply.github.com>2021-02-02 07:34:56 -0800
commitb4160c228e789639dc9f434100976c5eb1f95d8d (patch)
tree7a17215b2435a7a9531f1436bffc9b518e91f752
parentf3a7c691a317fafd48b9142ff0c688e75bbb6424 (diff)
downloadnextpnr-b4160c228e789639dc9f434100976c5eb1f95d8d.tar.gz
nextpnr-b4160c228e789639dc9f434100976c5eb1f95d8d.tar.bz2
nextpnr-b4160c228e789639dc9f434100976c5eb1f95d8d.zip
Add archcheck for partition methods.
Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com>
-rw-r--r--common/archcheck.cc64
-rw-r--r--docs/archapi.md23
-rw-r--r--generic/arch.h28
-rw-r--r--generic/archdefs.h1
4 files changed, 113 insertions, 3 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
diff --git a/docs/archapi.md b/docs/archapi.md
index 3a0efcce..53132bd9 100644
--- a/docs/archapi.md
+++ b/docs/archapi.md
@@ -88,6 +88,14 @@ Get Z dimension for the specified tile for bels. All bels with at specified X an
Get Z dimension for the specified tile for pips. All pips with at specified X and Y coordinates must have a Z coordinate in the range `0 .. getTileDimZ(X,Y)-1` (inclusive).
+Cell Methods
+-----------
+
+### const\_range\<IdString\> getCellTypes() const
+
+Get list of cell types that this architecture accepts.
+
+
Bel Methods
-----------
@@ -478,8 +486,8 @@ information for all edges. `index` must be in [0, clockInfoCount), behaviour is
Partition Methods
-----------------
-Partitions are used by analytic placement to seperate types of BELs during
-placement. Typical partitions are:
+Partitions are subsets of BelIds and cell types used by analytic placement to
+seperate types of BELs during placement. Typical partitions are:
- All LUT BELs
- All FF BELs
- All multipliers BELs
@@ -487,7 +495,8 @@ placement. Typical partitions are:
- etc.
The general rule here is to include all BELs that are roughly interchangable
-during placement.
+during placement. Partitions should form an exact cover over all BelIds and
+cell types.
### const\_range\<PartitionId\> getPartitions() const
@@ -497,8 +506,16 @@ Return a list of all partitions on the device.
Return the name of the partition.
+### PartitionId getPartitionByName(IdString partition\_name) const
+
+Return the partition for the specified partition name.
+
### PartitionId getPartitionForBel(BelId bel) const
+Returns the partition for a particular BEL.
+
+### PartitionId getPartitionForCell(IdString cell\_type) const
+
Returns the partition for a particular cell type.
### const\_range\<BelId\> getBelsForPartition(PartitionId partition) const
diff --git a/generic/arch.h b/generic/arch.h
index abe7ff7d..b1af5175 100644
--- a/generic/arch.h
+++ b/generic/arch.h
@@ -271,6 +271,34 @@ struct Arch : BaseCtx
bool place();
bool route();
+ std::vector<IdString> getCellTypes() const {
+ return {};
+ }
+
+ std::vector<PartitionId> getPartitions() const {
+ return {};
+ }
+
+ IdString getPartitionName(PartitionId partition) const {
+ return partition;
+ }
+
+ PartitionId getPartitionByName(IdString partition) const {
+ return partition;
+ }
+
+ PartitionId getPartitionForBel(BelId bel) const {
+ return getBelType(bel);
+ }
+
+ PartitionId getPartitionForCellType(IdString cell_type) const {
+ return cell_type;
+ }
+
+ std::vector<BelId> getBelsForPartition(PartitionId partition) const {
+ return {};
+ }
+
const std::vector<GraphicElement> &getDecalGraphics(DecalId decal) const;
DecalXY getBelDecal(BelId bel) const;
DecalXY getWireDecal(WireId wire) const;
diff --git a/generic/archdefs.h b/generic/archdefs.h
index 978c9c9b..cb78249a 100644
--- a/generic/archdefs.h
+++ b/generic/archdefs.h
@@ -51,6 +51,7 @@ typedef IdString WireId;
typedef IdString PipId;
typedef IdString GroupId;
typedef IdString DecalId;
+typedef IdString PartitionId;
struct ArchNetInfo
{