aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Shah <dave@ds0.me>2018-12-01 14:06:51 +0000
committerDavid Shah <dave@ds0.me>2018-12-06 10:53:01 +0000
commitcd9a65a84c34bfeb6d759e3c147272e09880cb0f (patch)
tree6d114a2fc28933555bf447a2a6a37cc7b73c9947
parent2de506c071b090c18977a594efbd6effd0315bf5 (diff)
downloadnextpnr-cd9a65a84c34bfeb6d759e3c147272e09880cb0f.tar.gz
nextpnr-cd9a65a84c34bfeb6d759e3c147272e09880cb0f.tar.bz2
nextpnr-cd9a65a84c34bfeb6d759e3c147272e09880cb0f.zip
timing_opt: Neigbour bel validity checking
Signed-off-by: David Shah <dave@ds0.me>
-rw-r--r--common/timing_opt.cc53
1 files changed, 48 insertions, 5 deletions
diff --git a/common/timing_opt.cc b/common/timing_opt.cc
index 97860a23..abfe5cf1 100644
--- a/common/timing_opt.cc
+++ b/common/timing_opt.cc
@@ -106,7 +106,10 @@ class TimingOptimiser
goto unbind;
}
-
+ if (!check_cell_delay_limits(cell) || (other_cell != nullptr && !check_cell_delay_limits(other_cell))) {
+ result = false;
+ goto unbind;
+ }
unbind:
ctx->unbindBel(newBel);
@@ -120,9 +123,10 @@ unbind:
return result;
}
- void find_neighbours(CellInfo *cell, int d) {
+ int find_neighbours(CellInfo *cell, IdString prev_cell, int d, bool allow_swap) {
BelId curr = cell->bel;
Loc curr_loc = ctx->getBelLocation(curr);
+ int found_count = 0;
for (int dy = -d; dy <= d; dy++) {
for (int dx = -d; dx <= d; dx++) {
if (dx == 0 && dy == 0)
@@ -143,12 +147,51 @@ unbind:
bound_bels_at_loc.push_back(bel);
}
}
- bool found = false;
+ BelId candidate;
+
+ while (!free_bels_at_loc.empty() && !bound_bels_at_loc.empty()) {
+ BelId try_bel;
+ if (!free_bels_at_loc.empty()) {
+ int try_idx = ctx->rng(int(free_bels_at_loc.size()));
+ try_bel = free_bels_at_loc.at(try_idx);
+ free_bels_at_loc.erase(free_bels_at_loc.begin() + try_idx);
+ } else {
+ int try_idx = ctx->rng(int(bound_bels_at_loc.size()));
+ try_bel = bound_bels_at_loc.at(try_idx);
+ bound_bels_at_loc.erase(bound_bels_at_loc.begin() + try_idx);
+ }
+ if (bel_candidate_cells.count(try_bel) && !allow_swap) {
+ // Overlap is only allowed if it is with the previous cell (this is handled by removing those
+ // edges in the graph), or if allow_swap is true to deal with cases where overlap means few neighbours
+ // are identified
+ if (bel_candidate_cells.at(try_bel).size() > 1 || (bel_candidate_cells.at(try_bel).size() == 0 ||
+ *(bel_candidate_cells.at(try_bel).begin()) != prev_cell))
+ continue;
+ }
+ if (acceptable_bel_candidate(cell, try_bel)) {
+ candidate = try_bel;
+ break;
+ }
+ }
- if (found)
- continue;
+ if (candidate != BelId()) {
+ cell_neighbour_bels[cell->name].insert(candidate);
+ bel_candidate_cells[candidate].insert(cell->name);
+ // Work out if we need to delete any overlap
+ std::vector<IdString> overlap;
+ for (auto other : bel_candidate_cells[candidate])
+ if (other != cell->name && other != prev_cell)
+ overlap.push_back(other);
+ if (overlap.size() > 0)
+ NPNR_ASSERT(allow_swap);
+ for (auto ov : overlap) {
+ bel_candidate_cells[candidate].erase(ov);
+ cell_neighbour_bels[ov].erase(candidate);
+ }
+ }
}
}
+ return found_count;
}
// Current candidate Bels for cells (linked in both direction>