aboutsummaryrefslogtreecommitdiffstats
path: root/ice40/arch_place.cc
diff options
context:
space:
mode:
authorSergiusz Bazanski <q3k@q3k.org>2018-07-24 01:18:49 +0100
committerSergiusz Bazanski <q3k@q3k.org>2018-07-24 02:55:40 +0100
commit1d3147e26a2d57085199b645c12df5ab4836850e (patch)
treeaed7d2d6bc88f7d339db761b494a0913c68ecef9 /ice40/arch_place.cc
parente6c7b1446580c92e9581593c78dd21753b409606 (diff)
downloadnextpnr-1d3147e26a2d57085199b645c12df5ab4836850e.tar.gz
nextpnr-1d3147e26a2d57085199b645c12df5ab4836850e.tar.bz2
nextpnr-1d3147e26a2d57085199b645c12df5ab4836850e.zip
ice40: Prevent placement of SB_IOs in IO blocks used by PLL outputs
Diffstat (limited to 'ice40/arch_place.cc')
-rw-r--r--ice40/arch_place.cc24
1 files changed, 24 insertions, 0 deletions
diff --git a/ice40/arch_place.cc b/ice40/arch_place.cc
index cf1276a7..9c76851b 100644
--- a/ice40/arch_place.cc
+++ b/ice40/arch_place.cc
@@ -106,6 +106,30 @@ bool Arch::isValidBelForCell(CellInfo *cell, BelId bel) const
bel_cells.push_back(cell);
return logicCellsCompatible(bel_cells);
} else if (cell->type == id_sb_io) {
+ // Do not allow placement of input SB_IOs on blocks where there a PLL is outputting to.
+ for (auto iter_bel : getBels()) {
+ if (getBelType(iter_bel) != TYPE_ICESTORM_PLL)
+ continue;
+ if (checkBelAvail(iter_bel))
+ continue;
+
+ auto bel_cell = cells.at(getBoundBelCell(iter_bel)).get();
+ for (auto type : {id("PLLOUT_A"), id("PLLOUT_B")}) {
+ auto it = bel_cell->ports.find(type);
+ if (it == bel_cell->ports.end())
+ continue;
+ if (it->second.net == nullptr)
+ continue;
+ auto wire = getBelPinWire(iter_bel, portPinFromId(type));
+ for (auto pip : getPipsDownhill(wire)) {
+ auto driven_wire = getPipDstWire(pip);
+ auto io_bel = chip_info->wire_data[driven_wire.index].bel_uphill.bel_index;
+ if (io_bel == bel.index) {
+ return false;
+ }
+ }
+ }
+ }
return getBelPackagePin(bel) != "";
} else if (cell->type == id_sb_gb) {
NPNR_ASSERT(cell->ports.at(id_glb_buf_out).net != nullptr);