timing_opt: Neigbour bel validity checking
Signed-off-by: David Shah <dave@ds0.me>
This commit is contained in:
parent
2de506c071
commit
cd9a65a84c
@ -106,7 +106,10 @@ class TimingOptimiser
|
|||||||
goto unbind;
|
goto unbind;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!check_cell_delay_limits(cell) || (other_cell != nullptr && !check_cell_delay_limits(other_cell))) {
|
||||||
|
result = false;
|
||||||
|
goto unbind;
|
||||||
|
}
|
||||||
|
|
||||||
unbind:
|
unbind:
|
||||||
ctx->unbindBel(newBel);
|
ctx->unbindBel(newBel);
|
||||||
@ -120,9 +123,10 @@ unbind:
|
|||||||
return result;
|
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;
|
BelId curr = cell->bel;
|
||||||
Loc curr_loc = ctx->getBelLocation(curr);
|
Loc curr_loc = ctx->getBelLocation(curr);
|
||||||
|
int found_count = 0;
|
||||||
for (int dy = -d; dy <= d; dy++) {
|
for (int dy = -d; dy <= d; dy++) {
|
||||||
for (int dx = -d; dx <= d; dx++) {
|
for (int dx = -d; dx <= d; dx++) {
|
||||||
if (dx == 0 && dy == 0)
|
if (dx == 0 && dy == 0)
|
||||||
@ -143,14 +147,53 @@ unbind:
|
|||||||
bound_bels_at_loc.push_back(bel);
|
bound_bels_at_loc.push_back(bel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool found = false;
|
BelId candidate;
|
||||||
|
|
||||||
if (found)
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (acceptable_bel_candidate(cell, try_bel)) {
|
||||||
|
candidate = try_bel;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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>
|
// Current candidate Bels for cells (linked in both direction>
|
||||||
std::vector<IdString> path_cells;
|
std::vector<IdString> path_cells;
|
||||||
std::unordered_map<IdString, std::unordered_set<BelId>> cell_neighbour_bels;
|
std::unordered_map<IdString, std::unordered_set<BelId>> cell_neighbour_bels;
|
||||||
|
Loading…
Reference in New Issue
Block a user