diff --git a/src/V3Coverage.cpp b/src/V3Coverage.cpp index c5710190c..8e63fc25f 100644 --- a/src/V3Coverage.cpp +++ b/src/V3Coverage.cpp @@ -64,6 +64,7 @@ private: bool m_checkBlock; // Should this block get covered? AstNodeModule* m_modp; // Current module to add statement to bool m_inToggleOff; // In function/task etc + bool m_inModOff; // In module with no coverage FileMap m_fileps; // Column counts for each fileline string m_beginHier; // AstBegin hier name for user coverage points @@ -124,9 +125,11 @@ private: // VISITORS - BOTH virtual void visit(AstNodeModule* nodep, AstNUser*) { m_modp = nodep; + m_inModOff = nodep->isTop(); // Ignore coverage on top module; it's a shell we created m_fileps.clear(); nodep->iterateChildren(*this); m_modp = NULL; + m_inModOff = true; } // VISITORS - TOGGLE COVERAGE @@ -140,7 +143,7 @@ private: } virtual void visit(AstVar* nodep, AstNUser*) { nodep->iterateChildren(*this); - if (m_modp && !m_inToggleOff + if (m_modp && !m_inModOff && !m_inToggleOff && nodep->fileline()->coverageOn() && v3Global.opt.coverageToggle()) { const char* disablep = varIgnoreToggle(nodep); if (disablep) { @@ -231,7 +234,7 @@ private: UINFO(4," IF: "<ifsp()->iterateAndNext(*this); - if (m_checkBlock + if (m_checkBlock && !m_inModOff && nodep->fileline()->coverageOn() && v3Global.opt.coverageLine()) { // if a "if" branch didn't disable it if (!nodep->backp()->castIf() || nodep->backp()->castIf()->elsesp()!=nodep) { // Ignore if else; did earlier @@ -243,7 +246,7 @@ private: if (nodep->elsesp()) { m_checkBlock = true; nodep->elsesp()->iterateAndNext(*this); - if (m_checkBlock + if (m_checkBlock && !m_inModOff && nodep->fileline()->coverageOn() && v3Global.opt.coverageLine()) { // if a "else" branch didn't disable it UINFO(4," COVER: "<elsesp()->castIf()) { @@ -258,7 +261,7 @@ private: } virtual void visit(AstCaseItem* nodep, AstNUser*) { UINFO(4," CASEI: "<fileline()->coverageOn() && v3Global.opt.coverageLine()) { nodep->bodysp()->iterateAndNext(*this); if (m_checkBlock) { // if the case body didn't disable it @@ -327,6 +330,7 @@ public: m_checkBlock = true; m_beginHier = ""; m_inToggleOff = false; + m_inModOff = true; rootp->iterateChildren(*this); } virtual ~CoverageVisitor() {} diff --git a/src/V3LinkLevel.cpp b/src/V3LinkLevel.cpp index 37020c9ce..98291841e 100644 --- a/src/V3LinkLevel.cpp +++ b/src/V3LinkLevel.cpp @@ -95,6 +95,18 @@ void V3LinkLevel::wrapTop(AstNetlist* netlistp) { newmodp->modPublic(true); netlistp->addModulep(newmodp); + // TODO the module creation above could be done after linkcells, but + // the rest must be done after data type resolution + wrapTopCell(netlistp); + wrapTopPackages(netlistp); +} + +void V3LinkLevel::wrapTopCell(AstNetlist* netlistp) { + AstNodeModule* newmodp = netlistp->modulesp(); + if (!newmodp || !newmodp->isTop()) netlistp->v3fatalSrc("No TOP module found to process"); + AstNodeModule* oldmodp = newmodp->nextp()->castNodeModule(); + if (!oldmodp) netlistp->v3fatalSrc("No module found to process"); + // Add instance AstCell* cellp = new AstCell(newmodp->fileline(), (v3Global.opt.l2Name() ? "v" : oldmodp->name()), @@ -126,13 +138,13 @@ void V3LinkLevel::wrapTop(AstNetlist* netlistp) { } } } - - wrapTopPackages(netlistp, newmodp); } -void V3LinkLevel::wrapTopPackages(AstNetlist* netlistp, AstNodeModule* newmodp) { +void V3LinkLevel::wrapTopPackages(AstNetlist* netlistp) { // Instantiate all packages under the top wrapper // This way all later SCOPE based optimizations can ignore packages + AstNodeModule* newmodp = netlistp->modulesp(); + if (!newmodp || !newmodp->isTop()) netlistp->v3fatalSrc("No TOP module found to process"); for (AstNodeModule* modp = netlistp->modulesp(); modp; modp=modp->nextp()->castNodeModule()) { if (modp->castPackage()) { AstCell* cellp = new AstCell(modp->fileline(), diff --git a/src/V3LinkLevel.h b/src/V3LinkLevel.h index da8f89c0c..8fbdf15da 100644 --- a/src/V3LinkLevel.h +++ b/src/V3LinkLevel.h @@ -29,7 +29,8 @@ class V3LinkLevel { private: - static void wrapTopPackages(AstNetlist* nodep, AstNodeModule* newmodp); + static void wrapTopCell(AstNetlist* nodep); + static void wrapTopPackages(AstNetlist* nodep); public: static void modSortByLevel(); static void wrapTop(AstNetlist* nodep); diff --git a/src/Verilator.cpp b/src/Verilator.cpp index e8da2f6d9..8b6224ecd 100644 --- a/src/Verilator.cpp +++ b/src/Verilator.cpp @@ -228,8 +228,7 @@ void process () { if (!v3Global.opt.xmlOnly()) { // Add top level wrapper with instance pointing to old top // Move packages to under new top - // Must do this after we know the width of any parameters - // We also do it after coverage/assertion insertion so we don't 'cover' the top level. + // Must do this after we know parameters and dtypes (as don't clone dtype decls) V3LinkLevel::wrapTop(v3Global.rootp()); }