mirror of https://github.com/YosysHQ/nextpnr.git
gatemate: fix block RAM ECC status signal wiring and delay annotation (#1629)
* gatemate: fix ECC CPE connection * gatemate: fix typos * gatemate: add ECC signals to `ram_signal_clk` dictionary * gatemate: allow switching between NOECC and ECC block RAM delays
This commit is contained in:
parent
e2e7cf4997
commit
25c81e3a3e
|
|
@ -103,7 +103,7 @@ struct GateMateCCFReader
|
|||
if (uarch->die_to_index.count(ctx->id(value))) {
|
||||
props->emplace(ctx->id(name), Property(value));
|
||||
} else
|
||||
log_error("Uknown value '%s' for parameter '%s' in line %d.\n", value.c_str(), name.c_str(),
|
||||
log_error("Unknown value '%s' for parameter '%s' in line %d.\n", value.c_str(), name.c_str(),
|
||||
lineno);
|
||||
} else if (name == "SCHMITT_TRIGGER" || name == "PULLUP" || name == "PULLDOWN" || name == "KEEPER" ||
|
||||
name == "FF_IBF" || name == "FF_OBF" || name == "LVDS_BOOST" || name == "LVDS_RTERM") {
|
||||
|
|
@ -116,7 +116,7 @@ struct GateMateCCFReader
|
|||
} else if (value == "FALSE") {
|
||||
props->emplace(ctx->id(name), Property(Property::State::S0));
|
||||
} else
|
||||
log_error("Uknown value '%s' for parameter '%s' in line %d, must be TRUE or FALSE.\n",
|
||||
log_error("Unknown value '%s' for parameter '%s' in line %d, must be TRUE or FALSE.\n",
|
||||
value.c_str(), name.c_str(), lineno);
|
||||
} else if (name == "SLEW") {
|
||||
if (value == "1" || value == "TRUE")
|
||||
|
|
@ -126,7 +126,7 @@ struct GateMateCCFReader
|
|||
if (value == "FAST" || value == "SLOW") {
|
||||
props->emplace(ctx->id(name), Property(value));
|
||||
} else
|
||||
log_error("Uknown value '%s' for parameter '%s' in line %d, must be SLOW or FAST.\n", value.c_str(),
|
||||
log_error("Unknown value '%s' for parameter '%s' in line %d, must be SLOW or FAST.\n", value.c_str(),
|
||||
name.c_str(), lineno);
|
||||
} else if (name == "DRIVE") {
|
||||
try {
|
||||
|
|
@ -149,7 +149,7 @@ struct GateMateCCFReader
|
|||
log_error("Parameter '%s' must be number in line %d.\n", name.c_str(), lineno);
|
||||
}
|
||||
} else {
|
||||
log_error("Uknown parameter name '%s' in line %d.\n", name.c_str(), lineno);
|
||||
log_error("Unknown parameter name '%s' in line %d.\n", name.c_str(), lineno);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -378,34 +378,98 @@ TimingClockingInfo GateMateImpl::getPortClockingInfo(const CellInfo *cell, IdStr
|
|||
}
|
||||
} else if (cell->type.in(id_RAM, id_RAM_HALF)) {
|
||||
std::string name = port.str(ctx);
|
||||
if (boost::starts_with(name, "CLOCK"))
|
||||
get_delay_from_tmg_db(id_timing_RAM_NOECC_IOPATH_1, info.clockToQ);
|
||||
if (boost::starts_with(name, "DOA"))
|
||||
get_delay_from_tmg_db(id_timing_RAM_NOECC_IOPATH_2, info.clockToQ);
|
||||
if (boost::starts_with(name, "DOB"))
|
||||
get_delay_from_tmg_db(id_timing_RAM_NOECC_IOPATH_3, info.clockToQ);
|
||||
if (boost::starts_with(name, "ECC"))
|
||||
get_delay_from_tmg_db(id_timing_RAM_NOECC_IOPATH_4, info.clockToQ);
|
||||
if (boost::starts_with(name, "ADDR"))
|
||||
get_setuphold_from_tmg_db(id_timing_RAM_NOECC_SETUPHOLD_1, info.setup, info.hold);
|
||||
if (boost::starts_with(name, "CLOCK1"))
|
||||
get_setuphold_from_tmg_db(id_timing_RAM_NOECC_SETUPHOLD_2, info.setup, info.hold);
|
||||
if (boost::starts_with(name, "DIA"))
|
||||
get_setuphold_from_tmg_db(id_timing_RAM_NOECC_SETUPHOLD_3, info.setup, info.hold);
|
||||
if (boost::starts_with(name, "DIB"))
|
||||
get_setuphold_from_tmg_db(id_timing_RAM_NOECC_SETUPHOLD_4, info.setup, info.hold);
|
||||
if (boost::starts_with(name, "ENA"))
|
||||
get_setuphold_from_tmg_db(id_timing_RAM_NOECC_SETUPHOLD_5, info.setup, info.hold);
|
||||
if (boost::starts_with(name, "ENB"))
|
||||
get_setuphold_from_tmg_db(id_timing_RAM_NOECC_SETUPHOLD_6, info.setup, info.hold);
|
||||
if (boost::starts_with(name, "GLWEA"))
|
||||
get_setuphold_from_tmg_db(id_timing_RAM_NOECC_SETUPHOLD_7, info.setup, info.hold);
|
||||
if (boost::starts_with(name, "GLWEB"))
|
||||
get_setuphold_from_tmg_db(id_timing_RAM_NOECC_SETUPHOLD_8, info.setup, info.hold);
|
||||
if (boost::starts_with(name, "WEA"))
|
||||
get_setuphold_from_tmg_db(id_timing_RAM_NOECC_SETUPHOLD_9, info.setup, info.hold);
|
||||
if (boost::starts_with(name, "WEB"))
|
||||
get_setuphold_from_tmg_db(id_timing_RAM_NOECC_SETUPHOLD_10, info.setup, info.hold);
|
||||
int is_ecc_a = int_or_default(cell->params, id_A_ECC_EN, 0);
|
||||
int is_ecc_b = int_or_default(cell->params, id_B_ECC_EN, 0);
|
||||
if (boost::starts_with(name, "CLOCK")) {
|
||||
if (is_ecc_a || is_ecc_b)
|
||||
get_delay_from_tmg_db(id_timing_RAM_ECC_IOPATH_1, info.clockToQ);
|
||||
else
|
||||
get_delay_from_tmg_db(id_timing_RAM_NOECC_IOPATH_1, info.clockToQ);
|
||||
}
|
||||
if (boost::starts_with(name, "DOA")) {
|
||||
if (is_ecc_a)
|
||||
get_delay_from_tmg_db(id_timing_RAM_ECC_IOPATH_2, info.clockToQ);
|
||||
else
|
||||
get_delay_from_tmg_db(id_timing_RAM_NOECC_IOPATH_2, info.clockToQ);
|
||||
}
|
||||
if (boost::starts_with(name, "DOB")) {
|
||||
if (is_ecc_b)
|
||||
get_delay_from_tmg_db(id_timing_RAM_ECC_IOPATH_3, info.clockToQ);
|
||||
else
|
||||
get_delay_from_tmg_db(id_timing_RAM_NOECC_IOPATH_3, info.clockToQ);
|
||||
}
|
||||
if (boost::starts_with(name, "ECC")) {
|
||||
if (is_ecc_a || is_ecc_b)
|
||||
get_delay_from_tmg_db(id_timing_RAM_ECC_IOPATH_4, info.clockToQ);
|
||||
else
|
||||
get_delay_from_tmg_db(id_timing_RAM_NOECC_IOPATH_4, info.clockToQ);
|
||||
}
|
||||
if (boost::starts_with(name, "ADDRA")) {
|
||||
if (is_ecc_a)
|
||||
get_setuphold_from_tmg_db(id_timing_RAM_ECC_SETUPHOLD_1, info.setup, info.hold);
|
||||
else
|
||||
get_setuphold_from_tmg_db(id_timing_RAM_NOECC_SETUPHOLD_1, info.setup, info.hold);
|
||||
}
|
||||
if (boost::starts_with(name, "ADDRB")) {
|
||||
if (is_ecc_b)
|
||||
get_setuphold_from_tmg_db(id_timing_RAM_ECC_SETUPHOLD_1, info.setup, info.hold);
|
||||
else
|
||||
get_setuphold_from_tmg_db(id_timing_RAM_NOECC_SETUPHOLD_1, info.setup, info.hold);
|
||||
}
|
||||
if (boost::starts_with(name, "CLOCK1")) { // TODO CLOCK1 || CLOCK2 || CLOCK3 || CLOCK4?
|
||||
if (is_ecc_a || is_ecc_b)
|
||||
get_setuphold_from_tmg_db(id_timing_RAM_ECC_SETUPHOLD_2, info.setup, info.hold);
|
||||
else
|
||||
get_setuphold_from_tmg_db(id_timing_RAM_NOECC_SETUPHOLD_2, info.setup, info.hold);
|
||||
}
|
||||
if (boost::starts_with(name, "DIA")) {
|
||||
if (is_ecc_a)
|
||||
get_setuphold_from_tmg_db(id_timing_RAM_ECC_SETUPHOLD_3, info.setup, info.hold);
|
||||
else
|
||||
get_setuphold_from_tmg_db(id_timing_RAM_NOECC_SETUPHOLD_3, info.setup, info.hold);
|
||||
}
|
||||
if (boost::starts_with(name, "DIB")) {
|
||||
if (is_ecc_b)
|
||||
get_setuphold_from_tmg_db(id_timing_RAM_ECC_SETUPHOLD_4, info.setup, info.hold);
|
||||
else
|
||||
get_setuphold_from_tmg_db(id_timing_RAM_NOECC_SETUPHOLD_4, info.setup, info.hold);
|
||||
}
|
||||
if (boost::starts_with(name, "ENA")) {
|
||||
if (is_ecc_a)
|
||||
get_setuphold_from_tmg_db(id_timing_RAM_ECC_SETUPHOLD_5, info.setup, info.hold);
|
||||
else
|
||||
get_setuphold_from_tmg_db(id_timing_RAM_NOECC_SETUPHOLD_5, info.setup, info.hold);
|
||||
}
|
||||
if (boost::starts_with(name, "ENB")) {
|
||||
if (is_ecc_b)
|
||||
get_setuphold_from_tmg_db(id_timing_RAM_ECC_SETUPHOLD_6, info.setup, info.hold);
|
||||
else
|
||||
get_setuphold_from_tmg_db(id_timing_RAM_NOECC_SETUPHOLD_6, info.setup, info.hold);
|
||||
}
|
||||
if (boost::starts_with(name, "GLWEA")) {
|
||||
if (is_ecc_a)
|
||||
get_setuphold_from_tmg_db(id_timing_RAM_ECC_SETUPHOLD_7, info.setup, info.hold);
|
||||
else
|
||||
get_setuphold_from_tmg_db(id_timing_RAM_NOECC_SETUPHOLD_7, info.setup, info.hold);
|
||||
}
|
||||
if (boost::starts_with(name, "GLWEB")) {
|
||||
if (is_ecc_b)
|
||||
get_setuphold_from_tmg_db(id_timing_RAM_ECC_SETUPHOLD_8, info.setup, info.hold);
|
||||
else
|
||||
get_setuphold_from_tmg_db(id_timing_RAM_NOECC_SETUPHOLD_8, info.setup, info.hold);
|
||||
}
|
||||
if (boost::starts_with(name, "WEA")) {
|
||||
if (is_ecc_a)
|
||||
get_setuphold_from_tmg_db(id_timing_RAM_ECC_SETUPHOLD_9, info.setup, info.hold);
|
||||
else
|
||||
get_setuphold_from_tmg_db(id_timing_RAM_NOECC_SETUPHOLD_9, info.setup, info.hold);
|
||||
}
|
||||
if (boost::starts_with(name, "WEB")) {
|
||||
if (is_ecc_b)
|
||||
get_setuphold_from_tmg_db(id_timing_RAM_ECC_SETUPHOLD_10, info.setup, info.hold);
|
||||
else
|
||||
get_setuphold_from_tmg_db(id_timing_RAM_NOECC_SETUPHOLD_10, info.setup, info.hold);
|
||||
}
|
||||
bool is_clk_b = false;
|
||||
for (auto c : boost::adaptors::reverse(name)) {
|
||||
if (std::isdigit(c) || c == 'X' || c == '[' || c == ']')
|
||||
|
|
@ -452,7 +516,7 @@ TimingClockingInfo GateMateImpl::getPortClockingInfo(const CellInfo *cell, IdStr
|
|||
break;
|
||||
}
|
||||
} else {
|
||||
log_error("Uknown clock signal for %s\n", name.c_str());
|
||||
log_error("Unknown clock signal for %s\n", name.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -147,6 +147,10 @@ void GateMateImpl::init(Context *ctx)
|
|||
ram_signal_clk.emplace(ctx->idf("ENB[%d]", index), num + 2);
|
||||
ram_signal_clk.emplace(ctx->idf("GLWEA[%d]", index), num);
|
||||
ram_signal_clk.emplace(ctx->idf("GLWEB[%d]", index), num + 2);
|
||||
ram_signal_clk.emplace(ctx->idf("ECC1B_ERRA[%d]", index), num);
|
||||
ram_signal_clk.emplace(ctx->idf("ECC1B_ERRB[%d]", index), num + 2);
|
||||
ram_signal_clk.emplace(ctx->idf("ECC2B_ERRA[%d]", index), num);
|
||||
ram_signal_clk.emplace(ctx->idf("ECC2B_ERRB[%d]", index), num + 2);
|
||||
for (int i = 0; i < 20; i++) {
|
||||
ram_signal_clk.emplace(ctx->idf("WEA[%d]", i + num * 20), num);
|
||||
ram_signal_clk.emplace(ctx->idf("WEB[%d]", i + num * 20), num + 2);
|
||||
|
|
|
|||
|
|
@ -424,10 +424,10 @@ void GateMatePacker::pack_ram()
|
|||
move_ram_o(&ci, ctx->idf("ENB[%d]", i));
|
||||
move_ram_o(&ci, ctx->idf("GLWEA[%d]", i));
|
||||
move_ram_o(&ci, ctx->idf("GLWEB[%d]", i));
|
||||
move_ram_o(&ci, ctx->idf("ECC1B_ERRA[%d]", i));
|
||||
move_ram_o(&ci, ctx->idf("ECC1B_ERRB[%d]", i));
|
||||
move_ram_o(&ci, ctx->idf("ECC2B_ERRA[%d]", i));
|
||||
move_ram_o(&ci, ctx->idf("ECC2B_ERRB[%d]", i));
|
||||
move_ram_i(&ci, ctx->idf("ECC1B_ERRA[%d]", i));
|
||||
move_ram_i(&ci, ctx->idf("ECC1B_ERRB[%d]", i));
|
||||
move_ram_i(&ci, ctx->idf("ECC2B_ERRA[%d]", i));
|
||||
move_ram_i(&ci, ctx->idf("ECC2B_ERRB[%d]", i));
|
||||
}
|
||||
|
||||
if (is_fifo) {
|
||||
|
|
|
|||
|
|
@ -232,7 +232,7 @@ void GateMatePacker::pack_bufg()
|
|||
else if (pll->getPort(id_CLK270) == in_net)
|
||||
pll_out = 3;
|
||||
else
|
||||
log_error("Uknown connecton on BUFG to PLL.\n");
|
||||
log_error("Unknown connecton on BUFG to PLL.\n");
|
||||
glb_mux = glb_mux_mapping[i * 16 + pll_index * 4 + pll_out];
|
||||
ci.movePortTo(id_I, uarch->glbout[die],
|
||||
ctx->idf("%s_%d", in_net->driver.port.c_str(ctx), pll_index));
|
||||
|
|
@ -418,7 +418,7 @@ void GateMatePacker::pack_pll()
|
|||
} else {
|
||||
// SER_CLK
|
||||
if (clk != net_SER_CLK)
|
||||
log_error("CLK_REF connected to uknown pin for cell '%s'.\n", ci.name.c_str(ctx));
|
||||
log_error("CLK_REF connected to unknown pin for cell '%s'.\n", ci.name.c_str(ctx));
|
||||
}
|
||||
if (clk->clkconstr)
|
||||
period = clk->clkconstr->period.minDelay();
|
||||
|
|
|
|||
Loading…
Reference in New Issue