diff options
author | Marcelina KoĆcielnicka <mwk@0x04.net> | 2021-03-17 18:30:49 +0100 |
---|---|---|
committer | Marcelina KoĆcielnicka <mwk@0x04.net> | 2021-03-18 00:52:00 +0100 |
commit | 8740fdf1d799fd8a3196bac28fe4e418e74f2acc (patch) | |
tree | 67442cc8304dff1a5536846fe34f9a2a10bdacc0 /frontends/ast/ast.cc | |
parent | cae905f55128a77e8d2eecc75d861292d79baa79 (diff) | |
download | yosys-8740fdf1d799fd8a3196bac28fe4e418e74f2acc.tar.gz yosys-8740fdf1d799fd8a3196bac28fe4e418e74f2acc.tar.bz2 yosys-8740fdf1d799fd8a3196bac28fe4e418e74f2acc.zip |
ast: Use better parameter serialization for paramod names.
Calling log_signal is problematic for several reasons:
- with recent changes, empty string is serialized as { }, which violates
the "no spaces in IdString" rule
- the type (plain / real / signed / string) is dropped, wrongly conflating
functionally different values and potentially introducing a subtle
elaboration bug
Instead, use a custom simple serialization scheme.
Diffstat (limited to 'frontends/ast/ast.cc')
-rw-r--r-- | frontends/ast/ast.cc | 27 |
1 files changed, 25 insertions, 2 deletions
diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 7aa391c93..84a4de41c 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -1575,6 +1575,29 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, const dict<RTLIL::IdStr return modname; } +static std::string serialize_param_value(const RTLIL::Const &val) { + std::string res; + if (val.flags & RTLIL::ConstFlags::CONST_FLAG_STRING) + res.push_back('t'); + if (val.flags & RTLIL::ConstFlags::CONST_FLAG_SIGNED) + res.push_back('s'); + if (val.flags & RTLIL::ConstFlags::CONST_FLAG_REAL) + res.push_back('r'); + res += stringf("%d", GetSize(val)); + res.push_back('\''); + for (int i = GetSize(val) - 1; i >= 0; i--) { + switch (val.bits[i]) { + case RTLIL::State::S0: res.push_back('0'); break; + case RTLIL::State::S1: res.push_back('1'); break; + case RTLIL::State::Sx: res.push_back('x'); break; + case RTLIL::State::Sz: res.push_back('z'); break; + case RTLIL::State::Sa: res.push_back('?'); break; + case RTLIL::State::Sm: res.push_back('m'); break; + } + } + return res; +} + // create a new parametric module (when needed) and return the name of the generated module std::string AstModule::derive_common(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> ¶meters, AstNode **new_ast_out, bool quiet) { @@ -1594,14 +1617,14 @@ std::string AstModule::derive_common(RTLIL::Design *design, const dict<RTLIL::Id if (it != parameters.end()) { if (!quiet) log("Parameter %s = %s\n", child->str.c_str(), log_signal(it->second)); - para_info += stringf("%s=%s", child->str.c_str(), log_signal(it->second)); + para_info += stringf("%s=%s", child->str.c_str(), serialize_param_value(it->second).c_str()); continue; } it = parameters.find(stringf("$%d", para_counter)); if (it != parameters.end()) { if (!quiet) log("Parameter %d (%s) = %s\n", para_counter, child->str.c_str(), log_signal(it->second)); - para_info += stringf("%s=%s", child->str.c_str(), log_signal(it->second)); + para_info += stringf("%s=%s", child->str.c_str(), serialize_param_value(it->second).c_str()); continue; } } |