Implement $displayb/o/h, $writeb/o/h, etc, Closes #1637.

This commit is contained in:
Wilson Snyder 2020-03-05 21:49:25 -05:00
parent c108f5def9
commit 75ecad591a
12 changed files with 111 additions and 40 deletions

View File

@ -15,6 +15,8 @@ The contributors that suggested a given feature are shown in []. Thanks!
*** Fix genblk naming with directly nested generate blocks, #2176. [Alexander Grobman]
**** Implement $displayb/o/h, $writeb/o/h, etc, #1637.
**** Use gcc -Os in examples instead of -O2 for better average performance.
**** Fix undeclared VL_SHIFTR_WWQ, #2114. [Alex Solomatnikov]

View File

@ -2956,17 +2956,21 @@ public:
class AstSFormatF : public AstNode {
// Convert format to string, generally under an AstDisplay or AstSFormat
// Also used as "real" function for /*verilator sformat*/ functions
string m_text;
bool m_hidden; // Under display, etc
bool m_hasFormat; // Has format code
string m_text;
bool m_hidden; // Under display, etc
bool m_hasFormat; // Has format code
char m_missingArgChar; // Format code when argument without format, 'h'/'o'/'b'
public:
class NoFormat {};
AstSFormatF(FileLine* fl, const string& text, bool hidden, AstNode* exprsp)
: ASTGEN_SUPER(fl), m_text(text), m_hidden(hidden), m_hasFormat(true) {
AstSFormatF(FileLine* fl, const string& text, bool hidden, AstNode* exprsp,
char missingArgChar = 'd')
: ASTGEN_SUPER(fl)
, m_text(text), m_hidden(hidden), m_hasFormat(true), m_missingArgChar(missingArgChar) {
dtypeSetString();
addNOp1p(exprsp); addNOp2p(NULL); }
AstSFormatF(FileLine* fl, NoFormat, AstNode* exprsp)
: ASTGEN_SUPER(fl), m_text(""), m_hidden(true), m_hasFormat(false) {
AstSFormatF(FileLine* fl, NoFormat, AstNode* exprsp, char missingArgChar = 'd')
: ASTGEN_SUPER(fl)
, m_text(""), m_hidden(true), m_hasFormat(false), m_missingArgChar(missingArgChar) {
dtypeSetString();
addNOp1p(exprsp); addNOp2p(NULL); }
ASTNODE_NODE_FUNCS(SFormatF)
@ -2988,6 +2992,7 @@ public:
bool hidden() const { return m_hidden; }
void hasFormat(bool flag) { m_hasFormat = flag; }
bool hasFormat() const { return m_hasFormat; }
char missingArgChar() const { return m_missingArgChar; }
};
class AstDisplay : public AstNodeStmt {
@ -2995,18 +3000,19 @@ class AstDisplay : public AstNodeStmt {
// Children: file which must be a varref
// Children: SFORMATF to generate print string
private:
AstDisplayType m_displayType;
AstDisplayType m_displayType;
public:
AstDisplay(FileLine* fl, AstDisplayType dispType, const string& text, AstNode* filep,
AstNode* exprsp)
AstNode* exprsp, char missingArgChar = 'd')
: ASTGEN_SUPER(fl) {
setOp1p(new AstSFormatF(fl, text, true, exprsp));
setOp1p(new AstSFormatF(fl, text, true, exprsp, missingArgChar));
setNOp3p(filep);
m_displayType = dispType;
}
AstDisplay(FileLine* fl, AstDisplayType dispType, AstNode* filep, AstNode* exprsp)
AstDisplay(FileLine* fl, AstDisplayType dispType, AstNode* filep, AstNode* exprsp,
char missingArgChar = 'd')
: ASTGEN_SUPER(fl) {
setOp1p(new AstSFormatF(fl, AstSFormatF::NoFormat(), exprsp));
setOp1p(new AstSFormatF(fl, AstSFormatF::NoFormat(), exprsp, missingArgChar));
setNOp3p(filep);
m_displayType = dispType;
}
@ -3092,9 +3098,10 @@ class AstSFormat : public AstNodeStmt {
// Children: string to load
// Children: SFORMATF to generate print string
public:
AstSFormat(FileLine* fl, AstNode* lhsp, const string& text, AstNode* exprsp)
AstSFormat(FileLine* fl, AstNode* lhsp, const string& text, AstNode* exprsp,
char missingArgChar = 'd')
: ASTGEN_SUPER(fl) {
setOp1p(new AstSFormatF(fl, text, true, exprsp));
setOp1p(new AstSFormatF(fl, text, true, exprsp, missingArgChar));
setOp3p(lhsp);
}
ASTNODE_NODE_FUNCS(SFormat)

View File

@ -2819,7 +2819,7 @@ private:
} else if (argp && argp->isString()) {
ch = '@';
} else {
ch = 'h';
ch = nodep->missingArgChar();
}
if (argp) argp = argp->nextp();
break;

View File

@ -197,6 +197,9 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5}
"$cos" { FL; return yD_COS; }
"$cosh" { FL; return yD_COSH; }
"$display" { FL; return yD_DISPLAY; }
"$displayb" { FL; return yD_DISPLAYB; }
"$displayh" { FL; return yD_DISPLAYH; }
"$displayo" { FL; return yD_DISPLAYO; }
"$dumpall" { FL; return yD_DUMPALL; }
"$dumpfile" { FL; return yD_DUMPFILE; }
"$dumpflush" { FL; return yD_DUMPFLUSH; }
@ -213,6 +216,9 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5}
"$exp" { FL; return yD_EXP; }
"$fclose" { FL; return yD_FCLOSE; }
"$fdisplay" { FL; return yD_FDISPLAY; }
"$fdisplayb" { FL; return yD_FDISPLAYB; }
"$fdisplayh" { FL; return yD_FDISPLAYH; }
"$fdisplayo" { FL; return yD_FDISPLAYO; }
"$feof" { FL; return yD_FEOF; }
"$fflush" { FL; return yD_FFLUSH; }
"$fgetc" { FL; return yD_FGETC; }
@ -227,6 +233,9 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5}
"$ftell" { FL; return yD_FTELL; }
"$fullskew" { FL; return yaTIMINGSPEC; }
"$fwrite" { FL; return yD_FWRITE; }
"$fwriteb" { FL; return yD_FWRITEB; }
"$fwriteh" { FL; return yD_FWRITEH; }
"$fwriteo" { FL; return yD_FWRITEO; }
"$hold" { FL; return yaTIMINGSPEC; }
"$hypot" { FL; return yD_HYPOT; }
"$itor" { FL; return yD_ITOR; }
@ -245,9 +254,9 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5}
"$removal" { FL; return yaTIMINGSPEC; }
"$rewind" { FL; return yD_REWIND; }
"$rtoi" { FL; return yD_RTOI; }
"$sampled" { FL; return yD_SAMPLED; }
"$setup" { FL; return yaTIMINGSPEC; }
"$setuphold" { FL; return yaTIMINGSPEC; }
"$sampled" { FL; return yD_SAMPLED; }
"$sformat" { FL; return yD_SFORMAT; }
"$sformatf" { FL; return yD_SFORMATF; }
"$shortrealtobits" { FL; return yD_SHORTREALTOBITS; }
@ -259,6 +268,9 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5}
"$stime" { FL; return yD_STIME; }
"$stop" { FL; return yD_STOP; }
"$swrite" { FL; return yD_SWRITE; }
"$swriteb" { FL; return yD_SWRITEB; }
"$swriteh" { FL; return yD_SWRITEH; }
"$swriteo" { FL; return yD_SWRITEO; }
"$system" { FL; return yD_SYSTEM; }
"$tan" { FL; return yD_TAN; }
"$tanh" { FL; return yD_TANH; }
@ -270,6 +282,9 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5}
"$value$plusargs" { FL; return yD_VALUEPLUSARGS; }
"$width" { FL; return yaTIMINGSPEC; }
"$write" { FL; return yD_WRITE; }
"$writeb" { FL; return yD_WRITEB; }
"$writeh" { FL; return yD_WRITEH; }
"$writeo" { FL; return yD_WRITEO; }
"$writememh" { FL; return yD_WRITEMEMH; }
/* Keywords */
"always" { FL; return yALWAYS; }
@ -374,19 +389,6 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5}
"wor" { FL; return yWOR; }
"xnor" { FL; return yXNOR; }
"xor" { FL; return yXOR; }
/* Special errors */
"$displayb" { FL; RETURN_BBOX_SYS_OR_MSG("Unsupported: Use $display with %%b format instead: %s", yytext); }
"$displayh" { FL; RETURN_BBOX_SYS_OR_MSG("Unsupported: Use $display with %%x format instead: %s", yytext); }
"$displayo" { FL; RETURN_BBOX_SYS_OR_MSG("Unsupported: Use $display with %%o format instead: %s", yytext); }
"$fdisplayb" { FL; RETURN_BBOX_SYS_OR_MSG("Unsupported: Use $fdisplay with %%b format instead: %s", yytext); }
"$fdisplayh" { FL; RETURN_BBOX_SYS_OR_MSG("Unsupported: Use $fdisplay with %%x format instead: %s", yytext); }
"$fdisplayo" { FL; RETURN_BBOX_SYS_OR_MSG("Unsupported: Use $fdisplay with %%o format instead: %s", yytext); }
"$fwriteb" { FL; RETURN_BBOX_SYS_OR_MSG("Unsupported: Use $fwrite with %%b format instead: %s", yytext); }
"$fwriteh" { FL; RETURN_BBOX_SYS_OR_MSG("Unsupported: Use $fwrite with %%x format instead: %s", yytext); }
"$fwriteo" { FL; RETURN_BBOX_SYS_OR_MSG("Unsupported: Use $fwrite with %%o format instead: %s", yytext); }
"$writeb" { FL; RETURN_BBOX_SYS_OR_MSG("Unsupported: Use $write with %%b format instead: %s", yytext); }
"$writeh" { FL; RETURN_BBOX_SYS_OR_MSG("Unsupported: Use $write with %%x format instead: %s", yytext); }
"$writeo" { FL; RETURN_BBOX_SYS_OR_MSG("Unsupported: Use $write with %%o format instead: %s", yytext); }
}
/* Verilog 2001 */

