diff --git a/Changes b/Changes index 6131c239e..cfdbffddf 100644 --- a/Changes +++ b/Changes @@ -5,16 +5,18 @@ indicates the contributor was also the author of the fix; Thanks! * Verilator 3.70** +*** Add --debugi- option. [Art Stamness] + **** Fix compile issues with GCC 4.3, bug47. [Lane Brooks] **** Fix VL_RANDom to better randomize bits. [Art Stamness] * Verilator 3.700 2009/01/08 -** Add limited support for tristate inouts. Written by Lane Brooks. - This allows common pad ring and tristate-mux structures to be - Verilated. See the documentation for more information on supported - constructs. +** Add limited support for tristate inouts. Written by Lane Brooks, + under support by Ubixum Inc. This allows common pad ring and + tristate-mux structures to be Verilated. See the documentation for + more information on supported constructs. ** Add --coverage_toggle for toggle coverage analysis. Running coverage now requires SystemPerl 1.301 or newer. diff --git a/bin/verilator b/bin/verilator index 643335fc3..faf9a0e39 100755 --- a/bin/verilator +++ b/bin/verilator @@ -188,6 +188,8 @@ descriptions in the next sections for more information. -D[=] Set preprocessor define --debug Enable debugging --debug-check Enable debugging assertions + --debugi Enable debugging at a specified level + --debugi- Enable debugging a source file at a level --dump-tree Enable dumping .tree files -E Preprocess, but do not compile --error-limit Abort after this number of errors @@ -375,6 +377,12 @@ internal assertions, debugging messages, and intermediate form dump files. Rarely needed. Enable internal debugging assertion checks, without changing debug verbosity. Enabled automatically when --debug specified. +=item --debugi +=item --debugi- + +Rarely needed - for developer use. Set internal debugging level globally +or on the specified source file to the specified level. + =item --dump-tree Rarely needed. Enable writing .tree debug files. This is enabled with diff --git a/src/V3Active.cpp b/src/V3Active.cpp index cad1a7449..f9d841fd2 100644 --- a/src/V3Active.cpp +++ b/src/V3Active.cpp @@ -52,7 +52,11 @@ class ActiveBaseVisitor : public AstNVisitor { protected: - //int debug() { return 9; } + static int debug() { + static int level = -1; + if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); + return level; + } }; class ActiveNamer : public ActiveBaseVisitor { diff --git a/src/V3ActiveTop.cpp b/src/V3ActiveTop.cpp index e53060cbd..fa7277663 100644 --- a/src/V3ActiveTop.cpp +++ b/src/V3ActiveTop.cpp @@ -56,7 +56,13 @@ private: // STATE AstTopScope* m_topscopep; // Top scope for adding sentrees under SenTreeFinder m_finder; // Find global sentree's and add them - //int debug() { return 9; } + + // METHODS + static int debug() { + static int level = -1; + if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); + return level; + } // VISITORS virtual void visit(AstTopScope* nodep, AstNUser*) { diff --git a/src/V3AssertPre.cpp b/src/V3AssertPre.cpp index 5d40138fd..d615bbcf5 100644 --- a/src/V3AssertPre.cpp +++ b/src/V3AssertPre.cpp @@ -48,9 +48,13 @@ private: // Reset each assertion: AstNodeSenItem* m_senip; // Last sensitivity - int debug() { return 0; } - // METHODS + static int debug() { + static int level = -1; + if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); + return level; + } + AstSenTree* newSenTree(AstNode* nodep) { // Create sentree based on clocked or default clock // Return NULL for always diff --git a/src/V3Begin.cpp b/src/V3Begin.cpp index fc01f394b..79ad83056 100644 --- a/src/V3Begin.cpp +++ b/src/V3Begin.cpp @@ -47,7 +47,13 @@ private: AstModule* m_modp; // Current module AstNodeFTask* m_ftaskp; // Current function/task string m_beginScope; // Name of begin blocks above us - //int debug() { return 9; } + + // METHODS + static int debug() { + static int level = -1; + if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); + return level; + } // VISITORS virtual void visit(AstModule* nodep, AstNUser*) { diff --git a/src/V3Branch.cpp b/src/V3Branch.cpp index 7521cb477..04b1ff0f2 100644 --- a/src/V3Branch.cpp +++ b/src/V3Branch.cpp @@ -43,9 +43,14 @@ private: // STATE int m_likely; // Excuses for branch likely taken int m_unlikely; // Excuses for branch likely not taken - //int debug() { return 9; } // METHODS + static int debug() { + static int level = -1; + if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); + return level; + } + void reset() { m_likely = false; m_unlikely = false; diff --git a/src/V3Case.cpp b/src/V3Case.cpp index ef176e13e..4e0ff855b 100644 --- a/src/V3Case.cpp +++ b/src/V3Case.cpp @@ -58,7 +58,12 @@ class CaseLintVisitor : public AstNVisitor { private: AstNodeCase* m_caseExprp; // Under a CASE value node, if so the relevant case statement - //int debug() { return 9; } + + static int debug() { + static int level = -1; + if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); + return level; + } virtual void visit(AstNodeCase* nodep, AstNUser*) { // Detect multiple defaults @@ -130,9 +135,13 @@ private: int m_caseNoOverlapsAllCovered; // Proven to be synopsys parallel_case compliant AstNode* m_valueItem[1<v3fatalSrc("Not applicable\n"); diff --git a/src/V3Clean.cpp b/src/V3Clean.cpp index 9021a2bd9..ce438c671 100644 --- a/src/V3Clean.cpp +++ b/src/V3Clean.cpp @@ -50,14 +50,19 @@ private: AstUser1InUse m_inuser1; AstUser2InUse m_inuser2; - // STATE - AstModule* m_modp; - //int debug() { return 9; } - - // ENUMS + // TYPES enum CleanState { UNKNOWN, CLEAN, DIRTY }; + // STATE + AstModule* m_modp; + // METHODS + static int debug() { + static int level = -1; + if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); + return level; + } + // Width resetting int cppWidth(AstNode* nodep) { if (nodep->width()<=VL_WORDSIZE) return VL_WORDSIZE; diff --git a/src/V3ClkGater.cpp b/src/V3ClkGater.cpp index 154b79f77..b8a4784bc 100644 --- a/src/V3ClkGater.cpp +++ b/src/V3ClkGater.cpp @@ -52,7 +52,11 @@ class GaterBaseVisitor : public AstNVisitor { protected: - //int debug() { return 9; } + static int debug() { + static int level = -1; + if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); + return level; + } }; //###################################################################### diff --git a/src/V3Clock.cpp b/src/V3Clock.cpp index b27e1b987..e579c4630 100644 --- a/src/V3Clock.cpp +++ b/src/V3Clock.cpp @@ -71,9 +71,14 @@ private: AstSenTree* m_lastSenp; // Last sensitivity match, so we can detect duplicates. AstIf* m_lastIfp; // Last sensitivity if active to add more under int m_stableNum; // Number of each untilstable - //int debug() { return 9; } // METHODS + static int debug() { + static int level = -1; + if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); + return level; + } + AstVarScope* getCreateLastClk(AstVarScope* vscp) { if (vscp->user1p()) return ((AstVarScope*)vscp->user1p()); AstVar* varp = vscp->varp(); diff --git a/src/V3Combine.cpp b/src/V3Combine.cpp index 9bede2862..e5d74025d 100644 --- a/src/V3Combine.cpp +++ b/src/V3Combine.cpp @@ -58,8 +58,14 @@ class CombBaseVisitor : public AstNVisitor { protected: // STATE - //int debug() { return 9; } + // METHODS + static int debug() { + static int level = -1; + if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); + return level; + } + virtual ~CombBaseVisitor() {} //***** optimization levels diff --git a/src/V3Const.cpp b/src/V3Const.cpp index 24b2ad530..ee7b6f2e7 100644 --- a/src/V3Const.cpp +++ b/src/V3Const.cpp @@ -105,9 +105,14 @@ private: bool m_expensive; // Enable computationally expensive optimizations AstModule* m_modp; // Current module AstNode* m_scopep; // Current scope - //int debug() { return 9; } // METHODS + static int debug() { + static int level = -1; + if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); + return level; + } + bool operandConst (AstNode* nodep) { return (nodep->castConst()); } diff --git a/src/V3Coverage.cpp b/src/V3Coverage.cpp index 17801ed4b..b702f195f 100644 --- a/src/V3Coverage.cpp +++ b/src/V3Coverage.cpp @@ -54,9 +54,13 @@ private: FileMap m_fileps; // Column counts for each fileline string m_beginHier; // AstBegin hier name for user coverage points - //int debug() { return 9; } - // METHODS + static int debug() { + static int level = -1; + if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); + return level; + } + const char* varIgnoreToggle(AstVar* nodep) { // Return true if this shouldn't be traced // See also similar rule in V3TraceDecl::varIgnoreTrace diff --git a/src/V3CoverageJoin.cpp b/src/V3CoverageJoin.cpp index ba1347f01..05016fe6c 100644 --- a/src/V3CoverageJoin.cpp +++ b/src/V3CoverageJoin.cpp @@ -53,9 +53,13 @@ private: V3Double0 m_statToggleJoins; // Statistic tracking - //int debug() { return 9; } - // METHODS + static int debug() { + static int level = -1; + if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); + return level; + } + void detectDuplicates() { UINFO(9,"Finding duplicates\n"); // Note uses user4 diff --git a/src/V3Dead.cpp b/src/V3Dead.cpp index b15bace8b..9b4911860 100644 --- a/src/V3Dead.cpp +++ b/src/V3Dead.cpp @@ -81,9 +81,13 @@ private: AssignMap m_assignMap; // List of all simple assignments for each variable bool m_elimUserVars; // Allow removal of user's vars bool m_sideEffect; // Side effects discovered in assign RHS - //int debug() { return 9; } // METHODS + static int debug() { + static int level = -1; + if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); + return level; + } // VISITORS virtual void visit(AstCell* nodep, AstNUser*) { diff --git a/src/V3Delayed.cpp b/src/V3Delayed.cpp index 85f82348a..b5611f1d5 100644 --- a/src/V3Delayed.cpp +++ b/src/V3Delayed.cpp @@ -101,9 +101,14 @@ private: VarMap m_modVarMap; // Table of new var names created under module V3Double0 m_statSharedSet;// Statistic tracking - //static int debug() { return 9; } // METHODS + static int debug() { + static int level = -1; + if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); + return level; + } + void markVarUsage(AstVar* nodep, uint32_t flags) { //UINFO(4," MVU "<user1( nodep->user1() | flags ); diff --git a/src/V3Depth.cpp b/src/V3Depth.cpp index f786308c8..ba41d75d6 100644 --- a/src/V3Depth.cpp +++ b/src/V3Depth.cpp @@ -51,9 +51,13 @@ private: int m_depth; // How deep in an expression int m_maxdepth; // Maximum depth in an expression - //int debug() { return 9; } - // METHODS + static int debug() { + static int level = -1; + if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); + return level; + } + void createDeepTemp(AstNode* nodep) { UINFO(6," Deep "<=9) nodep->dumpTree(cout,"deep:"); diff --git a/src/V3DepthBlock.cpp b/src/V3DepthBlock.cpp index f4b3a9c77..61b431e25 100644 --- a/src/V3DepthBlock.cpp +++ b/src/V3DepthBlock.cpp @@ -48,9 +48,13 @@ private: int m_depth; // How deep in an expression int m_deepNum; // How many functions made - //int debug() { return 9; } - // METHODS + static int debug() { + static int level = -1; + if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); + return level; + } + AstCFunc* createDeepFunc(AstNode* nodep) { AstNRelinker relinkHandle; nodep->unlinkFrBack(&relinkHandle); diff --git a/src/V3Descope.cpp b/src/V3Descope.cpp index fea3fd56d..5d0d762ad 100644 --- a/src/V3Descope.cpp +++ b/src/V3Descope.cpp @@ -55,9 +55,14 @@ private: AstScope* m_scopep; // Current scope bool m_needThis; // Add thisp to function FuncMmap m_modFuncs; // Name of public functions added - //int debug() { return 9; } // METHODS + static int debug() { + static int level = -1; + if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); + return level; + } + string descopedName(AstScope* scopep, bool& hierThisr, AstVar* varp=NULL) { UASSERT(scopep, "Var/Func not scoped\n"); hierThisr = true; diff --git a/src/V3EmitC.cpp b/src/V3EmitC.cpp index 5bb9dd275..3d165aa10 100644 --- a/src/V3EmitC.cpp +++ b/src/V3EmitC.cpp @@ -44,8 +44,14 @@ private: vector m_ctorVarsVec; // All variables in constructor order int m_splitSize; // # of cfunc nodes placed into output file int m_splitFilenum; // File number being created, 0 = primary + public: - //int debug() { return 9; } + // METHODS + static int debug() { + static int level = -1; + if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); + return level; + } // ACCESSORS int splitFilenum() { return m_splitFilenum; } @@ -1680,8 +1686,7 @@ void EmitCImp::main(AstModule* modp, bool slow, bool fast) { string filenameNoExt = v3Global.opt.makeDir()+"/"+ modClassName(modp)+(m_fast ? "" : "__Slow"); if (debug()>=5) { - for (int i=0;ilevel();i++) { cout<<" "; } - UINFONL(0," Emitting "<width()+(VL_WORDSIZE-1)) & ~(VL_WORDSIZE-1); diff --git a/src/V3Gate.cpp b/src/V3Gate.cpp index f03e66a18..9288a7e5c 100644 --- a/src/V3Gate.cpp +++ b/src/V3Gate.cpp @@ -48,7 +48,11 @@ typedef list GateVarRefList; class GateBaseVisitor : public AstNVisitor { public: - //int debug() { return 9; } + static int debug() { + static int level = -1; + if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); + return level; + } }; //###################################################################### diff --git a/src/V3GenClk.cpp b/src/V3GenClk.cpp index 3fe0b5a23..777a723b4 100644 --- a/src/V3GenClk.cpp +++ b/src/V3GenClk.cpp @@ -38,7 +38,11 @@ class GenClkBaseVisitor : public AstNVisitor { protected: - //static int debug() { return 9; } + static int debug() { + static int level = -1; + if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); + return level; + } }; //###################################################################### diff --git a/src/V3GraphAcyc.cpp b/src/V3GraphAcyc.cpp index 070d184b2..062280cdf 100644 --- a/src/V3GraphAcyc.cpp +++ b/src/V3GraphAcyc.cpp @@ -106,7 +106,7 @@ private: V3EdgeFuncP m_origEdgeFuncp; // Function that says we follow this edge (in original graph) uint32_t m_placeStep; // Number that user() must be equal to to indicate processing - int debug() { return V3Graph::debug(); } + static int debug() { return V3Graph::debug(); } // METHODS void buildGraph (V3Graph* origGraphp); diff --git a/src/V3GraphTest.cpp b/src/V3GraphTest.cpp index f88fe95dc..49181da12 100644 --- a/src/V3GraphTest.cpp +++ b/src/V3GraphTest.cpp @@ -35,8 +35,12 @@ class V3GraphTest { public: // ***These tests only run with DEBUG ON*** - //static int debug() { return 9; } - static int debug() { return 0; } + static int debug() { + static int level = -1; + // Note setting just --debug will not enable this, as we exit when we run the test + if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__, 0); + return level; + } protected: // MEMBERS diff --git a/src/V3Hashed.cpp b/src/V3Hashed.cpp index 5c264d3c0..8e4e39f31 100644 --- a/src/V3Hashed.cpp +++ b/src/V3Hashed.cpp @@ -53,7 +53,11 @@ private: // STATE V3Hash m_lowerHash; // Hash of the statement we're building - //int debug() { return 9; } + static int debug() { + static int level = -1; + if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); + return level; + } // METHODS void hashNodeIterate(AstNode* nodep) { diff --git a/src/V3Hashed.h b/src/V3Hashed.h index 19d8dfe67..a453a55f3 100644 --- a/src/V3Hashed.h +++ b/src/V3Hashed.h @@ -42,7 +42,7 @@ public: private: // MEMBERS HashMmap m_hashMmap; // hashvalue -> nodes with that hash - int debug() { return 0; } + public: // CONSTRUCTORS V3Hashed(); @@ -51,7 +51,13 @@ public: HashMmap& mmap() { return m_hashMmap; } // Return map for iteration HashMmap::iterator begin() { return m_hashMmap.begin(); } HashMmap::iterator end() { return m_hashMmap.end(); } + // METHODS + static int debug() { + static int level = -1; + if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); + return level; + } void clear() { m_hashMmap.clear(); } void hashAndInsert(AstNode* nodep); // Hash the node, and insert into map bool sameNodes(AstNode* node1p, AstNode* node2p); // After hashing, and tell if identical diff --git a/src/V3Inline.cpp b/src/V3Inline.cpp index 052f8a64f..f7c19f215 100644 --- a/src/V3Inline.cpp +++ b/src/V3Inline.cpp @@ -62,7 +62,11 @@ private: AstCell* m_cellp; // Cell being cloned V3Double0 m_statCells; // Statistic tracking - //int debug() { return 9; } + static int debug() { + static int level = -1; + if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); + return level; + } // VISITORS virtual void visit(AstNetlist* nodep, AstNUser*) { diff --git a/src/V3Inst.cpp b/src/V3Inst.cpp index 6f4554a56..c03a6e531 100644 --- a/src/V3Inst.cpp +++ b/src/V3Inst.cpp @@ -53,7 +53,11 @@ private: AstModule* m_modp; // Current module AstCell* m_cellp; // Current cell - //int debug() { return 8; } + static int debug() { + static int level = -1; + if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); + return level; + } //int m_debug; int debug() { return m_debug; } // VISITORS @@ -147,7 +151,11 @@ private: int m_instNum; // Current instantiation number int m_instLsb; // Current instantiation number - //int debug() { return 9; } + static int debug() { + static int level = -1; + if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); + return level; + } // VISITORS virtual void visit(AstCell* nodep, AstNUser*) { diff --git a/src/V3Life.cpp b/src/V3Life.cpp index cb08d2038..e9d27c492 100644 --- a/src/V3Life.cpp +++ b/src/V3Life.cpp @@ -270,7 +270,6 @@ private: // STATE LifeState* m_statep; // Current state bool m_sideEffect; // Side effects discovered in assign RHS - //static int debug() { return 9; } // LIFE MAP // For each basic block, we'll make a new map of what variables that if/else is changing @@ -278,6 +277,12 @@ private: LifeBlock* m_lifep; // Current active lifetime map for current scope // METHODS + static int debug() { + static int level = -1; + if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); + return level; + } + // VISITORS virtual void visit(AstVarRef* nodep, AstNUser*) { // Consumption/generation of a variable, diff --git a/src/V3LifePost.cpp b/src/V3LifePost.cpp index 4ef200999..12e8725d0 100644 --- a/src/V3LifePost.cpp +++ b/src/V3LifePost.cpp @@ -44,7 +44,11 @@ class LifePostBaseVisitor : public AstNVisitor { protected: -// static int debug() { return 9; } + static int debug() { + static int level = -1; + if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); + return level; + } }; //###################################################################### diff --git a/src/V3Link.cpp b/src/V3Link.cpp index ca7594522..c67444561 100644 --- a/src/V3Link.cpp +++ b/src/V3Link.cpp @@ -71,7 +71,11 @@ private: int m_beginNum; // Begin block number, 0=none seen vector m_delSymps; // Symbol tables to delete - //int debug() { return 9; } + static int debug() { + static int level = -1; + if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); + return level; + } // METHODS void linkVarName (AstVarRef* nodep) { diff --git a/src/V3LinkCells.cpp b/src/V3LinkCells.cpp index 5ad9f0ea1..9d98240bd 100644 --- a/src/V3LinkCells.cpp +++ b/src/V3LinkCells.cpp @@ -96,7 +96,11 @@ private: LinkCellsGraph m_graph; // Linked graph of all cell interconnects LibraryVertex* m_libVertexp; // Vertex at root of all libraries - //int debug() { return 9; } + static int debug() { + static int level = -1; + if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); + return level; + } // METHODS V3GraphVertex* vertex(AstModule* nodep) { diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index dcbbd557c..fe2914b7b 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -186,8 +186,12 @@ private: bool m_forPrearray; // Compress cell__[array] refs bool m_forScopeCreation; // Remove VarXRefs for V3Scope public: - static int debug() { return V3Error::debugDefault(); } -// static int debug() { return 9; } + + static int debug() { + static int level = -1; + if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); + return level; + } // CONSTRUCTORS LinkDotState(bool forPrearray, bool forScopeCreation) { @@ -372,6 +376,7 @@ private: LinkDotBaseVertex* m_inlineVxp; // Vertex for current module, possibly a fake inlined one string m_scope; // Scope text AstBegin* m_beginp; // Current Begin/end block + int debug() { return LinkDotState::debug(); } // VISITs @@ -518,6 +523,7 @@ private: // STATE LinkDotState* m_statep; // State to pass between visitors, including symbol table LinkDotCellVertex* m_cellVxp; // Vertex for current module + int debug() { return LinkDotState::debug(); } // VISITs @@ -580,6 +586,7 @@ private: // STATE LinkDotState* m_statep; // State, including dotted symbol table LinkDotCellVertex* m_cellVxp; // Vertex for current module + int debug() { return LinkDotState::debug(); } // METHODS diff --git a/src/V3LinkLValue.cpp b/src/V3LinkLValue.cpp index b1ee93d3d..d866d53ec 100644 --- a/src/V3LinkLValue.cpp +++ b/src/V3LinkLValue.cpp @@ -46,9 +46,12 @@ private: bool m_setRefLvalue; // Set VarRefs to lvalues for pin assignments AstNodeFTask* m_ftaskp; // Function or task we're inside - //int debug() { return 9; } - // METHODS + static int debug() { + static int level = -1; + if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); + return level; + } // VISITs // Result handing diff --git a/src/V3LinkParse.cpp b/src/V3LinkParse.cpp index 58445bfde..64b9437f8 100644 --- a/src/V3LinkParse.cpp +++ b/src/V3LinkParse.cpp @@ -55,9 +55,13 @@ private: AstParseRefExp m_exp; // Type of data we're looking for AstText* m_baseTextp; // Lowest TEXT node that needs replacement with varref - //int debug() { return 9; } - // METHODS + static int debug() { + static int level = -1; + if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); + return level; + } + void checkExpected(AstNode* nodep) { if (m_exp != AstParseRefExp::NONE) { nodep->v3fatalSrc("Tree syntax error: Not expecting "<type()<<" under a "<backp()->type()); diff --git a/src/V3LinkResolve.cpp b/src/V3LinkResolve.cpp index 5a341905b..d2971f9be 100644 --- a/src/V3LinkResolve.cpp +++ b/src/V3LinkResolve.cpp @@ -58,9 +58,13 @@ private: AstVAssert* m_assertp; // Current assertion int m_senitemCvtNum; // Temporary signal counter - //int debug() { return 9; } - // METHODS + static int debug() { + static int level = -1; + if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); + return level; + } + // VISITs virtual void visit(AstModule* nodep, AstNUser*) { // Module: Create sim table for entire module and iterate @@ -484,7 +488,13 @@ class LinkBotupVisitor : public AstNVisitor { private: // STATE AstModule* m_modp; // Current module - //int debug() { return 9; } + + // METHODS + static int debug() { + static int level = -1; + if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); + return level; + } // VISITs virtual void visit(AstNetlist* nodep, AstNUser*) { diff --git a/src/V3Localize.cpp b/src/V3Localize.cpp index 6a08da47e..99ecc5058 100644 --- a/src/V3Localize.cpp +++ b/src/V3Localize.cpp @@ -49,7 +49,12 @@ protected: // AstVar::user2() -> VarFlags. Flag state // AstVar::user4() -> AstVarRef*. First place signal set; must be first assignment - //int debug() { return 9; } + // METHODS + static int debug() { + static int level = -1; + if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); + return level; + } // TYPES union VarFlags { diff --git a/src/V3Name.cpp b/src/V3Name.cpp index e0b1038fa..64789d61c 100644 --- a/src/V3Name.cpp +++ b/src/V3Name.cpp @@ -53,7 +53,12 @@ private: // STATE AstModule* m_modp; - //int debug() { return 9; } + // METHODS + static int debug() { + static int level = -1; + if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); + return level; + } // VISITORS virtual void visit(AstModule* nodep, AstNUser*) { diff --git a/src/V3Options.cpp b/src/V3Options.cpp index 6261eefe4..8004ec222 100644 --- a/src/V3Options.cpp +++ b/src/V3Options.cpp @@ -532,7 +532,7 @@ void V3Options::parseOptsList(FileLine* fl, int argc, char** argv) { shift; } // + options else if (argv[i][0]=='-') { - char *sw = argv[i]; + const char *sw = argv[i]; bool flag = true; // Allow gnu -- switches if (sw[0]=='-' && sw[1]=='-') ++sw; @@ -544,6 +544,11 @@ void V3Options::parseOptsList(FileLine* fl, int argc, char** argv) { shift; setDebugMode(atoi(argv[i])); } + else if ( !strncmp (sw, "-debugi-", strlen("-debugi-"))) { + const char* src = sw+strlen("-debugi-"); + shift; + setDebugSrcLevel(src, atoi(argv[i])); + } else if ( !strcmp (sw, "-error-limit") ) { shift; m_inlineMult = atoi(argv[i]); @@ -631,7 +636,7 @@ void V3Options::parseOptsList(FileLine* fl, int argc, char** argv) { else if ( onoff (sw, "-underline-zero", flag/*ref*/) ) { m_underlineZero = flag; } // Optimization else if ( !strncmp (sw, "-O", 2) ) { - for (char* cp=sw+strlen("-O"); *cp; ++cp) { + for (const char* cp=sw+strlen("-O"); *cp; ++cp) { flag = isupper(*cp); switch (tolower(*cp)) { case '0': optimize(0); break; // 0=all off @@ -919,6 +924,27 @@ void V3Options::setDebugMode(int level) { cout << "Starting "<second = level; + } else { + m_debugSrcs.insert(make_pair(srcfile,level)); + } +} + +int V3Options::debugSrcLevel(const string& srcfile_path, int default_level) { + // 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 = V3Options::filenameNonDirExt(srcfile_path); + DebugSrcMap::iterator iter = m_debugSrcs.find(srcfile); + if (iter!=m_debugSrcs.end()) { + return iter->second; + } else { + return default_level; + } +} + 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 1600f58fa..7a6c14218 100644 --- a/src/V3Options.h +++ b/src/V3Options.h @@ -26,6 +26,7 @@ #include "verilatedos.h" #include #include +#include #include #include "V3Global.h" @@ -75,6 +76,9 @@ typedef vector V3StringList; typedef set V3StringSet; class V3Options { + // TYPES + typedef map DebugSrcMap; + // MEMBERS (general options) V3OptionsImp* m_impp; // Slow hidden options @@ -82,6 +86,7 @@ class V3Options { V3StringSet m_futures; // argument: -Wfuture- list V3StringSet m_libraryFiles; // argument: Verilog -v files V3StringList m_vFiles; // argument: Verilog files to read + DebugSrcMap m_debugSrcs; // argument: --debugi-= bool m_preprocOnly; // main switch: -E bool m_makeDepend; // main switch: -MMD @@ -170,6 +175,8 @@ class V3Options { V3Options(); ~V3Options(); void setDebugMode(int level); + void setDebugSrcLevel(const string& srcfile, int level); + int debugSrcLevel(const string& srcfile, int default_level=V3Error::debugDefault()); // METHODS void addCppFile(const string& filename); @@ -187,7 +194,7 @@ class V3Options { bool systemPerl() const { return m_systemPerl; } bool skipIdentical() const { return m_skipIdentical; } bool stats() const { return m_stats; } - bool assertOn() const { return m_assert; } // assertOn as "assert" may be defined + bool assertOn() const { return m_assert; } // assertOn as __FILE__ may be defined bool autoflush() const { return m_autoflush; } bool coverage() const { return m_coverageLine || m_coverageToggle || m_coverageUser; } bool coverageLine() const { return m_coverageLine; } diff --git a/src/V3Order.cpp b/src/V3Order.cpp index d44860ad2..678cf3e96 100644 --- a/src/V3Order.cpp +++ b/src/V3Order.cpp @@ -254,8 +254,6 @@ private: AstUser3InUse m_inuser3; //AstUser4InUse m_inuser4; // Used only when building tree, so below - //int debug() { return 9; } - // STATE OrderGraph m_graph; // Scoreboard of var usages/dependencies SenTreeFinder m_finder; // Find global sentree's and add them @@ -296,6 +294,12 @@ private: enum VarUsage { VU_NONE=0, VU_CON=1, VU_GEN=2 }; // METHODS + static int debug() { + static int level = -1; + if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); + return level; + } + void iterateNewStmt(AstNode* nodep) { if (m_scopep) { UINFO(4," STMT "< usedLetter; usedLetter.resize(256); // Pass 1, assign first letter to each gparam's name diff --git a/src/V3PreShell.cpp b/src/V3PreShell.cpp index 6259a9a4f..946459d73 100644 --- a/src/V3PreShell.cpp +++ b/src/V3PreShell.cpp @@ -43,11 +43,15 @@ protected: static V3PreShellImp s_preImp; static V3PreProc* s_preprocp; - //int debug() { return 9; } - //--------------------------------------- // METHODS + static int debug() { + static int level = -1; + if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); + return level; + } + void boot(char** env) { // Create the implementation pointer if (env) {} diff --git a/src/V3Premit.cpp b/src/V3Premit.cpp index 1c8c41cd8..8e7cd334e 100644 --- a/src/V3Premit.cpp +++ b/src/V3Premit.cpp @@ -60,9 +60,13 @@ private: AstTraceInc* m_inTracep; // Inside while loop, special statement additions bool m_assignLhs; // Inside assignment lhs, don't breakup extracts - //int debug() { return 9; } - // METHODS + static int debug() { + static int level = -1; + if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); + return level; + } + bool assignNoTemp(AstNodeAssign* nodep) { return (nodep->lhsp()->castVarRef() && !nodep->lhsp()->castVarRef()->varp()->isSc() diff --git a/src/V3Read.h b/src/V3Read.h index 4202fbba9..559919734 100644 --- a/src/V3Read.h +++ b/src/V3Read.h @@ -51,6 +51,8 @@ class V3Read { deque m_numberps; // Created numbers for later cleanup deque m_lintState; // Current lint state for save/restore deque m_ppBuffers; // Preprocessor->lex buffer of characters to process + + // Options isn't visible, so not using debugSrcLevel //int debug() { return 9; } protected: diff --git a/src/V3Scope.cpp b/src/V3Scope.cpp index e3f34e69a..e5dd17011 100644 --- a/src/V3Scope.cpp +++ b/src/V3Scope.cpp @@ -56,7 +56,12 @@ private: AstCell* m_aboveCellp; // Cell that instantiates this module AstScope* m_aboveScopep; // Scope that instantiates this scope - //int debug() { return 9; } + // METHODS + static int debug() { + static int level = -1; + if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); + return level; + } // VISITORS virtual void visit(AstNetlist* nodep, AstNUser*) { @@ -250,9 +255,13 @@ private: // STATE AstScope* m_scopep; // Current scope we are building - //int debug() { return 9; } - // METHODS + static int debug() { + static int level = -1; + if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); + return level; + } + // VISITORS virtual void visit(AstScope* nodep, AstNUser*) { // Want to ignore blocks under it diff --git a/src/V3SenTree.h b/src/V3SenTree.h index 2054d146e..35737ed9b 100644 --- a/src/V3SenTree.h +++ b/src/V3SenTree.h @@ -55,8 +55,14 @@ private: // STATE AstTopScope* m_topscopep; // Top scope to add statement to vector m_treesp; // List of sensitive blocks, for folding - //int debug() { return 9; } + // VISITORS + static int debug() { + static int level = -1; + if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); + return level; + } + virtual void visit(AstModule* nodep, AstNUser*) { // Only do the top if (nodep->isTop()) { diff --git a/src/V3Split.cpp b/src/V3Split.cpp index 5fc6922bd..2f9ec017c 100644 --- a/src/V3Split.cpp +++ b/src/V3Split.cpp @@ -235,9 +235,13 @@ private: uint32_t m_stepNum; // Step number we need to ignore a edge in V3Double0 m_statSplits; // Statistic tracking - //int debug() { return 9; } - // METHODS + static int debug() { + static int level = -1; + if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); + return level; + } + void scoreboardClear() { //VV***** We reset user1p() and user2p on each block!!! m_inDly = false; diff --git a/src/V3SplitAs.cpp b/src/V3SplitAs.cpp index 5432ef5de..65e872731 100644 --- a/src/V3SplitAs.cpp +++ b/src/V3SplitAs.cpp @@ -44,7 +44,11 @@ class SplitAsBaseVisitor : public AstNVisitor { public: // METHODS - //int debug() { return 9; } + static int debug() { + static int level = -1; + if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); + return level; + } }; //###################################################################### diff --git a/src/V3Subst.cpp b/src/V3Subst.cpp index 310becaa9..f5fa2c777 100644 --- a/src/V3Subst.cpp +++ b/src/V3Subst.cpp @@ -45,8 +45,11 @@ class SubstBaseVisitor : public AstNVisitor { public: - static int debug() { return V3Error::debugDefault(); } -// static int debug() { return 9; } + static int debug() { + static int level = -1; + if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); + return level; + } }; //###################################################################### @@ -80,6 +83,7 @@ class SubstVarEntry { SubstVarWord m_whole; // Data for whole vector used at once vector m_words; // Data for every word, if multi word variable int debug() { return SubstBaseVisitor::debug(); } + public: // CONSTRUCTORS SubstVarEntry (AstVar* varp) { // Construction for when a var is used diff --git a/src/V3Table.cpp b/src/V3Table.cpp index 143545cd6..a8001970d 100644 --- a/src/V3Table.cpp +++ b/src/V3Table.cpp @@ -54,8 +54,11 @@ class TableVisitor; class TableBaseVisitor : public AstNVisitor { public: // Note level 8&9 include debugging each simulation value -// int debug() { return 7; } -// int debug() { return 9; } + static int debug() { + static int level = -1; + if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); + return level; + } }; //###################################################################### diff --git a/src/V3Task.cpp b/src/V3Task.cpp index e658057f5..1e147ac7c 100644 --- a/src/V3Task.cpp +++ b/src/V3Task.cpp @@ -314,9 +314,14 @@ private: InsertMode m_insMode; // How to insert AstNode* m_insStmtp; // Where to insert statement int m_modNCalls; // Incrementing func # for making symbols - //int debug() { return 9; } // METHODS + static int debug() { + static int level = -1; + if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); + return level; + } + AstVarScope* createVarScope(AstVar* invarp, const string& name) { // We could create under either the ref's scope or the ftask's scope. // It shouldn't matter, as they are only local variables. diff --git a/src/V3Trace.cpp b/src/V3Trace.cpp index 3d46aed88..9b6a9d958 100644 --- a/src/V3Trace.cpp +++ b/src/V3Trace.cpp @@ -189,9 +189,13 @@ private: V3Double0 m_statUniqSigs; // Statistic tracking V3Double0 m_statUniqCodes;// Statistic tracking - //int debug() { return 9; } - // METHODS + static int debug() { + static int level = -1; + if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); + return level; + } + void detectDuplicates() { UINFO(9,"Finding duplicates\n"); // Note uses user4 diff --git a/src/V3TraceDecl.cpp b/src/V3TraceDecl.cpp index 2aab12de1..e5c6c2c4c 100644 --- a/src/V3TraceDecl.cpp +++ b/src/V3TraceDecl.cpp @@ -54,9 +54,14 @@ private: V3Double0 m_statSigs; // Statistic tracking V3Double0 m_statIgnSigs; // Statistic tracking - //int debug() { return 9; } // METHODS + static int debug() { + static int level = -1; + if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); + return level; + } + const char* varIgnoreTrace(AstVar* nodep) { // Return true if this shouldn't be traced // See also similar rule in V3Coverage::varIgnoreToggle diff --git a/src/V3Tristate.cpp b/src/V3Tristate.cpp index 1ac0800fd..66d95b89d 100644 --- a/src/V3Tristate.cpp +++ b/src/V3Tristate.cpp @@ -68,7 +68,11 @@ typedef std::map VarMap; class TristateBaseVisitor : public AstNVisitor { public: - //int debug() { return 9; } + static int debug() { + static int level = -1; + if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); + return level; + } }; //###################################################################### diff --git a/src/V3Unknown.cpp b/src/V3Unknown.cpp index 62a5ce9a4..c439fabe8 100644 --- a/src/V3Unknown.cpp +++ b/src/V3Unknown.cpp @@ -58,7 +58,12 @@ private: bool m_constXCvt; // Convert X's V3Double0 m_statUnkVars; // Statistic tracking - //int debug() { return 9; } + // METHODS + static int debug() { + static int level = -1; + if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); + return level; + } // VISITORS virtual void visit(AstModule* nodep, AstNUser*) { diff --git a/src/V3Unroll.cpp b/src/V3Unroll.cpp index a8c036875..839822842 100644 --- a/src/V3Unroll.cpp +++ b/src/V3Unroll.cpp @@ -59,7 +59,12 @@ private: V3Double0 m_statLoops; // Statistic tracking V3Double0 m_statIters; // Statistic tracking - //int debug() { return 9; } + // METHODS + static int debug() { + static int level = -1; + if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); + return level; + } // VISITORS virtual void visit(AstModule* nodep, AstNUser*) { diff --git a/src/V3Width.cpp b/src/V3Width.cpp index 3b459333e..860f8664c 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -81,15 +81,18 @@ private: AstRange* m_cellRangep; // Range for arrayed instantiations, NULL for normal instantiations AstNodeCase* m_casep; // Current case statement CaseItem is under - //int debug() { return 9; } - // CLASSES #define ANYSIZE 0 // METHODS - // Naming: width_{output size rule}_{lhs rule}_{rhs rule} + static int debug() { + static int level = -1; + if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); + return level; + } // VISITORS + // Naming: width_{output size rule}_{lhs rule}_{rhs rule} // Widths: 1 bit out, lhs 1 bit void width_O1_L1(AstNode* nodep, AstNUser* vup); virtual void visit(AstLogNot* nodep, AstNUser* vup) { width_O1_L1(nodep,vup); } diff --git a/test_regress/driver.pl b/test_regress/driver.pl index f97d8bf38..cdeb3fdf3 100755 --- a/test_regress/driver.pl +++ b/test_regress/driver.pl @@ -1,17 +1,5 @@ #!/usr/bin/perl -w -###################################################################### -# -# This program is Copyright 2003-2009 by Wilson Snyder. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of either the GNU General Public License or the -# Perl Artistic License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# +# See copyright, etc in below POD section. ###################################################################### require 5.006_001; @@ -60,6 +48,9 @@ my $opt_gdb; my $opt_jobs = 1; my $opt_verbose; my $Opt_Verilated_Debug; +our @Opt_Driver_Verilator_Flags; + +Getopt::Long::config ("pass_through"); if (! GetOptions ( "help" => \&usage, "debug" => \&debug, @@ -75,7 +66,7 @@ if (! GetOptions ( "verbose!" => \$opt_verbose, "<>" => \¶meter, )) { - usage(); + die "%Error: Bad usage, try '$0 --help'\n"; } $opt_jobs = calc_jobs() if defined $opt_jobs && $opt_jobs==0; @@ -155,14 +146,28 @@ sub usage { sub debug { $Debug = 1; + push @Opt_Driver_Verilator_Flags, "--debug"; } +our $_Parameter_Next_Level; + sub parameter { my $param = shift; - if ($param =~ /\.pl/) { + if ($_Parameter_Next_Level) { + ($param =~ /^(\d+)$/) + or die "%Error: Expected number following $_Parameter_Next_Level: $param\n"; + push @Opt_Driver_Verilator_Flags, $param; + $_Parameter_Next_Level = undef; + } + elsif ($param =~ /\.pl/) { push @opt_tests, $param; - } else { - die "%Error: Unknown parameter: $param\n"; + } + elsif ($param =~ /^--debugi/) { + push @Opt_Driver_Verilator_Flags, $param; + $_Parameter_Next_Level = $param; + } + else { + warn "%Error: Unknown parameter: $param\n"; } } @@ -379,7 +384,7 @@ sub compile { $opt_gdb="gdbrun" if defined $opt_gdb; my @verilator_flags = @{$param{verilator_flags}}; unshift @verilator_flags, "--gdb $opt_gdb" if $opt_gdb; - unshift @verilator_flags, "--debug" if $::Debug; + unshift @verilator_flags, @Opt_Driver_Verilator_Flags; unshift @verilator_flags, "--x-assign unique"; # More likely to be buggy # unshift @verilator_flags, "--trace"; if (defined $opt_optimize) { @@ -1057,12 +1062,22 @@ Command to use to invoke VCS. =back -=head1 SEE ALSO +=head1 DISTRIBUTION + +The latest version is available from L. + +Copyright 2003-2009 by Wilson Snyder. Verilator is free software; you can +redistribute it and/or modify it under the terms of either the GNU Lesser +General Public License or the Perl Artistic License. =head1 AUTHORS Wilson Snyder +=head1 SEE ALSO + +L + =cut ######################################################################