diff options
Diffstat (limited to 'ice40/place_legaliser.cc')
-rw-r--r-- | ice40/place_legaliser.cc | 38 |
1 files changed, 37 insertions, 1 deletions
diff --git a/ice40/place_legaliser.cc b/ice40/place_legaliser.cc index 29dab0a0..8f5680bf 100644 --- a/ice40/place_legaliser.cc +++ b/ice40/place_legaliser.cc @@ -93,11 +93,13 @@ class PlacementLegaliser bool legalise() { + log_info("Legalising design..\n"); init_logic_cells(); bool legalised_carries = legalise_carries(); if (!legalised_carries && !ctx->force) return false; - return legalised_carries; + bool replaced_cells = replace_cells(); + return legalised_carries && replaced_cells; } private: @@ -313,6 +315,40 @@ class PlacementLegaliser return ctx->cells[name].get(); } + // Replace ripped-up cells + bool replace_cells() + { + bool success = true; + for (auto cell : sorted(rippedCells)) { + CellInfo *ci = ctx->cells.at(cell).get(); + bool placed = place_single_cell(ci); + if (!placed) { + if (ctx->force) { + log_warning("failed to place cell '%s' of type '%s'\n", cell.c_str(ctx), + ci->type.c_str(ctx)); + success = false; + } else { + log_error("failed to place cell '%s' of type '%s'\n", cell.c_str(ctx), + ci->type.c_str(ctx)); + } + } + } + return success; + } + + // Place a single cell in the first valid location + bool place_single_cell(CellInfo *cell) + { + BelType tgtType = ctx->belTypeFromId(cell->type); + for (auto bel : ctx->getBels()) { + if (ctx->getBelType(bel) == tgtType && ctx->checkBelAvail(bel) && ctx->isValidBelForCell(cell, bel)) { + ctx->bindBel(bel, cell->name, STRENGTH_WEAK); + return true; + } + } + return false; + } + Context *ctx; std::unordered_set<IdString> rippedCells; std::unordered_set<IdString> createdCells; |