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

View File

@ -336,6 +336,7 @@ public:
NO_INLINE_TASK, NO_INLINE_TASK,
PUBLIC_MODULE, PUBLIC_MODULE,
PUBLIC_TASK, PUBLIC_TASK,
TIMEUNIT_SET,
UNROLL_DISABLE, UNROLL_DISABLE,
UNROLL_FULL, UNROLL_FULL,
FULL_CASE, FULL_CASE,

View File

@ -1494,18 +1494,24 @@ public:
}; };
class AstPragma final : public AstNode { class AstPragma final : public AstNode {
const VPragmaType m_pragType; // Type of pragma const VPragmaType m_pragType; // Type of pragma
const VTimescale m_timescale; // For TIMEUNIT_SET
public: public:
// Pragmas don't result in any output code, they're just flags that affect // Pragmas don't result in any output code, they're just flags that affect
// other processing in verilator. // other processing in verilator.
AstPragma(FileLine* fl, VPragmaType pragType) AstPragma(FileLine* fl, VPragmaType pragType)
: ASTGEN_SUPER_Pragma(fl) : ASTGEN_SUPER_Pragma(fl)
, m_pragType{pragType} {} , m_pragType{pragType} {}
AstPragma(FileLine* fl, VPragmaType pragType, const VTimescale& timescale)
: ASTGEN_SUPER_Pragma(fl)
, m_pragType{pragType}
, m_timescale(timescale) {}
ASTGEN_MEMBERS_AstPragma; ASTGEN_MEMBERS_AstPragma;
VPragmaType pragType() const { return m_pragType; } // *=type of the pragma VPragmaType pragType() const { return m_pragType; } // *=type of the pragma
bool isPredictOptimizable() const override { return false; } bool isPredictOptimizable() const override { return false; }
bool sameNode(const AstNode* samep) const override { bool sameNode(const AstNode* samep) const override {
return pragType() == VN_DBG_AS(samep, Pragma)->pragType(); return pragType() == VN_DBG_AS(samep, Pragma)->pragType();
} }
VTimescale timescale() const { return m_timescale; }
}; };
class AstPropSpec final : public AstNode { class AstPropSpec final : public AstNode {
// A clocked property // A clocked property

View File

@ -88,9 +88,24 @@ void V3LinkLevel::modSortByLevel() {
void V3LinkLevel::timescaling(const ModVec& mods) { void V3LinkLevel::timescaling(const ModVec& mods) {
// Timescale determination // Timescale determination
const AstNodeModule* modTimedp = nullptr; 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 // 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()) { if (!modTimedp && !modp->timeunit().isNone()) {
modTimedp = modp; modTimedp = modp;
unit = modTimedp->timeunit(); unit = modTimedp->timeunit();
@ -106,24 +121,24 @@ void V3LinkLevel::timescaling(const ModVec& mods) {
if (!upkgp->timeunit().isNone()) dunitTimed = true; if (!upkgp->timeunit().isNone()) dunitTimed = true;
} }
for (AstNodeModule* nodep : mods) { for (AstNodeModule* modp : mods) {
if (!v3Global.opt.timeOverrideUnit().isNone()) nodep->timeunit(unit); if (!v3Global.opt.timeOverrideUnit().isNone()) modp->timeunit(unit);
if (nodep->timeunit().isNone()) { if (modp->timeunit().isNone()) {
if (modTimedp // Got previous if (modTimedp // Got previous
&& !dunitTimed && !dunitTimed
&& ( // unit doesn't already include an override && ( // unit doesn't already include an override
v3Global.opt.timeOverrideUnit().isNone() v3Global.opt.timeOverrideUnit().isNone()
&& v3Global.opt.timeDefaultUnit().isNone()) && v3Global.opt.timeDefaultUnit().isNone())
&& nodep->timescaleMatters()) { && modp->timescaleMatters()) {
nodep->v3warn(TIMESCALEMOD, modp->v3warn(TIMESCALEMOD,
"Timescale missing on this module as other modules have " "Timescale missing on this module as other modules have "
"it (IEEE 1800-2023 3.14.2.3)\n" "it (IEEE 1800-2023 3.14.2.3)\n"
<< nodep->warnContextPrimary() << '\n' << modp->warnContextPrimary() << '\n'
<< modTimedp->warnOther() << modTimedp->warnOther()
<< "... Location of module with timescale\n" << "... Location of module with timescale\n"
<< modTimedp->warnContextSecondary()); << modTimedp->warnContextSecondary());
} }
nodep->timeunit(unit); modp->timeunit(unit);
} }
} }

View File

@ -126,8 +126,8 @@ void V3ParseImp::lexTimescaleParse(FileLine* fl, const char* textp) {
m_timeLastUnit = v3Global.opt.timeComputeUnit(unit); m_timeLastUnit = v3Global.opt.timeComputeUnit(unit);
v3Global.rootp()->timeprecisionMerge(fl, prec); v3Global.rootp()->timeprecisionMerge(fl, prec);
} }
void V3ParseImp::timescaleMod(FileLine* fl, AstNodeModule* modp, bool unitSet, double unitVal, AstPragma* V3ParseImp::createTimescale(FileLine* fl, bool unitSet, double unitVal, bool precSet,
bool precSet, double precVal) { double precVal) {
VTimescale unit{VTimescale::NONE}; VTimescale unit{VTimescale::NONE};
if (unitSet) { if (unitSet) {
bool bad; bool bad;
@ -146,16 +146,13 @@ void V3ParseImp::timescaleMod(FileLine* fl, AstNodeModule* modp, bool unitSet, d
fl->v3error("timeprecision illegal value"); fl->v3error("timeprecision illegal value");
} }
} }
if (!unit.isNone()) {
unit = v3Global.opt.timeComputeUnit(unit);
if (modp) {
modp->timeunit(unit);
} else {
v3Global.rootp()->timeunit(unit);
unitPackage(fl)->timeunit(unit);
}
}
v3Global.rootp()->timeprecisionMerge(fl, prec); v3Global.rootp()->timeprecisionMerge(fl, prec);
if (unit.isNone()) {
return nullptr;
} else {
unit = v3Global.opt.timeComputeUnit(unit);
return new AstPragma{fl, VPragmaType::TIMEUNIT_SET, unit};
}
} }
void V3ParseImp::lexVerilatorCmtLintSave(const FileLine* fl) { m_lexLintState.push_back(*fl); } void V3ParseImp::lexVerilatorCmtLintSave(const FileLine* fl) { m_lexLintState.push_back(*fl); }

