mirror of https://github.com/YosysHQ/yosys.git
Added $display %m support, fixed mem leak in $display, fixes #128
This commit is contained in:
parent
ff5c61b120
commit
e5d42ebb4d
|
@ -193,13 +193,13 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
|
||||||
// but should be good enough for most uses
|
// but should be good enough for most uses
|
||||||
if ((type == AST_TCALL) && ((str == "$display") || (str == "$write")))
|
if ((type == AST_TCALL) && ((str == "$display") || (str == "$write")))
|
||||||
{
|
{
|
||||||
size_t nargs = GetSize(children);
|
int nargs = GetSize(children);
|
||||||
if(nargs < 1)
|
if (nargs < 1)
|
||||||
log_error("System task `%s' got %d arguments, expected >= 1 at %s:%d.\n",
|
log_error("System task `%s' got %d arguments, expected >= 1 at %s:%d.\n",
|
||||||
str.c_str(), int(children.size()), filename.c_str(), linenum);
|
str.c_str(), int(children.size()), filename.c_str(), linenum);
|
||||||
|
|
||||||
// First argument is the format string
|
// First argument is the format string
|
||||||
AstNode *node_string = children[0]->clone();
|
AstNode *node_string = children[0];
|
||||||
while (node_string->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
|
while (node_string->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
|
||||||
if (node_string->type != AST_CONSTANT)
|
if (node_string->type != AST_CONSTANT)
|
||||||
log_error("Failed to evaluate system task `%s' with non-constant 1st argument at %s:%d.\n", str.c_str(), filename.c_str(), linenum);
|
log_error("Failed to evaluate system task `%s' with non-constant 1st argument at %s:%d.\n", str.c_str(), filename.c_str(), linenum);
|
||||||
|
@ -207,37 +207,57 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
|
||||||
|
|
||||||
// Other arguments are placeholders. Process the string as we go through it
|
// Other arguments are placeholders. Process the string as we go through it
|
||||||
std::string sout;
|
std::string sout;
|
||||||
size_t next_arg = 1;
|
int next_arg = 1;
|
||||||
for(size_t i=0; i<sformat.length(); i++)
|
for (size_t i = 0; i < sformat.length(); i++)
|
||||||
{
|
{
|
||||||
// format specifier
|
// format specifier
|
||||||
if(sformat[i] == '%')
|
if (sformat[i] == '%')
|
||||||
{
|
{
|
||||||
// If there's no next character, that's a problem
|
// If there's no next character, that's a problem
|
||||||
if(i+1 >= sformat.length())
|
if (i+1 >= sformat.length())
|
||||||
log_error("System task `%s' called with `%%' at end of string at %s:%d.\n", str.c_str(), filename.c_str(), linenum);
|
log_error("System task `%s' called with `%%' at end of string at %s:%d.\n", str.c_str(), filename.c_str(), linenum);
|
||||||
|
|
||||||
char cformat = sformat[++i];
|
char cformat = sformat[++i];
|
||||||
|
|
||||||
// %% is special, does not need a matching argument
|
// %% is special, does not need a matching argument
|
||||||
if(cformat == '%')
|
if (cformat == '%')
|
||||||
{
|
{
|
||||||
sout += '%';
|
sout += '%';
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we're out of arguments, that's a problem!
|
|
||||||
if(next_arg >= nargs)
|
|
||||||
log_error("System task `%s' called with more format specifiers than arguments at %s:%d.\n", str.c_str(), filename.c_str(), linenum);
|
|
||||||
|
|
||||||
// Simplify the argument
|
// Simplify the argument
|
||||||
AstNode *node_arg = children[next_arg ++]->clone();
|
AstNode *node_arg = nullptr;
|
||||||
while (node_arg->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
|
|
||||||
if (node_arg->type != AST_CONSTANT)
|
|
||||||
log_error("Failed to evaluate system task `%s' with non-constant argument at %s:%d.\n", str.c_str(), filename.c_str(), linenum);
|
|
||||||
|
|
||||||
// Everything from here on depends on the format specifier
|
// Everything from here on depends on the format specifier
|
||||||
switch(cformat)
|
switch (cformat)
|
||||||
|
{
|
||||||
|
case 's':
|
||||||
|
case 'S':
|
||||||
|
case 'd':
|
||||||
|
case 'D':
|
||||||
|
case 'x':
|
||||||
|
case 'X':
|
||||||
|
if (next_arg >= GetSize(children))
|
||||||
|
log_error("Missing argument for %%%c format specifier in system task `%s' at %s:%d.\n",
|
||||||
|
cformat, str.c_str(), filename.c_str(), linenum);
|
||||||
|
|
||||||
|
node_arg = children[next_arg++];
|
||||||
|
while (node_arg->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
|
||||||
|
if (node_arg->type != AST_CONSTANT)
|
||||||
|
log_error("Failed to evaluate system task `%s' with non-constant argument at %s:%d.\n", str.c_str(), filename.c_str(), linenum);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'm':
|
||||||
|
case 'M':
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
log_error("System task `%s' called with invalid/unsupported format specifier at %s:%d.\n", str.c_str(), filename.c_str(), linenum);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (cformat)
|
||||||
{
|
{
|
||||||
case 's':
|
case 's':
|
||||||
case 'S':
|
case 'S':
|
||||||
|
@ -262,9 +282,13 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
case 'm':
|
||||||
log_error("System task `%s' called with invalid format specifier at %s:%d.\n", str.c_str(), filename.c_str(), linenum);
|
case 'M':
|
||||||
|
sout += log_id(current_module->name);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
log_abort();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -275,7 +299,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
|
||||||
|
|
||||||
// Finally, print the message (only include a \n for $display, not for $write)
|
// Finally, print the message (only include a \n for $display, not for $write)
|
||||||
log("%s", sout.c_str());
|
log("%s", sout.c_str());
|
||||||
if(str == "$display")
|
if (str == "$display")
|
||||||
log("\n");
|
log("\n");
|
||||||
delete_children();
|
delete_children();
|
||||||
str = std::string();
|
str = std::string();
|
||||||
|
|
Loading…
Reference in New Issue