aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSylvain Munaut <tnt@246tNt.com>2018-11-18 19:21:41 +0100
committerSylvain Munaut <tnt@246tNt.com>2018-11-19 18:20:20 +0100
commitc219d8fe4d3b8b6c79a715ca5808156287e7f642 (patch)
tree1bc7c68317cc4339848e99a47120e23111e7825a
parent9483a95a4adfe9f9715a0066770e12f8b581185e (diff)
downloadnextpnr-c219d8fe4d3b8b6c79a715ca5808156287e7f642.tar.gz
nextpnr-c219d8fe4d3b8b6c79a715ca5808156287e7f642.tar.bz2
nextpnr-c219d8fe4d3b8b6c79a715ca5808156287e7f642.zip
ice40: Fix BEL validity check for PLL vs SB_IO
Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
-rw-r--r--ice40/arch_place.cc41
1 files changed, 20 insertions, 21 deletions
diff --git a/ice40/arch_place.cc b/ice40/arch_place.cc
index c97b9c26..a09a5092 100644
--- a/ice40/arch_place.cc
+++ b/ice40/arch_place.cc
@@ -114,31 +114,30 @@ bool Arch::isValidBelForCell(CellInfo *cell, BelId bel) const
// Find shared PLL by looking for driving bel siblings from D_IN_0
// that are a PLL clock output.
auto wire = getBelPinWire(bel, id_D_IN_0);
- IdString pll_bel_pin;
- BelId pll_bel;
for (auto pin : getWireBelPins(wire)) {
if (pin.pin == id_PLLOUT_A || pin.pin == id_PLLOUT_B) {
- pll_bel = pin.bel;
- pll_bel_pin = pin.pin;
- break;
- }
- }
- // Is there a PLL that shares this IO buffer?
- if (pll_bel.index != -1) {
- auto pll_cell = getBoundBelCell(pll_bel);
- // Is a PLL placed in this PLL bel?
- if (pll_cell != nullptr) {
- // Is the shared port driving a net?
- auto pi = pll_cell->ports[pll_bel_pin];
- if (pi.net != nullptr) {
- // Are we perhaps a PAD INPUT Bel that can be placed here?
- if (pll_cell->attrs[id("BEL_PAD_INPUT")] == getBelName(bel).str(this)) {
- return true;
- }
- return false;
- }
+ // Is there a PLL there ?
+ auto pll_cell = getBoundBelCell(pin.bel);
+ if (pll_cell == nullptr)
+ break;
+
+ // Is that port actually used ?
+ if ((pin.pin == id_PLLOUT_B) && !is_sb_pll40_dual(this, pll_cell))
+ break;
+
+ // Is that SB_IO used at an input ?
+ if ((cell->ports[id_D_IN_0].net == nullptr) && (cell->ports[id_D_IN_1].net == nullptr))
+ break;
+
+ // Are we perhaps a PAD INPUT Bel that can be placed here?
+ if (pll_cell->attrs[id("BEL_PAD_INPUT")] == getBelName(bel).str(this))
+ return true;
+
+ // Conflict
+ return false;
}
}
+
Loc ioLoc = getBelLocation(bel);
Loc compLoc = ioLoc;
compLoc.z = 1 - compLoc.z;