aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Shah <dave@ds0.me>2020-11-17 19:49:54 +0000
committerDavid Shah <dave@ds0.me>2020-11-30 08:45:28 +0000
commit5cf7f01169a009b0ac87d908683523bf0cfe1d37 (patch)
tree3616c7c08ab4821359c814a50c36fe01971477d6
parentf79552745494455267beb1a1cea0658e54ffebe7 (diff)
downloadnextpnr-5cf7f01169a009b0ac87d908683523bf0cfe1d37.tar.gz
nextpnr-5cf7f01169a009b0ac87d908683523bf0cfe1d37.tar.bz2
nextpnr-5cf7f01169a009b0ac87d908683523bf0cfe1d37.zip
nexus: Add MULTADDSUB36X36
Signed-off-by: David Shah <dave@ds0.me>
-rw-r--r--nexus/pack.cc25
1 files changed, 21 insertions, 4 deletions
diff --git a/nexus/pack.cc b/nexus/pack.cc
index eef1334b..3332f848 100644
--- a/nexus/pack.cc
+++ b/nexus/pack.cc
@@ -1528,6 +1528,7 @@ struct NexusPacker
{id_MULTPREADD9X9, {9, 9, 9, 18, 1, 0, 0, true, false}},
{id_MULTPREADD18X18, {18, 18, 18, 36, 2, 1, 0, true, false}},
{id_MULTADDSUB18X18, {18, 18, 54, 54, 2, 1, 0, false, true}},
+ {id_MULTADDSUB36X36, {36, 36, 108, 108, 8, 4, 2, false, true}},
};
void pack_dsps()
@@ -1554,7 +1555,10 @@ struct NexusPacker
for (int i = 0; i < mt.N18x36; i++)
mult18x36[i] = create_dsp_cell(ci->name, id_MULT18X36_CORE, preadd9[0], (i * 4) + 2, 4);
for (int i = 0; i < Nreg18; i++) {
- reg18[i] = create_dsp_cell(ci->name, id_REG18_CORE, preadd9[0], (i / 4) * 4 + 2, i % 4);
+ int idx = i;
+ if (mt.has_addsub && (i >= 4))
+ idx += 2;
+ reg18[i] = create_dsp_cell(ci->name, id_REG18_CORE, preadd9[0], (idx / 4) * 4 + 2, idx % 4);
}
// Configure the 9x9 preadd+multiply blocks
@@ -1591,7 +1595,7 @@ struct NexusPacker
preadd9[i]->params[id_PREADDCAS_EN] = std::string("ENABLED");
} else if (mt.has_addsub) {
// Connect only for routeability reasons
- copy_bus(ctx, ci, id_C, 10 * i, true, preadd9[i], id_C, 0, false, 10);
+ copy_bus(ctx, ci, id_C, 10 * i + ((i >= 4) ? 14 : 0), true, preadd9[i], id_C, 0, false, 10);
}
// Connect up signedness for the most significant nonet
@@ -1648,8 +1652,12 @@ struct NexusPacker
copy_port(ctx, ci, id_RSTOUT, acc54[i], id_RSTO);
copy_port(ctx, ci, id_CEOUT, acc54[i], id_CEO);
// Add/acc control
- copy_port(ctx, ci, id_CIN, acc54[i], id_CIN);
- copy_port(ctx, ci, id_SIGNED, acc54[i], id_SIGNEDI);
+ if (i == 0)
+ copy_port(ctx, ci, id_CIN, acc54[i], id_CIN);
+ else
+ ctx->set_cell_pinmux(acc54[i], id_CIN, PINMUX_1);
+ if (i == (Nacc54 - 1))
+ copy_port(ctx, ci, id_SIGNED, acc54[i], id_SIGNEDI);
copy_port(ctx, ci, id_ADDSUB, acc54[i], id_ADDSUB0);
copy_port(ctx, ci, id_ADDSUB, acc54[i], id_ADDSUB1);
copy_port(ctx, ci, id_LOADC, acc54[i], id_LOAD);
@@ -1666,6 +1674,15 @@ struct NexusPacker
copy_param(ci, id_REGPIPELINE, acc54[i], id_CINREGBYPS2);
copy_param(ci, id_REGPIPELINE, acc54[i], id_M9ADDSUBREGBYPS2);
copy_param(ci, id_REGOUTPUT, acc54[i], id_OUTREGBYPS);
+
+ if (i == 1) {
+ // Top ACC54 in a 108-bit config
+ acc54[i]->params[id_ACCUMODE] = std::string("MODE6");
+ acc54[i]->params[id_ACC108CASCADE] = std::string("CASCADE2ACCU54TOFORMACCU108");
+ } else if ((i == 0) && (Nacc54 == 2)) {
+ // Bottom ACC54 in a 108-bit config
+ acc54[i]->params[id_ACCUMODE] = std::string("MODE2");
+ }
}
}