Internals: Move timeunit to pragma, in prep for future parser. No user-functional change intended.

This commit is contained in:
Wilson Snyder
2025-05-06 06:34:49 -04:00
parent 2ed754d5ea
commit da5eb620bf
6 changed files with 49 additions and 33 deletions
+29 -14
View File
@@ -88,9 +88,24 @@ void V3LinkLevel::modSortByLevel() {
void V3LinkLevel::timescaling(const ModVec& mods) {
// Timescale determination
const AstNodeModule* modTimedp = nullptr;
VTimescale unit(VTimescale::NONE);
VTimescale unit{VTimescale::NONE};
// Move timeunit attributes from parse to module unit
// Grammar only allows timeunit as module_item, so no need to recurse full tree
for (AstNodeModule* modp : mods) {
for (AstNode *nextp, *childp = modp->stmtsp(); childp; childp = nextp) {
nextp = childp->nextp();
if (AstPragma* pragp = VN_CAST(childp, Pragma)) {
if (pragp->pragType() == VPragmaType::TIMEUNIT_SET) {
modp->timeunit(pragp->timescale());
VL_DO_DANGLING(pragp->unlinkFrBack()->deleteTree(), pragp);
}
}
}
}
// Use highest level module as default unit - already sorted in proper order
for (const auto& modp : mods) {
// Combine timing into later modules
for (AstNodeModule* modp : mods) {
if (!modTimedp && !modp->timeunit().isNone()) {
modTimedp = modp;
unit = modTimedp->timeunit();
@@ -106,24 +121,24 @@ void V3LinkLevel::timescaling(const ModVec& mods) {
if (!upkgp->timeunit().isNone()) dunitTimed = true;
}
for (AstNodeModule* nodep : mods) {
if (!v3Global.opt.timeOverrideUnit().isNone()) nodep->timeunit(unit);
if (nodep->timeunit().isNone()) {
for (AstNodeModule* modp : mods) {
if (!v3Global.opt.timeOverrideUnit().isNone()) modp->timeunit(unit);
if (modp->timeunit().isNone()) {
if (modTimedp // Got previous
&& !dunitTimed
&& ( // unit doesn't already include an override
v3Global.opt.timeOverrideUnit().isNone()
&& v3Global.opt.timeDefaultUnit().isNone())
&& nodep->timescaleMatters()) {
nodep->v3warn(TIMESCALEMOD,
"Timescale missing on this module as other modules have "
"it (IEEE 1800-2023 3.14.2.3)\n"
<< nodep->warnContextPrimary() << '\n'
<< modTimedp->warnOther()
<< "... Location of module with timescale\n"
<< modTimedp->warnContextSecondary());
&& modp->timescaleMatters()) {
modp->v3warn(TIMESCALEMOD,
"Timescale missing on this module as other modules have "
"it (IEEE 1800-2023 3.14.2.3)\n"
<< modp->warnContextPrimary() << '\n'
<< modTimedp->warnOther()
<< "... Location of module with timescale\n"
<< modTimedp->warnContextSecondary());
}
nodep->timeunit(unit);
modp->timeunit(unit);
}
}