aboutsummaryrefslogtreecommitdiffstats
path: root/frontends/ast
diff options
context:
space:
mode:
authorClaire Wolf <claire@symbioticeda.com>2020-04-18 14:08:51 +0200
committerClaire Wolf <claire@symbioticeda.com>2020-04-18 14:08:51 +0200
commit35990b95ec3b306f5ff0edf84c7d83aada1005d0 (patch)
tree3e863d810955b6bf4dca0e425babd0850693ab93 /frontends/ast
parentc98cde88427aedacbcaf66d915912377ccb0cb01 (diff)
downloadyosys-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.cc46
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;