From b0a249f33814694f83ffc912602515dd0932eda6 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Tue, 10 Nov 2015 21:12:15 -0500 Subject: [PATCH] Fix display %u, %v, %p, %z, bug989. --- Changes | 2 + include/verilated.cpp | 29 ++++++++++++-- src/V3Const.cpp | 26 ++++++------- src/V3EmitC.cpp | 18 ++++----- src/V3LinkResolve.cpp | 34 ++++++++-------- src/V3Number.cpp | 64 +++++++++++++++++++++++++------ src/V3Number.h | 2 +- src/V3Simulate.h | 2 +- src/V3String.cpp | 9 +++++ src/V3String.h | 1 + src/V3Width.cpp | 31 ++++++++++++--- test_regress/driver.pl | 3 +- test_regress/t/t_display.pl | 23 +++++++---- test_regress/t/t_display.v | 33 ++++++++++++++-- test_regress/t/t_display_noopt.pl | 23 +++++++---- test_regress/t/t_sys_sformat.v | 17 ++++++-- 16 files changed, 234 insertions(+), 83 deletions(-) diff --git a/Changes b/Changes index 6a2c363cc..c61e56fa5 100644 --- a/Changes +++ b/Changes @@ -9,6 +9,8 @@ indicates the contributor was also the author of the fix; Thanks! **** Fix size-changing cast on packed struct, bug993. [Johan Bjork] +**** Fix display %u, %v, %p, %z, bug989. [Johan Bjork] + * Verilator 3.878 2015-11-01 diff --git a/include/verilated.cpp b/include/verilated.cpp index 85e373395..d0b002686 100644 --- a/include/verilated.cpp +++ b/include/verilated.cpp @@ -374,7 +374,7 @@ void _vl_vsformat(string& output, const char* formatp, va_list ap) { } else { lwp = va_arg(ap,WDataInP); ld = lwp[0]; - if (fmt == 'u' || fmt == 'd') fmt = 'x'; // Not supported, but show something + if (fmt == 'd' || fmt == '#') fmt = 'x'; // Not supported, but show something } int lsb=lbits-1; if (widthSet && width==0) while (lsb && !VL_BITISSET_W(lwp,lsb)) lsb--; @@ -404,7 +404,7 @@ void _vl_vsformat(string& output, const char* formatp, va_list ap) { output += tmp; break; } - case 'u': { // Unsigned decimal + case '#': { // Unsigned decimal int digits=sprintf(tmp,"%" VL_PRI64 "u",ld); int needmore = width-digits; if (needmore>0) { @@ -438,6 +438,7 @@ void _vl_vsformat(string& output, const char* formatp, va_list ap) { output += ((lwp[VL_BITWORD_I(lsb)]>>VL_BITBIT_I(lsb)) & 1) + '0'; } break; + break; case 'o': for (; lsb>=0; lsb--) { lsb = (lsb / 3) * 3; // Next digit @@ -450,6 +451,28 @@ void _vl_vsformat(string& output, const char* formatp, va_list ap) { + ((VL_BITISSETLIMIT_W(lwp, lbits, lsb+2)) ? 4 : 0)); } break; + case 'u': // Packed 2-state + output.reserve(output.size() + 4*VL_WORDS_I(lbits)); + for (int i=0; i> 0) & 0xff); + output += (char)((lwp[i] >> 8) & 0xff); + output += (char)((lwp[i] >> 16) & 0xff); + output += (char)((lwp[i] >> 24) & 0xff); + } + case 'z': // Packed 4-state + output.reserve(output.size() + 8*VL_WORDS_I(lbits)); + for (int i=0; i> 0) & 0xff); + output += (char)((lwp[i] >> 8) & 0xff); + output += (char)((lwp[i] >> 16) & 0xff); + output += (char)((lwp[i] >> 24) & 0xff); + output += "\0\0\0\0"; // No tristate + } + case 'v': // Strength; assume always strong + for (lsb=lbits-1; lsb>=0; lsb--) { + if ((lwp[VL_BITWORD_I(lsb)]>>VL_BITBIT_I(lsb)) & 1) output += "St1 "; + else output += "St0 "; + } case 'x': for (; lsb>=0; lsb--) { lsb = (lsb / 4) * 4; // Next digit @@ -633,7 +656,7 @@ IData _vl_vsscanf(FILE* fp, // If a fscanf break; } case 't': // FALLTHRU // Time - case 'u': { // Unsigned decimal + case '#': { // Unsigned decimal _vl_vsss_skipspace(fp,floc,fromp,fstr); _vl_vsss_read(fp,floc,fromp,fstr, tmp, "0123456789+-xXzZ?_"); if (!tmp[0]) goto done; diff --git a/src/V3Const.cpp b/src/V3Const.cpp index 594dfc285..24606eedf 100644 --- a/src/V3Const.cpp +++ b/src/V3Const.cpp @@ -33,6 +33,7 @@ #include #include "V3Global.h" +#include "V3String.h" #include "V3Const.h" #include "V3Ast.h" #include "V3Width.h" @@ -1828,7 +1829,7 @@ private: } if (m_doNConst && anyconst) { //UINFO(9," Display in "<text()<exprsp(); @@ -1846,33 +1847,30 @@ private: switch (tolower(ch)) { case '%': break; // %% - just output a % case 'm': break; // %m - auto insert "name" - case 'l': break; // %m - auto insert "library" + case 'l': break; // %l - auto insert "library" default: // Most operators, just move to next argument if (argp) { AstNode* nextp=argp->nextp(); if (argp && argp->castConst()) { // Convert it - string out = argp->castConst()->num().displayed(fmt); + string out = argp->castConst()->num().displayed(nodep->fileline(), fmt); UINFO(9," DispConst: "< "<unlinkFrBack()->deleteTree(); } argp=nextp; } break; } // switch - dispout += fmt; + newFormat += fmt; } else { - dispout += ch; + newFormat += ch; } } - nodep->text(dispout); - //UINFO(9," Display out "<text()<text()) { + nodep->text(newFormat); + UINFO(9," Display out "<exprsp() && nodep->name().find("%") == string::npos diff --git a/src/V3EmitC.cpp b/src/V3EmitC.cpp index 522bfa502..040d545b9 100644 --- a/src/V3EmitC.cpp +++ b/src/V3EmitC.cpp @@ -295,6 +295,7 @@ public: case 'h': // FALLTHRU case 'x': // FALLTHRU case 'b': // FALLTHRU + case 'v': // FALLTHRU case 's': got++; format = tolower(ch); break; @@ -1273,17 +1274,18 @@ void EmitCStmts::displayArg(AstNode* dispp, AstNode** elistp, bool isScan, dispp->v3error("Exceeded limit of "+cvtToStr(VL_VALUE_STRING_MAX_WIDTH)+" bits for any $display-like arguments"); } if (argp && argp->isWide() - && (fmtLetter=='d'||fmtLetter=='u')) { + && (fmtLetter=='d'||fmtLetter=='#')) { argp->v3error("Unsupported: "<verilogKwd()<<" of dec format of > 64 bit results (use hex format instead)"); } if (argp && argp->widthMin()>8 && fmtLetter=='c') { // Technically legal, but surely not what the user intended. - argp->v3error(dispp->verilogKwd()<<" of char format of > 8 bit result"); + argp->v3warn(WIDTH,dispp->verilogKwd()<<"of %c format of > 8 bit value"); + } //string pfmt = "%"+displayFormat(argp, vfmt, fmtLetter)+fmtLetter; string pfmt; - if ((fmtLetter=='u' || fmtLetter=='d' || fmtLetter=='t') + if ((fmtLetter=='#' || fmtLetter=='d' || fmtLetter=='t') && !isScan && vfmt == "") { // Size decimal output. Spec says leading spaces, not zeros double mantissabits = argp->widthMin() - ((fmtLetter=='d')?1:0); @@ -1341,14 +1343,15 @@ void EmitCStmts::displayNode(AstNode* nodep, AstScopeName* scopenamep, case 'b': displayArg(nodep,&elistp,isScan, vfmt,'b'); break; case 'c': displayArg(nodep,&elistp,isScan, vfmt,'c'); break; case 't': displayArg(nodep,&elistp,isScan, vfmt,'t'); break; - case 'd': displayArg(nodep,&elistp,isScan, vfmt,'u'); break; // Unsigned decimal + case 'd': displayArg(nodep,&elistp,isScan, vfmt,'#'); break; // Unsigned decimal case 'o': displayArg(nodep,&elistp,isScan, vfmt,'o'); break; - case 'h': + case 'h': //FALLTHRU case 'x': displayArg(nodep,&elistp,isScan, vfmt,'x'); break; case 's': displayArg(nodep,&elistp,isScan, vfmt,'s'); break; case 'e': displayArg(nodep,&elistp,isScan, vfmt,'e'); break; case 'f': displayArg(nodep,&elistp,isScan, vfmt,'f'); break; case 'g': displayArg(nodep,&elistp,isScan, vfmt,'g'); break; + case 'v': displayArg(nodep,&elistp,isScan, vfmt,'v'); break; case 'm': { if (!scopenamep) nodep->v3fatalSrc("Display with %m but no AstScopeName"); string suffix = scopenamep->scopePrettySymName(); @@ -1363,11 +1366,6 @@ void EmitCStmts::displayNode(AstNode* nodep, AstScopeName* scopenamep, emitDispState.pushFormat("----"); break; } - case 'u': - case 'z': - case 'v': - nodep->v3error("Unsupported: $display-like format code: %"<v3error("Unknown $display-like format code: %"< #include "V3Global.h" +#include "V3String.h" #include "V3LinkResolve.h" #include "V3Ast.h" @@ -255,26 +256,29 @@ private: } string expectFormat(AstNode* nodep, const string& format, AstNode* argp, bool isScan) { - // Check display arguments + // Check display arguments, return new format string + string newFormat; bool inPct = false; + string fmt = ""; for (string::const_iterator it = format.begin(); it != format.end(); ++it) { - char ch = tolower(*it); + char ch = *it; if (!inPct && ch=='%') { inPct = true; + fmt = ch; + } else if (inPct && (isdigit(ch) || ch=='.')) { + fmt += ch; } else if (inPct) { inPct = false; + fmt += ch; switch (tolower(ch)) { - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - case '.': - inPct = true; + case '%': // %% - just output a % break; - case '%': break; // %% - just output a % case 'm': // %m - auto insert "name" - if (isScan) nodep->v3error("Unsupported: %m in $fscanf"); + if (isScan) { nodep->v3error("Unsupported: %m in $fscanf"); fmt = ""; } break; case 'l': // %l - auto insert "library" - if (isScan) nodep->v3error("Unsupported: %l in $fscanf"); + if (isScan) { nodep->v3error("Unsupported: %l in $fscanf"); fmt = ""; } + if (m_modp) fmt = VString::quotePercent(m_modp->prettyName()); break; default: // Most operators, just move to next argument if (!V3Number::displayedFmtLegal(ch)) { @@ -288,11 +292,14 @@ private: } break; } // switch + newFormat += fmt; + } else { + newFormat += ch; } } + if (argp && !isScan) { int skipCount = 0; // number of args consume by any additional format strings - string newFormat(format); while (argp) { if (skipCount) { argp = argp->nextp(); @@ -338,10 +345,8 @@ private: argp = argp->nextp(); } } - return newFormat; - } else { - return string(); } + return newFormat; } void expectDescriptor(AstNode* nodep, AstNodeVarRef* filep) { @@ -372,8 +377,7 @@ private: virtual void visit(AstSFormatF* nodep, AstNUser*) { nodep->iterateChildren(*this); string newFormat = expectFormat(nodep, nodep->text(), nodep->exprsp(), false); - if (newFormat.size()) - nodep->text(newFormat); + nodep->text(newFormat); if ((nodep->backp()->castDisplay() && nodep->backp()->castDisplay()->displayType().needScopeTracking()) || nodep->formatScopeTracking()) { nodep->scopeNamep(new AstScopeName(nodep->fileline())); diff --git a/src/V3Number.cpp b/src/V3Number.cpp index 73c438365..8196083ce 100644 --- a/src/V3Number.cpp +++ b/src/V3Number.cpp @@ -396,12 +396,12 @@ string V3Number::ascii(bool prefixed, bool cleanVerilog) const { if (binary) { out<<"b"; - out<>6)&3, (pos[0]>>3)&7, pos[0]&7); out += octal; } } @@ -441,16 +442,20 @@ bool V3Number::displayedFmtLegal(char format) { case 'g': return true; case 'h': return true; case 'o': return true; + case 'p': return true; // Pattern case 's': return true; case 't': return true; + case 'u': return true; // Packed 2-state + case 'v': return true; // Strength case 'x': return true; + case 'z': return true; // Packed 4-state case '@': return true; // Packed string case '~': return true; // Signed decimal default: return false; } } -string V3Number::displayed(const string& vformat) const { +string V3Number::displayed(FileLine*fl, const string& vformat) const { string::const_iterator pos = vformat.begin(); UASSERT(pos != vformat.end() && pos[0]=='%', "$display-like function with non format argument "<<*this); ++pos; @@ -495,14 +500,12 @@ string V3Number::displayed(const string& vformat) const { return str; } case 'c': { - if (this->width()>8) m_fileline->v3error("$display-like format of char of > 8 bit value"); - int v = bitsValue(0, 8); - str += (char)(v); + if (this->width()>8) fl->v3warn(WIDTH,"$display-like format of %c format of > 8 bit value"); + unsigned int v = bitsValue(0, 8); + char strc[2]; strc[0] = v&0xff; strc[1] = '\0'; + str = strc; return str; } - case '@': { // Packed string - return toString(); - } case 's': { // Spec says always drop leading zeros, this isn't quite right, we space pad. int bit=this->width()-1; @@ -531,7 +534,7 @@ string V3Number::displayed(const string& vformat) const { fmtsize = cvtToStr(int(dchars)); } if (width() > 64) { - m_fileline->v3error("Unsupported: $display-like format of decimal of > 64 bit results (use hex format instead)"); + fl->v3error("Unsupported: $display-like format of decimal of > 64 bit results (use hex format instead)"); return "ERR"; } if (issigned) { @@ -554,8 +557,45 @@ string V3Number::displayed(const string& vformat) const { sprintf(tmp, vformat.c_str(), toDouble()); return tmp; } + // 'l' // Library - converted to text by V3LinkResolve + // 'p' // Packed - converted to another code by V3Width + case 'u': { // Packed 2-state + for (int i=0; i> 0) & 0xff); + str += (char)((m_value[i] >> 8) & 0xff); + str += (char)((m_value[i] >> 16) & 0xff); + str += (char)((m_value[i] >> 24) & 0xff); + } + return str; + } + case 'z': { // Packed 4-state + for (int i=0; i> 0) & 0xff); + str += (char)((m_value[i] >> 8) & 0xff); + str += (char)((m_value[i] >> 16) & 0xff); + str += (char)((m_value[i] >> 24) & 0xff); + str += (char)((m_valueX[i] >> 0) & 0xff); + str += (char)((m_valueX[i] >> 8) & 0xff); + str += (char)((m_valueX[i] >> 16) & 0xff); + str += (char)((m_valueX[i] >> 24) & 0xff); + } + return str; + } + case 'v': { // Strength + int bit = width()-1; + for (; bit>=0; bit--) { + if (bitIs0(bit)) str+="St0 "; // Yes, always a space even for bit 0 + else if (bitIs1(bit)) str+="St1 "; + else if (bitIsZ(bit)) str+="StZ "; + else str+="StX"; + } + return str; + } + case '@': { // Packed string + return toString(); + } default: - m_fileline->v3fatalSrc("Unknown $display-like format code for number: %"<v3fatalSrc("Unknown $display-like format code for number: %"<displayed(format); + result += nump->displayed(nodep->fileline(), format); } else { switch (tolower(pos[0])) { case '%': diff --git a/src/V3String.cpp b/src/V3String.cpp index 151849bc2..9ade77ab7 100644 --- a/src/V3String.cpp +++ b/src/V3String.cpp @@ -77,6 +77,15 @@ string VString::downcase(const string& str) { return out; } +string VString::quotePercent(const string& str) { + string out; + for (string::const_iterator pos = str.begin(); pos != str.end(); ++pos) { + if (*pos == '%') out += '%'; + out += *pos; + } + return out; +} + //###################################################################### // VHashSha1 diff --git a/src/V3String.h b/src/V3String.h index 355de273d..15b5af8c7 100644 --- a/src/V3String.h +++ b/src/V3String.h @@ -35,6 +35,7 @@ public: // METHODS (generic string utilities) static bool wildmatch(const char* s, const char* p); static string downcase(const string& str); + static string quotePercent(const string& str); }; //###################################################################### diff --git a/src/V3Width.cpp b/src/V3Width.cpp index 4ec37ea1c..727d025d6 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -1897,28 +1897,44 @@ private: nodep->iterateChildren(*this,WidthVP(SELF,BOTH).p()); // UINFO(9," Display in "<text()<exprsp(); string txt = nodep->text(); + string fmt; for (string::const_iterator it = txt.begin(); it!=txt.end(); ++it) { char ch = *it; if (!inPct && ch=='%') { inPct = true; - } else if (inPct && isdigit(ch)) { + fmt = ch; + } else if (inPct && (isdigit(ch) || ch=='.')) { + fmt += ch; } else if (tolower(inPct)) { inPct = false; + bool added = false; switch (tolower(ch)) { case '%': break; // %% - just output a % case 'm': break; // %m - auto insert "name" case 'l': break; // %m - auto insert "library" - case 'd': { // Convert decimal to either 'd' or 'u' + case 'd': { // Convert decimal to either 'd' or '#' if (argp && argp->isSigned()) { // Convert it ch = '~'; } if (argp) argp=argp->nextp(); break; } + case 'p': { // Packed + // Very hacky and non-compliant; print strings as strings, otherwise as hex + if (argp && argp->dtypep()->basicp()->isString()) { // Convert it + added = true; + newFormat += "\"%@\""; + } else { + added = true; + newFormat += "'h%0h"; + } + if (argp) argp=argp->nextp(); + break; + } case 's': { // Convert string to pack string if (argp && argp->dtypep()->basicp()->isString()) { // Convert it ch = '@'; @@ -1931,10 +1947,15 @@ private: break; } } // switch + if (!added) { + fmt += ch; + newFormat += fmt; + } + } else { + newFormat += ch; } - dispout += ch; } - nodep->text(dispout); + nodep->text(newFormat); UINFO(9," Display out "<text()<{name} $param{logfile} MT $moretry $try\n"; diff --git a/test_regress/t/t_display.pl b/test_regress/t/t_display.pl index c3c28ffaa..df8a0c615 100755 --- a/test_regress/t/t_display.pl +++ b/test_regress/t/t_display.pl @@ -12,12 +12,12 @@ compile ( execute ( check_finished=>1, - expect=>quotemeta(dequote( -'[0] In top.v: Hi -[0] In top.v.sub -[0] In top.v.sub.subblock -[0] In top.v.sub2 -[0] In top.v.sub2.subblock2 + expect=>dequote( +q{[0] In top.v: Hi +[0] In top.v.sub (sub) +[0] In top.v.sub.subblock (sub) +[0] In top.v.sub2 (sub2) +[0] In top.v.sub2.subblock2 (sub2) [0] Back \ Quote " [0] %b=000001100 %0b=1100 %b=00000101010111011101110111100110011001100 %0b=101010111011101110111100110011001100 %b=000001010101111000001001000110100010101100111100000010010001101000101011001111000 %0b=1010101111000001001000110100010101100111100000010010001101000101011001111000 [0] %B=000001100 %0B=1100 %B=00000101010111011101110111100110011001100 %0B=101010111011101110111100110011001100 %B=000001010101111000001001000110100010101100111100000010010001101000101011001111000 %0B=1010101111000001001000110100010101100111100000010010001101000101011001111000 @@ -29,6 +29,15 @@ execute ( [0] %O=014 %0O=14 %O=00527356746314 %0O=527356746314 %O=012570110642547402215053170 %0O=12570110642547402215053170 [0] %x=00c %0x=c %x=00abbbbcccc %0x=abbbbcccc %x=00abc1234567812345678 %0x=abc1234567812345678 [0] %X=00c %0X=c %X=00abbbbcccc %0X=abbbbcccc %X=00abc1234567812345678 %0X=abc1234567812345678 +[0] %C=m %0C=m +[0] %c=m %0c=m +[0] %v=St0 St0 St0 St0 St0 St1 St1 St0 St0 %0v=St0 St0 St0 St0 St0 St1 St1 St0 St0 %v=St0 St0 St0 St0 St0 St1 St0 St1 St0 St1 St0 St1 St1 St1 St0 St1 St1 St1 St0 St1 St1 St1 St0 St1 St1 St1 St1 St0 St0 St1 St1 St0 St0 St1 St1 St0 St0 St1 St1 St0 St0 %0v=St0 St0 St0 St0 St0 St1 St0 St1 St0 St1 St0 St1 St1 St1 St0 St1 St1 St1 St0 St1 St1 St1 St0 St1 St1 St1 St1 St0 St0 St1 St1 St0 St0 St1 St1 St0 St0 St1 St1 St0 St0 %v=St0 St0 St0 St0 St0 St1 St0 St1 St0 St1 St0 St1 St1 St1 St1 St0 St0 St0 St0 St0 St1 St0 St0 St1 St0 St0 St0 St1 St1 St0 St1 St0 St0 St0 St1 St0 St1 St0 St1 St1 St0 St0 St1 St1 St1 St1 St0 St0 St0 St0 St0 St0 St1 St0 St0 St1 St0 St0 St0 St1 St1 St0 St1 St0 St0 St0 St1 St0 St1 St0 St1 St1 St0 St0 St1 St1 St1 St1 St0 St0 St0 %0v=St0 St0 St0 St0 St0 St1 St0 St1 St0 St1 St0 St1 St1 St1 St1 St0 St0 St0 St0 St0 St1 St0 St0 St1 St0 St0 St0 St1 St1 St0 St1 St0 St0 St0 St1 St0 St1 St0 St1 St1 St0 St0 St1 St1 St1 St1 St0 St0 St0 St0 St0 St0 St1 St0 St0 St1 St0 St0 St0 St1 St1 St0 St1 St0 St0 St0 St1 St0 St1 St0 St1 St1 St0 St0 St1 St1 St1 St1 St0 St0 St0 +[0] %V=St0 St0 St0 St0 St0 St1 St1 St0 St0 %0V=St0 St0 St0 St0 St0 St1 St1 St0 St0 %V=St0 St0 St0 St0 St0 St1 St0 St1 St0 St1 St0 St1 St1 St1 St0 St1 St1 St1 St0 St1 St1 St1 St0 St1 St1 St1 St1 St0 St0 St1 St1 St0 St0 St1 St1 St0 St0 St1 St1 St0 St0 %0V=St0 St0 St0 St0 St0 St1 St0 St1 St0 St1 St0 St1 St1 St1 St0 St1 St1 St1 St0 St1 St1 St1 St0 St1 St1 St1 St1 St0 St0 St1 St1 St0 St0 St1 St1 St0 St0 St1 St1 St0 St0 %V=St0 St0 St0 St0 St0 St1 St0 St1 St0 St1 St0 St1 St1 St1 St1 St0 St0 St0 St0 St0 St1 St0 St0 St1 St0 St0 St0 St1 St1 St0 St1 St0 St0 St0 St1 St0 St1 St0 St1 St1 St0 St0 St1 St1 St1 St1 St0 St0 St0 St0 St0 St0 St1 St0 St0 St1 St0 St0 St0 St1 St1 St0 St1 St0 St0 St0 St1 St0 St1 St0 St1 St1 St0 St0 St1 St1 St1 St1 St0 St0 St0 %0V=St0 St0 St0 St0 St0 St1 St0 St1 St0 St1 St0 St1 St1 St1 St1 St0 St0 St0 St0 St0 St1 St0 St0 St1 St0 St0 St0 St1 St1 St0 St1 St0 St0 St0 St1 St0 St1 St0 St1 St1 St0 St0 St1 St1 St1 St1 St0 St0 St0 St0 St0 St0 St1 St0 St0 St1 St0 St0 St0 St1 St1 St0 St1 St0 St0 St0 St1 St0 St1 St0 St1 St1 St0 St0 St1 St1 St1 St1 St0 St0 St0 +[0] %p='hc %0p='hc %p='habbbbcccc %0p='habbbbcccc %p='habc1234567812345678 %0p='habc1234567812345678 +[0] %P='hc %0P='hc %P='habbbbcccc %0P='habbbbcccc %P='habc1234567812345678 %0P='habc1234567812345678 +[0] %P="sv-str" +[0] %u=dcba %0u=dcba +[0] %U=dcba %0U=dcba [0] %D= 12 %d= 12 %01d=12 %06d=000012 %6d= 12 [0] %t= 0 %03t= 0 %0t=0 @@ -41,7 +50,7 @@ extra argument: 0000000000000000 [0] Embedded multiline *-* All Finished *-* -')), +}), ); ok(1); diff --git a/test_regress/t/t_display.v b/test_regress/t/t_display.v index f6d3c361f..f97ea502c 100644 --- a/test_regress/t/t_display.v +++ b/test_regress/t/t_display.v @@ -10,6 +10,7 @@ module t; reg [47:0] str2; initial str2 = "\000what!"; reg [79:0] str3; initial str3 = "\000hmmm!1234"; reg [8:0] nine; initial nine = 12; + string svs = "sv-str"; sub sub (); sub2 sub2 (); @@ -44,6 +45,30 @@ module t; $display("[%0t] %%X=%X %%0X=%0X %%X=%X %%0X=%0X %%X=%X %%0X=%0X", $time, nine, nine, quad, quad, wide, wide); // + // verilator lint_off WIDTH + $display("[%0t] %%C=%C %%0C=%0C", $time, + "a"+nine, "a"+nine); + $display("[%0t] %%c=%c %%0c=%0c", $time, + "a"+nine, "a"+nine); + // verilator lint_on WIDTH + + $display("[%0t] %%v=%v %%0v=%0v %%v=%v %%0v=%0v %%v=%v %%0v=%0v", $time, + nine, nine, quad, quad, wide, wide); + $display("[%0t] %%V=%V %%0V=%0V %%V=%V %%0V=%0V %%V=%V %%0V=%0V", $time, + nine, nine, quad, quad, wide, wide); + $display("[%0t] %%p=%p %%0p=%0p %%p=%p %%0p=%0p %%p=%p %%0p=%0p", $time, + nine, nine, quad, quad, wide, wide); + $display("[%0t] %%P=%P %%0P=%0P %%P=%P %%0P=%0P %%P=%P %%0P=%0P", $time, + nine, nine, quad, quad, wide, wide); + $display("[%0t] %%P=%P", $time, + svs); + + $display("[%0t] %%u=%u %%0u=%0u", $time, + {"a","b","c","d"}, {"a","b","c","d"}); // Avoid binary output + $display("[%0t] %%U=%U %%0U=%0U", $time, + {"a","b","c","d"}, {"a","b","c","d"}); // Avoid binary output + // %z is tested in t_sys_sformat.v + $display("[%0t] %%D=%D %%d=%d %%01d=%01d %%06d=%06d %%6d=%6d", $time, nine, nine, nine, nine, nine); $display("[%0t] %%t=%t %%03t=%03t %%0t=%0t", $time, @@ -74,9 +99,9 @@ endmodule module sub; task write_m; begin - $write("[%0t] In %m\n", $time); + $write("[%0t] In %m (%l)\n", $time); begin : subblock - $write("[%0t] In %M\n", $time); // Uppercase %M test + $write("[%0t] In %M (%L)\n", $time); // Uppercase %M test end end endtask @@ -86,9 +111,9 @@ module sub2; // verilator no_inline_module task write_m; begin - $write("[%0t] In %m\n", $time); + $write("[%0t] In %m (%l)\n", $time); begin : subblock2 - $write("[%0t] In %m\n", $time); + $write("[%0t] In %m (%L)\n", $time); end end endtask diff --git a/test_regress/t/t_display_noopt.pl b/test_regress/t/t_display_noopt.pl index e39487891..d49c6e580 100755 --- a/test_regress/t/t_display_noopt.pl +++ b/test_regress/t/t_display_noopt.pl @@ -15,12 +15,12 @@ compile ( execute ( check_finished=>1, - expect=>quotemeta(dequote( -'[0] In top.v: Hi -[0] In top.v.sub -[0] In top.v.sub.subblock -[0] In top.v.sub2 -[0] In top.v.sub2.subblock2 + expect=>dequote( +q{[0] In top.v: Hi +[0] In top.v.sub (sub) +[0] In top.v.sub.subblock (sub) +[0] In top.v.sub2 (sub2) +[0] In top.v.sub2.subblock2 (sub2) [0] Back \ Quote " [0] %b=000001100 %0b=1100 %b=00000101010111011101110111100110011001100 %0b=101010111011101110111100110011001100 %b=000001010101111000001001000110100010101100111100000010010001101000101011001111000 %0b=1010101111000001001000110100010101100111100000010010001101000101011001111000 [0] %B=000001100 %0B=1100 %B=00000101010111011101110111100110011001100 %0B=101010111011101110111100110011001100 %B=000001010101111000001001000110100010101100111100000010010001101000101011001111000 %0B=1010101111000001001000110100010101100111100000010010001101000101011001111000 @@ -32,6 +32,15 @@ execute ( [0] %O=014 %0O=14 %O=00527356746314 %0O=527356746314 %O=012570110642547402215053170 %0O=12570110642547402215053170 [0] %x=00c %0x=c %x=00abbbbcccc %0x=abbbbcccc %x=00abc1234567812345678 %0x=abc1234567812345678 [0] %X=00c %0X=c %X=00abbbbcccc %0X=abbbbcccc %X=00abc1234567812345678 %0X=abc1234567812345678 +[0] %C=m %0C=m +[0] %c=m %0c=m +[0] %v=St0 St0 St0 St0 St0 St1 St1 St0 St0 %0v=St0 St0 St0 St0 St0 St1 St1 St0 St0 %v=St0 St0 St0 St0 St0 St1 St0 St1 St0 St1 St0 St1 St1 St1 St0 St1 St1 St1 St0 St1 St1 St1 St0 St1 St1 St1 St1 St0 St0 St1 St1 St0 St0 St1 St1 St0 St0 St1 St1 St0 St0 %0v=St0 St0 St0 St0 St0 St1 St0 St1 St0 St1 St0 St1 St1 St1 St0 St1 St1 St1 St0 St1 St1 St1 St0 St1 St1 St1 St1 St0 St0 St1 St1 St0 St0 St1 St1 St0 St0 St1 St1 St0 St0 %v=St0 St0 St0 St0 St0 St1 St0 St1 St0 St1 St0 St1 St1 St1 St1 St0 St0 St0 St0 St0 St1 St0 St0 St1 St0 St0 St0 St1 St1 St0 St1 St0 St0 St0 St1 St0 St1 St0 St1 St1 St0 St0 St1 St1 St1 St1 St0 St0 St0 St0 St0 St0 St1 St0 St0 St1 St0 St0 St0 St1 St1 St0 St1 St0 St0 St0 St1 St0 St1 St0 St1 St1 St0 St0 St1 St1 St1 St1 St0 St0 St0 %0v=St0 St0 St0 St0 St0 St1 St0 St1 St0 St1 St0 St1 St1 St1 St1 St0 St0 St0 St0 St0 St1 St0 St0 St1 St0 St0 St0 St1 St1 St0 St1 St0 St0 St0 St1 St0 St1 St0 St1 St1 St0 St0 St1 St1 St1 St1 St0 St0 St0 St0 St0 St0 St1 St0 St0 St1 St0 St0 St0 St1 St1 St0 St1 St0 St0 St0 St1 St0 St1 St0 St1 St1 St0 St0 St1 St1 St1 St1 St0 St0 St0 +[0] %V=St0 St0 St0 St0 St0 St1 St1 St0 St0 %0V=St0 St0 St0 St0 St0 St1 St1 St0 St0 %V=St0 St0 St0 St0 St0 St1 St0 St1 St0 St1 St0 St1 St1 St1 St0 St1 St1 St1 St0 St1 St1 St1 St0 St1 St1 St1 St1 St0 St0 St1 St1 St0 St0 St1 St1 St0 St0 St1 St1 St0 St0 %0V=St0 St0 St0 St0 St0 St1 St0 St1 St0 St1 St0 St1 St1 St1 St0 St1 St1 St1 St0 St1 St1 St1 St0 St1 St1 St1 St1 St0 St0 St1 St1 St0 St0 St1 St1 St0 St0 St1 St1 St0 St0 %V=St0 St0 St0 St0 St0 St1 St0 St1 St0 St1 St0 St1 St1 St1 St1 St0 St0 St0 St0 St0 St1 St0 St0 St1 St0 St0 St0 St1 St1 St0 St1 St0 St0 St0 St1 St0 St1 St0 St1 St1 St0 St0 St1 St1 St1 St1 St0 St0 St0 St0 St0 St0 St1 St0 St0 St1 St0 St0 St0 St1 St1 St0 St1 St0 St0 St0 St1 St0 St1 St0 St1 St1 St0 St0 St1 St1 St1 St1 St0 St0 St0 %0V=St0 St0 St0 St0 St0 St1 St0 St1 St0 St1 St0 St1 St1 St1 St1 St0 St0 St0 St0 St0 St1 St0 St0 St1 St0 St0 St0 St1 St1 St0 St1 St0 St0 St0 St1 St0 St1 St0 St1 St1 St0 St0 St1 St1 St1 St1 St0 St0 St0 St0 St0 St0 St1 St0 St0 St1 St0 St0 St0 St1 St1 St0 St1 St0 St0 St0 St1 St0 St1 St0 St1 St1 St0 St0 St1 St1 St1 St1 St0 St0 St0 +[0] %p='hc %0p='hc %p='habbbbcccc %0p='habbbbcccc %p='habc1234567812345678 %0p='habc1234567812345678 +[0] %P='hc %0P='hc %P='habbbbcccc %0P='habbbbcccc %P='habc1234567812345678 %0P='habc1234567812345678 +[0] %P="sv-str" +[0] %u=dcba %0u=dcba +[0] %U=dcba %0U=dcba [0] %D= 12 %d= 12 %01d=12 %06d=000012 %6d= 12 [0] %t= 0 %03t= 0 %0t=0 @@ -44,7 +53,7 @@ extra argument: 0000000000000000 [0] Embedded multiline *-* All Finished *-* -')), +}), ); ok(1); diff --git a/test_regress/t/t_sys_sformat.v b/test_regress/t/t_sys_sformat.v index ff2a6d172..4ea8fc522 100644 --- a/test_regress/t/t_sys_sformat.v +++ b/test_regress/t/t_sys_sformat.v @@ -13,7 +13,7 @@ module t; reg [63:0] q; reg [16*8:1] wide; - reg [8:1] char; + reg [8:1] ochar; reg [48*8:1] str; reg [48*8:1] str2; string str3; @@ -55,8 +55,19 @@ module t; if (str2 !== "mod=top.t") $stop; `endif - $sformat(char,"%s","c"); - if (char != "c") $stop; + $swrite(str2, "lib=%l"); +`ifdef TEST_VERBOSE $display("chkl %0s",str2); `endif + if (str2 !== "lib=t") $stop; + + str3 = $sformatf("u=%u", {"a","b","c","d"}); // Value selected so is printable +`ifdef TEST_VERBOSE $display("chku %0x %s",str3,str3); `endif + if (str3 !== "u=dcba") $stop; + + str3 = $sformatf("v=%v", {"a","b","c","d"}); // Value selected so is printable +`ifdef TEST_VERBOSE $display("chkv %0x %s",str3,str3); `endif + + $sformat(ochar,"%s","c"); + if (ochar != "c") $stop; $write("*-* All Finished *-*\n"); $finish;