aboutsummaryrefslogtreecommitdiffstats
path: root/ecp5
diff options
context:
space:
mode:
authorDavid Shah <dave@ds0.me>2019-11-29 10:50:13 +0000
committerDavid Shah <dave@ds0.me>2019-11-29 10:50:13 +0000
commitff30bc87fed024189a49bc372b1db0bde6db29f2 (patch)
tree20fe3c6b15b8dddf9ae40d8c7191cd01d29feab6 /ecp5
parentbefc9948065084193ee828ff6d3e9c8402579cf2 (diff)
downloadnextpnr-ff30bc87fed024189a49bc372b1db0bde6db29f2.tar.gz
nextpnr-ff30bc87fed024189a49bc372b1db0bde6db29f2.tar.bz2
nextpnr-ff30bc87fed024189a49bc372b1db0bde6db29f2.zip
ecp5: Fix placement of DDRDLLA
Signed-off-by: David Shah <dave@ds0.me>
Diffstat (limited to 'ecp5')
-rw-r--r--ecp5/pack.cc26
1 files changed, 26 insertions, 0 deletions
diff --git a/ecp5/pack.cc b/ecp5/pack.cc
index d2a21c87..09947d88 100644
--- a/ecp5/pack.cc
+++ b/ecp5/pack.cc
@@ -2688,12 +2688,37 @@ class Ecp5Packer
const NetInfo *clk = net_or_nullptr(ci, id_CLK);
if (clk == nullptr)
log_error("DDRDLLA '%s' has disconnected port CLK\n", ci->name.c_str(ctx));
+
+ bool left_bank_users = false, right_bank_users = false;
+ // Check which side the delay codes (DDRDEL) are used on
+ const NetInfo *ddrdel = net_or_nullptr(ci, id_DDRDEL);
+ if (ddrdel != nullptr) {
+ for (auto &usr : ddrdel->users) {
+ const CellInfo *uc = usr.cell;
+ if (uc->type != id_DQSBUFM || !uc->attrs.count(ctx->id("BEL")))
+ continue;
+ BelId dqsb_bel = ctx->getBelByName(ctx->id(uc->attrs.at(ctx->id("BEL")).as_string()));
+ Loc dqsb_loc = ctx->getBelLocation(dqsb_bel);
+ if (dqsb_loc.x > 15)
+ right_bank_users = true;
+ if (dqsb_loc.x < 15)
+ left_bank_users = true;
+ }
+ }
+
+ if (left_bank_users && right_bank_users)
+ log_error("DDRDLLA '%s' has DDRDEL uses on both sides of the chip.\n", ctx->nameOf(ci));
+
for (auto &eclk : eclks) {
if (eclk.second.unbuf == clk) {
for (auto bel : ctx->getBels()) {
if (ctx->getBelType(bel) != id_DDRDLL)
continue;
Loc loc = ctx->getBelLocation(bel);
+ if (loc.x > 15 && left_bank_users)
+ continue;
+ if (loc.x < 15 && right_bank_users)
+ continue;
int ddrdll_bank = -1;
if (loc.x < 15 && loc.y < 15)
ddrdll_bank = 7;
@@ -2705,6 +2730,7 @@ class Ecp5Packer
ddrdll_bank = 3;
if (eclk.first.first != ddrdll_bank)
continue;
+ log_info("Constraining DDRDLLA '%s' to bel '%s'\n", ctx->nameOf(ci), ctx->nameOfBel(bel));
ci->attrs[ctx->id("BEL")] = ctx->getBelName(bel).str(ctx);
make_eclk(ci->ports.at(id_CLK), ci, bel, eclk.first.first);
goto ddrdll_done;