With --Wall, add IFDEPTH warning on deep if statements.
This commit is contained in:
parent
bb9ee46f40
commit
850de5913d
16
Changes
16
Changes
|
|
@ -7,24 +7,26 @@ indicates the contributor was also the author of the fix; Thanks!
|
||||||
|
|
||||||
** Add limited support for VPI access to public signals, see docs.
|
** Add limited support for VPI access to public signals, see docs.
|
||||||
|
|
||||||
** Add -Wall, -Wwarn-style, -Wno-style to enable code style warnings
|
|
||||||
that have been added to this release, and disabled by default.
|
|
||||||
|
|
||||||
*** Add -F option to read relative option files, bug297. [Neil Hamilton]
|
*** Add -F option to read relative option files, bug297. [Neil Hamilton]
|
||||||
|
|
||||||
*** Support ++,--,+= etc as standalone statements. [Alex Solomatnikov]
|
*** Support ++,--,+= etc as standalone statements. [Alex Solomatnikov]
|
||||||
|
|
||||||
*** Suppress WIDTH warnings when adding/subtracting 1'b1.
|
**** When running with VERILATOR_ROOT, optionally find binaries under bin.
|
||||||
|
|
||||||
|
**** Suppress WIDTH warnings when adding/subtracting 1'b1.
|
||||||
|
|
||||||
|
** Add -Wall, -Wwarn-style, -Wno-style to enable code style warnings
|
||||||
|
that have been added to this release, and disabled by default:
|
||||||
|
|
||||||
*** With --Wall, add DECLFILENAME warning on modules not matching filename.
|
*** With --Wall, add DECLFILENAME warning on modules not matching filename.
|
||||||
|
|
||||||
*** With --Wall, add DEFPARAM warning on deprecated defparam statements.
|
*** With --Wall, add DEFPARAM warning on deprecated defparam statements.
|
||||||
|
|
||||||
|
*** With --Wall, add IFDEPTH warning on deep if statements.
|
||||||
|
|
||||||
*** With --Wall, add INCABSPATH warning on `include with absolute paths.
|
*** With --Wall, add INCABSPATH warning on `include with absolute paths.
|
||||||
|
|
||||||
**** When running with VERILATOR_ROOT, optionally find binaries under bin.
|
*** The VARHIDDEN warning is now disabled by default, use -Wall to enable.
|
||||||
|
|
||||||
**** The VARHIDDEN warning is now disabled by default, use -Wall to enable.
|
|
||||||
|
|
||||||
* Verilator 3.805 2010/11/02
|
* Verilator 3.805 2010/11/02
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -255,6 +255,7 @@ descriptions in the next sections for more information.
|
||||||
--gdbbt Run Verilator under GDB for backtrace
|
--gdbbt Run Verilator under GDB for backtrace
|
||||||
--help Display this help
|
--help Display this help
|
||||||
-I<dir> Directory to search for includes
|
-I<dir> Directory to search for includes
|
||||||
|
--if-depth <value> Tune IFDEPTH warning
|
||||||
+incdir+<dir> Directory to search for includes
|
+incdir+<dir> Directory to search for includes
|
||||||
--inhibit-sim Create function to turn off sim
|
--inhibit-sim Create function to turn off sim
|
||||||
--inline-mult <value> Tune module inlining
|
--inline-mult <value> Tune module inlining
|
||||||
|
|
@ -558,6 +559,11 @@ include directories or libraries. Same as +incdir and -y; +incdir and -y
|
||||||
are fairly standard across Verilog tools while -I is an alias for GCC
|
are fairly standard across Verilog tools while -I is an alias for GCC
|
||||||
compatibility.
|
compatibility.
|
||||||
|
|
||||||
|
=item --if-depth I<value>
|
||||||
|
|
||||||
|
Rarely needed. Set the depth at which the IFDEPTH warning will fire,
|
||||||
|
defaults to 0 which disables this warning.
|
||||||
|
|
||||||
=item +incdir+I<dir>
|
=item +incdir+I<dir>
|
||||||
|
|
||||||
Add the directory to the list of directories that should be searched for
|
Add the directory to the list of directories that should be searched for
|
||||||
|
|
@ -2420,6 +2426,16 @@ additional ones.)
|
||||||
Ignoring this warning may make Verilator simulations differ from other
|
Ignoring this warning may make Verilator simulations differ from other
|
||||||
simulators.
|
simulators.
|
||||||
|
|
||||||
|
=item IFDEPTH
|
||||||
|
|
||||||
|
Warns that if/if else statements have exceeded the depth specified with
|
||||||
|
--if-depth, as they are likely to result in slow priority encoders. Unique
|
||||||
|
and priority if statements are ignored. Solutions include changing the
|
||||||
|
code to a case statement, or a SystemVerilog 'unique if' or 'priority if'.
|
||||||
|
|
||||||
|
Disabled by default as this is a code style warning, it will simulate
|
||||||
|
correctly.
|
||||||
|
|
||||||
=item IMPERFECTSCH
|
=item IMPERFECTSCH
|
||||||
|
|
||||||
Warns that the scheduling of the model is not absolutely perfect, and some
|
Warns that the scheduling of the model is not absolutely perfect, and some
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,7 @@ private:
|
||||||
string m_namedScope; // Name of begin blocks above us
|
string m_namedScope; // Name of begin blocks above us
|
||||||
string m_unnamedScope; // Name of begin blocks, including unnamed blocks
|
string m_unnamedScope; // Name of begin blocks, including unnamed blocks
|
||||||
int m_repeatNum; // Repeat counter
|
int m_repeatNum; // Repeat counter
|
||||||
|
int m_ifDepth; // Current if depth
|
||||||
|
|
||||||
// METHODS
|
// METHODS
|
||||||
static int debug() {
|
static int debug() {
|
||||||
|
|
@ -152,6 +153,21 @@ private:
|
||||||
// any BEGINs, but V3Coverage adds them all under the module itself.
|
// any BEGINs, but V3Coverage adds them all under the module itself.
|
||||||
nodep->iterateChildren(*this);
|
nodep->iterateChildren(*this);
|
||||||
}
|
}
|
||||||
|
// VISITORS - LINT CHECK
|
||||||
|
virtual void visit(AstIf* nodep, AstNUser*) { // Note not AstNodeIf; other types don't get covered
|
||||||
|
// Check IFDEPTH warning - could be in other transform files if desire
|
||||||
|
int prevIfDepth = m_ifDepth;
|
||||||
|
if (m_ifDepth == -1 || v3Global.opt.ifDepth()<1) { // Turned off
|
||||||
|
} else if (nodep->uniquePragma() || nodep->unique0Pragma() || nodep->priorityPragma()) {
|
||||||
|
m_ifDepth = -1;
|
||||||
|
} else if (++m_ifDepth > v3Global.opt.ifDepth()) {
|
||||||
|
nodep->v3warn(IFDEPTH,"Deep 'if' statement; suggest unique/priority to avoid slow logic");
|
||||||
|
nodep->fileline()->warnOn(V3ErrorCode::IFDEPTH, false); // Warn only once
|
||||||
|
m_ifDepth = -1;
|
||||||
|
}
|
||||||
|
nodep->iterateChildren(*this);
|
||||||
|
m_ifDepth = prevIfDepth;
|
||||||
|
}
|
||||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||||
nodep->iterateChildren(*this);
|
nodep->iterateChildren(*this);
|
||||||
}
|
}
|
||||||
|
|
@ -161,6 +177,7 @@ public:
|
||||||
m_modp = NULL;
|
m_modp = NULL;
|
||||||
m_ftaskp = NULL;
|
m_ftaskp = NULL;
|
||||||
m_repeatNum = 0;
|
m_repeatNum = 0;
|
||||||
|
m_ifDepth = 0;
|
||||||
nodep->accept(*this);
|
nodep->accept(*this);
|
||||||
}
|
}
|
||||||
virtual ~BeginVisitor() {}
|
virtual ~BeginVisitor() {}
|
||||||
|
|
|
||||||
|
|
@ -63,9 +63,8 @@ public:
|
||||||
COMBDLY, // Combinatorial delayed assignment
|
COMBDLY, // Combinatorial delayed assignment
|
||||||
DEFPARAM, // Style: Defparam
|
DEFPARAM, // Style: Defparam
|
||||||
DECLFILENAME, // Declaration doesn't match filename
|
DECLFILENAME, // Declaration doesn't match filename
|
||||||
STMTDLY, // Delayed statement
|
|
||||||
SYMRSVDWORD, // Symbol is Reserved Word
|
|
||||||
GENCLK, // Generated Clock
|
GENCLK, // Generated Clock
|
||||||
|
IFDEPTH, // If statements too deep
|
||||||
IMPERFECTSCH, // Imperfect schedule (disabled by default)
|
IMPERFECTSCH, // Imperfect schedule (disabled by default)
|
||||||
IMPLICIT, // Implicit wire
|
IMPLICIT, // Implicit wire
|
||||||
IMPURE, // Impure function not being inlined
|
IMPURE, // Impure function not being inlined
|
||||||
|
|
@ -74,6 +73,8 @@ public:
|
||||||
MODDUP, // Duplicate module
|
MODDUP, // Duplicate module
|
||||||
MULTIDRIVEN, // Driven from multiple blocks
|
MULTIDRIVEN, // Driven from multiple blocks
|
||||||
REDEFMACRO, // Redefining existing define macro
|
REDEFMACRO, // Redefining existing define macro
|
||||||
|
STMTDLY, // Delayed statement
|
||||||
|
SYMRSVDWORD, // Symbol is Reserved Word
|
||||||
UNDRIVEN, // No drivers
|
UNDRIVEN, // No drivers
|
||||||
UNOPT, // Unoptimizable block
|
UNOPT, // Unoptimizable block
|
||||||
UNOPTFLAT, // Unoptimizable block after flattening
|
UNOPTFLAT, // Unoptimizable block after flattening
|
||||||
|
|
@ -104,10 +105,11 @@ public:
|
||||||
"BLKANDNBLK",
|
"BLKANDNBLK",
|
||||||
"CASEINCOMPLETE", "CASEOVERLAP", "CASEWITHX", "CASEX", "CDCRSTLOGIC", "CMPCONST",
|
"CASEINCOMPLETE", "CASEOVERLAP", "CASEWITHX", "CASEX", "CDCRSTLOGIC", "CMPCONST",
|
||||||
"COMBDLY", "DEFPARAM", "DECLFILENAME",
|
"COMBDLY", "DEFPARAM", "DECLFILENAME",
|
||||||
"STMTDLY", "SYMRSVDWORD", "GENCLK", "IMPERFECTSCH", "IMPLICIT", "IMPURE",
|
"GENCLK",
|
||||||
"INCABSPATH",
|
"IFDEPTH", "IMPERFECTSCH", "IMPLICIT", "IMPURE", "INCABSPATH",
|
||||||
"LITENDIAN", "MODDUP",
|
"LITENDIAN", "MODDUP",
|
||||||
"MULTIDRIVEN", "REDEFMACRO",
|
"MULTIDRIVEN", "REDEFMACRO",
|
||||||
|
"STMTDLY", "SYMRSVDWORD",
|
||||||
"UNDRIVEN", "UNOPT", "UNOPTFLAT", "UNSIGNED", "UNUSED",
|
"UNDRIVEN", "UNOPT", "UNOPTFLAT", "UNSIGNED", "UNUSED",
|
||||||
"VARHIDDEN", "WIDTH", "WIDTHCONCAT",
|
"VARHIDDEN", "WIDTH", "WIDTHCONCAT",
|
||||||
" MAX"
|
" MAX"
|
||||||
|
|
|
||||||
|
|
@ -705,6 +705,10 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
|
||||||
else if ( !strncmp (sw, "-I", 2)) {
|
else if ( !strncmp (sw, "-I", 2)) {
|
||||||
addIncDir (parseFileArg(optdir, string (sw+strlen("-I"))));
|
addIncDir (parseFileArg(optdir, string (sw+strlen("-I"))));
|
||||||
}
|
}
|
||||||
|
else if ( !strcmp (sw, "-if-depth") && (i+1)<argc ) {
|
||||||
|
shift;
|
||||||
|
m_ifDepth = atoi(argv[i]);
|
||||||
|
}
|
||||||
else if ( !strcmp (sw, "-inline-mult") && (i+1)<argc ) {
|
else if ( !strcmp (sw, "-inline-mult") && (i+1)<argc ) {
|
||||||
shift;
|
shift;
|
||||||
m_inlineMult = atoi(argv[i]);
|
m_inlineMult = atoi(argv[i]);
|
||||||
|
|
@ -1061,6 +1065,7 @@ V3Options::V3Options() {
|
||||||
m_underlineZero = false;
|
m_underlineZero = false;
|
||||||
|
|
||||||
m_errorLimit = 50;
|
m_errorLimit = 50;
|
||||||
|
m_ifDepth = 0;
|
||||||
m_inlineMult = 2000;
|
m_inlineMult = 2000;
|
||||||
m_outputSplit = 0;
|
m_outputSplit = 0;
|
||||||
m_outputSplitCFuncs = 0;
|
m_outputSplitCFuncs = 0;
|
||||||
|
|
|
||||||
|
|
@ -127,6 +127,7 @@ class V3Options {
|
||||||
bool m_underlineZero;// main switch: --underline-zero; undocumented old Verilator 2
|
bool m_underlineZero;// main switch: --underline-zero; undocumented old Verilator 2
|
||||||
|
|
||||||
int m_errorLimit; // main switch: --error-limit
|
int m_errorLimit; // main switch: --error-limit
|
||||||
|
int m_ifDepth; // main switch: --if-depth
|
||||||
int m_inlineMult; // main switch: --inline-mult
|
int m_inlineMult; // main switch: --inline-mult
|
||||||
int m_outputSplit; // main switch: --output-split
|
int m_outputSplit; // main switch: --output-split
|
||||||
int m_outputSplitCFuncs;// main switch: --output-split-cfuncs
|
int m_outputSplitCFuncs;// main switch: --output-split-cfuncs
|
||||||
|
|
@ -245,6 +246,7 @@ class V3Options {
|
||||||
bool inhibitSim() const { return m_inhibitSim; }
|
bool inhibitSim() const { return m_inhibitSim; }
|
||||||
|
|
||||||
int errorLimit() const { return m_errorLimit; }
|
int errorLimit() const { return m_errorLimit; }
|
||||||
|
int ifDepth() const { return m_ifDepth; }
|
||||||
int inlineMult() const { return m_inlineMult; }
|
int inlineMult() const { return m_inlineMult; }
|
||||||
int outputSplit() const { return m_outputSplit; }
|
int outputSplit() const { return m_outputSplit; }
|
||||||
int outputSplitCFuncs() const { return m_outputSplitCFuncs; }
|
int outputSplitCFuncs() const { return m_outputSplitCFuncs; }
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# Copyright 2008 by Wilson Snyder. This program is free software; you can
|
||||||
|
# redistribute it and/or modify it under the terms of either the GNU
|
||||||
|
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
|
# Version 2.0.
|
||||||
|
|
||||||
|
compile (
|
||||||
|
v_flags2 => ["--lint-only -Wall -Wno-DECLFILENAME --if-depth 10"],
|
||||||
|
fails=>1,
|
||||||
|
verilator_make_gcc => 0,
|
||||||
|
make_top_shell => 0,
|
||||||
|
make_main => 0,
|
||||||
|
expect=>
|
||||||
|
'%Warning-IFDEPTH: t/t_lint_ifdepth_bad.v:\d+: Deep \'if\' statement; suggest unique/priority to avoid slow logic
|
||||||
|
%Warning-IFDEPTH: Use .* to disable this message.
|
||||||
|
%Error: Exiting due to.*',
|
||||||
|
) if $Self->{v3};
|
||||||
|
|
||||||
|
ok(1);
|
||||||
|
1;
|
||||||
|
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
//
|
||||||
|
// This file ONLY is placed into the Public Domain, for any use,
|
||||||
|
// without warranty, 2010 by Wilson Snyder.
|
||||||
|
|
||||||
|
module t;
|
||||||
|
|
||||||
|
integer v = 19;
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
if (v==1) begin end
|
||||||
|
else if (v==2) begin end
|
||||||
|
else if (v==3) begin end
|
||||||
|
else if (v==4) begin end
|
||||||
|
else if (v==5) begin end
|
||||||
|
else if (v==6) begin end
|
||||||
|
else if (v==7) begin end
|
||||||
|
else if (v==8) begin end
|
||||||
|
else if (v==9) begin end
|
||||||
|
else if (v==10) begin end
|
||||||
|
else if (v==11) begin end // Warn about this one
|
||||||
|
else if (v==12) begin end
|
||||||
|
end
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
unique0 if (v==1) begin end
|
||||||
|
else if (v==2) begin end
|
||||||
|
else if (v==3) begin end
|
||||||
|
else if (v==4) begin end
|
||||||
|
else if (v==5) begin end
|
||||||
|
else if (v==6) begin end
|
||||||
|
else if (v==7) begin end
|
||||||
|
else if (v==8) begin end
|
||||||
|
else if (v==9) begin end
|
||||||
|
else if (v==10) begin end
|
||||||
|
else if (v==11) begin end // Warn about this one
|
||||||
|
else if (v==12) begin end
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
Loading…
Reference in New Issue