From 1d3147e26a2d57085199b645c12df5ab4836850e Mon Sep 17 00:00:00 2001 From: Sergiusz Bazanski Date: Tue, 24 Jul 2018 01:18:49 +0100 Subject: ice40: Prevent placement of SB_IOs in IO blocks used by PLL outputs --- ice40/arch_place.cc | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'ice40/arch_place.cc') 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); -- cgit v1.2.3 From 65ceb20784ccd0e2be71c733dbc23dc61d83d653 Mon Sep 17 00:00:00 2001 From: Sergiusz Bazanski Date: Tue, 24 Jul 2018 02:05:30 +0100 Subject: ice40: emit list of upbels in chipdb --- ice40/arch_place.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ice40/arch_place.cc') diff --git a/ice40/arch_place.cc b/ice40/arch_place.cc index 9c76851b..95cebb48 100644 --- a/ice40/arch_place.cc +++ b/ice40/arch_place.cc @@ -123,7 +123,7 @@ bool Arch::isValidBelForCell(CellInfo *cell, BelId bel) const 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; + auto io_bel = chip_info->wire_data[driven_wire.index].bels_uphill[0].bel_index; if (io_bel == bel.index) { return false; } -- cgit v1.2.3 From eaae1d299c030be85aa9eb3a45ce2c02afe919f1 Mon Sep 17 00:00:00 2001 From: Sergiusz Bazanski Date: Tue, 24 Jul 2018 02:35:16 +0100 Subject: ice40: move PLL->IO from pseudo pip to second uphill bel --- ice40/arch_place.cc | 40 +++++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 19 deletions(-) (limited to 'ice40/arch_place.cc') diff --git a/ice40/arch_place.cc b/ice40/arch_place.cc index 95cebb48..00c960b6 100644 --- a/ice40/arch_place.cc +++ b/ice40/arch_place.cc @@ -107,26 +107,28 @@ bool Arch::isValidBelForCell(CellInfo *cell, BelId bel) const 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].bels_uphill[0].bel_index; - if (io_bel == bel.index) { - return false; - } + // 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; } } } -- cgit v1.2.3 From 90ba958abe85ced03f16888644dd026b133cab36 Mon Sep 17 00:00:00 2001 From: Sergiusz Bazanski Date: Tue, 24 Jul 2018 03:03:31 +0100 Subject: ice40: fixes before review --- ice40/arch_place.cc | 1 + 1 file changed, 1 insertion(+) (limited to 'ice40/arch_place.cc') diff --git a/ice40/arch_place.cc b/ice40/arch_place.cc index 00c960b6..16cc757e 100644 --- a/ice40/arch_place.cc +++ b/ice40/arch_place.cc @@ -3,6 +3,7 @@ * * Copyright (C) 2018 Clifford Wolf * Copyright (C) 2018 David Shah + * Copyright (C) 2018 Serge Bazanski * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above -- cgit v1.2.3