View File

@ -553,6 +553,9 @@ class AstSenTree;
%token<fl> yD_COUNTONES "$countones"
%token<fl> yD_DIMENSIONS "$dimensions"
%token<fl> yD_DISPLAY "$display"
%token<fl> yD_DISPLAYB "$displayb"
%token<fl> yD_DISPLAYH "$displayh"
%token<fl> yD_DISPLAYO "$displayo"
%token<fl> yD_DUMPALL "$dumpall"
%token<fl> yD_DUMPFILE "$dumpfile"
%token<fl> yD_DUMPFLUSH "$dumpflush"
@ -566,6 +569,9 @@ class AstSenTree;
%token<fl> yD_FATAL "$fatal"
%token<fl> yD_FCLOSE "$fclose"
%token<fl> yD_FDISPLAY "$fdisplay"
%token<fl> yD_FDISPLAYB "$fdisplayb"
%token<fl> yD_FDISPLAYH "$fdisplayh"
%token<fl> yD_FDISPLAYO "$fdisplayo"
%token<fl> yD_FEOF "$feof"
%token<fl> yD_FFLUSH "$fflush"
%token<fl> yD_FGETC "$fgetc"
@ -579,6 +585,9 @@ class AstSenTree;
%token<fl> yD_FSEEK "$fseek"
%token<fl> yD_FTELL "$ftell"
%token<fl> yD_FWRITE "$fwrite"
%token<fl> yD_FWRITEB "$fwriteb"
%token<fl> yD_FWRITEH "$fwriteh"
%token<fl> yD_FWRITEO "$fwriteo"
%token<fl> yD_HIGH "$high"
%token<fl> yD_HYPOT "$hypot"
%token<fl> yD_INCREMENT "$increment"
@ -614,6 +623,9 @@ class AstSenTree;
%token<fl> yD_STIME "$stime"
%token<fl> yD_STOP "$stop"
%token<fl> yD_SWRITE "$swrite"
%token<fl> yD_SWRITEB "$swriteb"
%token<fl> yD_SWRITEH "$swriteh"
%token<fl> yD_SWRITEO "$swriteo"
%token<fl> yD_SYSTEM "$system"
%token<fl> yD_TAN "$tan"
%token<fl> yD_TANH "$tanh"
@ -627,7 +639,10 @@ class AstSenTree;
%token<fl> yD_VALUEPLUSARGS "$value$plusargs"
%token<fl> yD_WARNING "$warning"
%token<fl> yD_WRITE "$write"
%token<fl> yD_WRITEB "$writeb"
%token<fl> yD_WRITEH "$writeh"
%token<fl> yD_WRITEMEMH "$writememh"
%token<fl> yD_WRITEO "$writeo"
%token<fl> yVL_CLOCK "/*verilator sc_clock*/"
%token<fl> yVL_CLOCKER "/*verilator clocker*/"
@ -3195,16 +3210,40 @@ system_t_call<nodep>: // IEEE: system_tf_call (as task)
| yD_STOP parenE { $$ = new AstStop($1, false); }
| yD_STOP '(' expr ')' { $$ = new AstStop($1, false); DEL($3); }
//
| yD_SFORMAT '(' expr ',' str commaEListE ')' { $$ = new AstSFormat($1,$3,*$5,$6); }
| yD_SWRITE '(' expr ',' str commaEListE ')' { $$ = new AstSFormat($1,$3,*$5,$6); }
| yD_SFORMAT '(' expr ',' str commaEListE ')' { $$ = new AstSFormat($1, $3, *$5, $6); }
| yD_SWRITE '(' expr ',' str commaEListE ')' { $$ = new AstSFormat($1, $3, *$5, $6); }
| yD_SWRITEB '(' expr ',' str commaEListE ')' { $$ = new AstSFormat($1, $3, *$5, $6, 'b'); }
| yD_SWRITEH '(' expr ',' str commaEListE ')' { $$ = new AstSFormat($1, $3, *$5, $6, 'h'); }
| yD_SWRITEO '(' expr ',' str commaEListE ')' { $$ = new AstSFormat($1, $3, *$5, $6, 'o'); }
//
| yD_DISPLAY parenE { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY, NULL, NULL); }
| yD_DISPLAY '(' exprList ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY, NULL, $3); }
| yD_DISPLAYB parenE { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY, NULL, NULL, 'b'); }
| yD_DISPLAYB '(' exprList ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY, NULL, $3, 'b'); }
| yD_DISPLAYH parenE { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY, NULL, NULL, 'h'); }
| yD_DISPLAYH '(' exprList ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY, NULL, $3, 'h'); }
| yD_DISPLAYO parenE { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY, NULL, NULL, 'o'); }
| yD_DISPLAYO '(' exprList ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY, NULL, $3, 'o'); }
| yD_WRITE parenE { $$ = NULL; } // NOP
| yD_WRITE '(' exprList ')' { $$ = new AstDisplay($1,AstDisplayType::DT_WRITE, NULL, $3); }
| yD_WRITEB parenE { $$ = NULL; } // NOP
| yD_WRITEB '(' exprList ')' { $$ = new AstDisplay($1,AstDisplayType::DT_WRITE, NULL, $3, 'b'); }
| yD_WRITEH parenE { $$ = NULL; } // NOP
| yD_WRITEH '(' exprList ')' { $$ = new AstDisplay($1,AstDisplayType::DT_WRITE, NULL, $3, 'h'); }
| yD_WRITEO parenE { $$ = NULL; } // NOP
| yD_WRITEO '(' exprList ')' { $$ = new AstDisplay($1,AstDisplayType::DT_WRITE, NULL, $3, 'o'); }
| yD_FDISPLAY '(' expr ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY, $3, NULL); }
| yD_FDISPLAY '(' expr ',' exprListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY, $3, $5); }
| yD_FDISPLAYB '(' expr ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY, $3, NULL, 'b'); }
| yD_FDISPLAYB '(' expr ',' exprListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY, $3, $5, 'b'); }
| yD_FDISPLAYH '(' expr ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY, $3, NULL, 'h'); }
| yD_FDISPLAYH '(' expr ',' exprListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY, $3, $5, 'h'); }
| yD_FDISPLAYO '(' expr ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY, $3, NULL, 'o'); }
| yD_FDISPLAYO '(' expr ',' exprListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY, $3, $5, 'o'); }
| yD_FWRITE '(' expr ',' exprListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_WRITE, $3, $5); }
| yD_FWRITEB '(' expr ',' exprListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_WRITE, $3, $5, 'b'); }
| yD_FWRITEO '(' expr ',' exprListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_WRITE, $3, $5, 'h'); }
| yD_FWRITEH '(' expr ',' exprListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_WRITE, $3, $5, 'o'); }
| yD_INFO parenE { $$ = new AstDisplay($1,AstDisplayType::DT_INFO, NULL, NULL); }
| yD_INFO '(' exprList ')' { $$ = new AstDisplay($1,AstDisplayType::DT_INFO, NULL, $3); }
| yD_WARNING parenE { $$ = new AstDisplay($1,AstDisplayType::DT_WARNING, NULL, NULL); }

