aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ice40/arch.cc2
-rw-r--r--ice40/arch_place.cc21
-rw-r--r--ice40/archdefs.h5
-rw-r--r--ice40/constids.inc1
4 files changed, 29 insertions, 0 deletions
diff --git a/ice40/arch.cc b/ice40/arch.cc
index 7ce967ec..43a3dec2 100644
--- a/ice40/arch.cc
+++ b/ice40/arch.cc
@@ -975,6 +975,8 @@ void Arch::assignCellInfo(CellInfo *cell)
cell->lcInfo.inputCount++;
if (get_net_or_empty(cell, id_I3))
cell->lcInfo.inputCount++;
+ } else if (cell->type == id_SB_IO) {
+ cell->ioInfo.lvds = str_or_default(cell->params, id_IO_STANDARD, "SB_LVCMOS") == "SB_LVDS_INPUT";
}
}
diff --git a/ice40/arch_place.cc b/ice40/arch_place.cc
index a050e39f..b436f7d7 100644
--- a/ice40/arch_place.cc
+++ b/ice40/arch_place.cc
@@ -139,6 +139,27 @@ bool Arch::isValidBelForCell(CellInfo *cell, BelId bel) const
}
}
}
+ Loc ioLoc = getBelLocation(bel);
+ Loc compLoc = ioLoc;
+ compLoc.z = 1 - compLoc.z;
+
+ // Check LVDS pairing
+ if (cell->ioInfo.lvds) {
+ // Check correct z and complement location is free
+ if (ioLoc.z != 0)
+ return false;
+ BelId compBel = getBelByLocation(compLoc);
+ CellInfo *compCell = getBoundBelCell(compBel);
+ if (compCell)
+ return false;
+ } else {
+ // Check LVDS IO is not placed at complement location
+ BelId compBel = getBelByLocation(compLoc);
+ CellInfo *compCell = getBoundBelCell(compBel);
+ if (compCell && compCell->ioInfo.lvds)
+ return false;
+ }
+
return getBelPackagePin(bel) != "";
} else if (cell->type == id_SB_GB) {
NPNR_ASSERT(cell->ports.at(id_GLOBAL_BUFFER_OUTPUT).net != nullptr);
diff --git a/ice40/archdefs.h b/ice40/archdefs.h
index 8e20de23..c04033e7 100644
--- a/ice40/archdefs.h
+++ b/ice40/archdefs.h
@@ -144,6 +144,11 @@ struct ArchCellInfo
int inputCount;
const NetInfo *clk, *cen, *sr;
} lcInfo;
+ struct
+ {
+ bool lvds;
+ // TODO: clk packing checks...
+ } ioInfo;
};
};
diff --git a/ice40/constids.inc b/ice40/constids.inc
index adcea7ad..dad08e59 100644
--- a/ice40/constids.inc
+++ b/ice40/constids.inc
@@ -435,3 +435,4 @@ X(ICESTORM_SPRAM)
X(DFF_ENABLE)
X(CARRY_ENABLE)
X(NEG_CLK)
+X(IO_STANDARD) \ No newline at end of file