Support `$timeformat` with missing arguments (#6113).

This commit is contained in:
Wilson Snyder 2025-06-24 17:30:05 -04:00
parent f9f70383fa
commit 6af694b04b
9 changed files with 69 additions and 19 deletions

View File

@ -18,6 +18,7 @@ Verilator 5.037 devel
* Support assignments to concatenations with impure RHS (#6002). [Ryszard Rozak, Antmicro Ltd.]
* Support SARIF JSON diagnostic output with `--diagnostics-sarif`. (#6017)
* Support 1-bit params with -G and -pvalue (#6051) (#6082). [Paul Swirhun]
* Support `$timeformat` with missing arguments (#6113). [Alex Solomatnikov]
* Support parameter forward types.
* Add PROCINITASSIGN on initial assignments to process variables (#2481). [Niraj Menon]
* Add BADVLTPRAGMA on unknown Verilator pragmas (#5945). [Shou-Li Hsu]

View File

@ -2567,12 +2567,13 @@ void VL_PRINTTIMESCALE(const char* namep, const char* timeunitp,
VL_PRINTF_MT("Time scale of %s is %s / %s\n", namep, timeunitp,
contextp->timeprecisionString());
}
void VL_TIMEFORMAT_IINI(int units, int precision, const std::string& suffix, int width,
void VL_TIMEFORMAT_IINI(bool hasUnits, int units, bool hasPrecision, int precision, bool hasSuffix,
const std::string& suffix, bool hasWidth, int width,
VerilatedContext* contextp) VL_MT_SAFE {
contextp->impp()->timeFormatUnits(units);
contextp->impp()->timeFormatPrecision(precision);
contextp->impp()->timeFormatSuffix(suffix);
contextp->impp()->timeFormatWidth(width);
if (hasUnits) contextp->impp()->timeFormatUnits(units);
if (hasPrecision) contextp->impp()->timeFormatPrecision(precision);
if (hasSuffix) contextp->impp()->timeFormatSuffix(suffix);
if (hasWidth) contextp->impp()->timeFormatWidth(width);
}
//======================================================================

View File

@ -2800,7 +2800,8 @@ extern IData VL_SSCANF_INNX(int lbits, const std::string& ld, const std::string&
extern void VL_SFORMAT_NX(int obits_ignored, std::string& output, const std::string& format,
int argc, ...) VL_MT_SAFE;
extern std::string VL_SFORMATF_N_NX(const std::string& format, int argc, ...) VL_MT_SAFE;
extern void VL_TIMEFORMAT_IINI(int units, int precision, const std::string& suffix, int width,
extern void VL_TIMEFORMAT_IINI(bool hasUnits, int units, bool hasPrecision, int precision,
bool hasSuffix, const std::string& suffix, bool hasWidth, int width,
VerilatedContext* contextp) VL_MT_SAFE;
extern IData VL_VALUEPLUSARGS_INW(int rbits, const std::string& ld, WDataOutP rwp) VL_MT_SAFE;
inline IData VL_VALUEPLUSARGS_INI(int rbits, const std::string& ld, CData& rdr) VL_MT_SAFE {

View File

@ -3490,10 +3490,10 @@ public:
};
class AstTimeFormat final : public AstNodeStmt {
// Parents: stmtlist
// @astgen op1 := unitsp : AstNodeExpr
// @astgen op2 := precisionp : AstNodeExpr
// @astgen op3 := suffixp : AstNodeExpr
// @astgen op4 := widthp : AstNodeExpr
// @astgen op1 := unitsp : Optional[AstNodeExpr]
// @astgen op2 := precisionp : Optional[AstNodeExpr]
// @astgen op3 := suffixp : Optional[AstNodeExpr]
// @astgen op4 := widthp : Optional[AstNodeExpr]
public:
AstTimeFormat(FileLine* fl, AstNodeExpr* unitsp, AstNodeExpr* precisionp, AstNodeExpr* suffixp,
AstNodeExpr* widthp)

View File

@ -1083,13 +1083,33 @@ public:
}
void visit(AstTimeFormat* nodep) override {
putns(nodep, "VL_TIMEFORMAT_IINI(");
iterateAndNextConstNull(nodep->unitsp());
if (nodep->unitsp()) {
puts("true, ");
iterateAndNextConstNull(nodep->unitsp());
} else {
puts("false, 0");
}
puts(", ");
iterateAndNextConstNull(nodep->precisionp());
if (nodep->precisionp()) {
puts("true, ");
iterateAndNextConstNull(nodep->precisionp());
} else {
puts("false, 0");
}
puts(", ");
emitCvtPackStr(nodep->suffixp());
if (nodep->suffixp()) {
puts("true, ");
emitCvtPackStr(nodep->suffixp());
} else {
puts("false, \"\"");
}
puts(", ");
iterateAndNextConstNull(nodep->widthp());
if (nodep->widthp()) {
puts("true, ");
iterateAndNextConstNull(nodep->widthp());
} else {
puts("false, 0");
}
puts(", vlSymsp->_vm_contextp__);\n");
}
void visit(AstTimePrecision* nodep) override {

View File

@ -5718,10 +5718,11 @@ class WidthVisitor final : public VNVisitor {
}
void visit(AstTimeFormat* nodep) override {
assertAtStatement(nodep);
iterateCheckSigned32(nodep, "units", nodep->unitsp(), BOTH);
iterateCheckSigned32(nodep, "precision", nodep->precisionp(), BOTH);
iterateCheckString(nodep, "suffix", nodep->suffixp(), BOTH);
iterateCheckSigned32(nodep, "width", nodep->widthp(), BOTH);
if (nodep->unitsp()) iterateCheckSigned32(nodep, "units", nodep->unitsp(), BOTH);
if (nodep->precisionp())
iterateCheckSigned32(nodep, "precision", nodep->precisionp(), BOTH);
if (nodep->suffixp()) iterateCheckString(nodep, "suffix", nodep->suffixp(), BOTH);
if (nodep->widthp()) iterateCheckSigned32(nodep, "width", nodep->widthp(), BOTH);
}
void visit(AstUCStmt* nodep) override {
// Just let all arguments seek their natural sizes

View File

@ -4362,8 +4362,14 @@ system_t_call<nodeStmtp>: // IEEE: system_tf_call (as task)
| yD_PRINTTIMESCALE { $$ = new AstPrintTimeScale{$1}; }
| yD_PRINTTIMESCALE '(' ')' { $$ = new AstPrintTimeScale{$1}; }
| yD_PRINTTIMESCALE '(' idClassSel ')' { $$ = new AstPrintTimeScale{$1}; DEL($3); }
| yD_TIMEFORMAT '(' expr ',' expr ',' expr ',' expr ')'
| yD_TIMEFORMAT '(' exprE ',' exprE ',' exprE ',' exprE ')'
{ $$ = new AstTimeFormat{$1, $3, $5, $7, $9}; }
| yD_TIMEFORMAT '(' exprE ',' exprE ',' exprE ')'
{ $$ = new AstTimeFormat{$1, $3, $5, $7, nullptr}; }
| yD_TIMEFORMAT '(' exprE ',' exprE ')'
{ $$ = new AstTimeFormat{$1, $3, $5, nullptr, nullptr}; }
| yD_TIMEFORMAT '(' exprE ')'
{ $$ = new AstTimeFormat{$1, $3, nullptr, nullptr, nullptr}; }
//
| yD_READMEMB '(' expr ',' idClassSel ')' { $$ = new AstReadMem{$1, false, $3, $5, nullptr, nullptr}; }
| yD_READMEMB '(' expr ',' idClassSel ',' expr ')' { $$ = new AstReadMem{$1, false, $3, $5, $7, nullptr}; }

View File

@ -3,5 +3,10 @@ default: [10] 0t time [ 10] No0 time p= 10
-9,0,,10: [10] 0t time [ 10] No0 time p= 10 0p='ha
-9,0,ns,5: [10ns] 0t time [ 10ns] No0 time p= 10 0p='ha
-9,3,ns,8: [10.000ns] 0t time [10.000ns] No0 time p= 10 0p='ha
-9,3,ns : [10.000ns] 0t time [10.000ns] No0 time p= 10 0p='ha
-9,3: [10.000ns] 0t time [10.000ns] No0 time p= 10 0p='ha
-9: [10.000ns] 0t time [10.000ns] No0 time p= 10 0p='ha
: [10.000ns] 0t time [10.000ns] No0 time p= 10 0p='ha
-9,,,: [10.000ns] 0t time [10.000ns] No0 time p= 10 0p='ha
*-* All Finished *-*

View File

@ -30,6 +30,21 @@ module t (/*AUTOARG*/
$timeformat(-9, 3, "ns", 8);
$write("-9,3,ns,8: [%0t] 0t time [%t] No0 time p=%p 0p=%0p\n",
$time, $time, $time, $time);
$timeformat(-9, 3, "ns");
$write("-9,3,ns : [%0t] 0t time [%t] No0 time p=%p 0p=%0p\n",
$time, $time, $time, $time);
$timeformat(-9, 3);
$write("-9,3: [%0t] 0t time [%t] No0 time p=%p 0p=%0p\n",
$time, $time, $time, $time);
$timeformat(-9);
$write("-9: [%0t] 0t time [%t] No0 time p=%p 0p=%0p\n",
$time, $time, $time, $time);
$timeformat();
$write(": [%0t] 0t time [%t] No0 time p=%p 0p=%0p\n",
$time, $time, $time, $time);
$timeformat(-9,,,);
$write("-9,,,: [%0t] 0t time [%t] No0 time p=%p 0p=%0p\n",
$time, $time, $time, $time);
$write("\n");
$write("*-* All Finished *-*\n");
$finish;