diff options
Diffstat (limited to 'common')
-rw-r--r-- | common/nextpnr.h | 2 | ||||
-rw-r--r-- | common/place_common.cc | 17 | ||||
-rw-r--r-- | common/placer1.cc | 25 | ||||
-rw-r--r-- | common/placer_heap.cc | 18 |
4 files changed, 38 insertions, 24 deletions
diff --git a/common/nextpnr.h b/common/nextpnr.h index b6ee33fe..4ddf8fef 100644 --- a/common/nextpnr.h +++ b/common/nextpnr.h @@ -1169,7 +1169,6 @@ template <typename R> struct ArchAPI : BaseCtx virtual BelBucketId getBelBucketByName(IdString name) const = 0; virtual BelBucketId getBelBucketForBel(BelId bel) const = 0; virtual BelBucketId getBelBucketForCellType(IdString cell_type) const = 0; - virtual bool isValidBelForCell(CellInfo *cell, BelId bel) const = 0; virtual bool isBelLocationValid(BelId bel) const = 0; virtual typename R::CellTypeRangeT getCellTypes() const = 0; virtual typename R::BelBucketRangeT getBelBuckets() const = 0; @@ -1420,7 +1419,6 @@ template <typename R> struct BaseArch : ArchAPI<R> { return getBelBucketByName(cell_type); }; - virtual bool isValidBelForCell(CellInfo *cell, BelId bel) const override { return true; } virtual bool isBelLocationValid(BelId bel) const override { return true; } virtual typename R::CellTypeRangeT getCellTypes() const override { diff --git a/common/place_common.cc b/common/place_common.cc index 6526c38e..e5b48ffb 100644 --- a/common/place_common.cc +++ b/common/place_common.cc @@ -118,8 +118,7 @@ bool place_single_cell(Context *ctx, CellInfo *cell, bool require_legality) } IdString targetType = cell->type; for (auto bel : ctx->getBels()) { - if (ctx->isValidBelForCellType(targetType, bel) && - (!require_legality || ctx->isValidBelForCell(cell, bel))) { + if (ctx->isValidBelForCellType(targetType, bel)) { if (ctx->checkBelAvail(bel)) { wirelen_t wirelen = get_cell_metric_at_bel(ctx, cell, bel, MetricType::COST); if (iters >= 4) @@ -155,12 +154,20 @@ bool place_single_cell(Context *ctx, CellInfo *cell, bool require_legality) ctx->unbindBel(ripup_target->bel); best_bel = ripup_bel; } else { + ripup_target = nullptr; all_placed = true; } + ctx->bindBel(best_bel, cell, STRENGTH_WEAK); + if (require_legality && !ctx->isBelLocationValid(best_bel)) { + ctx->unbindBel(best_bel); + if (ripup_target != nullptr) { + ctx->bindBel(best_bel, ripup_target, STRENGTH_WEAK); + } + all_placed = false; + continue; + } if (ctx->verbose) log_info(" placed single cell '%s' at '%s'\n", cell->name.c_str(ctx), ctx->nameOfBel(best_bel)); - ctx->bindBel(best_bel, cell, STRENGTH_WEAK); - cell = ripup_target; } return true; @@ -387,7 +394,7 @@ class ConstraintLegaliseWorker for (auto bel : ctx->getBelsByTile(cp.second.x, cp.second.y)) { CellInfo *belCell = ctx->getBoundBelCell(bel); if (belCell != nullptr && !solution.count(belCell->name)) { - if (!ctx->isValidBelForCell(belCell, bel)) { + if (!ctx->isBelLocationValid(bel)) { NPNR_ASSERT(belCell->belStrength < STRENGTH_STRONG); ctx->unbindBel(bel); rippedCells.insert(belCell->name); diff --git a/common/placer1.cc b/common/placer1.cc index 280dd02e..270430e9 100644 --- a/common/placer1.cc +++ b/common/placer1.cc @@ -167,13 +167,6 @@ class SAPlacer "\'%s\' of type \'%s\'\n", loc_name.c_str(), bel_type.c_str(ctx), cell->name.c_str(ctx), cell->type.c_str(ctx)); } - if (!ctx->isValidBelForCell(cell, bel)) { - IdString bel_type = ctx->getBelType(bel); - log_error("Bel \'%s\' of type \'%s\' is not valid for cell " - "\'%s\' of type \'%s\'\n", - loc_name.c_str(), bel_type.c_str(ctx), cell->name.c_str(ctx), cell->type.c_str(ctx)); - } - auto bound_cell = ctx->getBoundBelCell(bel); if (bound_cell) { log_error( @@ -182,6 +175,12 @@ class SAPlacer } ctx->bindBel(bel, cell, STRENGTH_USER); + if (!ctx->isBelLocationValid(bel)) { + IdString bel_type = ctx->getBelType(bel); + log_error("Bel \'%s\' of type \'%s\' is not valid for cell " + "\'%s\' of type \'%s\'\n", + loc_name.c_str(), bel_type.c_str(ctx), cell->name.c_str(ctx), cell->type.c_str(ctx)); + } locked_bels.insert(bel); placed_cells++; } @@ -444,7 +443,7 @@ class SAPlacer IdString targetType = cell->type; auto proc_bel = [&](BelId bel) { - if (ctx->isValidBelForCellType(targetType, bel) && ctx->isValidBelForCell(cell, bel)) { + if (ctx->isValidBelForCellType(targetType, bel)) { if (ctx->checkBelAvail(bel)) { uint64_t score = ctx->rng64(); if (score <= best_score) { @@ -480,10 +479,20 @@ class SAPlacer ctx->unbindBel(ripup_target->bel); best_bel = ripup_bel; } else { + ripup_target = nullptr; all_placed = true; } ctx->bindBel(best_bel, cell, STRENGTH_WEAK); + if (!ctx->isBelLocationValid(best_bel)) { + ctx->unbindBel(best_bel); + if (ripup_target != nullptr) { + ctx->bindBel(best_bel, ripup_target, STRENGTH_WEAK); + } + all_placed = false; + continue; + } + // Back annotate location cell->attrs[ctx->id("BEL")] = ctx->getBelName(cell->bel).str(ctx); cell = ripup_target; diff --git a/common/placer_heap.cc b/common/placer_heap.cc index 7882c8da..7d529401 100644 --- a/common/placer_heap.cc +++ b/common/placer_heap.cc @@ -392,13 +392,6 @@ class HeAPPlacer "\'%s\' of type \'%s\'\n", loc_name.c_str(), bel_type.c_str(ctx), cell->name.c_str(ctx), cell->type.c_str(ctx)); } - if (!ctx->isValidBelForCell(cell, bel)) { - IdString bel_type = ctx->getBelType(bel); - log_error("Bel \'%s\' of type \'%s\' is not valid for cell " - "\'%s\' of type \'%s\'\n", - loc_name.c_str(), bel_type.c_str(ctx), cell->name.c_str(ctx), cell->type.c_str(ctx)); - } - auto bound_cell = ctx->getBoundBelCell(bel); if (bound_cell) { log_error("Cell \'%s\' cannot be bound to bel \'%s\' since it is already bound to cell \'%s\'\n", @@ -406,6 +399,12 @@ class HeAPPlacer } ctx->bindBel(bel, cell, STRENGTH_USER); + if (!ctx->isBelLocationValid(bel)) { + IdString bel_type = ctx->getBelType(bel); + log_error("Bel \'%s\' of type \'%s\' is not valid for cell " + "\'%s\' of type \'%s\'\n", + loc_name.c_str(), bel_type.c_str(ctx), cell->name.c_str(ctx), cell->type.c_str(ctx)); + } placed_cells++; } } @@ -571,12 +570,13 @@ class HeAPPlacer place_cells.push_back(ci); placed = true; } else { - if (ctx->isValidBelForCell(ci, bel)) { - ctx->bindBel(bel, ci, STRENGTH_STRONG); + ctx->bindBel(bel, ci, STRENGTH_STRONG); + if (ctx->isBelLocationValid(bel)) { cell_locs[cell.first].locked = true; placed = true; bels_used.insert(bel); } else { + ctx->unbindBel(bel); available_bels.at(ci->type).push_front(bel); } } |