From b12dd526f9e3f3b1c413b961ce4fdfdd000eb1fd Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Fri, 17 Mar 2017 18:40:16 -0400 Subject: [PATCH] Fix calling sformatf to display, and elab , bug1139. --- Changes | 2 ++ src/V3Simulate.h | 38 ++++++++++++++++++++++++------ test_regress/t/t_func_const_bad.pl | 7 ++++++ test_regress/t/t_func_const_bad.v | 8 +++++++ 4 files changed, 48 insertions(+), 7 deletions(-) diff --git a/Changes b/Changes index 5ee8a1c68..da21e4d4a 100644 --- a/Changes +++ b/Changes @@ -19,6 +19,8 @@ The contributors that suggested a given feature are shown in []. Thanks! **** Fix internal error on interface arrays, bug1135. [John Stevenson] +**** Fix calling sformatf to display, and elab $displays, bug1139. [Johan Bjork] + **** Fix realpath compile issue on MSVC++, bug1141. [Miodrag Milanovic] diff --git a/src/V3Simulate.h b/src/V3Simulate.h index 6c9bb1d0b..9d4d59ac3 100644 --- a/src/V3Simulate.h +++ b/src/V3Simulate.h @@ -91,6 +91,11 @@ private: deque m_numFreeps; ///< List of all numbers free and not in use deque m_numAllps; ///< List of all numbers free and in use + // Cleanup + // V3Numbers that represents strings are a bit special and the API for V3Number does not allow changing them. + deque m_stringNumbersp; // List of allocated string numbers + + // Note level 8&9 include debugging each simulation value static int debug() { static int level = -1; @@ -726,6 +731,12 @@ private: if (!m_params) { badNodeType(nodep); return; } } + virtual void visit(AstScopeName *nodep) { + if (jumpingOver(nodep)) return; + if (!m_params) { badNodeType(nodep); return; } + // Ignore + } + virtual void visit(AstSFormatF *nodep) { if (jumpingOver(nodep)) return; if (!optimizable()) return; // Accelerate @@ -743,11 +754,11 @@ private: } else if (!inPct) { // Normal text result += *pos; } else { // Format character - AstNode* argp = nextArgp; inPct = false; - nextArgp = nextArgp->nextp(); if (V3Number::displayedFmtLegal(tolower(pos[0]))) { + AstNode* argp = nextArgp; + nextArgp = nextArgp->nextp(); V3Number* nump = fetchNumberNull(argp); if (!nump) { clearOptimizable(nodep, "Argument for $display like statement is not constant"); @@ -760,6 +771,10 @@ private: case '%': result += "%"; break; + case 'm': + // This happens prior to AstScope so we don't know the scope name. Leave the %m in place. + result += "%m"; + break; default: clearOptimizable(nodep, "Unknown $display-like format code."); break; @@ -767,7 +782,11 @@ private: } } } - nodep->text(result); + + V3Number* resultNump = new V3Number(V3Number::String(), nodep->fileline(), result); + setNumber(nodep, resultNump); + m_stringNumbersp.push_back(resultNump); + } } @@ -776,19 +795,20 @@ private: if (!optimizable()) return; // Accelerate nodep->iterateChildren(*this); if (m_params) { + V3Number* textp = fetchNumber(nodep->fmtp()); switch (nodep->displayType()) { case AstDisplayType::DT_DISPLAY: // FALLTHRU case AstDisplayType::DT_INFO: - v3warn(USERINFO, nodep->fmtp()->text()); + v3warn(USERINFO, textp->toString()); break; case AstDisplayType::DT_ERROR: - v3warn(USERERROR, nodep->fmtp()->text()); + v3warn(USERERROR, textp->toString()); break; case AstDisplayType::DT_WARNING: - v3warn(USERWARN, nodep->fmtp()->text()); + v3warn(USERWARN, textp->toString()); break; case AstDisplayType::DT_FATAL: - v3warn(USERFATAL, nodep->fmtp()->text()); + v3warn(USERFATAL, textp->toString()); break; case AstDisplayType::DT_WRITE: // FALLTHRU default: @@ -863,6 +883,10 @@ public: for (deque::iterator it = m_numAllps.begin(); it != m_numAllps.end(); ++it) { delete (*it); } + for (deque::iterator it = m_stringNumbersp.begin(); it != m_stringNumbersp.end(); ++it) { + delete (*it); + } + m_stringNumbersp.clear(); m_numFreeps.clear(); m_numAllps.clear(); } diff --git a/test_regress/t/t_func_const_bad.pl b/test_regress/t/t_func_const_bad.pl index 7754620f6..cc5968499 100755 --- a/test_regress/t/t_func_const_bad.pl +++ b/test_regress/t/t_func_const_bad.pl @@ -21,6 +21,13 @@ q{%Error: t/t_func_const_bad.v:\d+: Expecting expression to be constant, but can %Error: t/t_func_const_bad.v:\d+: ... Location of non-constant WHILE: Loop unrolling took too long; probably this is an infinite loop, or set --unroll-count above 1024 %Error: t/t_func_const_bad.v:\d+: Expecting expression to be constant, but can't determine constant for FUNCREF 'f_bad_stop' %Error: t/t_func_const_bad.v:\d+: ... Location of non-constant STOP: .stop executed during function constification; maybe indicates assertion firing +-Info: Printing in loop: 0 +-Info: Printing in loop: 1 +-Info: Printing in loop: 2 +%Warning-USERFATAL: Fatal Error +%Warning-USERFATAL: Use ... verilator lint_off USERFATAL ... and lint_on around source to disable this message. +%Error: t/t_func_const_bad.v:\d+: Expecting expression to be constant, but can't determine constant for FUNCREF 'f_bad_fatal' +%Error: t/t_func_const_bad.v:\d+: ... Location of non-constant STOP: .stop executed during function constification; maybe indicates assertion firing %Error: Exiting due to.*}, ); diff --git a/test_regress/t/t_func_const_bad.v b/test_regress/t/t_func_const_bad.v index 8f1e6bf1c..d96750098 100644 --- a/test_regress/t/t_func_const_bad.v +++ b/test_regress/t/t_func_const_bad.v @@ -45,4 +45,12 @@ module t; $stop; endfunction + // Verify $fatal works with sformatf as argument + localparam BFATAL = f_bad_fatal(3); + function integer f_bad_fatal(input [31:0] a); + for (integer i=0;i<3;i++) begin + $display("Printing in loop: %s", $sformatf("%d", i)); + end + $fatal(2, "%s", $sformatf("Fatal Error")); + endfunction endmodule