aboutsummaryrefslogtreecommitdiffstats
path: root/common/placer_heap.cc
diff options
context:
space:
mode:
Diffstat (limited to 'common/placer_heap.cc')
-rw-r--r--common/placer_heap.cc62
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);
}