aboutsummaryrefslogtreecommitdiffstats
path: root/ice40/arch_place.cc
diff options
context:
space:
mode:
authorSerge Bazanski <q3k@q3k.org>2018-07-24 15:01:12 +0000
committerSerge Bazanski <q3k@q3k.org>2018-07-24 15:01:12 +0000
commit62bcda87bdd6a847b4ff27e59cf122caa7efba11 (patch)
tree15fc886cd9c25072e87b17eebc2009e3d3430d7b /ice40/arch_place.cc
parentc57463e87b4976f63f04eff133c554af7e8d59d3 (diff)
parent2039112a472fade4b161502dc683461640386304 (diff)
downloadnextpnr-62bcda87bdd6a847b4ff27e59cf122caa7efba11.tar.gz
nextpnr-62bcda87bdd6a847b4ff27e59cf122caa7efba11.tar.bz2
nextpnr-62bcda87bdd6a847b4ff27e59cf122caa7efba11.zip
Merge branch 'q3k/pll' into 'master'
ice40: support CORE PLLs See merge request SymbioticEDA/nextpnr!17
Diffstat (limited to 'ice40/arch_place.cc')
-rw-r--r--ice40/arch_place.cc27
1 files changed, 27 insertions, 0 deletions
diff --git a/ice40/arch_place.cc b/ice40/arch_place.cc
index d32ebe98..59e1807d 100644
--- a/ice40/arch_place.cc
+++ b/ice40/arch_place.cc
@@ -3,6 +3,7 @@
*
* Copyright (C) 2018 Clifford Wolf <clifford@symbioticeda.com>
* Copyright (C) 2018 David Shah <david@symbioticeda.com>
+ * Copyright (C) 2018 Serge Bazanski <q3k@symbioticeda.com>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -107,6 +108,32 @@ 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.
+
+ // Find shared PLL by looking for driving bel siblings from D_IN_0
+ // that are a PLL clock output.
+ auto wire = getBelPinWire(bel, PIN_D_IN_0);
+ PortPin pll_bel_pin;
+ BelId pll_bel;
+ for (auto pin : getWireBelPins(wire)) {
+ if (pin.pin == PIN_PLLOUT_A || pin.pin == PIN_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) {
+ // Is a PLL placed in this PLL bel?
+ if (!checkBelAvail(pll_bel)) {
+ // Is the shared port driving a net?
+ auto pll_cell = getBoundBelCell(pll_bel);
+ auto pi = cells.at(pll_cell)->ports[portPinToId(pll_bel_pin)];
+ if (pi.net != nullptr) {
+ return false;
+ }
+ }
+ }
return getBelPackagePin(bel) != "";
} else if (cell->type == id_sb_gb) {
NPNR_ASSERT(cell->ports.at(id_glb_buf_out).net != nullptr);