mirror of
https://github.com/verilator/verilator.git
synced 2026-10-06 10:03:44 +02:00
Internals: Move wrapTop before V3Coverage (#8291)
This commit is contained in:
+4
-4
@@ -433,20 +433,20 @@ class AssertVisitor final : public VNVisitor {
|
||||
if (!m_monitorNumVarp) {
|
||||
m_monitorNumVarp = new AstVar{nodep->fileline(), VVarType::MODULETEMP, "__VmonitorNum",
|
||||
nodep->findUInt64DType()};
|
||||
v3Global.rootp()->dollarUnitPkgAddp()->addStmtsp(m_monitorNumVarp);
|
||||
v3Global.rootp()->dollarUnitPkgp()->addStmtsp(m_monitorNumVarp);
|
||||
}
|
||||
AstVarRef* const varrefp = new AstVarRef{nodep->fileline(), m_monitorNumVarp, access};
|
||||
varrefp->classOrPackagep(v3Global.rootp()->dollarUnitPkgAddp());
|
||||
varrefp->classOrPackagep(v3Global.rootp()->dollarUnitPkgp());
|
||||
return varrefp;
|
||||
}
|
||||
AstVarRef* newMonitorOffVarRefp(const AstNode* nodep, VAccess access) {
|
||||
if (!m_monitorOffVarp) {
|
||||
m_monitorOffVarp = new AstVar{nodep->fileline(), VVarType::MODULETEMP, "__VmonitorOff",
|
||||
nodep->findBitDType()};
|
||||
v3Global.rootp()->dollarUnitPkgAddp()->addStmtsp(m_monitorOffVarp);
|
||||
v3Global.rootp()->dollarUnitPkgp()->addStmtsp(m_monitorOffVarp);
|
||||
}
|
||||
AstVarRef* const varrefp = new AstVarRef{nodep->fileline(), m_monitorOffVarp, access};
|
||||
varrefp->classOrPackagep(v3Global.rootp()->dollarUnitPkgAddp());
|
||||
varrefp->classOrPackagep(v3Global.rootp()->dollarUnitPkgp());
|
||||
return varrefp;
|
||||
}
|
||||
static AstIf* newIfAssertOn(AstNode* bodyp, VAssertDirectiveType directiveType,
|
||||
|
||||
@@ -313,7 +313,6 @@ class AstNodeModule VL_NOT_FINAL : public AstNode {
|
||||
bool m_hasParameterList : 1; // Has #() for parameter declaration
|
||||
bool m_hierBlock : 1; // Hierarchical Block marked by HIER_BLOCK pragma
|
||||
bool m_hierParams : 1; // Block containing params for parameterized hier blocks
|
||||
bool m_internal : 1; // Internally created
|
||||
bool m_recursive : 1; // Recursive module
|
||||
bool m_recursiveClone : 1; // If recursive, what module it clones, otherwise nullptr
|
||||
bool m_parameterizedTemplate : 1; // True when at least one specialized clone exists;
|
||||
@@ -335,7 +334,6 @@ protected:
|
||||
, m_hasParameterList{false}
|
||||
, m_hierBlock{false}
|
||||
, m_hierParams{false}
|
||||
, m_internal{false}
|
||||
, m_recursive{false}
|
||||
, m_recursiveClone{false}
|
||||
, m_parameterizedTemplate{false}
|
||||
@@ -379,8 +377,6 @@ public:
|
||||
void hierBlock(bool flag) { m_hierBlock = flag; }
|
||||
bool hierParams() const { return m_hierParams; }
|
||||
void hierParams(bool flag) { m_hierParams = flag; }
|
||||
bool internal() const { return m_internal; }
|
||||
void internal(bool flag) { m_internal = flag; }
|
||||
bool recursive() const { return m_recursive; }
|
||||
void recursive(bool flag) { m_recursive = flag; }
|
||||
void recursiveClone(bool flag) { m_recursiveClone = flag; }
|
||||
@@ -1492,7 +1488,7 @@ public:
|
||||
void astConstOrigParamName(const AstConst* nodep, const string& name);
|
||||
void astConstOrigParamNameErase(const AstConst* nodep);
|
||||
AstPackage* dollarUnitPkgp() const { return m_dollarUnitPkgp; }
|
||||
AstPackage* dollarUnitPkgAddp();
|
||||
void dollarUnitPkgp(AstPackage* const packagep) { m_dollarUnitPkgp = packagep; }
|
||||
AstCFunc* evalFuncp(VEval eval) const { return m_evalFuncps[eval]; }
|
||||
void evalFuncp(VEval eval, AstCFunc* funcp) { m_evalFuncps[eval] = funcp; }
|
||||
AstCFunc* dumpTriggersFuncp(VEval eval) const { return m_dumpTriggersFuncps[eval]; }
|
||||
|
||||
+7
-13
@@ -1863,9 +1863,15 @@ AstNodeBiop* AstNeq::newTyped(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp
|
||||
AstNetlist::AstNetlist()
|
||||
: ASTGEN_SUPER_Netlist(new FileLine{FileLine::builtInFilename()})
|
||||
, m_typeTablep{new AstTypeTable{fileline()}}
|
||||
, m_constPoolp{new AstConstPool{fileline()}} {
|
||||
, m_constPoolp{new AstConstPool{fileline()}}
|
||||
, m_dollarUnitPkgp{new AstPackage{fileline(), AstPackage::dollarUnitName(), "work"}} {
|
||||
addMiscsp(m_typeTablep);
|
||||
addMiscsp(m_constPoolp);
|
||||
// packages are always libraries; don't want to make them a "top"
|
||||
m_dollarUnitPkgp->level(1);
|
||||
m_dollarUnitPkgp->inLibrary(true);
|
||||
m_dollarUnitPkgp->modTrace(false); // may reconsider later
|
||||
addModulesp(m_dollarUnitPkgp);
|
||||
}
|
||||
void AstNetlist::addEvalStats(const std::string& phase) {
|
||||
if (!v3Global.opt.stats()) return;
|
||||
@@ -1932,18 +1938,6 @@ void AstNetlist::deleteContents() {
|
||||
if (op4p()) op4p()->unlinkFrBackWithNext()->deleteTree();
|
||||
#undef VN_DELETE_ONE
|
||||
}
|
||||
AstPackage* AstNetlist::dollarUnitPkgAddp() {
|
||||
if (!m_dollarUnitPkgp) {
|
||||
m_dollarUnitPkgp = new AstPackage{fileline(), AstPackage::dollarUnitName(), "work"};
|
||||
// packages are always libraries; don't want to make them a "top"
|
||||
m_dollarUnitPkgp->level(1);
|
||||
m_dollarUnitPkgp->inLibrary(true);
|
||||
m_dollarUnitPkgp->modTrace(false); // may reconsider later
|
||||
m_dollarUnitPkgp->internal(true);
|
||||
addModulesp(m_dollarUnitPkgp);
|
||||
}
|
||||
return m_dollarUnitPkgp;
|
||||
}
|
||||
void AstNetlist::dump(std::ostream& str) const {
|
||||
Super::dump(str);
|
||||
if (timescaleSpecified()) str << " [TIMESCALES]";
|
||||
|
||||
+1
-1
@@ -283,7 +283,7 @@ class CoverageVisitor final : public VNVisitor {
|
||||
VL_RESTORER_COPY(m_funcTemps);
|
||||
createHandle(nodep);
|
||||
m_modp = nodep;
|
||||
m_state.m_inModOff = false; // Haven't made top shell, so tops are real tops
|
||||
m_state.m_inModOff = nodep->isTop(); // Already made top shell, no coverage for it
|
||||
if (!origModp) {
|
||||
// No blocks cross (non-nested) modules, so save some memory
|
||||
m_varnames.clear();
|
||||
|
||||
+7
-1
@@ -400,7 +400,10 @@ class DeadVisitor final : public VNVisitor {
|
||||
AstNodeModule* nextmodp;
|
||||
for (AstNodeModule* modp = v3Global.rootp()->modulesp(); modp; modp = nextmodp) {
|
||||
nextmodp = VN_AS(modp->nextp(), NodeModule);
|
||||
if (modp->dead() || (!modp->isTop() && modp->user1() == 0 && !modp->internal())) {
|
||||
// Keep $unit until m_elimCells stages. Note v3Global.opt.serializeOnly()
|
||||
// won't reach this stage, and will always have an empty $unit. That's ok.
|
||||
const bool keep = !m_elimCells && modp == v3Global.rootp()->dollarUnitPkgp();
|
||||
if (modp->dead() || (!modp->isTop() && modp->user1() == 0 && !keep)) {
|
||||
// > 2 because L1 is the wrapper, L2 is the top user module
|
||||
UINFO(4, " Dead module " << modp);
|
||||
// And its children may now be killable too; correct counts
|
||||
@@ -410,6 +413,9 @@ class DeadVisitor final : public VNVisitor {
|
||||
cellp->modp()->user1Inc(-1);
|
||||
});
|
||||
}
|
||||
if (modp == v3Global.rootp()->dollarUnitPkgp()) {
|
||||
v3Global.rootp()->dollarUnitPkgp(nullptr);
|
||||
}
|
||||
deleting(modp);
|
||||
retry = true;
|
||||
}
|
||||
|
||||
+1
-1
@@ -467,7 +467,7 @@ class LinkCellsVisitor final : public VNVisitor {
|
||||
if (nodep->fileline()->filebasenameNoExt() != nodep->prettyName()
|
||||
&& !v3Global.opt.isLibraryFile(nodep->fileline()->filename(), nodep->libname())
|
||||
&& !VN_IS(nodep, NotFoundModule) && !nodep->recursiveClone()
|
||||
&& !nodep->internal()) {
|
||||
&& nodep != v3Global.rootp()->dollarUnitPkgp()) {
|
||||
// We only complain once per file, otherwise library-like files
|
||||
// have a huge mess of warnings
|
||||
const auto itFoundPair = m_declfnWarned.insert(nodep->fileline()->filename());
|
||||
|
||||
+9
-2
@@ -1216,7 +1216,14 @@ class LinkDotFindVisitor final : public VNVisitor {
|
||||
// (sorted before this is called).
|
||||
// This may not be the module with isTop() set, as early in the steps,
|
||||
// wrapTop may have not been created yet.
|
||||
if (!nodep->modulesp()) nodep->v3error("No top level module found");
|
||||
// $unit always exists, so nothing else, and nothing in it, means nothing was given
|
||||
AstNodeModule* const modulesp = nodep->modulesp();
|
||||
UASSERT_OBJ(modulesp, nodep, "$unit should always be in the netlist");
|
||||
if (!modulesp->nextp()) {
|
||||
UASSERT_OBJ(modulesp == v3Global.rootp()->dollarUnitPkgp(), modulesp,
|
||||
"Sole module should be $unit");
|
||||
if (!modulesp->stmtsp()) nodep->v3error("No top level module found");
|
||||
}
|
||||
for (AstNodeModule* modp = nodep->modulesp(); modp && modp->isTop();
|
||||
modp = VN_AS(modp->nextp(), NodeModule)) {
|
||||
UINFO(8, "Top Module: " << modp);
|
||||
@@ -1405,7 +1412,7 @@ class LinkDotFindVisitor final : public VNVisitor {
|
||||
}
|
||||
void visit(AstClassOrPackageRef* nodep) override { // FindVisitor::
|
||||
if (!nodep->classOrPackageNodep() && nodep->name() == "$unit") {
|
||||
nodep->classOrPackageNodep(v3Global.rootp()->dollarUnitPkgAddp());
|
||||
nodep->classOrPackageNodep(v3Global.rootp()->dollarUnitPkgp());
|
||||
}
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
|
||||
+2
-2
@@ -211,7 +211,7 @@ class LinkJumpVisitor final : public VNVisitor {
|
||||
if (!processQueuep->lifetime().isStatic() || processQueuep->isTemp()) {
|
||||
return new AstVarRef{fl, processQueuep, access};
|
||||
}
|
||||
AstPackage* const topPkgp = v3Global.rootp()->dollarUnitPkgAddp();
|
||||
AstPackage* const topPkgp = v3Global.rootp()->dollarUnitPkgp();
|
||||
return new AstVarRef{fl, topPkgp, processQueuep, access};
|
||||
}
|
||||
static AstStmtExpr* getQueuePushProcessSelfp(FileLine* const fl, AstVar* const processQueuep) {
|
||||
@@ -275,7 +275,7 @@ class LinkJumpVisitor final : public VNVisitor {
|
||||
AstNodeModule* const ownerp = findOwnerModulep(nodep);
|
||||
|
||||
if (VN_IS(ownerp, Package) || VN_IS(ownerp, Class)) {
|
||||
AstPackage* const topPkgp = v3Global.rootp()->dollarUnitPkgAddp();
|
||||
AstPackage* const topPkgp = v3Global.rootp()->dollarUnitPkgp();
|
||||
AstVar* const processQueuep = newProcessQueuep(nodep, fl, VVarType::VAR);
|
||||
processQueuep->lifetime(VLifetime::STATIC_EXPLICIT);
|
||||
topPkgp->addStmtsp(processQueuep);
|
||||
|
||||
+1
-1
@@ -291,7 +291,7 @@ public:
|
||||
size_t flexPpInputToLex(char* buf, size_t max_size) { return ppInputToLex(buf, max_size); }
|
||||
|
||||
//==== Symbol tables
|
||||
AstPackage* unitPackage(FileLine* /*fl*/) { return parsep()->rootp()->dollarUnitPkgAddp(); }
|
||||
AstPackage* unitPackage(FileLine* /*fl*/) { return parsep()->rootp()->dollarUnitPkgp(); }
|
||||
|
||||
// CONSTRUCTORS
|
||||
V3ParseImp(AstNetlist* rootp, VInFilter* filterp)
|
||||
|
||||
+2
-2
@@ -4006,7 +4006,7 @@ class RandomizeVisitor final : public VNVisitor {
|
||||
varp->isStatic(true);
|
||||
varp->valuep(initp);
|
||||
// Add to root, as don't know module we are in, and aids later structure sharing
|
||||
v3Global.rootp()->dollarUnitPkgAddp()->addStmtsp(varp);
|
||||
v3Global.rootp()->dollarUnitPkgp()->addStmtsp(varp);
|
||||
|
||||
UASSERT_OBJ(nodep->itemsp(), nodep, "Enum without items");
|
||||
for (AstEnumItem* itemp = nodep->itemsp(); itemp;
|
||||
@@ -4179,7 +4179,7 @@ class RandomizeVisitor final : public VNVisitor {
|
||||
EnumDType)) {
|
||||
AstVarRef* const tabRefp
|
||||
= new AstVarRef{fl, enumValueTabp(enumDtp), VAccess::READ};
|
||||
tabRefp->classOrPackagep(v3Global.rootp()->dollarUnitPkgAddp());
|
||||
tabRefp->classOrPackagep(v3Global.rootp()->dollarUnitPkgp());
|
||||
AstNodeExpr* const randp
|
||||
= newRandValue(fl, randcVarp, exprp->findBasicDType(VBasicDTypeKwd::UINT32));
|
||||
AstNodeExpr* const moddivp = new AstModDiv{
|
||||
|
||||
+3
-3
@@ -9928,7 +9928,7 @@ class WidthVisitor final : public VNVisitor {
|
||||
varp->isStatic(true);
|
||||
varp->valuep(initp);
|
||||
// Add to root, as don't know module we are in, and aids later structure sharing
|
||||
v3Global.rootp()->dollarUnitPkgAddp()->addStmtsp(varp);
|
||||
v3Global.rootp()->dollarUnitPkgp()->addStmtsp(varp);
|
||||
// Element 0 is a non-index and has speced values
|
||||
initp->addValuep(dimensionValue(nodep->fileline(), nodep, attrType, 0));
|
||||
for (unsigned i = 1; i < msbdim + 1; ++i) {
|
||||
@@ -9997,7 +9997,7 @@ class WidthVisitor final : public VNVisitor {
|
||||
varp->isStatic(true);
|
||||
varp->valuep(initp);
|
||||
// Add to root, as don't know module we are in, and aids later structure sharing
|
||||
v3Global.rootp()->dollarUnitPkgAddp()->addStmtsp(varp);
|
||||
v3Global.rootp()->dollarUnitPkgp()->addStmtsp(varp);
|
||||
|
||||
// Default for all unspecified values
|
||||
if (attrType == VAttrType::ENUM_NAME) {
|
||||
@@ -10294,7 +10294,7 @@ class WidthVisitor final : public VNVisitor {
|
||||
}
|
||||
static AstVarRef* newVarRefDollarUnit(AstVar* nodep) {
|
||||
AstVarRef* const varrefp = new AstVarRef{nodep->fileline(), nodep, VAccess::READ};
|
||||
varrefp->classOrPackagep(v3Global.rootp()->dollarUnitPkgAddp());
|
||||
varrefp->classOrPackagep(v3Global.rootp()->dollarUnitPkgp());
|
||||
return varrefp;
|
||||
}
|
||||
AstNode* nodeForUnsizedWarning(AstNode* nodep) {
|
||||
|
||||
+16
-14
@@ -233,11 +233,22 @@ static void process() {
|
||||
v3Global.vlExit(0);
|
||||
}
|
||||
|
||||
// Insert generic non-FSM coverage before dead code elimination and
|
||||
// inlining, or those opportunities may be optimized away. FSM
|
||||
// coverage is handled later in V3FsmDetect, after scoping has created
|
||||
// the AST context needed to recover and lower FSMs reliably.
|
||||
if (v3Global.opt.coverageNonFsm()) V3Coverage::coverage(v3Global.rootp());
|
||||
if (!v3Global.opt.serializeOnly() || v3Global.opt.flatten()) {
|
||||
// Add top level wrapper with instance pointing to old top
|
||||
// Move packages to under new top
|
||||
// Must do this after we know parameters and dtypes (as don't clone dtype decls)
|
||||
V3LinkLevel::wrapTop(v3Global.rootp());
|
||||
} else {
|
||||
V3LinkLevel::nonWrapTop(v3Global.rootp());
|
||||
}
|
||||
|
||||
if (!v3Global.opt.serializeOnly()) {
|
||||
// Insert generic code coverage before dead code elimination and
|
||||
// inlining, or those opportunities may be optimized away. FSM
|
||||
// coverage is handled later in V3FsmDetect, after scoping has created
|
||||
// the AST context needed to recover and lower FSMs reliably.
|
||||
if (v3Global.opt.coverageNonFsm()) V3Coverage::coverage(v3Global.rootp());
|
||||
}
|
||||
|
||||
// Functional coverage code generation
|
||||
// Generate code for covergroups/coverpoints
|
||||
@@ -268,15 +279,6 @@ static void process() {
|
||||
//
|
||||
V3Assert::assertAll(v3Global.rootp());
|
||||
|
||||
if (!(v3Global.opt.serializeOnly() && !v3Global.opt.flatten())) {
|
||||
// Add top level wrapper with instance pointing to old top
|
||||
// Move packages to under new top
|
||||
// Must do this after we know parameters and dtypes (as don't clone dtype decls)
|
||||
V3LinkLevel::wrapTop(v3Global.rootp());
|
||||
} else {
|
||||
V3LinkLevel::nonWrapTop(v3Global.rootp());
|
||||
}
|
||||
|
||||
// Propagate constants into expressions
|
||||
if (v3Global.opt.fConstBeforeDfg()) V3Const::constifyAllLint(v3Global.rootp());
|
||||
|
||||
|
||||
Reference in New Issue
Block a user