Rename Partition -> BelBucket.
Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com>
This commit is contained in:
parent
11c80c048b
commit
9fe546f279
@ -52,12 +52,12 @@ void archcheck_names(const Context *ctx)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log_info("Checking partition names..\n");
|
log_info("Checking bucket names..\n");
|
||||||
for(PartitionId partition : ctx->getPartitions()) {
|
for(BelBucketId bucket : ctx->getBelBuckets()) {
|
||||||
IdString name = ctx->getPartitionName(partition);
|
IdString name = ctx->getBelBucketName(bucket);
|
||||||
PartitionId partition2 = ctx->getPartitionByName(name);
|
BelBucketId bucket2 = ctx->getBelBucketByName(name);
|
||||||
if (partition != partition2) {
|
if (bucket != bucket2) {
|
||||||
log_error("partition != partition2, name = %s\n", name.c_str(ctx));
|
log_error("bucket != bucket2, name = %s\n", name.c_str(ctx));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -197,38 +197,38 @@ void archcheck_conn(const Context *ctx)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void archcheck_partitions(const Context *ctx)
|
void archcheck_buckets(const Context *ctx)
|
||||||
{
|
{
|
||||||
log_info("Checking partition data.\n");
|
log_info("Checking bucket data.\n");
|
||||||
|
|
||||||
// Partitions should be subsets of BELs that form an exact cover.
|
// BEL buckets should be subsets of BELs that form an exact cover.
|
||||||
// In particular that means cell types in a partition should only be
|
// In particular that means cell types in a bucket should only be
|
||||||
// placable in that partition.
|
// placable in that bucket.
|
||||||
for(PartitionId partition : ctx->getPartitions()) {
|
for(BelBucketId bucket : ctx->getBelBuckets()) {
|
||||||
|
|
||||||
// Find out which cell types are in this partition.
|
// Find out which cell types are in this bucket.
|
||||||
std::unordered_set<IdString> cell_types_in_partition;
|
std::unordered_set<IdString> cell_types_in_bucket;
|
||||||
for(IdString cell_type : ctx->getCellTypes()) {
|
for(IdString cell_type : ctx->getCellTypes()) {
|
||||||
if(ctx->getPartitionForCellType(cell_type) == partition) {
|
if(ctx->getBelBucketForCellType(cell_type) == bucket) {
|
||||||
cell_types_in_partition.insert(cell_type);
|
cell_types_in_bucket.insert(cell_type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure that all cell types in this partition have at least one
|
// Make sure that all cell types in this bucket have at least one
|
||||||
// BelId they can be placed at.
|
// BelId they can be placed at.
|
||||||
std::unordered_set<IdString> cell_types_unused;
|
std::unordered_set<IdString> cell_types_unused;
|
||||||
|
|
||||||
std::unordered_set<BelId> bels_in_partition;
|
std::unordered_set<BelId> bels_in_bucket;
|
||||||
for(BelId bel : ctx->getBelsForPartition(partition)) {
|
for(BelId bel : ctx->getBelsInBucket(bucket)) {
|
||||||
PartitionId partition2 = ctx->getPartitionForBel(bel);
|
BelBucketId bucket2 = ctx->getBelBucketForBel(bel);
|
||||||
log_assert(partition == partition2);
|
log_assert(bucket == bucket2);
|
||||||
|
|
||||||
bels_in_partition.insert(bel);
|
bels_in_bucket.insert(bel);
|
||||||
|
|
||||||
// Check to see if a cell type not in this partition can be
|
// Check to see if a cell type not in this bucket can be
|
||||||
// placed at a BEL in this partition.
|
// placed at a BEL in this bucket.
|
||||||
for(IdString cell_type : ctx->getCellTypes()) {
|
for(IdString cell_type : ctx->getCellTypes()) {
|
||||||
if(ctx->getPartitionForCellType(cell_type) == partition) {
|
if(ctx->getBelBucketForCellType(cell_type) == bucket) {
|
||||||
if(ctx->isValidBelForCellType(cell_type, bel)) {
|
if(ctx->isValidBelForCellType(cell_type, bel)) {
|
||||||
cell_types_unused.erase(cell_type);
|
cell_types_unused.erase(cell_type);
|
||||||
}
|
}
|
||||||
@ -238,11 +238,11 @@ void archcheck_partitions(const Context *ctx)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify that any BEL not in this partition reports a different
|
// Verify that any BEL not in this bucket reports a different
|
||||||
// partition.
|
// bucket.
|
||||||
for(BelId bel : ctx->getBels()) {
|
for(BelId bel : ctx->getBels()) {
|
||||||
if(ctx->getPartitionForBel(bel) != partition) {
|
if(ctx->getBelBucketForBel(bel) != bucket) {
|
||||||
log_assert(bels_in_partition.count(bel) == 0);
|
log_assert(bels_in_bucket.count(bel) == 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -262,7 +262,7 @@ void Context::archcheck() const
|
|||||||
archcheck_names(this);
|
archcheck_names(this);
|
||||||
archcheck_locs(this);
|
archcheck_locs(this);
|
||||||
archcheck_conn(this);
|
archcheck_conn(this);
|
||||||
archcheck_partitions(this);
|
archcheck_buckets(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
NEXTPNR_NAMESPACE_END
|
NEXTPNR_NAMESPACE_END
|
||||||
|
@ -83,7 +83,7 @@ struct FastBels {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void addPartition(PartitionId partition) {
|
void addBelBucket(BelBucketId partition) {
|
||||||
auto iter = partition_types.find(partition);
|
auto iter = partition_types.find(partition);
|
||||||
if(iter != partition_types.end()) {
|
if(iter != partition_types.end()) {
|
||||||
// This partition has already been added to the fast BEL lookup.
|
// This partition has already been added to the fast BEL lookup.
|
||||||
@ -98,7 +98,7 @@ struct FastBels {
|
|||||||
auto &bel_data = fast_bels_by_partition_type.at(type_idx);
|
auto &bel_data = fast_bels_by_partition_type.at(type_idx);
|
||||||
|
|
||||||
for (auto bel : ctx->getBels()) {
|
for (auto bel : ctx->getBels()) {
|
||||||
if(ctx->getPartitionForBel(bel) != partition) {
|
if(ctx->getBelBucketForBel(bel) != partition) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,7 +110,7 @@ struct FastBels {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ctx->getPartitionForBel(bel) != partition) {
|
if(ctx->getBelBucketForBel(bel) != partition) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,10 +147,10 @@ struct FastBels {
|
|||||||
return cell_type_data.number_of_possible_bels;
|
return cell_type_data.number_of_possible_bels;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t getBelsForPartition(PartitionId partition, FastBelsData **data) {
|
size_t getBelsForBelBucket(BelBucketId partition, FastBelsData **data) {
|
||||||
auto iter = partition_types.find(partition);
|
auto iter = partition_types.find(partition);
|
||||||
if(iter == partition_types.end()) {
|
if(iter == partition_types.end()) {
|
||||||
addPartition(partition);
|
addBelBucket(partition);
|
||||||
iter = partition_types.find(partition);
|
iter = partition_types.find(partition);
|
||||||
NPNR_ASSERT(iter != partition_types.end());
|
NPNR_ASSERT(iter != partition_types.end());
|
||||||
}
|
}
|
||||||
@ -168,7 +168,7 @@ struct FastBels {
|
|||||||
std::unordered_map<IdString, TypeData> cell_types;
|
std::unordered_map<IdString, TypeData> cell_types;
|
||||||
std::vector<FastBelsData> fast_bels_by_cell_type;
|
std::vector<FastBelsData> fast_bels_by_cell_type;
|
||||||
|
|
||||||
std::unordered_map<PartitionId, TypeData> partition_types;
|
std::unordered_map<BelBucketId, TypeData> partition_types;
|
||||||
std::vector<FastBelsData> fast_bels_by_partition_type;
|
std::vector<FastBelsData> fast_bels_by_partition_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -177,21 +177,21 @@ class HeAPPlacer
|
|||||||
|
|
||||||
std::vector<std::tuple<CellInfo *, BelId, PlaceStrength>> solution;
|
std::vector<std::tuple<CellInfo *, BelId, PlaceStrength>> solution;
|
||||||
|
|
||||||
std::vector<std::unordered_set<PartitionId>> heap_runs;
|
std::vector<std::unordered_set<BelBucketId>> heap_runs;
|
||||||
std::unordered_set<PartitionId> all_partitions;
|
std::unordered_set<BelBucketId> all_buckets;
|
||||||
std::unordered_map<PartitionId, int> partition_count;
|
std::unordered_map<BelBucketId, int> bucket_count;
|
||||||
|
|
||||||
for (auto cell : place_cells) {
|
for (auto cell : place_cells) {
|
||||||
PartitionId partition = ctx->getPartitionForCellType(cell->type);
|
BelBucketId bucket = ctx->getBelBucketForCellType(cell->type);
|
||||||
if (!all_partitions.count(partition)) {
|
if (!all_buckets.count(bucket)) {
|
||||||
heap_runs.push_back(std::unordered_set<PartitionId>{partition});
|
heap_runs.push_back(std::unordered_set<BelBucketId>{bucket});
|
||||||
all_partitions.insert(partition);
|
all_buckets.insert(bucket);
|
||||||
}
|
}
|
||||||
partition_count[partition]++;
|
bucket_count[bucket]++;
|
||||||
}
|
}
|
||||||
// If more than 98% of cells are one cell type, always solve all at once
|
// If more than 98% of cells are one cell type, always solve all at once
|
||||||
// Otherwise, follow full HeAP strategy of rotate&all
|
// Otherwise, follow full HeAP strategy of rotate&all
|
||||||
for (auto &c : partition_count) {
|
for (auto &c : bucket_count) {
|
||||||
if (c.second >= 0.98 * int(place_cells.size())) {
|
if (c.second >= 0.98 * int(place_cells.size())) {
|
||||||
heap_runs.clear();
|
heap_runs.clear();
|
||||||
break;
|
break;
|
||||||
@ -205,7 +205,7 @@ class HeAPPlacer
|
|||||||
heap_runs.clear();
|
heap_runs.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
heap_runs.push_back(all_partitions);
|
heap_runs.push_back(all_buckets);
|
||||||
// The main HeAP placer loop
|
// The main HeAP placer loop
|
||||||
log_info("Running main analytical placer.\n");
|
log_info("Running main analytical placer.\n");
|
||||||
while (stalled < 5 && (solved_hpwl <= legal_hpwl * 0.8)) {
|
while (stalled < 5 && (solved_hpwl <= legal_hpwl * 0.8)) {
|
||||||
@ -242,7 +242,7 @@ class HeAPPlacer
|
|||||||
|
|
||||||
for (auto type : sorted(run))
|
for (auto type : sorted(run))
|
||||||
if (std::all_of(cfg.cellGroups.begin(), cfg.cellGroups.end(),
|
if (std::all_of(cfg.cellGroups.begin(), cfg.cellGroups.end(),
|
||||||
[type](const std::unordered_set<PartitionId> &grp) { return !grp.count(type); }))
|
[type](const std::unordered_set<BelBucketId> &grp) { return !grp.count(type); }))
|
||||||
CutSpreader(this, {type}).run();
|
CutSpreader(this, {type}).run();
|
||||||
|
|
||||||
update_all_chains();
|
update_all_chains();
|
||||||
@ -253,9 +253,9 @@ class HeAPPlacer
|
|||||||
legal_hpwl = total_hpwl();
|
legal_hpwl = total_hpwl();
|
||||||
auto run_stopt = std::chrono::high_resolution_clock::now();
|
auto run_stopt = std::chrono::high_resolution_clock::now();
|
||||||
|
|
||||||
IdString partition_name = ctx->getPartitionName(*run.begin());
|
IdString bucket_name = ctx->getBelBucketName(*run.begin());
|
||||||
log_info(" at iteration #%d, type %s: wirelen solved = %d, spread = %d, legal = %d; time = %.02fs\n",
|
log_info(" at iteration #%d, type %s: wirelen solved = %d, spread = %d, legal = %d; time = %.02fs\n",
|
||||||
iter + 1, (run.size() > 1 ? "ALL" : partition_name.c_str(ctx)), int(solved_hpwl),
|
iter + 1, (run.size() > 1 ? "ALL" : bucket_name.c_str(ctx)), int(solved_hpwl),
|
||||||
int(spread_hpwl), int(legal_hpwl),
|
int(spread_hpwl), int(legal_hpwl),
|
||||||
std::chrono::duration<double>(run_stopt - run_startt).count());
|
std::chrono::duration<double>(run_stopt - run_startt).count());
|
||||||
}
|
}
|
||||||
@ -421,19 +421,19 @@ class HeAPPlacer
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::unordered_set<IdString> cell_types_in_use;
|
std::unordered_set<IdString> cell_types_in_use;
|
||||||
std::unordered_set<PartitionId> partitions_in_use;
|
std::unordered_set<BelBucketId> buckets_in_use;
|
||||||
for (auto cell : sorted(ctx->cells)) {
|
for (auto cell : sorted(ctx->cells)) {
|
||||||
IdString cell_type = cell.second->type;
|
IdString cell_type = cell.second->type;
|
||||||
cell_types_in_use.insert(cell_type);
|
cell_types_in_use.insert(cell_type);
|
||||||
PartitionId partition = ctx->getPartitionForCellType(cell_type);
|
BelBucketId bucket = ctx->getBelBucketForCellType(cell_type);
|
||||||
partitions_in_use.insert(partition);
|
buckets_in_use.insert(bucket);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(auto cell_type : cell_types_in_use) {
|
for(auto cell_type : cell_types_in_use) {
|
||||||
fast_bels.addCellType(cell_type);
|
fast_bels.addCellType(cell_type);
|
||||||
}
|
}
|
||||||
for(auto partition : partitions_in_use) {
|
for(auto bucket : buckets_in_use) {
|
||||||
fast_bels.addPartition(partition);
|
fast_bels.addBelBucket(bucket);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine bounding boxes of region constraints
|
// Determine bounding boxes of region constraints
|
||||||
@ -576,7 +576,7 @@ class HeAPPlacer
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Setup the cells to be solved, returns the number of rows
|
// Setup the cells to be solved, returns the number of rows
|
||||||
int setup_solve_cells(std::unordered_set<PartitionId> *partitions = nullptr)
|
int setup_solve_cells(std::unordered_set<BelBucketId> *buckets = nullptr)
|
||||||
{
|
{
|
||||||
int row = 0;
|
int row = 0;
|
||||||
solve_cells.clear();
|
solve_cells.clear();
|
||||||
@ -585,7 +585,7 @@ class HeAPPlacer
|
|||||||
cell.second->udata = dont_solve;
|
cell.second->udata = dont_solve;
|
||||||
// Then update cells to be placed, which excludes cell children
|
// Then update cells to be placed, which excludes cell children
|
||||||
for (auto cell : place_cells) {
|
for (auto cell : place_cells) {
|
||||||
if (partitions && !partitions->count(ctx->getPartitionForCellType(cell->type)))
|
if (buckets && !buckets->count(ctx->getBelBucketForCellType(cell->type)))
|
||||||
continue;
|
continue;
|
||||||
cell->udata = row++;
|
cell->udata = row++;
|
||||||
solve_cells.push_back(cell);
|
solve_cells.push_back(cell);
|
||||||
@ -1078,14 +1078,14 @@ class HeAPPlacer
|
|||||||
class CutSpreader
|
class CutSpreader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CutSpreader(HeAPPlacer *p, const std::unordered_set<PartitionId> &partitions) : p(p), ctx(p->ctx), partitions(partitions)
|
CutSpreader(HeAPPlacer *p, const std::unordered_set<BelBucketId> &buckets) : p(p), ctx(p->ctx), buckets(buckets)
|
||||||
{
|
{
|
||||||
// Get fast BELs data for all partitions being Cut/Spread.
|
// Get fast BELs data for all buckets being Cut/Spread.
|
||||||
size_t idx = 0;
|
size_t idx = 0;
|
||||||
for (PartitionId partition : sorted(partitions)) {
|
for (BelBucketId bucket : sorted(buckets)) {
|
||||||
type_index[partition] = idx;
|
type_index[bucket] = idx;
|
||||||
FastBels::FastBelsData *fast_bels;
|
FastBels::FastBelsData *fast_bels;
|
||||||
p->fast_bels.getBelsForPartition(partition, &fast_bels);
|
p->fast_bels.getBelsForBelBucket(bucket, &fast_bels);
|
||||||
fb.push_back(fast_bels);
|
fb.push_back(fast_bels);
|
||||||
++idx;
|
++idx;
|
||||||
NPNR_ASSERT(fb.size() == idx);
|
NPNR_ASSERT(fb.size() == idx);
|
||||||
@ -1170,8 +1170,8 @@ class HeAPPlacer
|
|||||||
private:
|
private:
|
||||||
HeAPPlacer *p;
|
HeAPPlacer *p;
|
||||||
Context *ctx;
|
Context *ctx;
|
||||||
std::unordered_set<PartitionId> partitions;
|
std::unordered_set<BelBucketId> buckets;
|
||||||
std::unordered_map<PartitionId, size_t> type_index;
|
std::unordered_map<BelBucketId, size_t> type_index;
|
||||||
std::vector<std::vector<std::vector<int>>> occupancy;
|
std::vector<std::vector<std::vector<int>>> occupancy;
|
||||||
std::vector<std::vector<int>> groups;
|
std::vector<std::vector<int>> groups;
|
||||||
std::vector<std::vector<ChainExtent>> chaines;
|
std::vector<std::vector<ChainExtent>> chaines;
|
||||||
@ -1194,23 +1194,23 @@ class HeAPPlacer
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool is_cell_fixed(const CellInfo & cell) const {
|
bool is_cell_fixed(const CellInfo & cell) const {
|
||||||
return partitions.count(ctx->getPartitionForCellType(cell.type)) == 0;
|
return buckets.count(ctx->getBelBucketForCellType(cell.type)) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t cell_index(const CellInfo & cell) const {
|
size_t cell_index(const CellInfo & cell) const {
|
||||||
return type_index.at(ctx->getPartitionForCellType(cell.type));
|
return type_index.at(ctx->getBelBucketForCellType(cell.type));
|
||||||
}
|
}
|
||||||
|
|
||||||
void init()
|
void init()
|
||||||
{
|
{
|
||||||
occupancy.resize(p->max_x + 1,
|
occupancy.resize(p->max_x + 1,
|
||||||
std::vector<std::vector<int>>(p->max_y + 1, std::vector<int>(partitions.size(), 0)));
|
std::vector<std::vector<int>>(p->max_y + 1, std::vector<int>(buckets.size(), 0)));
|
||||||
groups.resize(p->max_x + 1, std::vector<int>(p->max_y + 1, -1));
|
groups.resize(p->max_x + 1, std::vector<int>(p->max_y + 1, -1));
|
||||||
chaines.resize(p->max_x + 1, std::vector<ChainExtent>(p->max_y + 1));
|
chaines.resize(p->max_x + 1, std::vector<ChainExtent>(p->max_y + 1));
|
||||||
cells_at_location.resize(p->max_x + 1, std::vector<std::vector<CellInfo *>>(p->max_y + 1));
|
cells_at_location.resize(p->max_x + 1, std::vector<std::vector<CellInfo *>>(p->max_y + 1));
|
||||||
for (int x = 0; x <= p->max_x; x++)
|
for (int x = 0; x <= p->max_x; x++)
|
||||||
for (int y = 0; y <= p->max_y; y++) {
|
for (int y = 0; y <= p->max_y; y++) {
|
||||||
for (int t = 0; t < int(partitions.size()); t++) {
|
for (int t = 0; t < int(buckets.size()); t++) {
|
||||||
occupancy.at(x).at(y).at(t) = 0;
|
occupancy.at(x).at(y).at(t) = 0;
|
||||||
}
|
}
|
||||||
groups.at(x).at(y) = -1;
|
groups.at(x).at(y) = -1;
|
||||||
@ -1292,7 +1292,7 @@ class HeAPPlacer
|
|||||||
// log_info("%d %d\n", groups.at(x).at(y), mergee.id);
|
// log_info("%d %d\n", groups.at(x).at(y), mergee.id);
|
||||||
NPNR_ASSERT(groups.at(x).at(y) == mergee.id);
|
NPNR_ASSERT(groups.at(x).at(y) == mergee.id);
|
||||||
groups.at(x).at(y) = merged.id;
|
groups.at(x).at(y) = merged.id;
|
||||||
for (size_t t = 0; t < partitions.size(); t++) {
|
for (size_t t = 0; t < buckets.size(); t++) {
|
||||||
merged.cells.at(t) += occ_at(x, y, t);
|
merged.cells.at(t) += occ_at(x, y, t);
|
||||||
merged.bels.at(t) += bels_at(x, y, t);
|
merged.bels.at(t) += bels_at(x, y, t);
|
||||||
}
|
}
|
||||||
@ -1317,7 +1317,7 @@ class HeAPPlacer
|
|||||||
auto process_location = [&](int x, int y) {
|
auto process_location = [&](int x, int y) {
|
||||||
// Merge with any overlapping regions
|
// Merge with any overlapping regions
|
||||||
if (groups.at(x).at(y) == -1) {
|
if (groups.at(x).at(y) == -1) {
|
||||||
for (size_t t = 0; t < partitions.size(); t++) {
|
for (size_t t = 0; t < buckets.size(); t++) {
|
||||||
r.bels.at(t) += bels_at(x, y, t);
|
r.bels.at(t) += bels_at(x, y, t);
|
||||||
r.cells.at(t) += occ_at(x, y, t);
|
r.cells.at(t) += occ_at(x, y, t);
|
||||||
}
|
}
|
||||||
@ -1352,7 +1352,7 @@ class HeAPPlacer
|
|||||||
if (groups.at(x).at(y) != -1)
|
if (groups.at(x).at(y) != -1)
|
||||||
continue;
|
continue;
|
||||||
bool overutilised = false;
|
bool overutilised = false;
|
||||||
for (size_t t = 0; t < partitions.size(); t++) {
|
for (size_t t = 0; t < buckets.size(); t++) {
|
||||||
if (occ_at(x, y, t) > bels_at(x, y, t)) {
|
if (occ_at(x, y, t) > bels_at(x, y, t)) {
|
||||||
overutilised = true;
|
overutilised = true;
|
||||||
break;
|
break;
|
||||||
@ -1368,7 +1368,7 @@ class HeAPPlacer
|
|||||||
reg.id = id;
|
reg.id = id;
|
||||||
reg.x0 = reg.x1 = x;
|
reg.x0 = reg.x1 = x;
|
||||||
reg.y0 = reg.y1 = y;
|
reg.y0 = reg.y1 = y;
|
||||||
for (size_t t = 0; t < partitions.size(); t++) {
|
for (size_t t = 0; t < buckets.size(); t++) {
|
||||||
reg.bels.push_back(bels_at(x, y, t));
|
reg.bels.push_back(bels_at(x, y, t));
|
||||||
reg.cells.push_back(occ_at(x, y, t));
|
reg.cells.push_back(occ_at(x, y, t));
|
||||||
}
|
}
|
||||||
@ -1385,7 +1385,7 @@ class HeAPPlacer
|
|||||||
if (reg.x1 < p->max_x) {
|
if (reg.x1 < p->max_x) {
|
||||||
bool over_occ_x = false;
|
bool over_occ_x = false;
|
||||||
for (int y1 = reg.y0; y1 <= reg.y1; y1++) {
|
for (int y1 = reg.y0; y1 <= reg.y1; y1++) {
|
||||||
for (size_t t = 0; t < partitions.size(); t++) {
|
for (size_t t = 0; t < buckets.size(); t++) {
|
||||||
if (occ_at(reg.x1 + 1, y1, t) > bels_at(reg.x1 + 1, y1, t)) {
|
if (occ_at(reg.x1 + 1, y1, t) > bels_at(reg.x1 + 1, y1, t)) {
|
||||||
over_occ_x = true;
|
over_occ_x = true;
|
||||||
break;
|
break;
|
||||||
@ -1401,7 +1401,7 @@ class HeAPPlacer
|
|||||||
if (reg.y1 < p->max_y) {
|
if (reg.y1 < p->max_y) {
|
||||||
bool over_occ_y = false;
|
bool over_occ_y = false;
|
||||||
for (int x1 = reg.x0; x1 <= reg.x1; x1++) {
|
for (int x1 = reg.x0; x1 <= reg.x1; x1++) {
|
||||||
for (size_t t = 0; t < partitions.size(); t++) {
|
for (size_t t = 0; t < buckets.size(); t++) {
|
||||||
if (occ_at(x1, reg.y1 + 1, t) > bels_at(x1, reg.y1 + 1, t)) {
|
if (occ_at(x1, reg.y1 + 1, t) > bels_at(x1, reg.y1 + 1, t)) {
|
||||||
over_occ_y = true;
|
over_occ_y = true;
|
||||||
break;
|
break;
|
||||||
@ -1463,12 +1463,12 @@ class HeAPPlacer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!changed) {
|
if (!changed) {
|
||||||
for (auto partition : sorted(partitions)) {
|
for (auto bucket : sorted(buckets)) {
|
||||||
if (reg.cells > reg.bels) {
|
if (reg.cells > reg.bels) {
|
||||||
IdString partition_name = ctx->getPartitionName(partition);
|
IdString bucket_name = ctx->getBelBucketName(bucket);
|
||||||
log_error("Failed to expand region (%d, %d) |_> (%d, %d) of %d %ss\n", reg.x0, reg.y0,
|
log_error("Failed to expand region (%d, %d) |_> (%d, %d) of %d %ss\n", reg.x0, reg.y0,
|
||||||
reg.x1, reg.y1, reg.cells.at(type_index.at(partition)),
|
reg.x1, reg.y1, reg.cells.at(type_index.at(bucket)),
|
||||||
partition_name.c_str(ctx));
|
bucket_name.c_str(ctx));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1490,7 +1490,7 @@ class HeAPPlacer
|
|||||||
for (int x = r.x0; x <= r.x1; x++) {
|
for (int x = r.x0; x <= r.x1; x++) {
|
||||||
for (int y = r.y0; y <= r.y1; y++) {
|
for (int y = r.y0; y <= r.y1; y++) {
|
||||||
std::copy(cal.at(x).at(y).begin(), cal.at(x).at(y).end(), std::back_inserter(cut_cells));
|
std::copy(cal.at(x).at(y).begin(), cal.at(x).at(y).end(), std::back_inserter(cut_cells));
|
||||||
for (size_t t = 0; t < partitions.size(); t++)
|
for (size_t t = 0; t < buckets.size(); t++)
|
||||||
total_bels += bels_at(x, y, t);
|
total_bels += bels_at(x, y, t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1543,7 +1543,7 @@ class HeAPPlacer
|
|||||||
while (trimmed_l < (dir ? r.y1 : r.x1)) {
|
while (trimmed_l < (dir ? r.y1 : r.x1)) {
|
||||||
bool have_bels = false;
|
bool have_bels = false;
|
||||||
for (int i = dir ? r.x0 : r.y0; i <= (dir ? r.x1 : r.y1); i++) {
|
for (int i = dir ? r.x0 : r.y0; i <= (dir ? r.x1 : r.y1); i++) {
|
||||||
for (size_t t = 0; t < partitions.size(); t++) {
|
for (size_t t = 0; t < buckets.size(); t++) {
|
||||||
if (bels_at(dir ? i : trimmed_l, dir ? trimmed_l : i, t) > 0) {
|
if (bels_at(dir ? i : trimmed_l, dir ? trimmed_l : i, t) > 0) {
|
||||||
have_bels = true;
|
have_bels = true;
|
||||||
break;
|
break;
|
||||||
@ -1559,7 +1559,7 @@ class HeAPPlacer
|
|||||||
while (trimmed_r > (dir ? r.y0 : r.x0)) {
|
while (trimmed_r > (dir ? r.y0 : r.x0)) {
|
||||||
bool have_bels = false;
|
bool have_bels = false;
|
||||||
for (int i = dir ? r.x0 : r.y0; i <= (dir ? r.x1 : r.y1); i++) {
|
for (int i = dir ? r.x0 : r.y0; i <= (dir ? r.x1 : r.y1); i++) {
|
||||||
for (size_t t = 0; t < partitions.size(); t++) {
|
for (size_t t = 0; t < buckets.size(); t++) {
|
||||||
if (bels_at(dir ? i : trimmed_r, dir ? trimmed_r : i, t) > 0) {
|
if (bels_at(dir ? i : trimmed_r, dir ? trimmed_r : i, t) > 0) {
|
||||||
have_bels = true;
|
have_bels = true;
|
||||||
break;
|
break;
|
||||||
@ -1577,8 +1577,8 @@ class HeAPPlacer
|
|||||||
return {};
|
return {};
|
||||||
// Now find the initial target cut that minimises utilisation imbalance, whilst
|
// Now find the initial target cut that minimises utilisation imbalance, whilst
|
||||||
// meeting the clearance requirements for any large macros
|
// meeting the clearance requirements for any large macros
|
||||||
std::vector<int> left_cells_v(partitions.size(), 0), right_cells_v(partitions.size(), 0);
|
std::vector<int> left_cells_v(buckets.size(), 0), right_cells_v(buckets.size(), 0);
|
||||||
std::vector<int> left_bels_v(partitions.size(), 0), right_bels_v(r.bels);
|
std::vector<int> left_bels_v(buckets.size(), 0), right_bels_v(r.bels);
|
||||||
for (int i = 0; i <= pivot; i++)
|
for (int i = 0; i <= pivot; i++)
|
||||||
left_cells_v.at(cell_index(*cut_cells.at(i))) +=
|
left_cells_v.at(cell_index(*cut_cells.at(i))) +=
|
||||||
p->chain_size.count(cut_cells.at(i)->name) ? p->chain_size.at(cut_cells.at(i)->name) : 1;
|
p->chain_size.count(cut_cells.at(i)->name) ? p->chain_size.at(cut_cells.at(i)->name) : 1;
|
||||||
@ -1589,15 +1589,15 @@ class HeAPPlacer
|
|||||||
int best_tgt_cut = -1;
|
int best_tgt_cut = -1;
|
||||||
double best_deltaU = std::numeric_limits<double>::max();
|
double best_deltaU = std::numeric_limits<double>::max();
|
||||||
// std::pair<int, int> target_cut_bels;
|
// std::pair<int, int> target_cut_bels;
|
||||||
std::vector<int> slither_bels(partitions.size(), 0);
|
std::vector<int> slither_bels(buckets.size(), 0);
|
||||||
for (int i = trimmed_l; i <= trimmed_r; i++) {
|
for (int i = trimmed_l; i <= trimmed_r; i++) {
|
||||||
for (size_t t = 0; t < partitions.size(); t++)
|
for (size_t t = 0; t < buckets.size(); t++)
|
||||||
slither_bels.at(t) = 0;
|
slither_bels.at(t) = 0;
|
||||||
for (int j = dir ? r.x0 : r.y0; j <= (dir ? r.x1 : r.y1); j++) {
|
for (int j = dir ? r.x0 : r.y0; j <= (dir ? r.x1 : r.y1); j++) {
|
||||||
for (size_t t = 0; t < partitions.size(); t++)
|
for (size_t t = 0; t < buckets.size(); t++)
|
||||||
slither_bels.at(t) += dir ? bels_at(j, i, t) : bels_at(i, j, t);
|
slither_bels.at(t) += dir ? bels_at(j, i, t) : bels_at(i, j, t);
|
||||||
}
|
}
|
||||||
for (size_t t = 0; t < partitions.size(); t++) {
|
for (size_t t = 0; t < buckets.size(); t++) {
|
||||||
left_bels_v.at(t) += slither_bels.at(t);
|
left_bels_v.at(t) += slither_bels.at(t);
|
||||||
right_bels_v.at(t) -= slither_bels.at(t);
|
right_bels_v.at(t) -= slither_bels.at(t);
|
||||||
}
|
}
|
||||||
@ -1605,7 +1605,7 @@ class HeAPPlacer
|
|||||||
if (((i - trimmed_l) + 1) >= clearance_l && ((trimmed_r - i) + 1) >= clearance_r) {
|
if (((i - trimmed_l) + 1) >= clearance_l && ((trimmed_r - i) + 1) >= clearance_r) {
|
||||||
// Solution is potentially valid
|
// Solution is potentially valid
|
||||||
double aU = 0;
|
double aU = 0;
|
||||||
for (size_t t = 0; t < partitions.size(); t++)
|
for (size_t t = 0; t < buckets.size(); t++)
|
||||||
aU += (left_cells_v.at(t) + right_cells_v.at(t)) *
|
aU += (left_cells_v.at(t) + right_cells_v.at(t)) *
|
||||||
std::abs(double(left_cells_v.at(t)) / double(std::max(left_bels_v.at(t), 1)) -
|
std::abs(double(left_cells_v.at(t)) / double(std::max(left_bels_v.at(t), 1)) -
|
||||||
double(right_cells_v.at(t)) / double(std::max(right_bels_v.at(t), 1)));
|
double(right_cells_v.at(t)) / double(std::max(right_bels_v.at(t), 1)));
|
||||||
@ -1619,19 +1619,19 @@ class HeAPPlacer
|
|||||||
return {};
|
return {};
|
||||||
// left_bels = target_cut_bels.first;
|
// left_bels = target_cut_bels.first;
|
||||||
// right_bels = target_cut_bels.second;
|
// right_bels = target_cut_bels.second;
|
||||||
for (size_t t = 0; t < partitions.size(); t++) {
|
for (size_t t = 0; t < buckets.size(); t++) {
|
||||||
left_bels_v.at(t) = 0;
|
left_bels_v.at(t) = 0;
|
||||||
right_bels_v.at(t) = 0;
|
right_bels_v.at(t) = 0;
|
||||||
}
|
}
|
||||||
for (int x = r.x0; x <= (dir ? r.x1 : best_tgt_cut); x++)
|
for (int x = r.x0; x <= (dir ? r.x1 : best_tgt_cut); x++)
|
||||||
for (int y = r.y0; y <= (dir ? best_tgt_cut : r.y1); y++) {
|
for (int y = r.y0; y <= (dir ? best_tgt_cut : r.y1); y++) {
|
||||||
for (size_t t = 0; t < partitions.size(); t++) {
|
for (size_t t = 0; t < buckets.size(); t++) {
|
||||||
left_bels_v.at(t) += bels_at(x, y, t);
|
left_bels_v.at(t) += bels_at(x, y, t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (int x = dir ? r.x0 : (best_tgt_cut + 1); x <= r.x1; x++)
|
for (int x = dir ? r.x0 : (best_tgt_cut + 1); x <= r.x1; x++)
|
||||||
for (int y = dir ? (best_tgt_cut + 1) : r.y0; y <= r.y1; y++) {
|
for (int y = dir ? (best_tgt_cut + 1) : r.y0; y <= r.y1; y++) {
|
||||||
for (size_t t = 0; t < partitions.size(); t++) {
|
for (size_t t = 0; t < buckets.size(); t++) {
|
||||||
right_bels_v.at(t) += bels_at(x, y, t);
|
right_bels_v.at(t) += bels_at(x, y, t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,7 @@ struct PlacerHeapCfg
|
|||||||
std::unordered_set<IdString> ioBufTypes;
|
std::unordered_set<IdString> ioBufTypes;
|
||||||
// These cell types are part of the same unit (e.g. slices split into
|
// These cell types are part of the same unit (e.g. slices split into
|
||||||
// components) so will always be spread together
|
// components) so will always be spread together
|
||||||
std::vector<std::unordered_set<PartitionId>> cellGroups;
|
std::vector<std::unordered_set<BelBucketId>> cellGroups;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern bool placer_heap(Context *ctx, PlacerHeapCfg cfg);
|
extern bool placer_heap(Context *ctx, PlacerHeapCfg cfg);
|
||||||
|
@ -124,9 +124,9 @@ Arch::Arch(ArchArgs args) : args(args)
|
|||||||
for(IdString bel_type : bel_types) {
|
for(IdString bel_type : bel_types) {
|
||||||
cell_types.push_back(bel_type);
|
cell_types.push_back(bel_type);
|
||||||
|
|
||||||
PartitionId partition;
|
BelBucketId bucket;
|
||||||
partition.name = bel_type;
|
bucket.name = bel_type;
|
||||||
partitions.push_back(partition);
|
buckets.push_back(bucket);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
38
ecp5/arch.h
38
ecp5/arch.h
@ -958,36 +958,36 @@ struct Arch : BaseCtx
|
|||||||
return cell_types;
|
return cell_types;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<PartitionId> getPartitions() const {
|
std::vector<BelBucketId> getBelBuckets() const {
|
||||||
return partitions;
|
return buckets;
|
||||||
}
|
}
|
||||||
|
|
||||||
IdString getPartitionName(PartitionId partition) const {
|
IdString getBelBucketName(BelBucketId bucket) const {
|
||||||
return partition.name;
|
return bucket.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
PartitionId getPartitionByName(IdString name) const {
|
BelBucketId getBelBucketByName(IdString name) const {
|
||||||
PartitionId partition;
|
BelBucketId bucket;
|
||||||
partition.name = name;
|
bucket.name = name;
|
||||||
return partition;
|
return bucket;
|
||||||
}
|
}
|
||||||
|
|
||||||
PartitionId getPartitionForBel(BelId bel) const {
|
BelBucketId getBelBucketForBel(BelId bel) const {
|
||||||
PartitionId partition;
|
BelBucketId bucket;
|
||||||
partition.name = getBelType(bel);
|
bucket.name = getBelType(bel);
|
||||||
return partition;
|
return bucket;
|
||||||
}
|
}
|
||||||
|
|
||||||
PartitionId getPartitionForCellType(IdString cell_type) const {
|
BelBucketId getBelBucketForCellType(IdString cell_type) const {
|
||||||
PartitionId partition;
|
BelBucketId bucket;
|
||||||
partition.name = cell_type;
|
bucket.name = cell_type;
|
||||||
return partition;
|
return bucket;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<BelId> getBelsForPartition(PartitionId partition) const {
|
std::vector<BelId> getBelsInBucket(BelBucketId bucket) const {
|
||||||
std::vector<BelId> bels;
|
std::vector<BelId> bels;
|
||||||
for(BelId bel : getBels()) {
|
for(BelId bel : getBels()) {
|
||||||
if(getBelType(bel) == partition.name) {
|
if(getBelType(bel) == bucket.name) {
|
||||||
bels.push_back(bel);
|
bels.push_back(bel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1068,7 +1068,7 @@ struct Arch : BaseCtx
|
|||||||
static const std::vector<std::string> availableRouters;
|
static const std::vector<std::string> availableRouters;
|
||||||
|
|
||||||
std::vector<IdString> cell_types;
|
std::vector<IdString> cell_types;
|
||||||
std::vector<PartitionId> partitions;
|
std::vector<BelBucketId> buckets;
|
||||||
};
|
};
|
||||||
|
|
||||||
NEXTPNR_NAMESPACE_END
|
NEXTPNR_NAMESPACE_END
|
||||||
|
@ -126,12 +126,12 @@ struct PipId
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PartitionId {
|
struct BelBucketId {
|
||||||
IdString name;
|
IdString name;
|
||||||
|
|
||||||
bool operator==(const PartitionId &other) const { return (name == other.name); }
|
bool operator==(const BelBucketId &other) const { return (name == other.name); }
|
||||||
bool operator!=(const PartitionId &other) const { return (name != other.name); }
|
bool operator!=(const BelBucketId &other) const { return (name != other.name); }
|
||||||
bool operator<(const PartitionId &other) const
|
bool operator<(const BelBucketId &other) const
|
||||||
{
|
{
|
||||||
return name < other.name;
|
return name < other.name;
|
||||||
}
|
}
|
||||||
@ -273,9 +273,9 @@ template <> struct hash<NEXTPNR_NAMESPACE_PREFIX DecalId>
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <> struct hash<NEXTPNR_NAMESPACE_PREFIX PartitionId>
|
template <> struct hash<NEXTPNR_NAMESPACE_PREFIX BelBucketId>
|
||||||
{
|
{
|
||||||
std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX PartitionId &partition) const noexcept
|
std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX BelBucketId &partition) const noexcept
|
||||||
{
|
{
|
||||||
std::size_t seed = 0;
|
std::size_t seed = 0;
|
||||||
boost::hash_combine(seed, hash<NEXTPNR_NAMESPACE_PREFIX IdString>()(partition.name));
|
boost::hash_combine(seed, hash<NEXTPNR_NAMESPACE_PREFIX IdString>()(partition.name));
|
||||||
|
@ -281,30 +281,30 @@ struct Arch : BaseCtx
|
|||||||
return cell_types;
|
return cell_types;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<PartitionId> getPartitions() const {
|
std::vector<BelBucketId> getBelBuckets() const {
|
||||||
return getCellTypes();
|
return getCellTypes();
|
||||||
}
|
}
|
||||||
|
|
||||||
IdString getPartitionName(PartitionId partition) const {
|
IdString getBelBucketName(BelBucketId bucket) const {
|
||||||
return partition;
|
return bucket;
|
||||||
}
|
}
|
||||||
|
|
||||||
PartitionId getPartitionByName(IdString partition) const {
|
BelBucketId getBelBucketByName(IdString bucket) const {
|
||||||
return partition;
|
return bucket;
|
||||||
}
|
}
|
||||||
|
|
||||||
PartitionId getPartitionForBel(BelId bel) const {
|
BelBucketId getBelBucketForBel(BelId bel) const {
|
||||||
return getBelType(bel);
|
return getBelType(bel);
|
||||||
}
|
}
|
||||||
|
|
||||||
PartitionId getPartitionForCellType(IdString cell_type) const {
|
BelBucketId getBelBucketForCellType(IdString cell_type) const {
|
||||||
return cell_type;
|
return cell_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<BelId> getBelsForPartition(PartitionId partition) const {
|
std::vector<BelId> getBelsInBucket(BelBucketId bucket) const {
|
||||||
std::vector<BelId> bels;
|
std::vector<BelId> bels;
|
||||||
for(BelId bel : getBels()) {
|
for(BelId bel : getBels()) {
|
||||||
if(partition == getPartitionForBel(bel)) {
|
if(bucket == getBelBucketForBel(bel)) {
|
||||||
bels.push_back(bel);
|
bels.push_back(bel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -51,7 +51,7 @@ typedef IdString WireId;
|
|||||||
typedef IdString PipId;
|
typedef IdString PipId;
|
||||||
typedef IdString GroupId;
|
typedef IdString GroupId;
|
||||||
typedef IdString DecalId;
|
typedef IdString DecalId;
|
||||||
typedef IdString PartitionId;
|
typedef IdString BelBucketId;
|
||||||
|
|
||||||
struct ArchNetInfo
|
struct ArchNetInfo
|
||||||
{
|
{
|
||||||
|
16
gowin/arch.h
16
gowin/arch.h
@ -430,30 +430,30 @@ struct Arch : BaseCtx
|
|||||||
return cell_types;
|
return cell_types;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<PartitionId> getPartitions() const {
|
std::vector<BelBucketId> getBelBuckets() const {
|
||||||
return cell_types;
|
return cell_types;
|
||||||
}
|
}
|
||||||
|
|
||||||
IdString getPartitionName(PartitionId partition) const {
|
IdString getBelBucketName(BelBucketId bucket) const {
|
||||||
return partition;
|
return bucket;
|
||||||
}
|
}
|
||||||
|
|
||||||
PartitionId getPartitionByName(IdString name) const {
|
BelBucketId getBelBucketByName(IdString name) const {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
PartitionId getPartitionForBel(BelId bel) const {
|
BelBucketId getBelBucketForBel(BelId bel) const {
|
||||||
return getBelType(bel);
|
return getBelType(bel);
|
||||||
}
|
}
|
||||||
|
|
||||||
PartitionId getPartitionForCellType(IdString cell_type) const {
|
BelBucketId getBelBucketForCellType(IdString cell_type) const {
|
||||||
return cell_type;
|
return cell_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<BelId> getBelsForPartition(PartitionId partition) const {
|
std::vector<BelId> getBelsInBucket(BelBucketId bucket) const {
|
||||||
std::vector<BelId> bels;
|
std::vector<BelId> bels;
|
||||||
for(BelId bel : getBels()) {
|
for(BelId bel : getBels()) {
|
||||||
if(getBelType(bel) == partition) {
|
if(getBelType(bel) == bucket) {
|
||||||
bels.push_back(bel);
|
bels.push_back(bel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -72,7 +72,7 @@ typedef IdString WireId;
|
|||||||
typedef IdString PipId;
|
typedef IdString PipId;
|
||||||
typedef IdString GroupId;
|
typedef IdString GroupId;
|
||||||
typedef IdString DecalId;
|
typedef IdString DecalId;
|
||||||
typedef IdString PartitionId;
|
typedef IdString BelBucketId;
|
||||||
|
|
||||||
struct ArchNetInfo
|
struct ArchNetInfo
|
||||||
{
|
{
|
||||||
|
@ -124,9 +124,9 @@ Arch::Arch(ArchArgs args) : args(args)
|
|||||||
for(IdString bel_type : bel_types) {
|
for(IdString bel_type : bel_types) {
|
||||||
cell_types.push_back(bel_type);
|
cell_types.push_back(bel_type);
|
||||||
|
|
||||||
PartitionId partition;
|
BelBucketId bucket;
|
||||||
partition.name = bel_type;
|
bucket.name = bel_type;
|
||||||
partitions.push_back(partition);
|
buckets.push_back(bucket);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
38
ice40/arch.h
38
ice40/arch.h
@ -830,36 +830,36 @@ struct Arch : BaseCtx
|
|||||||
return cell_types;
|
return cell_types;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<PartitionId> getPartitions() const {
|
std::vector<BelBucketId> getBelBuckets() const {
|
||||||
return partitions;
|
return buckets;
|
||||||
}
|
}
|
||||||
|
|
||||||
IdString getPartitionName(PartitionId partition) const {
|
IdString getBelBucketName(BelBucketId bucket) const {
|
||||||
return partition.name;
|
return bucket.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
PartitionId getPartitionByName(IdString name) const {
|
BelBucketId getBelBucketByName(IdString name) const {
|
||||||
PartitionId partition;
|
BelBucketId bucket;
|
||||||
partition.name = name;
|
bucket.name = name;
|
||||||
return partition;
|
return bucket;
|
||||||
}
|
}
|
||||||
|
|
||||||
PartitionId getPartitionForBel(BelId bel) const {
|
BelBucketId getBelBucketForBel(BelId bel) const {
|
||||||
PartitionId partition;
|
BelBucketId bucket;
|
||||||
partition.name = getBelType(bel);
|
bucket.name = getBelType(bel);
|
||||||
return partition;
|
return bucket;
|
||||||
}
|
}
|
||||||
|
|
||||||
PartitionId getPartitionForCellType(IdString cell_type) const {
|
BelBucketId getBelBucketForCellType(IdString cell_type) const {
|
||||||
PartitionId partition;
|
BelBucketId bucket;
|
||||||
partition.name = cell_type;
|
bucket.name = cell_type;
|
||||||
return partition;
|
return bucket;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<BelId> getBelsForPartition(PartitionId partition) const {
|
std::vector<BelId> getBelsInBucket(BelBucketId bucket) const {
|
||||||
std::vector<BelId> bels;
|
std::vector<BelId> bels;
|
||||||
for(BelId bel : getBels()) {
|
for(BelId bel : getBels()) {
|
||||||
if(getBelType(bel) == partition.name) {
|
if(getBelType(bel) == bucket.name) {
|
||||||
bels.push_back(bel);
|
bels.push_back(bel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -909,7 +909,7 @@ struct Arch : BaseCtx
|
|||||||
static const std::vector<std::string> availableRouters;
|
static const std::vector<std::string> availableRouters;
|
||||||
|
|
||||||
std::vector<IdString> cell_types;
|
std::vector<IdString> cell_types;
|
||||||
std::vector<PartitionId> partitions;
|
std::vector<BelBucketId> buckets;
|
||||||
};
|
};
|
||||||
|
|
||||||
void ice40DelayFuzzerMain(Context *ctx);
|
void ice40DelayFuzzerMain(Context *ctx);
|
||||||
|
@ -170,12 +170,12 @@ struct ArchCellInfo
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PartitionId {
|
struct BelBucketId {
|
||||||
IdString name;
|
IdString name;
|
||||||
|
|
||||||
bool operator==(const PartitionId &other) const { return (name == other.name); }
|
bool operator==(const BelBucketId &other) const { return (name == other.name); }
|
||||||
bool operator!=(const PartitionId &other) const { return (name != other.name); }
|
bool operator!=(const BelBucketId &other) const { return (name != other.name); }
|
||||||
bool operator<(const PartitionId &other) const
|
bool operator<(const BelBucketId &other) const
|
||||||
{
|
{
|
||||||
return name < other.name;
|
return name < other.name;
|
||||||
}
|
}
|
||||||
@ -225,12 +225,12 @@ template <> struct hash<NEXTPNR_NAMESPACE_PREFIX DecalId>
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <> struct hash<NEXTPNR_NAMESPACE_PREFIX PartitionId>
|
template <> struct hash<NEXTPNR_NAMESPACE_PREFIX BelBucketId>
|
||||||
{
|
{
|
||||||
std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX PartitionId &partition) const noexcept
|
std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX BelBucketId &bucket) const noexcept
|
||||||
{
|
{
|
||||||
std::size_t seed = 0;
|
std::size_t seed = 0;
|
||||||
boost::hash_combine(seed, hash<NEXTPNR_NAMESPACE_PREFIX IdString>()(partition.name));
|
boost::hash_combine(seed, hash<NEXTPNR_NAMESPACE_PREFIX IdString>()(bucket.name));
|
||||||
return seed;
|
return seed;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -180,9 +180,9 @@ Arch::Arch(ArchArgs args) : args(args)
|
|||||||
for(IdString bel_type : bel_types) {
|
for(IdString bel_type : bel_types) {
|
||||||
cell_types.push_back(bel_type);
|
cell_types.push_back(bel_type);
|
||||||
|
|
||||||
PartitionId partition;
|
BelBucketId bucket;
|
||||||
partition.name = bel_type;
|
bucket.name = bel_type;
|
||||||
partitions.push_back(partition);
|
buckets.push_back(bucket);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
38
nexus/arch.h
38
nexus/arch.h
@ -1344,36 +1344,36 @@ struct Arch : BaseCtx
|
|||||||
return cell_types;
|
return cell_types;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<PartitionId> getPartitions() const {
|
std::vector<BelBucketId> getBelBuckets() const {
|
||||||
return partitions;
|
return buckets;
|
||||||
}
|
}
|
||||||
|
|
||||||
IdString getPartitionName(PartitionId partition) const {
|
IdString getBelBucketName(BelBucketId bucket) const {
|
||||||
return partition.name;
|
return bucket.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
PartitionId getPartitionByName(IdString name) const {
|
BelBucketId getBelBucketByName(IdString name) const {
|
||||||
PartitionId partition;
|
BelBucketId bucket;
|
||||||
partition.name = name;
|
bucket.name = name;
|
||||||
return partition;
|
return bucket;
|
||||||
}
|
}
|
||||||
|
|
||||||
PartitionId getPartitionForBel(BelId bel) const {
|
BelBucketId getBelBucketForBel(BelId bel) const {
|
||||||
PartitionId partition;
|
BelBucketId bucket;
|
||||||
partition.name = getBelType(bel);
|
bucket.name = getBelType(bel);
|
||||||
return partition;
|
return bucket;
|
||||||
}
|
}
|
||||||
|
|
||||||
PartitionId getPartitionForCellType(IdString cell_type) const {
|
BelBucketId getBelBucketForCellType(IdString cell_type) const {
|
||||||
PartitionId partition;
|
BelBucketId bucket;
|
||||||
partition.name = cell_type;
|
bucket.name = cell_type;
|
||||||
return partition;
|
return bucket;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<BelId> getBelsForPartition(PartitionId partition) const {
|
std::vector<BelId> getBelsInBucket(BelBucketId bucket) const {
|
||||||
std::vector<BelId> bels;
|
std::vector<BelId> bels;
|
||||||
for(BelId bel : getBels()) {
|
for(BelId bel : getBels()) {
|
||||||
if(getBelType(bel) == partition.name) {
|
if(getBelType(bel) == bucket.name) {
|
||||||
bels.push_back(bel);
|
bels.push_back(bel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1583,7 +1583,7 @@ struct Arch : BaseCtx
|
|||||||
void write_fasm(std::ostream &out) const;
|
void write_fasm(std::ostream &out) const;
|
||||||
|
|
||||||
std::vector<IdString> cell_types;
|
std::vector<IdString> cell_types;
|
||||||
std::vector<PartitionId> partitions;
|
std::vector<BelBucketId> buckets;
|
||||||
};
|
};
|
||||||
|
|
||||||
NEXTPNR_NAMESPACE_END
|
NEXTPNR_NAMESPACE_END
|
||||||
|
@ -114,12 +114,12 @@ struct PipId
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PartitionId {
|
struct BelBucketId {
|
||||||
IdString name;
|
IdString name;
|
||||||
|
|
||||||
bool operator==(const PartitionId &other) const { return (name == other.name); }
|
bool operator==(const BelBucketId &other) const { return (name == other.name); }
|
||||||
bool operator!=(const PartitionId &other) const { return (name != other.name); }
|
bool operator!=(const BelBucketId &other) const { return (name != other.name); }
|
||||||
bool operator<(const PartitionId &other) const
|
bool operator<(const BelBucketId &other) const
|
||||||
{
|
{
|
||||||
return name < other.name;
|
return name < other.name;
|
||||||
}
|
}
|
||||||
@ -262,12 +262,12 @@ template <> struct hash<NEXTPNR_NAMESPACE_PREFIX DecalId>
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <> struct hash<NEXTPNR_NAMESPACE_PREFIX PartitionId>
|
template <> struct hash<NEXTPNR_NAMESPACE_PREFIX BelBucketId>
|
||||||
{
|
{
|
||||||
std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX PartitionId &partition) const noexcept
|
std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX BelBucketId &bucket) const noexcept
|
||||||
{
|
{
|
||||||
std::size_t seed = 0;
|
std::size_t seed = 0;
|
||||||
boost::hash_combine(seed, hash<NEXTPNR_NAMESPACE_PREFIX IdString>()(partition.name));
|
boost::hash_combine(seed, hash<NEXTPNR_NAMESPACE_PREFIX IdString>()(bucket.name));
|
||||||
return seed;
|
return seed;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user