3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2026-07-17 04:35:44 +00:00

Merge branch 'main' of github.com:silimate/yosys into sim

This commit is contained in:
Stan Lee 2026-03-30 14:48:34 -07:00
commit d2cd4d2cc8
23 changed files with 1865 additions and 46 deletions

View file

@ -753,6 +753,40 @@ namespace {
int n_wr_ports = cell->parameters.at(ID::WR_PORTS).as_int();
Const rd_wide_continuation = is_compat ? Const(State::S0, n_rd_ports) : cell->parameters.at(ID::RD_WIDE_CONTINUATION);
Const wr_wide_continuation = is_compat ? Const(State::S0, n_wr_ports) : cell->parameters.at(ID::WR_WIDE_CONTINUATION);
pool<IdString> bad_params;
if (!is_compat) {
auto check_param_size = [&](IdString param_name, int expected_size) {
const Const &param = cell->parameters.at(param_name);
if (GetSize(param) != expected_size) {
log_warning("Memory cell %s.%s (%s) has inconsistent parameter %s: expected size %d, got %d\n",
log_id(cell->module), log_id(cell), log_id(res.memid),
log_id(param_name), expected_size, GetSize(param));
bad_params.insert(param_name);
}
};
check_param_size(ID::RD_WIDE_CONTINUATION, n_rd_ports);
check_param_size(ID::RD_CLK_ENABLE, n_rd_ports);
check_param_size(ID::RD_CLK_POLARITY, n_rd_ports);
check_param_size(ID::RD_CE_OVER_SRST, n_rd_ports);
check_param_size(ID::RD_ARST_VALUE, n_rd_ports * res.width);
check_param_size(ID::RD_SRST_VALUE, n_rd_ports * res.width);
check_param_size(ID::RD_INIT_VALUE, n_rd_ports * res.width);
check_param_size(ID::RD_TRANSPARENCY_MASK, n_rd_ports * n_wr_ports);
check_param_size(ID::RD_COLLISION_X_MASK, n_rd_ports * n_wr_ports);
check_param_size(ID::WR_WIDE_CONTINUATION, n_wr_ports);
check_param_size(ID::WR_CLK_ENABLE, n_wr_ports);
check_param_size(ID::WR_CLK_POLARITY, n_wr_ports);
check_param_size(ID::WR_PRIORITY_MASK, n_wr_ports * n_wr_ports);
if (bad_params.count(ID::RD_WIDE_CONTINUATION))
rd_wide_continuation = Const(State::S0, n_rd_ports);
if (bad_params.count(ID::WR_WIDE_CONTINUATION))
wr_wide_continuation = Const(State::S0, n_wr_ports);
}
auto safe_param_extract = [&](IdString param_name, int offset, int len) -> Const {
if (bad_params.count(param_name))
return Const(State::S0, len);
return cell->parameters.at(param_name).extract(offset, len);
};
for (int i = 0, ni; i < n_rd_ports; i = ni) {
ni = i + 1;
while (ni < n_rd_ports && rd_wide_continuation[ni] == State::S1)
@ -760,8 +794,8 @@ namespace {
MemRd mrd;
mrd.wide_log2 = ceil_log2(ni - i);
log_assert(ni - i == (1 << mrd.wide_log2));
mrd.clk_enable = cell->parameters.at(ID::RD_CLK_ENABLE).extract(i, 1).as_bool();
mrd.clk_polarity = cell->parameters.at(ID::RD_CLK_POLARITY).extract(i, 1).as_bool();
mrd.clk_enable = safe_param_extract(ID::RD_CLK_ENABLE, i, 1).as_bool();
mrd.clk_polarity = safe_param_extract(ID::RD_CLK_POLARITY, i, 1).as_bool();
mrd.clk = cell->getPort(ID::RD_CLK).extract(i, 1);
mrd.en = cell->getPort(ID::RD_EN).extract(i, 1);
mrd.addr = cell->getPort(ID::RD_ADDR).extract(i * abits, abits);
@ -774,16 +808,16 @@ namespace {
mrd.arst = State::S0;
mrd.srst = State::S0;
} else {
mrd.ce_over_srst = cell->parameters.at(ID::RD_CE_OVER_SRST).extract(i, 1).as_bool();
mrd.arst_value = cell->parameters.at(ID::RD_ARST_VALUE).extract(i * res.width, (ni - i) * res.width);
mrd.srst_value = cell->parameters.at(ID::RD_SRST_VALUE).extract(i * res.width, (ni - i) * res.width);
mrd.init_value = cell->parameters.at(ID::RD_INIT_VALUE).extract(i * res.width, (ni - i) * res.width);
mrd.ce_over_srst = safe_param_extract(ID::RD_CE_OVER_SRST, i, 1).as_bool();
mrd.arst_value = safe_param_extract(ID::RD_ARST_VALUE, i * res.width, (ni - i) * res.width);
mrd.srst_value = safe_param_extract(ID::RD_SRST_VALUE, i * res.width, (ni - i) * res.width);
mrd.init_value = safe_param_extract(ID::RD_INIT_VALUE, i * res.width, (ni - i) * res.width);
mrd.arst = cell->getPort(ID::RD_ARST).extract(i, 1);
mrd.srst = cell->getPort(ID::RD_SRST).extract(i, 1);
}
if (!is_compat) {
Const transparency_mask = cell->parameters.at(ID::RD_TRANSPARENCY_MASK).extract(i * n_wr_ports, n_wr_ports);
Const collision_x_mask = cell->parameters.at(ID::RD_COLLISION_X_MASK).extract(i * n_wr_ports, n_wr_ports);
Const transparency_mask = safe_param_extract(ID::RD_TRANSPARENCY_MASK, i * n_wr_ports, n_wr_ports);
Const collision_x_mask = safe_param_extract(ID::RD_COLLISION_X_MASK, i * n_wr_ports, n_wr_ports);
for (int j = 0; j < n_wr_ports; j++)
if (wr_wide_continuation[j] != State::S1) {
mrd.transparency_mask.push_back(transparency_mask[j] == State::S1);
@ -799,14 +833,14 @@ namespace {
MemWr mwr;
mwr.wide_log2 = ceil_log2(ni - i);
log_assert(ni - i == (1 << mwr.wide_log2));
mwr.clk_enable = cell->parameters.at(ID::WR_CLK_ENABLE).extract(i, 1).as_bool();
mwr.clk_polarity = cell->parameters.at(ID::WR_CLK_POLARITY).extract(i, 1).as_bool();
mwr.clk_enable = safe_param_extract(ID::WR_CLK_ENABLE, i, 1).as_bool();
mwr.clk_polarity = safe_param_extract(ID::WR_CLK_POLARITY, i, 1).as_bool();
mwr.clk = cell->getPort(ID::WR_CLK).extract(i, 1);
mwr.en = cell->getPort(ID::WR_EN).extract(i * res.width, (ni - i) * res.width);
mwr.addr = cell->getPort(ID::WR_ADDR).extract(i * abits, abits);
mwr.data = cell->getPort(ID::WR_DATA).extract(i * res.width, (ni - i) * res.width);
if (!is_compat) {
Const priority_mask = cell->parameters.at(ID::WR_PRIORITY_MASK).extract(i * n_wr_ports, n_wr_ports);
Const priority_mask = safe_param_extract(ID::WR_PRIORITY_MASK, i * n_wr_ports, n_wr_ports);
for (int j = 0; j < n_wr_ports; j++)
if (wr_wide_continuation[j] != State::S1)
mwr.priority_mask.push_back(priority_mask[j] == State::S1);
@ -832,7 +866,7 @@ namespace {
auto &port = res.rd_ports[i];
port.transparency_mask.resize(GetSize(res.wr_ports));
port.collision_x_mask.resize(GetSize(res.wr_ports));
if (!cell->parameters.at(ID::RD_TRANSPARENT).extract(i, 1).as_bool())
if (!cell->parameters.at(ID::RD_TRANSPARENT).extract(i, 1, State::S0).as_bool())
continue;
if (!port.clk_enable)
continue;

View file

@ -4568,19 +4568,15 @@ const RTLIL::Const &RTLIL::Cell::getParam(RTLIL::IdString paramname) const
std::map<std::string, int> RTLIL::Cell::getParamsAsInts() const
{
std::map<std::string, int> result;
for (auto &param : parameters) {
std::string key = param.first.str();
if (key.size() > 0 && key[0] == '\\')
key = key.substr(1);
result[key] = param.second.as_int();
}
for (const auto &param : parameters)
result[RTLIL::unescape_id(param.first)] = param.second.as_int();
return result;
}
double RTLIL::Cell::maxInputConstRatio() const
{
double max_ratio = 0.0;
for (auto &conn : connections_) {
for (const auto &conn : connections_) {
if (input(conn.first)) {
double ratio = conn.second.const_ratio();
if (ratio > max_ratio)
@ -4590,6 +4586,24 @@ double RTLIL::Cell::maxInputConstRatio() const
return max_ratio;
}
std::vector<std::string> RTLIL::Cell::getOutputPortNames() const
{
std::vector<std::string> result;
for (const auto &conn : connections_) {
if (output(conn.first))
result.push_back(RTLIL::unescape_id(conn.first));
}
return result;
}
std::map<std::string, int> RTLIL::Cell::getConnectionSizes() const
{
std::map<std::string, int> result;
for (const auto &conn : connections_)
result[RTLIL::unescape_id(conn.first)] = conn.second.size();
return result;
}
void RTLIL::Cell::sort()
{
connections_.sort(sort_by_id_str());

View file

@ -2539,6 +2539,12 @@ public:
// Returns the maximum const_ratio() across all input ports, 0.0 if no input ports
double maxInputConstRatio() const;
// Returns the names of all output ports (backslash-stripped)
std::vector<std::string> getOutputPortNames() const;
// Returns {port_name: sig.size()} for all connections, port names backslash-stripped
std::map<std::string, int> getConnectionSizes() const;
void sort();
void check();
void fixup_parameters(bool set_a_signed = false, bool set_b_signed = false);