View File

@ -7,7 +7,7 @@
$warning("User compile-time warning");
^~~~~~~~
... Use "/* verilator lint_off USERWARN */" and lint_on around source to disable this message.
%Warning-USERWARN: t/t_assert_comp_bad.v:11: 00000001
%Warning-USERWARN: t/t_assert_comp_bad.v:11: 1
: ... In instance t
$warning(1);
^~~~~~~~

View File

@ -43,11 +43,15 @@
[0] %s=! %s= what! %s= hmmm!1234
[0] %6s=: !: %6s=: what!: %6s=: hmmm!1234:
[0] %8s=: sv-str:
d: 12 12
h: 00c 00c
o: 014 014
b: 000001100 000001100
[0] hello, from a very long string. Percent %s are literally substituted in.
hello, from a concatenated string.
hello, from a concatenated format string [0].
extra argument: 0000000000000000
0000000000000000: pre argument
extra argument: 0
0: pre argument
[0] Embedded <#013> return
[0] Embedded
multiline

View File

@ -132,6 +132,12 @@ module t;
$display("[%0t] %%8s=:%8s:", $time,
svs);
// Displays without format, must use default
$write("d: "); $write(nine); $write(" "); $display(nine);
$writeh("h: "); $writeh(nine); $writeh(" "); $displayh(nine);
$writeo("o: "); $writeo(nine); $writeo(" "); $displayo(nine);
$writeb("b: "); $writeb(nine); $writeb(" "); $displayb(nine);
$display("[%0t] %s%s%s", $time,
"hel", "lo, fr", "om a very long string. Percent %s are literally substituted in.");
$display("hel", "lo, fr", "om a concatenated string.");

