diff options
author | Claire Wolf <claire@symbioticeda.com> | 2020-04-18 14:08:51 +0200 |
---|---|---|
committer | Claire Wolf <claire@symbioticeda.com> | 2020-04-18 14:08:51 +0200 |
commit | 35990b95ec3b306f5ff0edf84c7d83aada1005d0 (patch) | |
tree | 3e863d810955b6bf4dca0e425babd0850693ab93 /frontends/ast | |
parent | c98cde88427aedacbcaf66d915912377ccb0cb01 (diff) | |
download | yosys-35990b95ec3b306f5ff0edf84c7d83aada1005d0.tar.gz yosys-35990b95ec3b306f5ff0edf84c7d83aada1005d0.tar.bz2 yosys-35990b95ec3b306f5ff0edf84c7d83aada1005d0.zip |
Extend support for format strings in Verilog front-end
Signed-off-by: Claire Wolf <claire@symbioticeda.com>
Diffstat (limited to 'frontends/ast')
-rw-r--r-- | frontends/ast/simplify.cc | 46 |
1 files changed, 38 insertions, 8 deletions
diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 372dcf95c..467afdd87 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -64,6 +64,21 @@ std::string AstNode::process_format_str(const std::string &sformat, int next_arg continue; } + bool got_len = false; + bool got_zlen = false; + int len_value = 0; + + while ('0' <= cformat && cformat <= '9') + { + if (!got_len && cformat == '0') + got_zlen = true; + + got_len = true; + len_value = 10*len_value + (cformat - '0'); + + cformat = sformat[++i]; + } + // Simplify the argument AstNode *node_arg = nullptr; @@ -74,6 +89,9 @@ std::string AstNode::process_format_str(const std::string &sformat, int next_arg case 'S': case 'd': case 'D': + if (got_len) + goto unsupported_format; + /* fall through */ case 'x': case 'X': if (next_arg >= GetSize(children)) @@ -88,9 +106,12 @@ std::string AstNode::process_format_str(const std::string &sformat, int next_arg case 'm': case 'M': + if (got_len) + goto unsupported_format; break; default: + unsupported_format: log_file_error(filename, location.first_line, "System task `%s' called with invalid/unsupported format specifier.\n", str.c_str()); break; } @@ -104,19 +125,28 @@ std::string AstNode::process_format_str(const std::string &sformat, int next_arg case 'd': case 'D': - { - char tmp[128]; - snprintf(tmp, sizeof(tmp), "%d", node_arg->bitsAsConst().as_int()); - sout += tmp; - } + sout += stringf("%d", node_arg->bitsAsConst().as_int()); break; case 'x': case 'X': { - char tmp[128]; - snprintf(tmp, sizeof(tmp), "%x", node_arg->bitsAsConst().as_int()); - sout += tmp; + Const val = node_arg->bitsAsConst(); + + while (GetSize(val) % 4 != 0) + val.bits.push_back(State::S0); + + int len = GetSize(val) / 4; + for (int i = len; i < len_value; i++) + sout += got_zlen ? '0' : ' '; + + for (int i = len-1; i >= 0; i--) { + Const digit = val.extract(4*i, 4); + if (digit.is_fully_def()) + sout += stringf(cformat == 'x' ? "%x" : "%X", digit.as_int()); + else + sout += cformat == 'x' ? "x" : "X"; + } } break; |