Support timeunit/timeprecision in $unit.

This commit is contained in:
Wilson Snyder 2021-07-29 08:40:41 -04:00
parent 3ec3c2c268
commit 6bad0e14ce
8 changed files with 84 additions and 18 deletions

View File

@ -14,6 +14,7 @@ Verilator 4.211 devel
**Minor:**
* Support unpacked array localparams in tasks/functions (#3078). [Geza Lore]
* Support timeunit/timeprecision in $unit.
* Add --instr-count-dpi to tune assumed DPI import cost for multithreaded
model scheduling. Default value changed to 200 (#3068). [Yinan Xu]
* Output files are split based on the set of headers required

View File

@ -100,10 +100,16 @@ void V3LinkLevel::timescaling(const ModVec& mods) {
if (unit.isNone()) unit = VTimescale(VTimescale::TS_DEFAULT);
v3Global.rootp()->timeunit(unit);
bool dunitTimed = false; // $unit had a timeunit
if (const AstPackage* const upkgp = v3Global.rootp()->dollarUnitPkgp()) {
if (!upkgp->timeunit().isNone()) dunitTimed = true;
}
for (AstNodeModule* nodep : mods) {
if (!v3Global.opt.timeOverrideUnit().isNone()) nodep->timeunit(unit);
if (nodep->timeunit().isNone()) {
if (modTimedp // Got previous
&& !dunitTimed
&& ( // unit doesn't already include an override
v3Global.opt.timeOverrideUnit().isNone()
&& v3Global.opt.timeDefaultUnit().isNone())

View File

@ -108,10 +108,12 @@ void V3ParseImp::timescaleMod(FileLine* fl, AstNodeModule* modp, bool unitSet, d
}
}
if (!unit.isNone()) {
unit = v3Global.opt.timeComputeUnit(unit);
if (modp) {
modp->timeunit(v3Global.opt.timeComputeUnit(unit));
modp->timeunit(unit);
} else {
fl->v3error("timeunit/timeprecision not under a module");
v3Global.rootp()->timeunit(unit);
unitPackage(fl)->timeunit(unit);
}
}
v3Global.rootp()->timeprecisionMerge(fl, prec);

View File

@ -301,6 +301,18 @@ public:
//==== Symbol tables
V3ParseSym* symp() { return m_symp; }
AstPackage* unitPackage(FileLine* fl) {
// Find one made earlier?
VSymEnt* const rootSymp = symp()->symRootp()->findIdFlat(AstPackage::dollarUnitName());
AstPackage* pkgp;
if (!rootSymp) {
pkgp = parsep()->rootp()->dollarUnitPkgAddp();
symp()->reinsert(pkgp, symp()->symRootp()); // Don't push/pop scope as they're global
} else {
pkgp = VN_CAST(rootSymp->nodep(), Package);
}
return pkgp;
}
public:
// CONSTRUCTORS

View File

@ -148,18 +148,6 @@ public:
m_pinNum = m_pinStack.top();
m_pinStack.pop();
}
AstPackage* unitPackage(FileLine* fl) {
// Find one made earlier?
VSymEnt* symp = SYMP->symRootp()->findIdFlat(AstPackage::dollarUnitName());
AstPackage* pkgp;
if (!symp) {
pkgp = PARSEP->rootp()->dollarUnitPkgAddp();
SYMP->reinsert(pkgp, SYMP->symRootp()); // Don't push/pop scope as they're global
} else {
pkgp = VN_CAST(symp->nodep(), Package);
}
return pkgp;
}
AstNodeDType* addRange(AstBasicDType* dtypep, AstNodeRange* rangesp, bool isPacked) {
// If dtypep isn't basic, don't use this, call createArray() instead
if (!rangesp) {
@ -1043,8 +1031,8 @@ description: // ==IEEE: description
| interface_declaration { }
| program_declaration { }
| package_declaration { }
| package_item { if ($1) GRAMMARP->unitPackage($1->fileline())->addStmtp($1); }
| bind_directive { if ($1) GRAMMARP->unitPackage($1->fileline())->addStmtp($1); }
| package_item { if ($1) PARSEP->unitPackage($1->fileline())->addStmtp($1); }
| bind_directive { if ($1) PARSEP->unitPackage($1->fileline())->addStmtp($1); }
// unsupported // IEEE: config_declaration
// // Verilator only
| yaT_RESETALL { } // Else, under design, and illegal based on IEEE 22.3
@ -6157,7 +6145,7 @@ dollarUnitNextId<nodep>: // $unit
// // if not needed must use packageClassScopeNoId
// // Must call nextId without any additional tokens following
yD_UNIT
{ $$ = new AstClassOrPackageRef($1, "$unit", GRAMMARP->unitPackage($<fl>1), nullptr);
{ $$ = new AstClassOrPackageRef{$1, "$unit", PARSEP->unitPackage($<fl>1), nullptr};
SYMP->nextId(PARSEP->rootp()); }
;
@ -6166,7 +6154,7 @@ localNextId<nodep>: // local
// // if not needed must use packageClassScopeNoId
// // Must call nextId without any additional tokens following
yLOCAL__COLONCOLON
{ $$ = new AstClassOrPackageRef($1, "local::", GRAMMARP->unitPackage($<fl>1), nullptr);
{ $$ = new AstClassOrPackageRef{$1, "local::", PARSEP->unitPackage($<fl>1), nullptr};
SYMP->nextId(PARSEP->rootp());
BBUNSUP($<fl>1, "Unsupported: Randomize 'local::'"); }
;

View File

@ -0,0 +1,4 @@
Time scale of __024unit is 10ps / 10ps
Time scale of from_unit is 10ps / 10ps
Time scale of t is 100ps / 10ps
*-* All Finished *-*

View File

@ -0,0 +1,23 @@
#!/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,
expect_filename => $Self->{golden_filename},
);
ok(1);
1;

View File

@ -0,0 +1,30 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under The Creative Commons Public Domain, for
// any use, without warranty, 2021 by Wilson Snyder.
// SPDX-License-Identifier: CC0-1.0
timeunit 10ps;
timeprecision 10ps;
task show;
$printtimescale;
endtask
module from_unit;
task show;
$printtimescale;
endtask
endmodule
module t;
from_unit from_unit();
timeunit 100ps;
initial begin
show();
from_unit.show();
$printtimescale;
$write("*-* All Finished *-*\n");
$finish;
end
endmodule