Internals: Move timeunit to pragma, in prep for future parser. No user-functional change intended.
This commit is contained in:
parent
2ed754d5ea
commit
da5eb620bf
|
|
@ -336,6 +336,7 @@ public:
|
|||
NO_INLINE_TASK,
|
||||
PUBLIC_MODULE,
|
||||
PUBLIC_TASK,
|
||||
TIMEUNIT_SET,
|
||||
UNROLL_DISABLE,
|
||||
UNROLL_FULL,
|
||||
FULL_CASE,
|
||||
|
|
|
|||
|
|
@ -1494,18 +1494,24 @@ public:
|
|||
};
|
||||
class AstPragma final : public AstNode {
|
||||
const VPragmaType m_pragType; // Type of pragma
|
||||
const VTimescale m_timescale; // For TIMEUNIT_SET
|
||||
public:
|
||||
// Pragmas don't result in any output code, they're just flags that affect
|
||||
// other processing in verilator.
|
||||
AstPragma(FileLine* fl, VPragmaType pragType)
|
||||
: ASTGEN_SUPER_Pragma(fl)
|
||||
, m_pragType{pragType} {}
|
||||
AstPragma(FileLine* fl, VPragmaType pragType, const VTimescale& timescale)
|
||||
: ASTGEN_SUPER_Pragma(fl)
|
||||
, m_pragType{pragType}
|
||||
, m_timescale(timescale) {}
|
||||
ASTGEN_MEMBERS_AstPragma;
|
||||
VPragmaType pragType() const { return m_pragType; } // *=type of the pragma
|
||||
bool isPredictOptimizable() const override { return false; }
|
||||
bool sameNode(const AstNode* samep) const override {
|
||||
return pragType() == VN_DBG_AS(samep, Pragma)->pragType();
|
||||
}
|
||||
VTimescale timescale() const { return m_timescale; }
|
||||
};
|
||||
class AstPropSpec final : public AstNode {
|
||||
// A clocked property
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -126,8 +126,8 @@ void V3ParseImp::lexTimescaleParse(FileLine* fl, const char* textp) {
|
|||
m_timeLastUnit = v3Global.opt.timeComputeUnit(unit);
|
||||
v3Global.rootp()->timeprecisionMerge(fl, prec);
|
||||
}
|
||||
void V3ParseImp::timescaleMod(FileLine* fl, AstNodeModule* modp, bool unitSet, double unitVal,
|
||||
bool precSet, double precVal) {
|
||||
AstPragma* V3ParseImp::createTimescale(FileLine* fl, bool unitSet, double unitVal, bool precSet,
|
||||
double precVal) {
|
||||
VTimescale unit{VTimescale::NONE};
|
||||
if (unitSet) {
|
||||
bool bad;
|
||||
|
|
@ -146,16 +146,13 @@ void V3ParseImp::timescaleMod(FileLine* fl, AstNodeModule* modp, bool unitSet, d
|
|||
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);
|
||||
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); }
|
||||
|
|
|
|||
|
|
@ -181,8 +181,8 @@ public:
|
|||
void tagNodep(AstNode* nodep) { m_tagNodep = nodep; }
|
||||
AstNode* tagNodep() const { return m_tagNodep; }
|
||||
void lexTimescaleParse(FileLine* fl, const char* textp) VL_MT_DISABLED;
|
||||
void timescaleMod(FileLine* fl, AstNodeModule* modp, bool unitSet, double unitVal,
|
||||
bool precSet, double precVal) VL_MT_DISABLED;
|
||||
AstPragma* createTimescale(FileLine* fl, bool unitSet, double unitVal, bool precSet,
|
||||
double precVal) VL_MT_DISABLED;
|
||||
VTimescale timeLastUnit() const { return m_timeLastUnit; }
|
||||
|
||||
void lexFileline(FileLine* fl) { m_lexFileline = fl; }
|
||||
|
|
|
|||
|
|
@ -1227,14 +1227,11 @@ description: // ==IEEE: description
|
|||
|
||||
timeunits_declaration<nodep>: // ==IEEE: timeunits_declaration
|
||||
yTIMEUNIT yaTIMENUM ';'
|
||||
{ PARSEP->timescaleMod($<fl>2, SYMP->findTopNodeModule($<fl>1, false), true, $2, false, 0);
|
||||
$$ = nullptr; }
|
||||
{ $$ = PARSEP->createTimescale($<fl>2, true, $2, false, 0); }
|
||||
| yTIMEUNIT yaTIMENUM '/' yaTIMENUM ';'
|
||||
{ PARSEP->timescaleMod($<fl>2, SYMP->findTopNodeModule($<fl>1, false), true, $2, true, $4);
|
||||
$$ = nullptr; }
|
||||
{ $$ = PARSEP->createTimescale($<fl>2, true, $2, true, $4); }
|
||||
| yTIMEPRECISION yaTIMENUM ';'
|
||||
{ PARSEP->timescaleMod($<fl>2, SYMP->findTopNodeModule($<fl>1, false), false, 0, true, $2);
|
||||
$$ = nullptr; }
|
||||
{ $$ = PARSEP->createTimescale($<fl>2, false, 0, true, $2); }
|
||||
;
|
||||
|
||||
//**********************************************************************
|
||||
|
|
|
|||
Loading…
Reference in New Issue