diff --git a/Changes b/Changes index c2e34da47..e18cdf780 100644 --- a/Changes +++ b/Changes @@ -11,6 +11,8 @@ indicates the contributor was also the author of the fix; Thanks! *** Add public enums, bug833. [Jonathon Donaldson] +*** Trace_off now operates on cells, bug826. [Lane Brooks] + **** Fix public parameters in unused packages, bug804. [Jonathon Donaldson] **** Fix generate unrolling with function call, bug830. [Steven Slatter] diff --git a/bin/verilator b/bin/verilator index d46b6e20c..33f431270 100755 --- a/bin/verilator +++ b/bin/verilator @@ -2346,12 +2346,14 @@ behavior. See the test_regress/t/t_dpi_display.v file for an example. =item /*verilator tracing_off*/ Disable waveform tracing for all future signals that are declared in this -module. Often this is placed just after a primitive's module statement, so -that the entire module is not traced. +module, or cells below this module. Often this is placed just after a +primitive's module statement, so that the entire module and cells below it +are not traced. =item /*verilator tracing_on*/ -Re-enable waveform tracing for all future signals that are declared. +Re-enable waveform tracing for all future signals or cells that are +declared. =back diff --git a/src/V3AstNodes.h b/src/V3AstNodes.h index 62e6249be..391c4340a 100644 --- a/src/V3AstNodes.h +++ b/src/V3AstNodes.h @@ -1219,11 +1219,13 @@ private: AstScope* m_scopep; // Scope variable is underneath AstVar* m_varp; // [AfterLink] Pointer to variable itself bool m_circular:1; // Used in circular ordering dependency, need change detect + bool m_trace:1; // Tracing is turned on for this scope public: AstVarScope(FileLine* fl, AstScope* scopep, AstVar* varp) :AstNode(fl) , m_scopep(scopep), m_varp(varp) { m_circular = false; + m_trace = true; dtypeFrom(varp); } ASTNODE_NODE_FUNCS(VarScope, VARSCOPE) @@ -1244,6 +1246,8 @@ public: void valuep(AstNode* valuep) { addOp1p(valuep); } bool isCircular() const { return m_circular; } void circular(bool flag) { m_circular = flag; } + bool isTrace() const { return m_trace; } + void trace(bool flag) { m_trace = flag; } }; class AstVarRef : public AstNodeVarRef { @@ -1501,13 +1505,14 @@ private: string m_origName; // Original name before dot addition string m_modName; // Module the cell instances AstNodeModule* m_modp; // [AfterLink] Pointer to module instanced - bool m_hasIfaceVar; // True if a Var has been created for this cell + bool m_hasIfaceVar:1; // True if a Var has been created for this cell + bool m_trace:1; // Trace this cell public: AstCell(FileLine* fl, const string& instName, const string& modName, AstPin* pinsp, AstPin* paramsp, AstRange* rangep) : AstNode(fl) , m_name(instName), m_origName(instName), m_modName(modName) - , m_modp(NULL), m_hasIfaceVar(false) { + , m_modp(NULL), m_hasIfaceVar(false), m_trace(true) { addNOp1p(pinsp); addNOp2p(paramsp); setNOp3p(rangep); } ASTNODE_NODE_FUNCS(Cell, CELL) // No cloneRelink, we presume cloneee's want the same module linkages @@ -1530,6 +1535,8 @@ public: void modp(AstNodeModule* nodep) { m_modp = nodep; } bool hasIfaceVar() const { return m_hasIfaceVar; } void hasIfaceVar(bool flag) { m_hasIfaceVar = flag; } + void trace(bool flag) { m_trace=flag; } + bool isTrace() const { return m_trace; } }; class AstCellInline : public AstNode { diff --git a/src/V3Inline.cpp b/src/V3Inline.cpp index 975443504..b98897af3 100644 --- a/src/V3Inline.cpp +++ b/src/V3Inline.cpp @@ -314,6 +314,7 @@ private: // Also clear I/O bits, as it is now local. string name = m_cellp->name() + "__DOT__" + nodep->name(); if (!nodep->isFuncLocal()) nodep->inlineAttrReset(name); + if (!m_cellp->isTrace()) nodep->trace(false); if (debug()>=9) { nodep->dumpTree(cout,"varchanged:"); } if (debug()>=9) { nodep->valuep()->dumpTree(cout,"varchangei:"); } // Iterate won't hit AstIfaceRefDType directly as it is no longer underneath the module diff --git a/src/V3Scope.cpp b/src/V3Scope.cpp index ce2dffa88..d3f2d734a 100644 --- a/src/V3Scope.cpp +++ b/src/V3Scope.cpp @@ -241,6 +241,7 @@ private: if (!nodep->user1p()) { AstVarScope* varscp = new AstVarScope(nodep->fileline(), m_scopep, nodep); UINFO(6," New scope "<isTrace()) varscp->trace(false); nodep->user1p(varscp); if (!m_scopep) nodep->v3fatalSrc("No scope for var"); m_varScopes.insert(make_pair(make_pair(nodep, m_scopep), varscp)); @@ -258,8 +259,8 @@ private: // the var's referenced package etc might not be created yet. // So push to a list and post-correct m_varRefScopes.insert(make_pair(nodep, m_scopep)); - } - } + } + } virtual void visit(AstScopeName* nodep, AstNUser*) { // If there's a %m in the display text, we add a special node that will contain the name() string prefix = (string)("__DOT__")+m_scopep->name(); diff --git a/src/V3TraceDecl.cpp b/src/V3TraceDecl.cpp index aa84f922e..2bbfbb409 100644 --- a/src/V3TraceDecl.cpp +++ b/src/V3TraceDecl.cpp @@ -64,13 +64,17 @@ private: return level; } - const char* varIgnoreTrace(AstVar* nodep) { + const char* vscIgnoreTrace(AstVarScope* nodep) { // Return true if this shouldn't be traced // See also similar rule in V3Coverage::varIgnoreToggle - string prettyName = nodep->prettyName(); - if (!nodep->isTrace()) { + AstVar* varp = nodep->varp(); + string prettyName = varp->prettyName(); + if (!varp->isTrace()) { return "Verilator trace_off"; } + else if (!nodep->isTrace()) { + return "Verilator cell trace_off"; + } else if (!v3Global.opt.traceUnderscore()) { if (prettyName.size()>=1 && prettyName[0] == '_') return "Leading underscore"; @@ -163,8 +167,8 @@ private: m_traVscp = nodep; m_traValuep = NULL; - if (varIgnoreTrace(varp)) { - addIgnore(varIgnoreTrace(varp)); + if (vscIgnoreTrace(nodep)) { + addIgnore(vscIgnoreTrace(nodep)); } else { ++m_statSigs; if (nodep->valuep()) m_traValuep = nodep->valuep()->cloneTree(true); diff --git a/src/verilog.y b/src/verilog.y index 2f6bb09a6..4cdeb177d 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -2038,9 +2038,11 @@ instnameList: | instnameList ',' instnameParen { $$ = $1->addNext($3); } ; -instnameParen: - id instRangeE '(' cellpinList ')' { $$ = new AstCell($1,*$1,GRAMMARP->m_instModule,$4, GRAMMARP->m_instParamp,$2); } - | id instRangeE { $$ = new AstCell($1,*$1,GRAMMARP->m_instModule,NULL,GRAMMARP->m_instParamp,$2); } +instnameParen: + id instRangeE '(' cellpinList ')' { $$ = new AstCell($1,*$1,GRAMMARP->m_instModule,$4, GRAMMARP->m_instParamp,$2); + $$->trace(GRAMMARP->allTracingOn($1)); } + | id instRangeE { $$ = new AstCell($1,*$1,GRAMMARP->m_instModule,NULL,GRAMMARP->m_instParamp,$2); + $$->trace(GRAMMARP->allTracingOn($1)); } //UNSUP instRangeE '(' cellpinList ')' { UNSUP } // UDP // // Adding above and switching to the Verilog-Perl syntax // // causes a shift conflict due to use of idClassSel inside exprScope. diff --git a/test_regress/t/t_trace_ena.v b/test_regress/t/t_trace_ena.v index 8e452797b..b47e3d671 100644 --- a/test_regress/t/t_trace_ena.v +++ b/test_regress/t/t_trace_ena.v @@ -17,6 +17,10 @@ module t (/*AUTOARG*/ integer c_trace_on; real r; + // verilator tracing_off + sub sub (); + // verilator tracing_on + always @ (posedge clk) begin if (cyc!=0) begin cyc <= cyc + 1; @@ -34,3 +38,7 @@ module t (/*AUTOARG*/ end endmodule + +module sub; + integer inside_sub = 0; +endmodule diff --git a/test_regress/t/t_trace_ena_cc.pl b/test_regress/t/t_trace_ena_cc.pl index 5f72b9acd..4d5b6f922 100755 --- a/test_regress/t/t_trace_ena_cc.pl +++ b/test_regress/t/t_trace_ena_cc.pl @@ -21,6 +21,7 @@ if ($Self->{vlt}) { file_grep ("$Self->{obj_dir}/V$Self->{name}__Trace__Slow.cpp", qr/c_trace_on\"/x); file_grep_not ("$Self->{obj_dir}/V$Self->{name}__Trace__Slow.cpp", qr/_trace_off\"/x); file_grep ("$Self->{obj_dir}/simx.vcd", qr/\$enddefinitions/x); + file_grep_not ("$Self->{obj_dir}/simx.vcd", qr/inside_sub/x); } ok(1);