aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common/place_sa.cc15
-rw-r--r--ice40/arch_place.cc21
-rw-r--r--ice40/arch_place.h3
3 files changed, 33 insertions, 6 deletions
diff --git a/common/place_sa.cc b/common/place_sa.cc
index a6d3040f..9e3d3022 100644
--- a/common/place_sa.cc
+++ b/common/place_sa.cc
@@ -177,13 +177,16 @@ static bool try_swap_position(Design *design, CellInfo *cell, BelId newBel,
}
chip.bindBel(newBel, cell->name);
+
if (other != IdString()) {
- if (!isValidBelForCell(design, other_cell, oldBel)) {
- chip.unbindBel(newBel);
- goto swap_fail;
- } else {
- chip.bindBel(oldBel, other_cell->name);
- }
+ chip.bindBel(oldBel, other_cell->name);
+ }
+
+ if (!isBelLocationValid(design, newBel) || ((other != IdString() && !isBelLocationValid(design, oldBel)))) {
+ chip.unbindBel(newBel);
+ if (other != IdString())
+ chip.unbindBel(oldBel);
+ goto swap_fail;
}
cell->bel = newBel;
diff --git a/ice40/arch_place.cc b/ice40/arch_place.cc
index c991af13..93b7beb4 100644
--- a/ice40/arch_place.cc
+++ b/ice40/arch_place.cc
@@ -79,6 +79,27 @@ static bool logicCellsCompatible(const std::vector<const CellInfo *> &cells)
return locals.size() <= 32;
}
+bool isBelLocationValid(Design *design, BelId bel) {
+ const Chip &chip = design->chip;
+ if (chip.getBelType(bel) == TYPE_ICESTORM_LC) {
+ std::vector<const CellInfo *> cells;
+ for (auto bel_other : chip.getBelsAtSameTile(bel)) {
+ IdString cell_other = chip.getBelCell(bel_other, false);
+ if (cell_other != IdString()) {
+ const CellInfo *ci_other = design->cells[cell_other];
+ cells.push_back(ci_other);
+ }
+ }
+ return logicCellsCompatible(cells);
+ } else {
+ IdString cellId = chip.getBelCell(bel, false);
+ if (cellId == IdString())
+ return true;
+ else
+ return isValidBelForCell(design, design->cells.at(cellId), bel);
+ }
+}
+
bool isValidBelForCell(Design *design, CellInfo *cell, BelId bel)
{
const Chip &chip = design->chip;
diff --git a/ice40/arch_place.h b/ice40/arch_place.h
index a505f4db..1db29a54 100644
--- a/ice40/arch_place.h
+++ b/ice40/arch_place.h
@@ -30,6 +30,9 @@ NEXTPNR_NAMESPACE_BEGIN
// such as conflicting set/reset signals, etc
bool isValidBelForCell(Design *design, CellInfo *cell, BelId bel);
+// Return true whether all Bels at a given location are valid
+bool isBelLocationValid(Design *design, BelId bel);
+
NEXTPNR_NAMESPACE_END
#endif