mirror of https://github.com/YosysHQ/yosys.git
Merge pull request #1964 from YosysHQ/claire/sformatf
Extend support for format strings in Verilog front-end
This commit is contained in:
commit
ae115fa3aa
|
@ -64,6 +64,21 @@ std::string AstNode::process_format_str(const std::string &sformat, int next_arg
|
||||||
continue;
|
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
|
// Simplify the argument
|
||||||
AstNode *node_arg = nullptr;
|
AstNode *node_arg = nullptr;
|
||||||
|
|
||||||
|
@ -74,6 +89,9 @@ std::string AstNode::process_format_str(const std::string &sformat, int next_arg
|
||||||
case 'S':
|
case 'S':
|
||||||
case 'd':
|
case 'd':
|
||||||
case 'D':
|
case 'D':
|
||||||
|
if (got_len)
|
||||||
|
goto unsupported_format;
|
||||||
|
/* fall through */
|
||||||
case 'x':
|
case 'x':
|
||||||
case 'X':
|
case 'X':
|
||||||
if (next_arg >= GetSize(children))
|
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':
|
||||||
case 'M':
|
case 'M':
|
||||||
|
if (got_len)
|
||||||
|
goto unsupported_format;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
unsupported_format:
|
||||||
log_file_error(filename, location.first_line, "System task `%s' called with invalid/unsupported format specifier.\n", str.c_str());
|
log_file_error(filename, location.first_line, "System task `%s' called with invalid/unsupported format specifier.\n", str.c_str());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -104,19 +125,28 @@ std::string AstNode::process_format_str(const std::string &sformat, int next_arg
|
||||||
|
|
||||||
case 'd':
|
case 'd':
|
||||||
case 'D':
|
case 'D':
|
||||||
{
|
sout += stringf("%d", node_arg->bitsAsConst().as_int());
|
||||||
char tmp[128];
|
|
||||||
snprintf(tmp, sizeof(tmp), "%d", node_arg->bitsAsConst().as_int());
|
|
||||||
sout += tmp;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'x':
|
case 'x':
|
||||||
case 'X':
|
case 'X':
|
||||||
{
|
{
|
||||||
char tmp[128];
|
Const val = node_arg->bitsAsConst();
|
||||||
snprintf(tmp, sizeof(tmp), "%x", node_arg->bitsAsConst().as_int());
|
|
||||||
sout += tmp;
|
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;
|
break;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue