Fix display %u, %v, %p, %z, bug989.

This commit is contained in:
Wilson Snyder 2015-11-10 21:12:15 -05:00
parent 0cb5d5cc5a
commit b0a249f338
16 changed files with 234 additions and 83 deletions

View File

@ -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

View File

@ -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<VL_WORDS_I(lbits); i++) {
output += (char)((lwp[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<VL_WORDS_I(lbits); i++) {
output += (char)((lwp[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;

View File

@ -33,6 +33,7 @@
#include <algorithm>
#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 "<<nodep->text()<<endl);
string dispout = "";
string newFormat = "";
string fmt = "";
bool inPct = false;
AstNode* argp = nodep->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: "<<fmt<<" -> "<<out<<" for "<<argp<<endl);
{ // fmt = out w/ replace % with %% as it must be literal.
fmt = "";
for (string::iterator pos = out.begin(); pos != out.end(); ++pos) {
if (*pos == '%') fmt += '%';
fmt += *pos;
}
}
// fmt = out w/ replace % with %% as it must be literal.
fmt = VString::quotePercent(out);
argp->unlinkFrBack()->deleteTree();
}
argp=nextp;
}
break;
} // switch
dispout += fmt;
newFormat += fmt;
} else {
dispout += ch;
newFormat += ch;
}
}
nodep->text(dispout);
//UINFO(9," Display out "<<nodep->text()<<endl);
if (newFormat != nodep->text()) {
nodep->text(newFormat);
UINFO(9," Display out "<<nodep<<endl);
}
}
if (!nodep->exprsp()
&& nodep->name().find("%") == string::npos

View File

@ -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: "<<dispp->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: %"<<pos[0]);
break;
default:
nodep->v3error("Unknown $display-like format code: %"<<pos[0]);
break;

View File

@ -38,6 +38,7 @@
#include <vector>
#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()));

View File

@ -396,12 +396,12 @@ string V3Number::ascii(bool prefixed, bool cleanVerilog) const {
if (binary) {
out<<"b";
out<<displayed("%0b");
out<<displayed(m_fileline, "%0b");
}
else {
if (prefixed) out<<"h";
// Always deal with 4 bits at once. Note no 4-state, it's above.
out<<displayed("%0h");
out<<displayed(m_fileline, "%0h");
}
return out.str();
}
@ -423,7 +423,8 @@ string V3Number::quoteNameControls(const string& namein) {
out += pos[0];
} else {
// This will also cover \a etc
char octal[10]; sprintf(octal,"\\%03o",pos[0]);
// Can't use %03o as messes up when signed
char octal[10]; sprintf(octal,"\\%o%o%o",(pos[0]>>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<words(); i++) {
str += (char)((m_value[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<words(); i++) {
str += (char)((m_value[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: %"<<pos[0]);
fl->v3fatalSrc("Unknown $display-like format code for number: %"<<pos[0]);
return "ERR";
}
}

View File

@ -171,7 +171,7 @@ public:
// ACCESSORS
string ascii(bool prefixed=true, bool cleanVerilog=false) const;
static string quoteNameControls(const string& namein); // Add backslash quotes to strings
string displayed(const string& format) const;
string displayed(FileLine* fl, const string& format) const;
static bool displayedFmtLegal(char format); // Is this a valid format letter?
int width() const { return m_width; }
int widthMin() const; // Minimum width that can represent this number (~== log2(num)+1)

View File

@ -723,7 +723,7 @@ private:
break;
}
string format = string("%") + pos[0];
result += nump->displayed(format);
result += nump->displayed(nodep->fileline(), format);
} else {
switch (tolower(pos[0])) {
case '%':

View File

@ -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

View File

@ -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);
};
//######################################################################

View File

@ -1897,28 +1897,44 @@ private:
nodep->iterateChildren(*this,WidthVP(SELF,BOTH).p());
//
UINFO(9," Display in "<<nodep->text()<<endl);
string dispout = "";
string newFormat;
bool inPct = false;
AstNode* argp = nodep->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 "<<nodep->text()<<endl);
}
virtual void visit(AstDisplay* nodep, AstNUser* vup) {

View File

@ -1013,7 +1013,8 @@ sub _run {
if ($param{expect}) {
# Compare
my $quoted = quotemeta ($param{expect});
my $bad = ($wholefile !~ /$param{expect}/ms
my $bad = ($wholefile ne $param{expect}
&& $wholefile !~ /$param{expect}/ms
&& $wholefile !~ /$quoted/ms);
if ($bad) {
#print "**BAD $self->{name} $param{logfile} MT $moretry $try\n";

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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;