aboutsummaryrefslogtreecommitdiffstats
path: root/ecp5/pack.cc
diff options
context:
space:
mode:
authorDavid Shah <dave@ds0.me>2019-02-12 13:13:06 +0000
committerDavid Shah <davey1576@gmail.com>2019-02-24 10:28:25 +0100
commit44023612465703682d883e29e0de9fb900e6e531 (patch)
treea0048adc4bb0c3f72b3ec1c47d0fc705386c8b7b /ecp5/pack.cc
parenteb45956d0ee7dffac4c1c0b242f15724a3e0a352 (diff)
downloadnextpnr-44023612465703682d883e29e0de9fb900e6e531.tar.gz
nextpnr-44023612465703682d883e29e0de9fb900e6e531.tar.bz2
nextpnr-44023612465703682d883e29e0de9fb900e6e531.zip
ecp5: Helper functions and bitstream for DQS
Signed-off-by: David Shah <dave@ds0.me>
Diffstat (limited to 'ecp5/pack.cc')
-rw-r--r--ecp5/pack.cc33
1 files changed, 33 insertions, 0 deletions
diff --git a/ecp5/pack.cc b/ecp5/pack.cc
index 7abad40b..7538989c 100644
--- a/ecp5/pack.cc
+++ b/ecp5/pack.cc
@@ -1673,6 +1673,39 @@ class Ecp5Packer
return iol_ptr;
};
+ auto process_dqs_port = [&](CellInfo *prim, CellInfo *pio, CellInfo *iol, IdString port) {
+ NetInfo *sig = nullptr;
+ if (prim->ports.count(port))
+ sig = prim->ports[port].net;
+ if (sig == nullptr || sig->driver.cell == nullptr)
+ log_error("Port %s of cell '%s' cannot be disconnected, it must be driven by a DQSBUFM\n",
+ port.c_str(ctx), prim->name.c_str(ctx));
+ if (iol->ports.at(port).net != nullptr) {
+ if (iol->ports.at(port).net != sig) {
+ log_error("IOLOGIC '%s' has conflicting %s signals '%s' and '%s'\n", iol->name.c_str(ctx),
+ port.c_str(ctx), iol->ports[port].net->name.c_str(ctx), sig->name.c_str(ctx));
+ }
+ } else {
+ bool dqsr;
+ int dqsgroup;
+ bool has_dqs = ctx->getPIODQSGroup(get_pio_bel(pio, prim), dqsr, dqsgroup);
+ if (!has_dqs)
+ log_error("Primitive '%s' cannot be connected to top level port '%s' as the associated pin is not "
+ "in any DQS group",
+ prim->name.c_str(ctx), pio->name.c_str(ctx));
+ if (sig->driver.cell->type != id_DQSBUFM || sig->driver.port != port)
+ log_error("Port %s of cell '%s' must be driven by port %s of a DQSBUFM", port.c_str(ctx),
+ prim->name.c_str(ctx), port.c_str(ctx));
+ auto &driver_group = dqsbuf_dqsg.at(sig->driver.cell->name);
+ if (driver_group.first != dqsr || driver_group.second != dqsgroup)
+ log_error("DQS group mismatch, port %s of '%s' in group %cDQ%d is driven by DQSBUFM '%s' in group "
+ "%cDQ%d\n",
+ port.c_str(ctx), prim->name.c_str(ctx), dqsr ? 'R' : 'L', dqsgroup,
+ sig->driver.cell->name.c_str(ctx), driver_group.first ? 'R' : 'L', driver_group.second);
+ replace_port(prim, port, iol, port);
+ }
+ };
+
for (auto cell : sorted(ctx->cells)) {
CellInfo *ci = cell.second;
if (ci->type == ctx->id("IDDRX1F")) {