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:
Patrick Urban 2026-01-23 09:34:57 +01:00 committed by GitHub
parent e2e7cf4997
commit 25c81e3a3e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 107 additions and 39 deletions

View File

@ -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);
}
}
}

View File

@ -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());
}
}

View File

@ -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);

View File

@ -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) {

View File

@ -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();