mirror of
https://github.com/verilator/verilator.git
synced 2026-09-04 16:40:12 +02:00
Rework $display/$write to go via new VL_WRITE function instead of
converting to pure C printf call. This makes the resulting code smaller, and allows sharing code with future $sprintf support.
This commit is contained in:
@@ -312,10 +312,46 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
void expectFormat(AstNode* nodep, const string& format, AstNode* argp) {
|
||||
// Check display arguments
|
||||
bool inPct = false;
|
||||
for (const char* inp = format.c_str(); *inp; inp++) {
|
||||
char ch = *inp; // Breaks with iterators...
|
||||
if (!inPct && ch=='%') {
|
||||
inPct = true;
|
||||
} else if (inPct) {
|
||||
inPct = false;
|
||||
switch (tolower(ch)) {
|
||||
case '0': case '1': case '2': case '3': case '4':
|
||||
case '5': case '6': case '7': case '8': case '9':
|
||||
inPct = true;
|
||||
break;
|
||||
case '%': break; // %% - just output a %
|
||||
case 'm': break; // %m - auto insert "name"
|
||||
default: // Most operators, just move to next argument
|
||||
if (!V3Number::displayedFmtLegal(ch)) {
|
||||
nodep->v3error("Unknown $display format code: %"<<ch);
|
||||
} else {
|
||||
if (!argp) {
|
||||
nodep->v3error("Missing arguments for $display format");
|
||||
} else {
|
||||
argp = argp->nextp();
|
||||
}
|
||||
}
|
||||
break;
|
||||
} // switch
|
||||
}
|
||||
}
|
||||
if (argp) {
|
||||
argp->v3error("Extra arguments for $display format\n");
|
||||
}
|
||||
}
|
||||
|
||||
void expectDescriptor(AstNode* nodep, AstNodeVarRef* filep) {
|
||||
if (!filep) nodep->v3error("Unsupported: $fopen/$fclose/$f* descriptor must be a simple variable");
|
||||
if (filep && filep->varp()) filep->varp()->attrFileDescr(true);
|
||||
}
|
||||
|
||||
virtual void visit(AstFOpen* nodep, AstNUser*) {
|
||||
nodep->iterateChildren(*this);
|
||||
expectDescriptor(nodep, nodep->filep()->castNodeVarRef());
|
||||
@@ -343,6 +379,7 @@ private:
|
||||
virtual void visit(AstDisplay* nodep, AstNUser*) {
|
||||
nodep->iterateChildren(*this);
|
||||
if (nodep->filep()) expectDescriptor(nodep, nodep->filep()->castNodeVarRef());
|
||||
expectFormat(nodep, nodep->name(), nodep->exprsp());
|
||||
if (!m_assertp
|
||||
&& (nodep->displayType() == AstDisplayType::INFO
|
||||
|| nodep->displayType() == AstDisplayType::WARNING
|
||||
|
||||
Reference in New Issue
Block a user