aboutsummaryrefslogtreecommitdiffstats
path: root/ecp5
diff options
context:
space:
mode:
authorDavid Shah <davey1576@gmail.com>2018-10-22 16:18:29 +0100
committerDavid Shah <davey1576@gmail.com>2018-10-22 16:18:29 +0100
commit0ac48c6a08ff1ed50fbd6edf4f2351a70695530c (patch)
tree6eb4c5f0adba5b6a1cd083c80040a0c31c1d0a58 /ecp5
parent535a6f625a8d1abca54fdc99e4ca40ca84c1f4af (diff)
downloadnextpnr-0ac48c6a08ff1ed50fbd6edf4f2351a70695530c.tar.gz
nextpnr-0ac48c6a08ff1ed50fbd6edf4f2351a70695530c.tar.bz2
nextpnr-0ac48c6a08ff1ed50fbd6edf4f2351a70695530c.zip
ecp5: DSP fixes
Signed-off-by: David Shah <davey1576@gmail.com>
Diffstat (limited to 'ecp5')
-rw-r--r--ecp5/bitstream.cc71
-rw-r--r--ecp5/pack.cc4
2 files changed, 42 insertions, 33 deletions
diff --git a/ecp5/bitstream.cc b/ecp5/bitstream.cc
index 60609ffd..c7b5d562 100644
--- a/ecp5/bitstream.cc
+++ b/ecp5/bitstream.cc
@@ -86,14 +86,11 @@ static void tie_cib_signal(Context *ctx, ChipConfig &cc, WireId wire, bool value
signals.push(wire);
WireId cibsig;
std::string basename;
- log_info("wire %s\n", ctx->getWireName(wire).c_str(ctx));
while (true) {
NPNR_ASSERT(!signals.empty());
NPNR_ASSERT(signals.size() < 100);
cibsig = signals.front();
basename = ctx->getWireBasename(cibsig).str(ctx);
- log_info(" wire %s\n", ctx->getWireName(cibsig).c_str(ctx));
-
signals.pop();
if (std::regex_match(basename, cib_re))
break;
@@ -139,9 +136,12 @@ std::vector<bool> parse_init_str(const std::string &str, int length)
char c = str.at((str.size() - i) - 1);
int nibble = chtohex(c);
result.at(i * 4) = nibble & 0x1;
- result.at(i * 4 + 1) = nibble & 0x2;
- result.at(i * 4 + 2) = nibble & 0x4;
- result.at(i * 4 + 3) = nibble & 0x8;
+ if (i * 4 + 1 < length)
+ result.at(i * 4 + 1) = nibble & 0x2;
+ if (i * 4 + 2 < length)
+ result.at(i * 4 + 2) = nibble & 0x4;
+ if (i * 4 + 3 < length)
+ result.at(i * 4 + 3) = nibble & 0x8;
}
} else {
// Yosys style binary string
@@ -420,7 +420,8 @@ void tieoff_dsp_ports(Context *ctx, ChipConfig &cc, CellInfo *ci)
port.first.str(ctx).substr(0, 3) == "SRI" || port.first.str(ctx).substr(0, 2) == "RO" ||
port.first.str(ctx).substr(0, 2) == "MA" || port.first.str(ctx).substr(0, 2) == "MB" ||
port.first.str(ctx).substr(0, 3) == "CFB" || port.first.str(ctx).substr(0, 3) == "CIN" ||
- port.first.str(ctx).substr(0, 6) == "SOURCE" || port.first.str(ctx).substr(0, 6) == "SIGNED")
+ port.first.str(ctx).substr(0, 6) == "SOURCE" || port.first.str(ctx).substr(0, 6) == "SIGNED" ||
+ port.first.str(ctx).substr(0, 2) == "OP")
continue;
bool value = bool_or_default(ci->params, ctx->id(port.first.str(ctx) + "MUX"), false);
tie_cib_signal(ctx, cc, ctx->getBelPinWire(ci->bel, port.first), value);
@@ -751,6 +752,10 @@ void write_bitstream(Context *ctx, std::string base_config_file, std::string tex
tg.config.add_enum(dsp + ".REG_PIPELINE_RST",
str_or_default(ci->params, ctx->id("REG_PIPELINE_RST"), "RST0"));
tg.config.add_enum(dsp + ".REG_OUTPUT_CLK", str_or_default(ci->params, ctx->id("REG_OUTPUT_CLK"), "NONE"));
+ if (dsp == "MULT18_0" || dsp == "MULT18_4")
+ tg.config.add_enum(dsp + ".REG_OUTPUT_RST",
+ str_or_default(ci->params, ctx->id("REG_OUTPUT_RST"), "RST0"));
+
tg.config.add_enum(dsp + ".CLK0_DIV", str_or_default(ci->params, ctx->id("CLK0_DIV"), "ENABLED"));
tg.config.add_enum(dsp + ".CLK1_DIV", str_or_default(ci->params, ctx->id("CLK1_DIV"), "ENABLED"));
tg.config.add_enum(dsp + ".CLK2_DIV", str_or_default(ci->params, ctx->id("CLK2_DIV"), "ENABLED"));
@@ -760,12 +765,21 @@ void write_bitstream(Context *ctx, std::string base_config_file, std::string tex
tg.config.add_enum(dsp + ".RESETMODE", str_or_default(ci->params, ctx->id("RESETMODE"), "SYNC"));
tg.config.add_enum(dsp + ".MODE", "MULT18X18D");
+ if (str_or_default(ci->params, ctx->id("REG_OUTPUT_CLK"), "NONE") == "NONE")
+ tg.config.add_enum(dsp + ".CIBOUT_BYP", "ON");
if (loc.z < 4)
tg.config.add_enum("DSP_LEFT.CIBOUT", "ON");
else
tg.config.add_enum("DSP_RIGHT.CIBOUT", "ON");
+ // Some muxes default to INV, make all pass-thru
+ for (auto port : {"CLK", "CE", "RST"}) {
+ for (int i = 0; i < 4; i++) {
+ std::string sig = port + std::to_string(i);
+ tg.config.add_enum(dsp + "." + sig + "MUX", sig);
+ }
+ }
tieoff_dsp_ports(ctx, cc, ci);
cc.tilegroups.push_back(tg);
@@ -777,14 +791,8 @@ void write_bitstream(Context *ctx, std::string base_config_file, std::string tex
std::string dsp = "ALU54_" + std::to_string(loc.z);
tg.config.add_enum(dsp + ".REG_INPUTC0_CLK",
str_or_default(ci->params, ctx->id("REG_INPUTC0_CLK"), "NONE"));
- tg.config.add_enum(dsp + ".REG_INPUTC0_CE", str_or_default(ci->params, ctx->id("REG_INPUTC0_CE"), "CE0"));
- tg.config.add_enum(dsp + ".REG_INPUTC0_RST",
- str_or_default(ci->params, ctx->id("REG_INPUTC0_RST"), "RST0"));
tg.config.add_enum(dsp + ".REG_INPUTC1_CLK",
str_or_default(ci->params, ctx->id("REG_INPUTC1_CLK"), "NONE"));
- tg.config.add_enum(dsp + ".REG_INPUTC1_CE", str_or_default(ci->params, ctx->id("REG_INPUTC1_CE"), "CE0"));
- tg.config.add_enum(dsp + ".REG_INPUTC1_RST",
- str_or_default(ci->params, ctx->id("REG_INPUTC1_RST"), "RST0"));
tg.config.add_enum(dsp + ".REG_OPCODEOP0_0_CLK",
str_or_default(ci->params, ctx->id("REG_OPCODEOP0_0_CLK"), "NONE"));
tg.config.add_enum(dsp + ".REG_OPCODEOP0_0_CE",
@@ -813,40 +821,26 @@ void write_bitstream(Context *ctx, std::string base_config_file, std::string tex
str_or_default(ci->params, ctx->id("REG_OPCODEIN_1_RST"), "RST0"));
tg.config.add_enum(dsp + ".REG_OUTPUT0_CLK",
str_or_default(ci->params, ctx->id("REG_OUTPUT0_CLK"), "NONE"));
- tg.config.add_enum(dsp + ".REG_OUTPUT0_CE", str_or_default(ci->params, ctx->id("REG_OUTPUT0_CE"), "CE0"));
- tg.config.add_enum(dsp + ".REG_OUTPUT0_RST",
- str_or_default(ci->params, ctx->id("REG_OUTPUT0_RST"), "RST0"));
tg.config.add_enum(dsp + ".REG_OUTPUT1_CLK",
str_or_default(ci->params, ctx->id("REG_OUTPUT1_CLK"), "NONE"));
- tg.config.add_enum(dsp + ".REG_OUTPUT1_CE", str_or_default(ci->params, ctx->id("REG_OUTPUT1_CE"), "CE0"));
- tg.config.add_enum(dsp + ".REG_OUTPUT1_RST",
- str_or_default(ci->params, ctx->id("REG_OUTPUT1_RST"), "RST0"));
tg.config.add_enum(dsp + ".REG_FLAG_CLK", str_or_default(ci->params, ctx->id("REG_FLAG_CLK"), "NONE"));
- tg.config.add_enum(dsp + ".REG_FLAG_CE", str_or_default(ci->params, ctx->id("REG_FLAG_CE"), "CE0"));
- tg.config.add_enum(dsp + ".REG_FLAG_RST", str_or_default(ci->params, ctx->id("REG_FLAG_RST"), "RST0"));
tg.config.add_enum(dsp + ".MCPAT_SOURCE", str_or_default(ci->params, ctx->id("MCPAT_SOURCE"), "STATIC"));
tg.config.add_enum(dsp + ".MASKPAT_SOURCE",
str_or_default(ci->params, ctx->id("MASKPAT_SOURCE"), "STATIC"));
tg.config.add_word(dsp + ".MASK01",
- parse_init_str(str_or_default(ci->params, ctx->id("MASK01"), "0x00000000000000"), 54));
- tg.config.add_enum(dsp + ".REG_INPUTCFB_CLK",
- str_or_default(ci->params, ctx->id("REG_INPUTCFB_CLK"), "NONE"));
- tg.config.add_enum(dsp + ".REG_INPUTCFB_CE", str_or_default(ci->params, ctx->id("REG_INPUTCFB_CE"), "CE0"));
- tg.config.add_enum(dsp + ".REG_INPUTCFB_RST",
- str_or_default(ci->params, ctx->id("REG_INPUTCFB_RST"), "RST0"));
+ parse_init_str(str_or_default(ci->params, ctx->id("MASK01"), "0x00000000000000"), 56));
tg.config.add_enum(dsp + ".CLK0_DIV", str_or_default(ci->params, ctx->id("CLK0_DIV"), "ENABLED"));
tg.config.add_enum(dsp + ".CLK1_DIV", str_or_default(ci->params, ctx->id("CLK1_DIV"), "ENABLED"));
tg.config.add_enum(dsp + ".CLK2_DIV", str_or_default(ci->params, ctx->id("CLK2_DIV"), "ENABLED"));
tg.config.add_enum(dsp + ".CLK3_DIV", str_or_default(ci->params, ctx->id("CLK3_DIV"), "ENABLED"));
tg.config.add_word(dsp + ".MCPAT",
- parse_init_str(str_or_default(ci->params, ctx->id("MCPAT"), "0x00000000000000"), 54));
+ parse_init_str(str_or_default(ci->params, ctx->id("MCPAT"), "0x00000000000000"), 56));
tg.config.add_word(dsp + ".MASKPAT",
- parse_init_str(str_or_default(ci->params, ctx->id("MASKPAT"), "0x00000000000000"), 54));
+ parse_init_str(str_or_default(ci->params, ctx->id("MASKPAT"), "0x00000000000000"), 56));
tg.config.add_word(dsp + ".RNDPAT",
- parse_init_str(str_or_default(ci->params, ctx->id("RNDPAT"), "0x00000000000000"), 54));
+ parse_init_str(str_or_default(ci->params, ctx->id("RNDPAT"), "0x00000000000000"), 56));
tg.config.add_enum(dsp + ".GSR", str_or_default(ci->params, ctx->id("GSR"), "ENABLED"));
tg.config.add_enum(dsp + ".RESETMODE", str_or_default(ci->params, ctx->id("RESETMODE"), "SYNC"));
- tg.config.add_enum(dsp + ".MULT9_MODE", str_or_default(ci->params, ctx->id("MULT9_MODE"), "DISABLED"));
tg.config.add_enum(dsp + ".FORCE_ZERO_BARREL_SHIFT",
str_or_default(ci->params, ctx->id("FORCE_ZERO_BARREL_SHIFT"), "DISABLED"));
tg.config.add_enum(dsp + ".LEGACY", str_or_default(ci->params, ctx->id("LEGACY"), "DISABLED"));
@@ -857,7 +851,20 @@ void write_bitstream(Context *ctx, std::string base_config_file, std::string tex
tg.config.add_enum("DSP_LEFT.CIBOUT", "ON");
else
tg.config.add_enum("DSP_RIGHT.CIBOUT", "ON");
-
+ if (str_or_default(ci->params, ctx->id("REG_FLAG_CLK"), "NONE") == "NONE") {
+ if (dsp == "ALU54_7") {
+ tg.config.add_enum("MULT18_5.CIBOUT_BYP", "ON");
+ } else if (dsp == "ALU54_3") {
+ tg.config.add_enum("MULT18_5.CIBOUT_BYP", "ON");
+ }
+ }
+ if (str_or_default(ci->params, ctx->id("REG_OUTPUT0_CLK"), "NONE") == "NONE") {
+ if (dsp == "ALU54_7") {
+ tg.config.add_enum("MULT18_4.CIBOUT_BYP", "ON");
+ } else if (dsp == "ALU54_3") {
+ tg.config.add_enum("MULT18_0.CIBOUT_BYP", "ON");
+ }
+ }
tieoff_dsp_ports(ctx, cc, ci);
cc.tilegroups.push_back(tg);
diff --git a/ecp5/pack.cc b/ecp5/pack.cc
index 8aa7f5c9..18debb74 100644
--- a/ecp5/pack.cc
+++ b/ecp5/pack.cc
@@ -862,12 +862,14 @@ class Ecp5Packer
user.port.str(ctx).substr(0, 3) == "SRI" || user.port.str(ctx).substr(0, 2) == "RO" ||
user.port.str(ctx).substr(0, 2) == "MA" || user.port.str(ctx).substr(0, 2) == "MB" ||
user.port.str(ctx).substr(0, 3) == "CFB" || user.port.str(ctx).substr(0, 3) == "CIN" ||
- user.port.str(ctx).substr(0, 6) == "SOURCE" || user.port.str(ctx).substr(0, 6) == "SIGNED") {
+ user.port.str(ctx).substr(0, 6) == "SOURCE" || user.port.str(ctx).substr(0, 6) == "SIGNED" ||
+ user.port.str(ctx).substr(0, 2) == "OP") {
uc->ports[user.port].net = constnet;
constnet->users.push_back(user);
} else {
// Connected to CIB ABCD. Default state is bitstream configurable
uc->params[ctx->id(user.port.str(ctx) + "MUX")] = constval ? "1" : "0";
+ uc->ports[user.port].net = nullptr;
}
} else {
uc->ports[user.port].net = constnet;