diff --git a/Changes b/Changes index ce2f1c88d..8f926736d 100644 --- a/Changes +++ b/Changes @@ -9,6 +9,8 @@ indicates the contributor was also the author of the fix; Thanks! *** Add --clk and related optimizations, msg1533. [Jie Xu] +**** Add --dump-treei-, bug894. [Jie Xu] + **** Fix comma-instantiations with parameters, bug884. [Franck Jullien] **** Fix SystemC arrayed bit vectors, bug886. [David Poole] diff --git a/bin/verilator b/bin/verilator index b5a60dba8..e0367ce7e 100755 --- a/bin/verilator +++ b/bin/verilator @@ -263,6 +263,7 @@ descriptions in the next sections for more information. +define+= Set preprocessor define --dump-tree Enable dumping .tree files --dump-treei Enable dumping .tree files at a level + --dump-treei- Enable dumping .tree file at a source file at a level -E Preprocess, but do not compile --error-limit Abort after this number of errors --exe Link to create executable @@ -592,7 +593,7 @@ alias for GCC compatibility. Select the debug built image of Verilator (if available), and enable more internal assertions (equivelent to C<--debug-check>), debugging messages (equivelent to C<--debugi 4>), and intermediate form dump files (equivilent -to C<--dump-tree>). +to C<--dump-treei 3>). =item --debug-check @@ -645,8 +646,12 @@ large and not desired. =item --dump-treei -Rarely needed. Enable writing .tree debug files with a specific dumping -level, 0 disbles dumps and is equivalent to "--no-dump-tree". Level 9 +=item --dump-treei- + +Rarely needed - for developer use. Set internal tree dumping level +globally to a specific dumping level or set the specified Verilator source +file to the specified tree dumping level (e.g. C<--dump-treei-V3Order 9>). +Level 0 disbles dumps and is equivalent to "--no-dump-tree". Level 9 enables dumping of every stage. =item -E diff --git a/src/V3Active.cpp b/src/V3Active.cpp index 220375d5e..5a215bf02 100644 --- a/src/V3Active.cpp +++ b/src/V3Active.cpp @@ -436,4 +436,5 @@ public: void V3Active::activeAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } diff --git a/src/V3ActiveTop.cpp b/src/V3ActiveTop.cpp index c01ea74d6..264876f38 100644 --- a/src/V3ActiveTop.cpp +++ b/src/V3ActiveTop.cpp @@ -160,4 +160,5 @@ public: void V3ActiveTop::activeTopAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } diff --git a/src/V3Assert.cpp b/src/V3Assert.cpp index baa846ed1..7b7d96a1f 100644 --- a/src/V3Assert.cpp +++ b/src/V3Assert.cpp @@ -337,4 +337,5 @@ public: void V3Assert::assertAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } diff --git a/src/V3AssertPre.cpp b/src/V3AssertPre.cpp index ee4a56b5c..c4fa770d8 100644 --- a/src/V3AssertPre.cpp +++ b/src/V3AssertPre.cpp @@ -137,4 +137,5 @@ public: void V3AssertPre::assertPreAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } diff --git a/src/V3Ast.cpp b/src/V3Ast.cpp index ec3b6476c..43da4b077 100644 --- a/src/V3Ast.cpp +++ b/src/V3Ast.cpp @@ -1013,7 +1013,7 @@ void AstNode::dumpTreeAndNext(ostream& os, const string& indent, int maxDepth) { } void AstNode::dumpTreeFile(const string& filename, bool append, bool doDump) { - if (v3Global.opt.dumpTree() && doDump) { + if (doDump) { { // Write log & close UINFO(2,"Dumping "< logsp (V3File::new_ofstream(filename, append)); diff --git a/src/V3Begin.cpp b/src/V3Begin.cpp index d9d9bf533..ba7f89fa2 100644 --- a/src/V3Begin.cpp +++ b/src/V3Begin.cpp @@ -271,4 +271,5 @@ void V3Begin::debeginAll(AstNetlist* nodep) { if (state.anyFuncInBegin()) { BeginRelinkVisitor brvisitor (nodep,&state); } + V3Global::dumpCheckGlobalTree("begin.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3); } diff --git a/src/V3Case.cpp b/src/V3Case.cpp index badf50b29..01cef885d 100644 --- a/src/V3Case.cpp +++ b/src/V3Case.cpp @@ -491,6 +491,7 @@ public: void V3Case::caseAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } void V3Case::caseLint(AstNodeCase* nodep) { UINFO(4,__FUNCTION__<<": "<= 3); } diff --git a/src/V3Changed.cpp b/src/V3Changed.cpp index f2e637a74..60558aeeb 100644 --- a/src/V3Changed.cpp +++ b/src/V3Changed.cpp @@ -252,4 +252,5 @@ void V3Changed::changedAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } diff --git a/src/V3Clean.cpp b/src/V3Clean.cpp index 720f84f73..192c245d5 100644 --- a/src/V3Clean.cpp +++ b/src/V3Clean.cpp @@ -292,4 +292,5 @@ public: void V3Clean::cleanAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } diff --git a/src/V3ClkGater.cpp b/src/V3ClkGater.cpp index 7773573b9..b9945a54a 100644 --- a/src/V3ClkGater.cpp +++ b/src/V3ClkGater.cpp @@ -914,4 +914,5 @@ void V3ClkGater::clkGaterAll(AstNetlist* nodep) { // While the gater does well at some modules, it seems to slow down many others UINFO(5,"ClkGater is disabled due to performance issues\n"); //GaterVisitor visitor (nodep); + V3Global::dumpCheckGlobalTree("clkgater.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3); } diff --git a/src/V3Clock.cpp b/src/V3Clock.cpp index c62267160..ef1c08e39 100644 --- a/src/V3Clock.cpp +++ b/src/V3Clock.cpp @@ -407,4 +407,5 @@ public: void V3Clock::clockAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } diff --git a/src/V3Combine.cpp b/src/V3Combine.cpp index 6b7bd50a1..9ee44d537 100644 --- a/src/V3Combine.cpp +++ b/src/V3Combine.cpp @@ -474,4 +474,5 @@ public: void V3Combine::combineAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } diff --git a/src/V3Const.cpp b/src/V3Const.cpp index 262916978..2f2ba5341 100644 --- a/src/V3Const.cpp +++ b/src/V3Const.cpp @@ -2383,12 +2383,14 @@ void V3Const::constifyAllLint(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } void V3Const::constifyCpp(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } AstNode* V3Const::constifyEdit(AstNode* nodep) { @@ -2404,6 +2406,7 @@ void V3Const::constifyAllLive(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } void V3Const::constifyAll(AstNetlist* nodep) { @@ -2411,6 +2414,7 @@ void V3Const::constifyAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } AstNode* V3Const::constifyExpensiveEdit(AstNode* nodep) { diff --git a/src/V3Coverage.cpp b/src/V3Coverage.cpp index 32b48a92d..b5ad49408 100644 --- a/src/V3Coverage.cpp +++ b/src/V3Coverage.cpp @@ -395,4 +395,5 @@ public: void V3Coverage::coverage(AstNetlist* rootp) { UINFO(2,__FUNCTION__<<": "<= 3); } diff --git a/src/V3CoverageJoin.cpp b/src/V3CoverageJoin.cpp index 8dc17c0f9..8a0010e9f 100644 --- a/src/V3CoverageJoin.cpp +++ b/src/V3CoverageJoin.cpp @@ -135,4 +135,5 @@ public: void V3CoverageJoin::coverageJoin(AstNetlist* rootp) { UINFO(2,__FUNCTION__<<": "<= 3); } diff --git a/src/V3Dead.cpp b/src/V3Dead.cpp index 088e3f6b5..ac2e20faf 100644 --- a/src/V3Dead.cpp +++ b/src/V3Dead.cpp @@ -291,12 +291,15 @@ public: void V3Dead::deadifyModules(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 6); } void V3Dead::deadifyDTypes(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } void V3Dead::deadifyAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } diff --git a/src/V3Delayed.cpp b/src/V3Delayed.cpp index 021575fe1..178b9bf0d 100644 --- a/src/V3Delayed.cpp +++ b/src/V3Delayed.cpp @@ -471,4 +471,5 @@ public: void V3Delayed::delayedAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } diff --git a/src/V3Depth.cpp b/src/V3Depth.cpp index bcecd4e1f..a5f734800 100644 --- a/src/V3Depth.cpp +++ b/src/V3Depth.cpp @@ -175,4 +175,5 @@ public: void V3Depth::depthAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 6); } diff --git a/src/V3DepthBlock.cpp b/src/V3DepthBlock.cpp index e9e7d8773..61be83491 100644 --- a/src/V3DepthBlock.cpp +++ b/src/V3DepthBlock.cpp @@ -140,4 +140,5 @@ public: void V3DepthBlock::depthBlockAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } diff --git a/src/V3Descope.cpp b/src/V3Descope.cpp index d710f33b1..3d91b3360 100644 --- a/src/V3Descope.cpp +++ b/src/V3Descope.cpp @@ -262,4 +262,5 @@ public: void V3Descope::descopeAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } diff --git a/src/V3Expand.cpp b/src/V3Expand.cpp index 5863d8409..d415641b3 100644 --- a/src/V3Expand.cpp +++ b/src/V3Expand.cpp @@ -937,4 +937,5 @@ public: void V3Expand::expandAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } diff --git a/src/V3Gate.cpp b/src/V3Gate.cpp index 25bef4992..e933ae4e5 100644 --- a/src/V3Gate.cpp +++ b/src/V3Gate.cpp @@ -1266,4 +1266,5 @@ void V3Gate::gateAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } diff --git a/src/V3GenClk.cpp b/src/V3GenClk.cpp index 711a11bb6..736bb6f9f 100644 --- a/src/V3GenClk.cpp +++ b/src/V3GenClk.cpp @@ -228,4 +228,5 @@ public: void V3GenClk::genClkAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } diff --git a/src/V3Inline.cpp b/src/V3Inline.cpp index bb451c6d5..eab88e831 100644 --- a/src/V3Inline.cpp +++ b/src/V3Inline.cpp @@ -563,4 +563,5 @@ void V3Inline::inlineAll(AstNetlist* nodep) { modp->unlinkFrBack()->deleteTree(); modp=NULL; } } + V3Global::dumpCheckGlobalTree("inline.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3); } diff --git a/src/V3Inst.cpp b/src/V3Inst.cpp index 63850a596..f67b4edc6 100644 --- a/src/V3Inst.cpp +++ b/src/V3Inst.cpp @@ -322,9 +322,11 @@ AstAssignW* V3Inst::pinReconnectSimple(AstPin* pinp, AstCell* cellp, AstNodeModu void V3Inst::instAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } void V3Inst::dearrayAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 6); } diff --git a/src/V3Life.cpp b/src/V3Life.cpp index 10c2afe68..69f2a653f 100644 --- a/src/V3Life.cpp +++ b/src/V3Life.cpp @@ -515,4 +515,5 @@ void V3Life::lifeAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } diff --git a/src/V3LifePost.cpp b/src/V3LifePost.cpp index 7d0c231f5..cce02402d 100644 --- a/src/V3LifePost.cpp +++ b/src/V3LifePost.cpp @@ -193,4 +193,5 @@ void V3LifePost::lifepostAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } diff --git a/src/V3LinkDot.h b/src/V3LinkDot.h index a3e4019d9..ef2bd11ae 100644 --- a/src/V3LinkDot.h +++ b/src/V3LinkDot.h @@ -35,13 +35,21 @@ private: static void linkDotGuts(AstNetlist* nodep, VLinkDotStep step); public: static void linkDotPrimary(AstNetlist* nodep) { - UINFO(2,__FUNCTION__<<": "<= 6); + } static void linkDotParamed(AstNetlist* nodep) { - UINFO(2,__FUNCTION__<<": "<= 3); + } static void linkDotArrayed(AstNetlist* nodep) { - UINFO(2,__FUNCTION__<<": "<= 6); + } static void linkDotScope(AstNetlist* nodep) { - UINFO(2,__FUNCTION__<<": "<= 3); + } }; #endif // Guard diff --git a/src/V3LinkJump.cpp b/src/V3LinkJump.cpp index 5671bb92d..4aeb3d3ee 100644 --- a/src/V3LinkJump.cpp +++ b/src/V3LinkJump.cpp @@ -263,4 +263,5 @@ public: void V3LinkJump::linkJump(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } diff --git a/src/V3LinkLValue.cpp b/src/V3LinkLValue.cpp index cf9c09332..5e4b8a35a 100644 --- a/src/V3LinkLValue.cpp +++ b/src/V3LinkLValue.cpp @@ -269,6 +269,7 @@ public: void V3LinkLValue::linkLValue(AstNetlist* rootp) { UINFO(4,__FUNCTION__<<": "<= 6); } void V3LinkLValue::linkLValueSet(AstNode* nodep) { // Called by later link functions when it is known a node needs diff --git a/src/V3LinkLevel.cpp b/src/V3LinkLevel.cpp index a940a952d..0d8312a77 100644 --- a/src/V3LinkLevel.cpp +++ b/src/V3LinkLevel.cpp @@ -80,6 +80,7 @@ void V3LinkLevel::modSortByLevel() { v3Global.rootp()->addModulep(nodep); } UINFO(9,"modSortByLevel() done\n"); // Comment required for gcc4.6.3 / bug666 + V3Global::dumpCheckGlobalTree("cells.tree", false, v3Global.opt.dumpTreeLevel(__FILE__) >= 3); } //###################################################################### diff --git a/src/V3LinkParse.cpp b/src/V3LinkParse.cpp index fa4b7a73d..76ea8c6a8 100644 --- a/src/V3LinkParse.cpp +++ b/src/V3LinkParse.cpp @@ -369,4 +369,5 @@ public: void V3LinkParse::linkParse(AstNetlist* rootp) { UINFO(4,__FUNCTION__<<": "<= 6); } diff --git a/src/V3LinkResolve.cpp b/src/V3LinkResolve.cpp index 26b85990f..5d229fc6f 100644 --- a/src/V3LinkResolve.cpp +++ b/src/V3LinkResolve.cpp @@ -462,4 +462,5 @@ void V3LinkResolve::linkResolve(AstNetlist* rootp) { UINFO(4,__FUNCTION__<<": "<= 6); } diff --git a/src/V3Localize.cpp b/src/V3Localize.cpp index 05626b35c..75c569b8f 100644 --- a/src/V3Localize.cpp +++ b/src/V3Localize.cpp @@ -250,4 +250,5 @@ void V3Localize::localizeAll(AstNetlist* nodep) { LocalizeVisitor visitor (nodep); // Fix up hiernames LocalizeDehierVisitor dvisitor (nodep); + V3Global::dumpCheckGlobalTree("localize.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 6); } diff --git a/src/V3Name.cpp b/src/V3Name.cpp index 8689efb4f..3bd52c632 100644 --- a/src/V3Name.cpp +++ b/src/V3Name.cpp @@ -149,4 +149,5 @@ public: void V3Name::nameAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 6); } diff --git a/src/V3Options.cpp b/src/V3Options.cpp index 2bdda7b50..54f8efeef 100644 --- a/src/V3Options.cpp +++ b/src/V3Options.cpp @@ -734,6 +734,11 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char shift; m_dumpTree = atoi(argv[i]); } + else if ( !strncmp (sw, "-dump-treei-", strlen("-dump-treei-"))) { + const char* src = sw+strlen("-dump-treei-"); + shift; + setDumpTreeLevel(src, atoi(argv[i])); + } else if ( !strcmp (sw, "-error-limit") && (i+1)second = level; + } else { + m_dumpTrees.insert(make_pair(srcfile,level)); + } +} + +int V3Options::dumpTreeLevel(const string& srcfile_path) { + // For simplicity, calling functions can just use __FILE__ for srcfile. + // That means though we need to cleanup the filename from ../Foo.cpp -> Foo + string srcfile = V3Os::filenameNonDirExt(srcfile_path); + DebugSrcMap::iterator iter = m_dumpTrees.find(srcfile); + if (iter!=m_dumpTrees.end()) { + return iter->second; + } else { + return m_dumpTree; + } +} + void V3Options::optimize(int level) { // Set all optimizations to on/off bool flag = level > 0; diff --git a/src/V3Options.h b/src/V3Options.h index 1dbf69f67..69194a3cf 100644 --- a/src/V3Options.h +++ b/src/V3Options.h @@ -57,6 +57,7 @@ class V3Options { V3StringSet m_noClockers; // argument: Verilog -noclk signals V3StringList m_vFiles; // argument: Verilog files to read DebugSrcMap m_debugSrcs; // argument: --debugi-= + DebugSrcMap m_dumpTrees; // argument: --dump-treei-= bool m_preprocOnly; // main switch: -E bool m_makeDepend; // main switch: -MMD @@ -180,6 +181,8 @@ class V3Options { void setDebugMode(int level); void setDebugSrcLevel(const string& srcfile, int level); int debugSrcLevel(const string& srcfile, int default_level=V3Error::debugDefault()); + void setDumpTreeLevel(const string& srcfile, int level); + int dumpTreeLevel(const string& srcfile); // METHODS void addCppFile(const string& filename); diff --git a/src/V3Order.cpp b/src/V3Order.cpp index f9abedbc2..e24428da3 100644 --- a/src/V3Order.cpp +++ b/src/V3Order.cpp @@ -1660,4 +1660,5 @@ void V3Order::orderAll(AstNetlist* nodep) { OrderClkMarkVisitor markVisitor(nodep); OrderVisitor visitor; visitor.main(nodep); + V3Global::dumpCheckGlobalTree("order.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3); } diff --git a/src/V3Param.cpp b/src/V3Param.cpp index 925804e45..5948d3bd4 100644 --- a/src/V3Param.cpp +++ b/src/V3Param.cpp @@ -570,4 +570,5 @@ void ParamVisitor::visitCell(AstCell* nodep) { void V3Param::param(AstNetlist* rootp) { UINFO(2,__FUNCTION__<<": "<= 6); } diff --git a/src/V3Premit.cpp b/src/V3Premit.cpp index 88e2dbee9..39163d931 100644 --- a/src/V3Premit.cpp +++ b/src/V3Premit.cpp @@ -403,4 +403,5 @@ public: void V3Premit::premitAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } diff --git a/src/V3Scope.cpp b/src/V3Scope.cpp index 1e00b7364..c253d0afd 100644 --- a/src/V3Scope.cpp +++ b/src/V3Scope.cpp @@ -416,4 +416,5 @@ void V3Scope::scopeAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } diff --git a/src/V3Slice.cpp b/src/V3Slice.cpp index f5de6b129..6403271cf 100644 --- a/src/V3Slice.cpp +++ b/src/V3Slice.cpp @@ -501,4 +501,5 @@ public: void V3Slice::sliceAll(AstNetlist* rootp) { UINFO(2,__FUNCTION__<<": "<= 3); } diff --git a/src/V3Split.cpp b/src/V3Split.cpp index 9719a9354..effdfbd8a 100644 --- a/src/V3Split.cpp +++ b/src/V3Split.cpp @@ -578,8 +578,10 @@ public: void V3Split::splitReorderAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } void V3Split::splitAlwaysAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 6); } diff --git a/src/V3SplitAs.cpp b/src/V3SplitAs.cpp index 8a8860f46..b0cd367e9 100644 --- a/src/V3SplitAs.cpp +++ b/src/V3SplitAs.cpp @@ -216,4 +216,5 @@ public: void V3SplitAs::splitAsAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } diff --git a/src/V3Subst.cpp b/src/V3Subst.cpp index b1a409aa7..3f248d733 100644 --- a/src/V3Subst.cpp +++ b/src/V3Subst.cpp @@ -401,4 +401,5 @@ public: void V3Subst::substituteAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } diff --git a/src/V3Table.cpp b/src/V3Table.cpp index 6f86a024a..18e32b2bd 100644 --- a/src/V3Table.cpp +++ b/src/V3Table.cpp @@ -466,4 +466,5 @@ void TableSimulateVisitor::varRefCb(AstVarRef* nodep) { void V3Table::tableAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } diff --git a/src/V3Task.cpp b/src/V3Task.cpp index a44ef2383..802457e11 100644 --- a/src/V3Task.cpp +++ b/src/V3Task.cpp @@ -1294,4 +1294,5 @@ void V3Task::taskAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } diff --git a/src/V3Trace.cpp b/src/V3Trace.cpp index 56c30208d..f35111006 100644 --- a/src/V3Trace.cpp +++ b/src/V3Trace.cpp @@ -709,4 +709,5 @@ public: void V3Trace::traceAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } diff --git a/src/V3TraceDecl.cpp b/src/V3TraceDecl.cpp index 7a057be98..91bbf7148 100644 --- a/src/V3TraceDecl.cpp +++ b/src/V3TraceDecl.cpp @@ -329,4 +329,5 @@ public: void V3TraceDecl::traceDeclAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } diff --git a/src/V3Tristate.cpp b/src/V3Tristate.cpp index f374d31a0..7f787a9da 100644 --- a/src/V3Tristate.cpp +++ b/src/V3Tristate.cpp @@ -1323,4 +1323,5 @@ public: void V3Tristate::tristateAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } diff --git a/src/V3Unknown.cpp b/src/V3Unknown.cpp index f56d89ea5..5b51dadb2 100644 --- a/src/V3Unknown.cpp +++ b/src/V3Unknown.cpp @@ -475,4 +475,5 @@ public: void V3Unknown::unknownAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } diff --git a/src/V3Unroll.cpp b/src/V3Unroll.cpp index 2e46b2cf8..306394338 100644 --- a/src/V3Unroll.cpp +++ b/src/V3Unroll.cpp @@ -463,6 +463,7 @@ public: void V3Unroll::unrollAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } void V3Unroll::unrollGen(AstNodeFor* nodep, string beginName) { diff --git a/src/V3Width.cpp b/src/V3Width.cpp index 9d1e913a2..42ac62291 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -3483,6 +3483,7 @@ void V3Width::width(AstNetlist* nodep) { (void)visitor.mainAcceptEdit(nodep); WidthRemoveVisitor rvisitor; (void)rvisitor.mainAcceptEdit(nodep); + V3Global::dumpCheckGlobalTree("width.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3); } //! Single node parameter propagation @@ -3520,4 +3521,5 @@ AstNode* V3Width::widthGenerateParamsEdit( void V3Width::widthCommit(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 6); } diff --git a/src/Verilator.cpp b/src/Verilator.cpp index 972aa422f..959c536f2 100644 --- a/src/Verilator.cpp +++ b/src/Verilator.cpp @@ -149,30 +149,22 @@ void V3Global::dumpCheckGlobalTree(const string& filename, int newNumber, bool d //###################################################################### void process () { - bool dumpMore = (v3Global.opt.dumpTree() >= 9); - // Sort modules by level so later algorithms don't need to care V3LinkLevel::modSortByLevel(); - V3Global::dumpCheckGlobalTree("cells.tree"); V3Error::abortIfErrors(); // Convert parseref's to varrefs, and other directly post parsing fixups V3LinkParse::linkParse(v3Global.rootp()); - V3Global::dumpCheckGlobalTree("linkparse.tree", 0, dumpMore); // Cross-link signal names // Cross-link dotted hierarchical references V3LinkDot::linkDotPrimary(v3Global.rootp()); - V3Global::dumpCheckGlobalTree("linkdot.tree", 0, dumpMore); v3Global.checkTree(); // Force a check, as link is most likely place for problems // Correct state we couldn't know at parse time, repair SEL's V3LinkResolve::linkResolve(v3Global.rootp()); - V3Global::dumpCheckGlobalTree("linkresolve.tree", 0, dumpMore); // Set Lvalue's in variable refs V3LinkLValue::linkLValue(v3Global.rootp()); - V3Global::dumpCheckGlobalTree("linklvalue.tree", 0, dumpMore); // Convert return/continue/disable to jumps V3LinkJump::linkJump(v3Global.rootp()); - V3Global::dumpCheckGlobalTree("link.tree"); V3Error::abortIfErrors(); if (v3Global.opt.stats()) V3Stats::statsStageAll(v3Global.rootp(), "Link"); @@ -180,19 +172,15 @@ void process () { // Remove parameters by cloning modules to de-parameterized versions // This requires some width calculations and constant propagation V3Param::param(v3Global.rootp()); - V3Global::dumpCheckGlobalTree("param.tree", 0, dumpMore); V3LinkDot::linkDotParamed(v3Global.rootp()); // Cleanup as made new modules - V3Global::dumpCheckGlobalTree("paramlink.tree"); V3Error::abortIfErrors(); // Remove any modules that were parameterized and are no longer referenced. V3Dead::deadifyModules(v3Global.rootp()); - V3Global::dumpCheckGlobalTree("dead.tree", 0, dumpMore); v3Global.checkTree(); // Calculate and check widths, edit tree to TRUNC/EXTRACT any width mismatches V3Width::width(v3Global.rootp()); - V3Global::dumpCheckGlobalTree("width.tree"); V3Error::abortIfErrors(); @@ -200,19 +188,16 @@ void process () { V3Width::widthCommit(v3Global.rootp()); v3Global.assertDTypesResolved(true); v3Global.assertWidthsMatch(true); - V3Global::dumpCheckGlobalTree("widthcommit.tree", 0, dumpMore); // Coverage insertion // Before we do dead code elimination and inlining, or we'll lose it. if (v3Global.opt.coverage()) { V3Coverage::coverage(v3Global.rootp()); - V3Global::dumpCheckGlobalTree("coverage.tree"); } // Push constants, but only true constants preserving liveness // so V3Undriven sees variables to be eliminated, ie "if (0 && foo) ..." V3Const::constifyAllLive(v3Global.rootp()); - V3Global::dumpCheckGlobalTree("const.tree"); // Signal based lint checks, no change to structures // Must be before first constification pass drops dead code @@ -221,10 +206,8 @@ void process () { // Assertion insertion // After we've added block coverage, but before other nasty transforms V3AssertPre::assertPreAll(v3Global.rootp()); - V3Global::dumpCheckGlobalTree("assertpre.tree"); // V3Assert::assertAll(v3Global.rootp()); - V3Global::dumpCheckGlobalTree("assert.tree"); if (!v3Global.opt.xmlOnly()) { // Add top level wrapper with instance pointing to old top @@ -235,39 +218,32 @@ void process () { // Propagate constants into expressions V3Const::constifyAllLint(v3Global.rootp()); - V3Global::dumpCheckGlobalTree("const.tree"); if (!v3Global.opt.xmlOnly()) { // Remove cell arrays (must be between V3Width and scoping) V3Inst::dearrayAll(v3Global.rootp()); - V3Global::dumpCheckGlobalTree("dearray.tree", 0, dumpMore); } if (!v3Global.opt.xmlOnly()) { // Expand inouts, stage 2 // Also simplify pin connections to always be AssignWs in prep for V3Unknown V3Tristate::tristateAll(v3Global.rootp()); - V3Global::dumpCheckGlobalTree("tristate.tree"); // Task inlining & pushing BEGINs names to variables/cells // Begin processing must be after Param, before module inlining V3Begin::debeginAll(v3Global.rootp()); // Flatten cell names, before inliner - V3Global::dumpCheckGlobalTree("begin.tree"); // Move assignments from X into MODULE temps. // (Before flattening, so each new X variable is shared between all scopes of that module.) V3Unknown::unknownAll(v3Global.rootp()); v3Global.constRemoveXs(true); - V3Global::dumpCheckGlobalTree("unknown.tree"); // Module inlining // Cannot remove dead variables after this, as alias information for final // V3Scope's V3LinkDot is in the AstVar. if (v3Global.opt.oInline()) { V3Inline::inlineAll(v3Global.rootp()); - V3Global::dumpCheckGlobalTree("inline.tree"); V3LinkDot::linkDotArrayed(v3Global.rootp()); // Cleanup as made new modules - V3Global::dumpCheckGlobalTree("linkdot.tree", 0, dumpMore); } } @@ -275,11 +251,9 @@ void process () { // Initial const/dead to reduce work for ordering code V3Const::constifyAll(v3Global.rootp()); - V3Global::dumpCheckGlobalTree("const_predead.tree", 0, dumpMore); v3Global.checkTree(); V3Dead::deadifyDTypes(v3Global.rootp()); - V3Global::dumpCheckGlobalTree("const.tree"); v3Global.checkTree(); V3Error::abortIfErrors(); @@ -292,17 +266,13 @@ void process () { // Convert instantiations to wassigns and always blocks V3Inst::instAll(v3Global.rootp()); - V3Global::dumpCheckGlobalTree("inst.tree"); // Inst may have made lots of concats; fix them V3Const::constifyAll(v3Global.rootp()); - V3Global::dumpCheckGlobalTree("const.tree"); // Flatten hierarchy, creating a SCOPE for each module's usage as a cell V3Scope::scopeAll(v3Global.rootp()); - V3Global::dumpCheckGlobalTree("scope.tree"); V3LinkDot::linkDotScope(v3Global.rootp()); - V3Global::dumpCheckGlobalTree("linkdot.tree"); } //--SCOPE BASED OPTIMIZATIONS-------------- @@ -310,87 +280,69 @@ void process () { if (!v3Global.opt.xmlOnly()) { // Cleanup V3Const::constifyAll(v3Global.rootp()); - V3Global::dumpCheckGlobalTree("const_predead.tree", 0, dumpMore); V3Dead::deadifyDTypes(v3Global.rootp()); v3Global.checkTree(); - V3Global::dumpCheckGlobalTree("const.tree"); // Convert case statements to if() blocks. Must be after V3Unknown // Must be before V3Task so don't need to deal with task in case value compares V3Case::caseAll(v3Global.rootp()); - V3Global::dumpCheckGlobalTree("case.tree"); // Inline all tasks V3Task::taskAll(v3Global.rootp()); - V3Global::dumpCheckGlobalTree("task.tree"); // Add __PVT's // After V3Task so task internal variables will get renamed V3Name::nameAll(v3Global.rootp()); - V3Global::dumpCheckGlobalTree("name.tree", 0, dumpMore); // Loop unrolling & convert FORs to WHILEs V3Unroll::unrollAll(v3Global.rootp()); - V3Global::dumpCheckGlobalTree("unroll.tree"); // Expand slices of arrays V3Slice::sliceAll(v3Global.rootp()); - V3Global::dumpCheckGlobalTree("slices.tree"); // Push constants across variables and remove redundant assignments V3Const::constifyAll(v3Global.rootp()); - V3Global::dumpCheckGlobalTree("const.tree"); if (v3Global.opt.oLife()) { V3Life::lifeAll(v3Global.rootp()); - V3Global::dumpCheckGlobalTree("life.tree"); } // Make large low-fanin logic blocks into lookup tables // This should probably be done much later, once we have common logic elimination. if (!v3Global.opt.lintOnly() && v3Global.opt.oTable()) { V3Table::tableAll(v3Global.rootp()); - V3Global::dumpCheckGlobalTree("table.tree"); } // Cleanup V3Const::constifyAll(v3Global.rootp()); - V3Global::dumpCheckGlobalTree("const_predead.tree", 0, dumpMore); V3Dead::deadifyDTypes(v3Global.rootp()); v3Global.checkTree(); - V3Global::dumpCheckGlobalTree("const.tree"); // Detect clock enables and mode into sensitives, and split always based on clocks // (so this is a good prelude to splitAlways.) if (v3Global.opt.oFlopGater()) { V3ClkGater::clkGaterAll(v3Global.rootp()); - V3Global::dumpCheckGlobalTree("clkgater.tree"); } // Move assignments/sensitives into a SBLOCK for each unique sensitivity list // (May convert some ALWAYS to combo blocks, so should be before V3Gate step.) V3Active::activeAll(v3Global.rootp()); - V3Global::dumpCheckGlobalTree("active.tree"); // Split single ALWAYS blocks into multiple blocks for better ordering chances if (v3Global.opt.oSplit()) { V3Split::splitAlwaysAll(v3Global.rootp()); - V3Global::dumpCheckGlobalTree("split.tree", 0, dumpMore); } V3SplitAs::splitAsAll(v3Global.rootp()); - V3Global::dumpCheckGlobalTree("splitas.tree"); // Create tracing sample points, before we start eliminating signals if (v3Global.opt.trace()) { V3TraceDecl::traceDeclAll(v3Global.rootp()); - V3Global::dumpCheckGlobalTree("tracedecl.tree"); } // Gate-based logic elimination; eliminate signals and push constant across cell boundaries // Instant propagation makes lots-o-constant reduction possibilities. if (v3Global.opt.oGate()) { V3Gate::gateAll(v3Global.rootp()); - V3Global::dumpCheckGlobalTree("gate.tree"); // V3Gate calls constant propagation itself. } else { v3info("Command Line disabled gate optimization with -Og/-O0. This may cause ordering problems."); @@ -399,14 +351,11 @@ void process () { // Combine COVERINCs with duplicate terms if (v3Global.opt.coverage()) { V3CoverageJoin::coverageJoin(v3Global.rootp()); - V3Global::dumpCheckGlobalTree("coveragejoin.tree"); } // Remove unused vars V3Const::constifyAll(v3Global.rootp()); - V3Global::dumpCheckGlobalTree("const_predead.tree", 0, dumpMore); V3Dead::deadifyAll(v3Global.rootp()); - V3Global::dumpCheckGlobalTree("const.tree"); // Clock domain crossing analysis if (v3Global.opt.cdc()) { @@ -418,32 +367,26 @@ void process () { // Reorder assignments in pipelined blocks if (v3Global.opt.oReorder()) { V3Split::splitReorderAll(v3Global.rootp()); - V3Global::dumpCheckGlobalTree("reorder.tree"); } // Create delayed assignments // This creates lots of duplicate ACTIVES so ActiveTop needs to be after this step V3Delayed::delayedAll(v3Global.rootp()); - V3Global::dumpCheckGlobalTree("delayed.tree"); // Make Active's on the top level // Differs from V3Active, because identical clocks may be pushed down to a module and now be identical V3ActiveTop::activeTopAll(v3Global.rootp()); - V3Global::dumpCheckGlobalTree("activetop.tree"); if (v3Global.opt.stats()) V3Stats::statsStageAll(v3Global.rootp(), "PreOrder"); // Order the code; form SBLOCKs and BLOCKCALLs V3Order::orderAll(v3Global.rootp()); - V3Global::dumpCheckGlobalTree("order.tree"); // Change generated clocks to look at delayed signals V3GenClk::genClkAll(v3Global.rootp()); - V3Global::dumpCheckGlobalTree("genclk.tree"); // Convert sense lists into IF statements. V3Clock::clockAll(v3Global.rootp()); - V3Global::dumpCheckGlobalTree("clock.tree"); // Cleanup any dly vars or other temps that are simple assignments // Life must be done before Subst, as it assumes each CFunc under _eval is called only once. @@ -454,33 +397,25 @@ void process () { if (v3Global.opt.oLifePost()) { V3LifePost::lifepostAll(v3Global.rootp()); } - if (v3Global.opt.oLife() || v3Global.opt.oLifePost()) { - V3Global::dumpCheckGlobalTree("life.tree"); - } // Remove unused vars V3Const::constifyAll(v3Global.rootp()); - V3Global::dumpCheckGlobalTree("const_predead.tree", 0, dumpMore); V3Dead::deadifyAll(v3Global.rootp()); - V3Global::dumpCheckGlobalTree("const.tree"); // Detect change loop V3Changed::changedAll(v3Global.rootp()); - V3Global::dumpCheckGlobalTree("changed.tree"); // Create tracing logic, since we ripped out some signals the user might want to trace // Note past this point, we presume traced variables won't move between CFuncs // (It's OK if untraced temporaries move around, or vars "effectively" activate the same way.) if (v3Global.opt.trace()) { V3Trace::traceAll(v3Global.rootp()); - V3Global::dumpCheckGlobalTree("trace.tree"); } if (v3Global.opt.stats()) V3Stats::statsStageAll(v3Global.rootp(), "Scoped"); // Remove scopes; make varrefs/funccalls relative to current module V3Descope::descopeAll(v3Global.rootp()); - V3Global::dumpCheckGlobalTree("descope.tree"); } //--MODULE OPTIMIZATIONS-------------- @@ -489,19 +424,16 @@ void process () { // Split deep blocks to appease MSVC++. Must be before Localize. if (!v3Global.opt.lintOnly() && v3Global.opt.compLimitBlocks()) { V3DepthBlock::depthBlockAll(v3Global.rootp()); - V3Global::dumpCheckGlobalTree("deepblock.tree"); } // Move BLOCKTEMPS from class to local variables if (v3Global.opt.oLocalize()) { V3Localize::localizeAll(v3Global.rootp()); - V3Global::dumpCheckGlobalTree("localize.tree", 0, dumpMore); } // Icache packing; combine common code in each module's functions into subroutines if (v3Global.opt.oCombine()) { V3Combine::combineAll(v3Global.rootp()); - V3Global::dumpCheckGlobalTree("combine.tree"); } } @@ -512,9 +444,7 @@ void process () { if (!v3Global.opt.xmlOnly()) { // Remove unused vars V3Const::constifyAll(v3Global.rootp()); - V3Global::dumpCheckGlobalTree("const_predead.tree", 0, dumpMore); V3Dead::deadifyAll(v3Global.rootp()); - V3Global::dumpCheckGlobalTree("const.tree"); // Here down, widthMin() is the Verilog width, and width() is the C++ width // Bits between widthMin() and width() are irrelevant, but may be non zero. @@ -522,18 +452,15 @@ void process () { // Make all math operations either 8, 16, 32 or 64 bits V3Clean::cleanAll(v3Global.rootp()); - V3Global::dumpCheckGlobalTree("clean.tree"); // Move wide constants to BLOCK temps. V3Premit::premitAll(v3Global.rootp()); - V3Global::dumpCheckGlobalTree("premit.tree"); } // Expand macros and wide operators into C++ primitives if (!v3Global.opt.xmlOnly() && v3Global.opt.oExpand()) { V3Expand::expandAll(v3Global.rootp()); - V3Global::dumpCheckGlobalTree("expand.tree"); } // Propagate constants across WORDSEL arrayed temporaries @@ -541,18 +468,14 @@ void process () { && v3Global.opt.oSubst()) { // Constant folding of expanded stuff V3Const::constifyCpp(v3Global.rootp()); - V3Global::dumpCheckGlobalTree("const.tree"); V3Subst::substituteAll(v3Global.rootp()); - V3Global::dumpCheckGlobalTree("subst.tree"); } if (!v3Global.opt.xmlOnly() && v3Global.opt.oSubstConst()) { // Constant folding of substitutions V3Const::constifyCpp(v3Global.rootp()); - V3Global::dumpCheckGlobalTree("constc.tree", 0, dumpMore); V3Dead::deadifyAll(v3Global.rootp()); - V3Global::dumpCheckGlobalTree("dead.tree"); } if (!v3Global.opt.lintOnly() @@ -560,7 +483,6 @@ void process () { // Fix very deep expressions // Mark evaluation functions as member functions, if needed. V3Depth::depthAll(v3Global.rootp()); - V3Global::dumpCheckGlobalTree("depth.tree", 0, dumpMore); // Branch prediction V3Branch::branchAll(v3Global.rootp()); @@ -568,7 +490,6 @@ void process () { // Add C casts when longs need to become long-long and vice-versa // Note depth may insert something needing a cast, so this must be last. V3Cast::castAll(v3Global.rootp()); - V3Global::dumpCheckGlobalTree("cast.tree"); } V3Error::abortIfErrors(); @@ -674,7 +595,7 @@ int main(int argc, char** argv, char** env) { } // Final steps - V3Global::dumpCheckGlobalTree("final.tree",990); + V3Global::dumpCheckGlobalTree("final.tree", 990, v3Global.opt.dumpTreeLevel(__FILE__) >= 3); V3Error::abortIfWarnings(); if (!v3Global.opt.lintOnly() && !v3Global.opt.cdc()