View File

@ -8,12 +8,12 @@ f
t2=0
post
t3=0
t4=0 t5=00000000000000000
t4=0 t5=0 0
m
t=0 t2=0 t3=0 t4=0 t5=0
t=0 t2=0 t3=0 t4=0 t5=0
mm
f a=top.t b=top.t pre t=0 t2=0 post t3=0 t4=0 t5=00000000000000000m t=0 t2=0 t3=0 t4=0 t5=0 t=0 t2=0 t3=0 t4=0 t5=0mm
f a=top.t b=top.t pre t=0 t2=0 post t3=0 t4=0 t5=0 0m t=0 t2=0 t3=0 t4=0 t5=0 t=0 t2=0 t3=0 t4=0 t5=0mm
*-* All Finished *-*

View File

@ -0,0 +1,6 @@
[0] hello v=12345667
[0] Hello2
d: 12 12
h: 00000000014 0000000c
o: 0000000c 00000000014
b: 00000000000000000000000000001100 00000000000000000000000000001100

View File

@ -21,10 +21,7 @@ execute(
check_finished => 1,
);
file_grep("$Self->{obj_dir}/t_sys_file_basic_test.log",
qr/\[0\] hello v=12345667
\[0\] Hello2
/);
files_identical("$Self->{obj_dir}/t_sys_file_basic_test.log", $Self->{golden_filename});
ok(1);
1;

View File

@ -19,6 +19,7 @@ module t;
reg [16*8:1] letterz;
real r;
string s;
integer i;
reg [7:0] v_a,v_b,v_c,v_d;
reg [31:0] v_worda;
@ -51,6 +52,13 @@ module t;
$fdisplay(file, "[%0t] hello v=%x", $time, 32'h12345667);
$fwrite(file, "[%0t] %s\n", $time, "Hello2");
i = 12;
$fwrite(file, "d: "); $fwrite(file, i); $fwrite(file, " "); $fdisplay(file, i);
$fwriteh(file, "h: "); $fwriteh(file, i); $fwriteh(file, " "); $fdisplayh(file, i);
$fwriteo(file, "o: "); $fwriteo(file, i); $fwriteo(file, " "); $fdisplayo(file, i);
$fwriteb(file, "b: "); $fwriteb(file, i); $fwriteb(file, " "); $fdisplayb(file, i);
$fflush(file);
$fclose(file);