Add archcheck for partition methods.

Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com>
This commit is contained in:
Keith Rothman 2021-01-28 16:48:22 -08:00
parent f3a7c691a3
commit b4160c228e
4 changed files with 113 additions and 3 deletions

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -51,6 +51,7 @@ typedef IdString WireId;
typedef IdString PipId;
typedef IdString GroupId;
typedef IdString DecalId;
typedef IdString PartitionId;
struct ArchNetInfo
{