Add /*verilator coverage_module_off*/
This commit is contained in:
parent
a1e091cff7
commit
0fed1d34d1
2
Changes
2
Changes
|
|
@ -5,6 +5,8 @@ indicates the contributor was also the author of the fix; Thanks!
|
|||
|
||||
* Verilator 3.700***
|
||||
|
||||
** Add /*verilator coverage_module_off*/.
|
||||
|
||||
*** Optimize two-level shift and and/or trees, +23% on one test.
|
||||
|
||||
*** Support posedge of bit-selected signals, bug45. [Rodney Sinclair]
|
||||
|
|
|
|||
|
|
@ -311,7 +311,8 @@ corresponding to each counter are written into logs/coverage.pl.
|
|||
Verilator automatically disables coverage of branches that have a $stop in
|
||||
them, as it is assumed $stop branches contain an error check that should
|
||||
not occur. A /*verilator coverage_block_off*/ comment will perform a
|
||||
similar function on any code in that block or below.
|
||||
similar function on any code in that block or below, or /*verilator
|
||||
coverage_module_off*/ will disable coverage on the entire module.
|
||||
|
||||
Note Verilator may over-count combinatorial (non-clocked) blocks when those
|
||||
blocks receive signals which have had the UNOPTFLAT warning disabled; for
|
||||
|
|
@ -1221,7 +1222,13 @@ ignored in the scheduling algorithm, improving performance.
|
|||
|
||||
=item /*verilator coverage_block_off*/
|
||||
|
||||
Specifies the entire begin/end block should be ignored for coverage analysis.
|
||||
Specifies the entire begin/end block should be ignored for coverage
|
||||
analysis purposes.
|
||||
|
||||
=item /*verilator coverage_module_off*/
|
||||
|
||||
Specifies the entire module should be ignored for coverage analysis
|
||||
purposes.
|
||||
|
||||
=item /*verilator inline_module*/
|
||||
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ class AstPragmaType {
|
|||
public:
|
||||
enum en {
|
||||
COVERAGE_BLOCK_OFF,
|
||||
COVERAGE_MODULE_OFF,
|
||||
INLINE_MODULE,
|
||||
NO_INLINE_MODULE,
|
||||
NO_INLINE_TASK,
|
||||
|
|
|
|||
|
|
@ -574,6 +574,7 @@ struct AstModule : public AstNode {
|
|||
private:
|
||||
string m_name; // Name of the module
|
||||
string m_origName; // Name of the module, ignoring name() changes, for dot lookup
|
||||
bool m_modCover:1; // Coverage of this module
|
||||
bool m_modPublic:1; // Module has public references
|
||||
bool m_modTrace:1; // Tracing this module
|
||||
bool m_inLibrary:1; // From a library, no error if not used, never top level
|
||||
|
|
@ -583,8 +584,8 @@ private:
|
|||
public:
|
||||
AstModule(FileLine* fl, const string& name)
|
||||
: AstNode (fl)
|
||||
,m_name(name), m_origName(name), m_modPublic(false)
|
||||
,m_modTrace(false), m_inLibrary(false)
|
||||
,m_name(name), m_origName(name), m_modCover(true)
|
||||
,m_modPublic(false), m_modTrace(false), m_inLibrary(false)
|
||||
,m_level(0), m_varNum(0), m_clkReqVarp(NULL) { }
|
||||
ASTNODE_NODE_FUNCS(Module, MODULE)
|
||||
virtual void dump(ostream& str);
|
||||
|
|
@ -608,6 +609,8 @@ public:
|
|||
int varNumGetInc() { return ++m_varNum; }
|
||||
AstVar* clkReqVarp() const { return m_clkReqVarp; }
|
||||
void clkReqVarp(AstVar* varp) { m_clkReqVarp = varp; }
|
||||
void modCover(bool flag) { m_modCover = flag; }
|
||||
bool modCover() const { return m_modCover; }
|
||||
void modPublic(bool flag) { m_modPublic = flag; }
|
||||
bool modPublic() const { return m_modPublic; }
|
||||
void modTrace(bool flag) { m_modTrace = flag; }
|
||||
|
|
|
|||
|
|
@ -73,13 +73,17 @@ private:
|
|||
return new AstCoverInc(fl, declp);
|
||||
}
|
||||
|
||||
// VISITORS
|
||||
// VISITORS - BOTH
|
||||
virtual void visit(AstModule* nodep, AstNUser*) {
|
||||
m_modp = nodep;
|
||||
m_fileps.clear();
|
||||
nodep->iterateChildren(*this);
|
||||
if (nodep->modCover()) { // Cleared by /*verilator coverage_module_off*/
|
||||
m_fileps.clear();
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
m_modp = NULL;
|
||||
}
|
||||
|
||||
// VISITORS - LINE COVERAGE
|
||||
virtual void visit(AstIf* nodep, AstNUser*) {
|
||||
UINFO(4," IF: "<<nodep<<endl);
|
||||
if (m_checkBlock) {
|
||||
|
|
@ -157,6 +161,8 @@ private:
|
|||
}
|
||||
m_beginHier = oldHier;
|
||||
}
|
||||
|
||||
// VISITORS - BOTH
|
||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||
// Default: Just iterate
|
||||
if (m_checkBlock) {
|
||||
|
|
|
|||
|
|
@ -157,12 +157,8 @@ class EmitVBaseVisitor : public EmitCBaseVisitor {
|
|||
puts((string)"// "+nodep->name()+"\n");
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
virtual void visit(AstCoverDecl*, AstNUser*) {
|
||||
// N/A
|
||||
}
|
||||
virtual void visit(AstCoverInc*, AstNUser*) {
|
||||
// N/A
|
||||
}
|
||||
virtual void visit(AstCoverDecl*, AstNUser*) {} // N/A
|
||||
virtual void visit(AstCoverInc*, AstNUser*) {} // N/A
|
||||
|
||||
void visitNodeDisplay(AstNode* nodep, AstNode* filep, const string& text, AstNode* exprsp) {
|
||||
putbs(nodep->verilogKwd());
|
||||
|
|
|
|||
|
|
@ -334,6 +334,11 @@ private:
|
|||
m_modp->modPublic(true); // Need to get to the task...
|
||||
nodep->unlinkFrBack(); pushDeletep(nodep); nodep=NULL;
|
||||
}
|
||||
else if (nodep->pragType() == AstPragmaType::COVERAGE_MODULE_OFF) {
|
||||
if (!m_modp) nodep->v3fatalSrc("COVERAGE_MODULE_OFF not under a module\n");
|
||||
m_modp->modCover(false);
|
||||
nodep->unlinkFrBack(); pushDeletep(nodep); nodep=NULL;
|
||||
}
|
||||
else if (nodep->pragType() == AstPragmaType::COVERAGE_BLOCK_OFF) {
|
||||
if (!v3Global.opt.coverageLine()) { // No need for block statements; may optimize better without
|
||||
nodep->unlinkFrBack(); pushDeletep(nodep); nodep=NULL;
|
||||
|
|
|
|||
|
|
@ -554,7 +554,8 @@ escid \\[^ \t\f\r\n]+
|
|||
<V95,V01,V05,S05,PSL>{
|
||||
"/*verilator"{ws}*"*/" {} /* Ignore empty comments, may be `endif // verilator */
|
||||
"/*verilator clock_enable*/" {yylval.fileline = CRELINE(); return yVL_CLOCK_ENABLE;}
|
||||
"/*verilator coverage_block_off*/" {yylval.fileline = CRELINE(); return yVL_COVER_OFF;}
|
||||
"/*verilator coverage_block_off*/" {yylval.fileline = CRELINE(); return yVL_COVERAGE_BLOCK_OFF;}
|
||||
"/*verilator coverage_module_off*/" {yylval.fileline = CRELINE(); return yVL_COVERAGE_MODULE_OFF;}
|
||||
"/*verilator full_case*/" {yylval.fileline = CRELINE(); return yVL_FULL_CASE;}
|
||||
"/*verilator inline_module*/" {yylval.fileline = CRELINE(); return yVL_INLINE_MODULE;}
|
||||
"/*verilator isolate_assignments*/" {yylval.fileline = CRELINE(); return yVL_ISOLATE_ASSIGNMENTS;}
|
||||
|
|
|
|||
|
|
@ -268,7 +268,8 @@ class AstSenTree;
|
|||
|
||||
%token<fileline> yVL_CLOCK "/*verilator sc_clock*/"
|
||||
%token<fileline> yVL_CLOCK_ENABLE "/*verilator clock_enable*/"
|
||||
%token<fileline> yVL_COVER_OFF "/*verilator coverage_block_off*/"
|
||||
%token<fileline> yVL_COVERAGE_BLOCK_OFF "/*verilator coverage_block_off*/"
|
||||
%token<fileline> yVL_COVERAGE_MODULE_OFF "/*verilator coverage_module_off*/"
|
||||
%token<fileline> yVL_FULL_CASE "/*verilator full_case*/"
|
||||
%token<fileline> yVL_INLINE_MODULE "/*verilator inline_module*/"
|
||||
%token<fileline> yVL_ISOLATE_ASSIGNMENTS "/*verilator isolate_assignments*/"
|
||||
|
|
@ -629,6 +630,7 @@ modItem<nodep>:
|
|||
| yaSCIMPH { $$ = new AstScImpHdr(CRELINE(),*$1); }
|
||||
| yaSCCTOR { $$ = new AstScCtor(CRELINE(),*$1); }
|
||||
| yaSCDTOR { $$ = new AstScDtor(CRELINE(),*$1); }
|
||||
| yVL_COVERAGE_MODULE_OFF { $$ = new AstPragma($1,AstPragmaType::COVERAGE_MODULE_OFF); }
|
||||
| yVL_INLINE_MODULE { $$ = new AstPragma($1,AstPragmaType::INLINE_MODULE); }
|
||||
| yVL_NO_INLINE_MODULE { $$ = new AstPragma($1,AstPragmaType::NO_INLINE_MODULE); }
|
||||
| yVL_PUBLIC_MODULE { $$ = new AstPragma($1,AstPragmaType::PUBLIC_MODULE); }
|
||||
|
|
@ -974,7 +976,7 @@ stmt<nodep>:
|
|||
| yD_FINISH '(' expr ')' ';' { $$ = new AstFinish($1); }
|
||||
| yD_STOP parenE ';' { $$ = new AstStop($1); }
|
||||
| yD_STOP '(' expr ')' ';' { $$ = new AstStop($1); }
|
||||
| yVL_COVER_OFF { $$ = new AstPragma($1,AstPragmaType::COVERAGE_BLOCK_OFF); }
|
||||
| yVL_COVERAGE_BLOCK_OFF { $$ = new AstPragma($1,AstPragmaType::COVERAGE_BLOCK_OFF); }
|
||||
| stateCaseForIf { $$ = $1; }
|
||||
| taskRef ';' { $$ = $1; }
|
||||
|
||||
|
|
|
|||
|
|
@ -473,6 +473,8 @@ sub execute {
|
|||
sub inline_checks {
|
||||
my $self = (ref $_[0]? shift : $Self);
|
||||
return 1 if $self->errors;
|
||||
return 1 if !$self->{v3};
|
||||
|
||||
my %param = (%{$self}, @_); # Default arguments are from $self
|
||||
|
||||
my $covfn = $Self->{coverage_filename};
|
||||
|
|
|
|||
|
|
@ -35,6 +35,10 @@ module t (/*AUTOARG*/
|
|||
// Inputs
|
||||
.clk (clk),
|
||||
.toggle (toggle));
|
||||
off o1 (/*AUTOINST*/
|
||||
// Inputs
|
||||
.clk (clk),
|
||||
.toggle (toggle));
|
||||
|
||||
always @ (posedge clk) begin
|
||||
if (cyc!=0) begin
|
||||
|
|
@ -134,3 +138,21 @@ module tsk (/*AUTOARG*/
|
|||
endtask
|
||||
|
||||
endmodule
|
||||
|
||||
module off (/*AUTOARG*/
|
||||
// Inputs
|
||||
clk, toggle
|
||||
);
|
||||
input clk;
|
||||
input toggle;
|
||||
|
||||
// verilator coverage_module_off
|
||||
|
||||
always @ (posedge clk) begin
|
||||
if (toggle) begin
|
||||
// CHECK_COVER_MISSING(-1)
|
||||
// because under coverage_module_off
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
|
|||
Loading…
Reference in New Issue