diff options
author | David Shah <dave@ds0.me> | 2018-12-01 14:06:51 +0000 |
---|---|---|
committer | David Shah <dave@ds0.me> | 2018-12-06 10:53:01 +0000 |
commit | cd9a65a84c34bfeb6d759e3c147272e09880cb0f (patch) | |
tree | 6d114a2fc28933555bf447a2a6a37cc7b73c9947 | |
parent | 2de506c071b090c18977a594efbd6effd0315bf5 (diff) | |
download | nextpnr-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.cc | 53 |
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> |