From f942aba855b418d70a2a67e2b4f3337ebf5e8681 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Mon, 9 Jan 2017 19:19:21 -0500 Subject: [PATCH] Support old-style (), bug467. --- Changes | 2 ++ src/V3AstNodes.h | 16 +++++++++++++++- src/V3LinkResolve.cpp | 11 +++++++++++ src/verilog.y | 17 +++++++++++------ test_regress/t/t_display.pl | 1 + test_regress/t/t_display.v | 1 + test_regress/t/t_display_noopt.pl | 1 + 7 files changed, 42 insertions(+), 7 deletions(-) diff --git a/Changes b/Changes index 50fbf7ae4..1620c9262 100644 --- a/Changes +++ b/Changes @@ -5,6 +5,8 @@ The contributors that suggested a given feature are shown in []. Thanks! * Verilator 3.891 devel +*** Support old-style $display($time), bug467. [John Demme] + **** With --bbox-unsup, suppress desassign and mixed edges, bug1120. [Galen Seitz] **** Fix parsing sensitivity with &&, bug934. [Luke Yang] diff --git a/src/V3AstNodes.h b/src/V3AstNodes.h index 0f891edf4..0be1692c9 100644 --- a/src/V3AstNodes.h +++ b/src/V3AstNodes.h @@ -2324,9 +2324,15 @@ class AstSFormatF : public AstNode { // Also used as "real" function for /*verilator sformat*/ functions string m_text; bool m_hidden; // Under display, etc + bool m_hasFormat; // Has format code public: + class NoFormat {}; AstSFormatF(FileLine* fl, const string& text, bool hidden, AstNode* exprsp) - : AstNode(fl), m_text(text), m_hidden(hidden) { + : AstNode(fl), m_text(text), m_hidden(hidden), m_hasFormat(true) { + dtypeSetString(); + addNOp1p(exprsp); addNOp2p(NULL); } + AstSFormatF(FileLine* fl, NoFormat, AstNode* exprsp) + : AstNode(fl), m_text(""), m_hidden(true), m_hasFormat(false) { dtypeSetString(); addNOp1p(exprsp); addNOp2p(NULL); } ASTNODE_NODE_FUNCS(SFormatF) @@ -2345,6 +2351,8 @@ public: bool formatScopeTracking() const { // Track scopeNamep(); Ok if false positive return (name().find("%m") != string::npos || name().find("%M") != string::npos); } bool hidden() const { return m_hidden; } + void hasFormat(bool flag) { m_hasFormat=flag; } + bool hasFormat() const { return m_hasFormat; } }; class AstDisplay : public AstNodeStmt { @@ -2360,6 +2368,12 @@ public: setNOp3p(filep); m_displayType = dispType; } + AstDisplay(FileLine* fileline, AstDisplayType dispType, AstNode* filep, AstNode* exprsp) + : AstNodeStmt (fileline) { + setOp1p(new AstSFormatF(fileline, AstSFormatF::NoFormat(), exprsp)); + setNOp3p(filep); + m_displayType = dispType; + } ASTNODE_NODE_FUNCS(Display) virtual void dump(ostream& str); virtual const char* broken() const { BROKEN_RTN(!fmtp()); return NULL; } diff --git a/src/V3LinkResolve.cpp b/src/V3LinkResolve.cpp index 17ed29abe..982e4796a 100644 --- a/src/V3LinkResolve.cpp +++ b/src/V3LinkResolve.cpp @@ -377,6 +377,17 @@ private: } virtual void visit(AstSFormatF* nodep) { nodep->iterateChildren(*this); + // Cleanup old-school displays without format arguments + if (!nodep->hasFormat()) { + if (nodep->text()!="") nodep->v3fatalSrc("Non-format $sformatf should have \"\" format"); + if (nodep->exprsp()->castConst() + && nodep->exprsp()->castConst()->num().isFromString()) { + AstConst* fmtp = nodep->exprsp()->unlinkFrBack()->castConst(); + nodep->text(fmtp->num().toString()); + pushDeletep(fmtp); VL_DANGLING(fmtp); + } + nodep->hasFormat(true); + } string newFormat = expectFormat(nodep, nodep->text(), nodep->exprsp(), false); nodep->text(newFormat); if ((nodep->backp()->castDisplay() && nodep->backp()->castDisplay()->displayType().needScopeTracking()) diff --git a/src/verilog.y b/src/verilog.y index 2e0126077..ada267a06 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -2629,13 +2629,13 @@ system_t_call: // IEEE: system_tf_call (as task) | yD_SWRITE '(' expr ',' str commaEListE ')' { $$ = new AstSFormat($1,$3,*$5,$6); } | yD_SYSTEM '(' expr ')' { $$ = new AstSystemT($1,$3); } // - | yD_DISPLAY parenE { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY,"", NULL,NULL); } - | yD_DISPLAY '(' str commaEListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY,*$3,NULL,$4); } + | yD_DISPLAY parenE { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY,NULL,NULL); } + | yD_DISPLAY '(' exprList ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY,NULL,$3); } | yD_WRITE parenE { $$ = NULL; } // NOP - | yD_WRITE '(' str commaEListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_WRITE, *$3,NULL,$4); } - | yD_FDISPLAY '(' expr ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY,"",$3,NULL); } - | yD_FDISPLAY '(' expr ',' str commaEListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY,*$5,$3,$6); } - | yD_FWRITE '(' expr ',' str commaEListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_WRITE, *$5,$3,$6); } + | yD_WRITE '(' exprList ')' { $$ = new AstDisplay($1,AstDisplayType::DT_WRITE, NULL,$3); } + | yD_FDISPLAY '(' expr ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY,$3,NULL); } + | yD_FDISPLAY '(' expr ',' exprListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY,$3,$5); } + | yD_FWRITE '(' expr ',' exprListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_WRITE, $3,$5); } | yD_INFO parenE { $$ = new AstDisplay($1,AstDisplayType::DT_INFO, "", NULL,NULL); } | yD_INFO '(' str commaEListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_INFO, *$3,NULL,$4); } | yD_WARNING parenE { $$ = new AstDisplay($1,AstDisplayType::DT_WARNING,"", NULL,NULL); } @@ -3162,6 +3162,11 @@ cateList: | cateList ',' stream_expression { $$ = new AstConcat($2,$1,$3); } ; +exprListE: + /* empty */ { $$ = NULL; } + | exprList { $$ = $1; } + ; + exprList: expr { $$ = $1; } | exprList ',' expr { $$ = $1;$1->addNext($3); } diff --git a/test_regress/t/t_display.pl b/test_regress/t/t_display.pl index 64f3c27b1..3ee1a9dd1 100755 --- a/test_regress/t/t_display.pl +++ b/test_regress/t/t_display.pl @@ -46,6 +46,7 @@ q{[0] In top.t: Hi hello, from a concatenated string. hello, from a concatenated format string [0]. extra argument: 0000000000000000 +0000000000000000: pre argument [0] Embedded <#013> return [0] Embedded multiline diff --git a/test_regress/t/t_display.v b/test_regress/t/t_display.v index f97ea502c..0c16b3191 100644 --- a/test_regress/t/t_display.v +++ b/test_regress/t/t_display.v @@ -83,6 +83,7 @@ module t; $display("hel", "lo, fr", "om a concatenated string."); $write("hel", "lo, fr", "om a concatenated format string [%0t].\n", $time); $display("extra argument: ", $time); + $display($time, ": pre argument"); $write("[%0t] Embedded \r return\n", $time); $display("[%0t] Embedded\ multiline", $time); diff --git a/test_regress/t/t_display_noopt.pl b/test_regress/t/t_display_noopt.pl index 59cbb7ee0..664b0166e 100755 --- a/test_regress/t/t_display_noopt.pl +++ b/test_regress/t/t_display_noopt.pl @@ -49,6 +49,7 @@ q{[0] In top.t: Hi hello, from a concatenated string. hello, from a concatenated format string [0]. extra argument: 0000000000000000 +0000000000000000: pre argument [0] Embedded <#013> return [0] Embedded multiline