diff options
Diffstat (limited to 'common/placer_heap.cc')
-rw-r--r-- | common/placer_heap.cc | 62 |
1 files changed, 40 insertions, 22 deletions
diff --git a/common/placer_heap.cc b/common/placer_heap.cc index 3e98b937..7e8323ca 100644 --- a/common/placer_heap.cc +++ b/common/placer_heap.cc @@ -34,6 +34,7 @@ #include "nextpnr.h" #include "place_common.h" #include "placer_math.h" +#include "placer1.h" #include "util.h" NEXTPNR_NAMESPACE_BEGIN @@ -191,6 +192,9 @@ class HeAPPlacer ++iter; } ctx->unlock(); + + placer1_refine(ctx, Placer1Cfg(ctx)); + return true; } @@ -355,14 +359,17 @@ class HeAPPlacer // FIXME: Are there better approaches to the initial placement (e.g. greedy?) void seed_placement() { - std::unordered_map<IdString, std::vector<BelId>> available_bels; + std::unordered_map<IdString, std::deque<BelId>> available_bels; for (auto bel : ctx->getBels()) { if (!ctx->checkBelAvail(bel)) continue; available_bels[ctx->getBelType(bel)].push_back(bel); } - for (auto &ab : available_bels) - ctx->shuffle(ab.second); + for (auto &t : available_bels) { + std::random_shuffle(t.second.begin(), t.second.end(), [&](size_t n){ + return ctx->rng(int(n)); + }); + } for (auto cell : sorted(ctx->cells)) { CellInfo *ci = cell.second; if (ci->bel != BelId()) { @@ -372,23 +379,34 @@ class HeAPPlacer cell_locs[cell.first].locked = true; cell_locs[cell.first].global = ctx->getBelGlobalBuf(ci->bel); } else if (ci->constr_parent == nullptr) { - if (!available_bels.count(ci->type) || available_bels.at(ci->type).empty()) - log_error("Unable to place cell '%s', no Bels remaining of type '%s'\n", ci->name.c_str(ctx), - ci->type.c_str(ctx)); - BelId bel = available_bels.at(ci->type).back(); - available_bels.at(ci->type).pop_back(); - Loc loc = ctx->getBelLocation(bel); - cell_locs[cell.first].x = loc.x; - cell_locs[cell.first].y = loc.y; - cell_locs[cell.first].locked = false; - cell_locs[cell.first].global = ctx->getBelGlobalBuf(bel); - // FIXME - if (has_connectivity(cell.second) && cell.second->type != ctx->id("SB_IO")) { - place_cells.push_back(ci); - } else { - ctx->bindBel(bel, ci, STRENGTH_STRONG); - cell_locs[cell.first].locked = true; + bool placed = false; + while (!placed) { + if (!available_bels.count(ci->type) || available_bels.at(ci->type).empty()) + log_error("Unable to place cell '%s', no Bels remaining of type '%s'\n", ci->name.c_str(ctx), + ci->type.c_str(ctx)); + BelId bel = available_bels.at(ci->type).back(); + available_bels.at(ci->type).pop_back(); + Loc loc = ctx->getBelLocation(bel); + cell_locs[cell.first].x = loc.x; + cell_locs[cell.first].y = loc.y; + cell_locs[cell.first].locked = false; + cell_locs[cell.first].global = ctx->getBelGlobalBuf(bel); + // FIXME + if (has_connectivity(cell.second) && cell.second->type != ctx->id("SB_IO")) { + place_cells.push_back(ci); + placed = true; + } else { + if (ctx->isValidBelForCell(ci, bel)) { + ctx->bindBel(bel, ci, STRENGTH_STRONG); + cell_locs[cell.first].locked = true; + placed = true; + } else { + available_bels.at(ci->type).push_front(bel); + } + + } } + } } } @@ -728,8 +746,8 @@ class HeAPPlacer for (auto &r : regions) { if (merged_regions.count(r.id)) continue; - /*log_info("%s (%d, %d) |_> (%d, %d) %d/%d\n", beltype.c_str(ctx), r.x0, r.y0, r.x1, r.y1, r.cells, - r.bels);*/ + log_info("%s (%d, %d) |_> (%d, %d) %d/%d\n", beltype.c_str(ctx), r.x0, r.y0, r.x1, r.y1, r.cells, + r.bels); workqueue.emplace(r.id, false); //cut_region(r, false); } @@ -865,7 +883,7 @@ class HeAPPlacer auto process_location = [&](int x, int y) { // Merge with any overlapping regions - if (groups.at(x).at(y) != r.id) { + if (groups.at(x).at(y) == -1) { r.bels += bels_at(x, y); r.cells += occ_at(x, y); } |