aboutsummaryrefslogtreecommitdiffstats
path: root/ice40
diff options
context:
space:
mode:
authorDavid Shah <davey1576@gmail.com>2019-04-17 16:18:40 +0100
committerGitHub <noreply@github.com>2019-04-17 16:18:40 +0100
commit0be844e6a8d0a36a50815ec5331fd7480dd20db6 (patch)
treef1f08bce2a062c5a8ae068c88f8a9380eb4d5e42 /ice40
parente7bb262e96b07b14644a098dbb109679f6af8f5d (diff)
parent66b64f928b97c94292751d94832c13fc47f2f122 (diff)
downloadnextpnr-0be844e6a8d0a36a50815ec5331fd7480dd20db6.tar.gz
nextpnr-0be844e6a8d0a36a50815ec5331fd7480dd20db6.tar.bz2
nextpnr-0be844e6a8d0a36a50815ec5331fd7480dd20db6.zip
Merge pull request #270 from smunaut/sb_io_conflict
SB IO conflict checks
Diffstat (limited to 'ice40')
-rw-r--r--ice40/arch.cc4
-rw-r--r--ice40/arch_place.cc36
2 files changed, 38 insertions, 2 deletions
diff --git a/ice40/arch.cc b/ice40/arch.cc
index bfcadc0b..d536ad35 100644
--- a/ice40/arch.cc
+++ b/ice40/arch.cc
@@ -1221,8 +1221,8 @@ void Arch::assignCellInfo(CellInfo *cell)
} else if (cell->type == id_SB_IO) {
cell->ioInfo.lvds = str_or_default(cell->params, id_IO_STANDARD, "SB_LVCMOS") == "SB_LVDS_INPUT";
cell->ioInfo.global = bool_or_default(cell->attrs, this->id("GLOBAL"));
- cell->ioInfo.pintype = int_or_default(cell->attrs, this->id("PIN_TYPE"));
- cell->ioInfo.negtrig = bool_or_default(cell->attrs, this->id("NEG_TRIGGER"));
+ cell->ioInfo.pintype = int_or_default(cell->params, this->id("PIN_TYPE"));
+ cell->ioInfo.negtrig = bool_or_default(cell->params, this->id("NEG_TRIGGER"));
} else if (cell->type == id_SB_GB) {
cell->gbInfo.forPadIn = bool_or_default(cell->attrs, this->id("FOR_PAD_IN"));
diff --git a/ice40/arch_place.cc b/ice40/arch_place.cc
index 90bb62b9..ede8d47f 100644
--- a/ice40/arch_place.cc
+++ b/ice40/arch_place.cc
@@ -91,6 +91,18 @@ bool Arch::isBelLocationValid(BelId bel) const
}
}
+static inline bool _io_pintype_need_clk_in(unsigned pin_type) { return (pin_type & 0x01) == 0x00; }
+
+static inline bool _io_pintype_need_clk_out(unsigned pin_type)
+{
+ return ((pin_type & 0x30) == 0x30) || ((pin_type & 0x3c) && ((pin_type & 0x0c) != 0x08));
+}
+
+static inline bool _io_pintype_need_clk_en(unsigned pin_type)
+{
+ return _io_pintype_need_clk_in(pin_type) || _io_pintype_need_clk_out(pin_type);
+}
+
bool Arch::isValidBelForCell(CellInfo *cell, BelId bel) const
{
if (cell->type == id_ICESTORM_LC) {
@@ -157,6 +169,30 @@ bool Arch::isValidBelForCell(CellInfo *cell, BelId bel) const
CellInfo *compCell = getBoundBelCell(compBel);
if (compCell && compCell->ioInfo.lvds)
return false;
+
+ // Check for conflicts on shared nets
+ // - CLOCK_ENABLE
+ // - OUTPUT_CLK
+ // - INPUT_CLK
+ if (compCell) {
+ bool use[6] = {
+ _io_pintype_need_clk_in(cell->ioInfo.pintype),
+ _io_pintype_need_clk_in(compCell->ioInfo.pintype),
+ _io_pintype_need_clk_out(cell->ioInfo.pintype),
+ _io_pintype_need_clk_out(compCell->ioInfo.pintype),
+ _io_pintype_need_clk_en(cell->ioInfo.pintype),
+ _io_pintype_need_clk_en(compCell->ioInfo.pintype),
+ };
+ NetInfo *nets[] = {
+ cell->ports[id_INPUT_CLK].net, compCell->ports[id_INPUT_CLK].net,
+ cell->ports[id_OUTPUT_CLK].net, compCell->ports[id_OUTPUT_CLK].net,
+ cell->ports[id_CLOCK_ENABLE].net, compCell->ports[id_CLOCK_ENABLE].net,
+ };
+
+ for (int i = 0; i < 6; i++)
+ if (use[i] && (nets[i] != nets[i ^ 1]) && (use[i ^ 1] || (nets[i ^ 1] != nullptr)))
+ return false;
+ }
}
return getBelPackagePin(bel) != "";