View File

@ -181,8 +181,8 @@ public:
void tagNodep(AstNode* nodep) { m_tagNodep = nodep; } void tagNodep(AstNode* nodep) { m_tagNodep = nodep; }
AstNode* tagNodep() const { return m_tagNodep; } AstNode* tagNodep() const { return m_tagNodep; }
void lexTimescaleParse(FileLine* fl, const char* textp) VL_MT_DISABLED; void lexTimescaleParse(FileLine* fl, const char* textp) VL_MT_DISABLED;
void timescaleMod(FileLine* fl, AstNodeModule* modp, bool unitSet, double unitVal, AstPragma* createTimescale(FileLine* fl, bool unitSet, double unitVal, bool precSet,
bool precSet, double precVal) VL_MT_DISABLED; double precVal) VL_MT_DISABLED;
VTimescale timeLastUnit() const { return m_timeLastUnit; } VTimescale timeLastUnit() const { return m_timeLastUnit; }
void lexFileline(FileLine* fl) { m_lexFileline = fl; } void lexFileline(FileLine* fl) { m_lexFileline = fl; }

View File

@ -1227,14 +1227,11 @@ description: // ==IEEE: description
timeunits_declaration<nodep>: // ==IEEE: timeunits_declaration timeunits_declaration<nodep>: // ==IEEE: timeunits_declaration
yTIMEUNIT yaTIMENUM ';' yTIMEUNIT yaTIMENUM ';'
{ PARSEP->timescaleMod($<fl>2, SYMP->findTopNodeModule($<fl>1, false), true, $2, false, 0); { $$ = PARSEP->createTimescale($<fl>2, true, $2, false, 0); }
$$ = nullptr; }
| yTIMEUNIT yaTIMENUM '/' yaTIMENUM ';' | yTIMEUNIT yaTIMENUM '/' yaTIMENUM ';'
{ PARSEP->timescaleMod($<fl>2, SYMP->findTopNodeModule($<fl>1, false), true, $2, true, $4); { $$ = PARSEP->createTimescale($<fl>2, true, $2, true, $4); }
$$ = nullptr; }
| yTIMEPRECISION yaTIMENUM ';' | yTIMEPRECISION yaTIMENUM ';'
{ PARSEP->timescaleMod($<fl>2, SYMP->findTopNodeModule($<fl>1, false), false, 0, true, $2); { $$ = PARSEP->createTimescale($<fl>2, false, 0, true, $2); }
$$ = nullptr; }
; ;
//********************************************************************** //**********************************************************************