Fix display %u, %v, %p, %z, bug989.
This commit is contained in:
parent
0cb5d5cc5a
commit
b0a249f338
2
Changes
2
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
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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()));
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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 '%':
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue