Support and

This commit is contained in:
Wilson Snyder 2022-11-16 21:10:39 -05:00
parent 3ddfa214e3
commit 3c77c7bb92
10 changed files with 119 additions and 4 deletions

View File

@ -17,6 +17,7 @@ Verilator 5.003 devel
* Support named properties (#3667). [Ryszard Rozak, Antmicro Ltd]
* Support randcase.
* Support pre_randomize and post_randomize.
* Support $timeunit and $timeprecision.
* Add ENUMVALUE warning when value misused for enum (#726).
* Internal AST improvements, also affect XML format (#3721). [Geza Lore]
* Change ENDLABEL from warning into an error.

View File

@ -73,6 +73,16 @@ or "`ifdef`"'s may break other tools.
prints 5 digits per the C standard (this is unspecified in Verilog, but
was incorporated into the 1800-2009).
.. option:: $timeprecision
Returns the timeprecision of the model as an integer. This extension is
experimental and may be removed without deprecation.
.. option:: $timeunit
Returns the timeunit of the current module as an integer. This
extension is experimental and may be removed without deprecation.
.. option:: `coverage_block_off
Specifies the entire begin/end block should be ignored for coverage

View File

@ -1597,6 +1597,39 @@ public:
AstNodeDType* getChildDTypep() const override { return childDTypep(); }
AstNodeDType* subDTypep() const { return dtypep() ? dtypep() : childDTypep(); }
};
class AstTimePrecision final : public AstNodeExpr {
// Verilog $timeprecision
public:
AstTimePrecision(FileLine* fl)
: ASTGEN_SUPER_TimePrecision(fl) {
dtypeSetSigned32();
}
ASTGEN_MEMBERS_AstTimePrecision;
string emitVerilog() override { return "$timeprecision"; }
string emitC() override { V3ERROR_NA_RETURN(""); }
string emitSimpleOperator() override { V3ERROR_NA_RETURN(""); }
bool cleanOut() const override { return true; }
int instrCount() const override { return widthInstrs(); }
bool same(const AstNode* /*samep*/) const override { return true; }
};
class AstTimeUnit final : public AstNodeExpr {
VTimescale m_timeunit; // Parent module time unit
// Verilog $timeunit
public:
AstTimeUnit(FileLine* fl)
: ASTGEN_SUPER_TimeUnit(fl) {
dtypeSetSigned32();
}
ASTGEN_MEMBERS_AstTimeUnit;
string emitVerilog() override { return "$timeunit"; }
string emitC() override { V3ERROR_NA_RETURN(""); }
string emitSimpleOperator() override { V3ERROR_NA_RETURN(""); }
bool cleanOut() const override { return true; }
int instrCount() const override { return widthInstrs(); }
bool same(const AstNode* /*samep*/) const override { return true; }
void timeunit(const VTimescale& flag) { m_timeunit = flag; }
VTimescale timeunit() const { return m_timeunit; }
};
class AstUCFunc final : public AstNodeExpr {
// User's $c function
// Perhaps this should be an AstNodeListop; but there's only one list math right now

View File

@ -909,6 +909,9 @@ public:
iterateAndNextNull(nodep->widthp());
puts(", vlSymsp->_vm_contextp__);\n");
}
void visit(AstTimePrecision* nodep) override {
puts("vlSymsp->_vm_contextp__->timeprecision()");
}
void visit(AstNodeSimpleText* nodep) override {
const string text = m_inUC && m_useSelfForThis
? VString::replaceWord(nodep->text(), "this", "vlSelf")

View File

@ -577,6 +577,10 @@ private:
iterateChildren(nodep);
nodep->timeunit(m_modp->timeunit());
}
void visit(AstTimeUnit* nodep) override {
iterateChildren(nodep);
nodep->timeunit(m_modp->timeunit());
}
void visit(AstEventControl* nodep) override {
cleanFileline(nodep);
iterateChildren(nodep);

View File

@ -446,6 +446,11 @@ private:
// Widths: Constant, terminal
void visit(AstTime* nodep) override { nodep->dtypeSetUInt64(); }
void visit(AstTimeD* nodep) override { nodep->dtypeSetDouble(); }
void visit(AstTimePrecision* nodep) override { nodep->dtypeSetSigned32(); }
void visit(AstTimeUnit* nodep) override {
nodep->replaceWith(
new AstConst{nodep->fileline(), AstConst::Signed32(), nodep->timeunit().powerOfTen()});
}
void visit(AstScopeName* nodep) override {
nodep->dtypeSetUInt64(); // A pointer, but not that it matters
}

View File

@ -281,7 +281,9 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5}
"$test$plusargs" { FL; return yD_TESTPLUSARGS; }
"$time" { FL; return yD_TIME; }
"$timeformat" { FL; return yD_TIMEFORMAT; }
"$timeprecision" { FL; return yD_TIMEPRECISION; }
"$timeskew" { FL; return yaTIMINGSPEC; }
"$timeunit" { FL; return yD_TIMEUNIT; }
"$typename" { FL; return yD_TYPENAME; }
"$ungetc" { FL; return yD_UNGETC; }
"$urandom" { FL; return yD_URANDOM; }

View File

@ -876,6 +876,8 @@ BISONPRE_VERSION(3.7,%define api.header.include {"V3ParseBison.h"})
%token<fl> yD_TESTPLUSARGS "$test$plusargs"
%token<fl> yD_TIME "$time"
%token<fl> yD_TIMEFORMAT "$timeformat"
%token<fl> yD_TIMEPRECISION "$timeprecision"
%token<fl> yD_TIMEUNIT "$timeunit"
%token<fl> yD_TYPENAME "$typename"
%token<fl> yD_UNGETC "$ungetc"
%token<fl> yD_UNIT "$unit"
@ -3861,10 +3863,11 @@ system_t_call<nodep>: // IEEE: system_tf_call (as task)
| yD_MONITOROFF parenE { $$ = new AstMonitorOff($1, true); }
| yD_MONITORON parenE { $$ = new AstMonitorOff($1, false); }
//
| yD_PRINTTIMESCALE { $$ = new AstPrintTimeScale($1); }
| yD_PRINTTIMESCALE '(' ')' { $$ = new AstPrintTimeScale($1); }
| yD_PRINTTIMESCALE '(' idClassSel ')' { $$ = new AstPrintTimeScale($1); DEL($3); }
| yD_TIMEFORMAT '(' expr ',' expr ',' expr ',' expr ')' { $$ = new AstTimeFormat($1, $3, $5, $7, $9); }
| yD_PRINTTIMESCALE { $$ = new AstPrintTimeScale{$1}; }
| yD_PRINTTIMESCALE '(' ')' { $$ = new AstPrintTimeScale{$1}; }
| yD_PRINTTIMESCALE '(' idClassSel ')' { $$ = new AstPrintTimeScale{$1}; DEL($3); }
| yD_TIMEFORMAT '(' expr ',' expr ',' expr ',' expr ')'
{ $$ = new AstTimeFormat{$1, $3, $5, $7, $9}; }
//
| 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); }
@ -3994,6 +3997,12 @@ system_f_call_or_t<nodeExprp>: // IEEE: part of system_tf_call (can be task
| yD_TANH '(' expr ')' { $$ = new AstTanhD($1,$3); }
| yD_TESTPLUSARGS '(' expr ')' { $$ = new AstTestPlusArgs($1, $3); }
| yD_TIME parenE { $$ = new AstTime{$1, VTimescale{VTimescale::NONE}}; }
| yD_TIMEPRECISION { $$ = new AstTimePrecision{$1}; }
| yD_TIMEPRECISION '(' ')' { $$ = new AstTimePrecision{$1}; }
| yD_TIMEPRECISION '(' idClassSel ')' { $$ = new AstTimePrecision{$1}; DEL($3); }
| yD_TIMEUNIT { $$ = new AstTimeUnit{$1}; }
| yD_TIMEUNIT '(' ')' { $$ = new AstTimeUnit{$1}; }
| yD_TIMEUNIT '(' idClassSel ')' { $$ = new AstTimeUnit{$1}; DEL($3); }
| yD_TYPENAME '(' exprOrDataType ')' { $$ = new AstAttrOf($1, VAttrType::TYPENAME, $3); }
| yD_UNGETC '(' expr ',' expr ')' { $$ = new AstFUngetC($1, $5, $3); } // Arg swap to file first
| yD_UNPACKED_DIMENSIONS '(' exprOrDataType ')' { $$ = new AstAttrOf($1,VAttrType::DIM_UNPK_DIMENSIONS,$3); }

View File

@ -0,0 +1,22 @@
#!/usr/bin/env perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003 by Wilson Snyder. This program is free software; you
# can redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
scenarios(simulator => 1);
compile(
);
execute(
check_finished => 1,
);
ok(1);
1;

View File

@ -0,0 +1,26 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under The Creative Commons Public Domain, for
// any use, without warranty, 2022 by Wilson Snyder.
// SPDX-License-Identifier: CC0-1.0
`define checkd(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0);
module t;
timeunit 1ns;
timeprecision 1ps;
initial begin
`checkd($timeunit, -9);
`checkd($timeunit(), -9);
`checkd($timeunit(t), -9);
`checkd($timeprecision, -12);
`checkd($timeprecision(), -12);
`checkd($timeprecision(t), -12);
$write("*-* All Finished *-*\n");
$finish;
end
endmodule