Add --unused-regexp

This commit is contained in:
Wilson Snyder 2011-01-01 19:43:22 -05:00
parent 2327698160
commit 1611362c22
5 changed files with 49 additions and 7 deletions

View File

@ -296,6 +296,7 @@ descriptions in the next sections for more information.
-U<var> Undefine preprocessor define -U<var> Undefine preprocessor define
--unroll-count <loops> Tune maximum loop iterations --unroll-count <loops> Tune maximum loop iterations
--unroll-stmts <stmts> Tune maximum loop body size --unroll-stmts <stmts> Tune maximum loop body size
--unused-regexp <regexp> Tune UNUSED lint signals
-V Verbose version and config -V Verbose version and config
-v <filename> Verilog library -v <filename> Verilog library
-Werror-<message> Convert warning to error -Werror-<message> Convert warning to error
@ -834,6 +835,12 @@ unrolled. See also BLKLOOPINIT warning.
Rarely needed. Specifies the maximum number of statements in a loop for Rarely needed. Specifies the maximum number of statements in a loop for
that loop to be unrolled. See also BLKLOOPINIT warning. that loop to be unrolled. See also BLKLOOPINIT warning.
=item --unused-regexp I<regexp>
Rarely needed. Specifies a simple regexp with * and ? that if a signal
name matches will suppress the UNUSED warning. Defaults to "*unused*".
Setting it to "" disables matching.
=item -V =item -V
Shows the verbose version, including configuration information compiled Shows the verbose version, including configuration information compiled
@ -2705,12 +2712,30 @@ correctly.
=item UNUSED =item UNUSED
Warns that the specified signal is never sinked. Verilator is fairly Warns that the specified signal is never sinked. Verilator is fairly
liberal in the usage calculations; making a signal public, or accessing liberal in the usage calculations; making a signal public, a signal
only a single array element marks the entire signal as used. matching --unused-regexp ("*unused*") or accessing only a single array
element marks the entire signal as used.
Disabled by default as this is a code style warning; it will simulate Disabled by default as this is a code style warning; it will simulate
correctly. correctly.
A recommended style for unused nets is to put at the bottom of a file code
similar to the following:
wire _unused_ok = &{1'b0,
sig_not_used_a,
sig_not_used_yet_b, // To be fixed
1'b0};
The reduction AND and constant zeros mean the net will always be zero, so
won't use simulation time. The redundant leading and trailing zeros avoid
syntax errors if there are no signals between them. The magic name
"unused" (-unused-regexp) is recognized by Verilator and suppresses
warnings; if using other lint tools, either teach to tool to ignore signals
with "unused" in the name, or put the appropriate lint_off around the wire.
Having unused signals in one place makes it easy to find what is unused,
and reduces the number of lint_off pragmas, reducing bugs.
=item VARHIDDEN =item VARHIDDEN
Warns that a task, function, or begin/end block is declaring a variable by Warns that a task, function, or begin/end block is declaring a variable by

View File

@ -872,6 +872,9 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
else if ( !strcmp (sw, "-top-module") && (i+1)<argc ) { else if ( !strcmp (sw, "-top-module") && (i+1)<argc ) {
shift; m_topModule = argv[i]; shift; m_topModule = argv[i];
} }
else if ( !strcmp (sw, "-unused-regexp") && (i+1)<argc ) {
shift; m_unusedRegexp = argv[i];
}
else if ( !strcmp (sw, "-x-assign") && (i+1)<argc) { else if ( !strcmp (sw, "-x-assign") && (i+1)<argc) {
shift; shift;
if (!strcmp (argv[i], "0")) { m_xAssign="0"; } if (!strcmp (argv[i], "0")) { m_xAssign="0"; }
@ -1083,6 +1086,7 @@ V3Options::V3Options() {
m_makeDir = "obj_dir"; m_makeDir = "obj_dir";
m_bin = ""; m_bin = "";
m_flags = ""; m_flags = "";
m_unusedRegexp = "*unused*";
m_xAssign = "fast"; m_xAssign = "fast";
m_language = V3LangCode::mostRecent(); m_language = V3LangCode::mostRecent();

View File

@ -147,8 +147,9 @@ class V3Options {
string m_modPrefix; // main switch: --mod-prefix string m_modPrefix; // main switch: --mod-prefix
string m_pipeFilter; // main switch: --pipe-filter string m_pipeFilter; // main switch: --pipe-filter
string m_prefix; // main switch: --prefix string m_prefix; // main switch: --prefix
string m_xAssign; // main switch: --x-assign
string m_topModule; // main switch: --top-module string m_topModule; // main switch: --top-module
string m_unusedRegexp; // main switch: --unused-regexp
string m_xAssign; // main switch: --x-assign
// Consider moving m_language into FileLine, so can know language per-node // Consider moving m_language into FileLine, so can know language per-node
V3LangCode m_language; // main switch: --language V3LangCode m_language; // main switch: --language
@ -266,6 +267,7 @@ class V3Options {
string pipeFilter() const { return m_pipeFilter; } string pipeFilter() const { return m_pipeFilter; }
string prefix() const { return m_prefix; } string prefix() const { return m_prefix; }
string topModule() const { return m_topModule; } string topModule() const { return m_topModule; }
string unusedRegexp() const { return m_unusedRegexp; }
string xAssign() const { return m_xAssign; } string xAssign() const { return m_xAssign; }
const V3StringSet& cppFiles() const { return m_cppFiles; } const V3StringSet& cppFiles() const { return m_cppFiles; }

View File

@ -133,6 +133,11 @@ public:
} }
} }
} }
bool unusedMatch(AstVar* nodep) {
const char* regexpp = v3Global.opt.unusedRegexp().c_str();
if (!regexpp || !*regexpp) return false;
return V3Options::wildmatch(nodep->prettyName().c_str(), regexpp);
}
void reportViolations() { void reportViolations() {
// Combine bits into overall state // Combine bits into overall state
AstVar* nodep = m_varp; AstVar* nodep = m_varp;
@ -163,18 +168,22 @@ public:
} else if (!anyD && !anyU) { } else if (!anyD && !anyU) {
// UNDRIVEN is considered more serious - as is more likely a bug, // UNDRIVEN is considered more serious - as is more likely a bug,
// thus undriven+unused bits get UNUSED warnings, as they're not as buggy. // thus undriven+unused bits get UNUSED warnings, as they're not as buggy.
nodep->v3warn(UNUSED, "Signal is not driven, nor used: "<<nodep->prettyName()); if (!unusedMatch(nodep)) {
nodep->v3warn(UNUSED, "Signal is not driven, nor used: "<<nodep->prettyName());
}
} else if (allD && !anyU) { } else if (allD && !anyU) {
nodep->v3warn(UNUSED, "Signal is not used: "<<nodep->prettyName()); if (!unusedMatch(nodep)) {
nodep->v3warn(UNUSED, "Signal is not used: "<<nodep->prettyName());
}
} else if (!anyD && allU) { } else if (!anyD && allU) {
nodep->v3warn(UNDRIVEN, "Signal is not driven: "<<nodep->prettyName()); nodep->v3warn(UNDRIVEN, "Signal is not driven: "<<nodep->prettyName());
} else { } else {
// Bits have different dispositions // Bits have different dispositions
if (anynotDU) { if (anynotDU && !unusedMatch(nodep)) {
nodep->v3warn(UNUSED, "Bits of signal are not driven, nor used: "<<nodep->prettyName() nodep->v3warn(UNUSED, "Bits of signal are not driven, nor used: "<<nodep->prettyName()
<<bitNames(BN_BOTH)); <<bitNames(BN_BOTH));
} }
if (anyDnotU) { if (anyDnotU && !unusedMatch(nodep)) {
nodep->v3warn(UNUSED, "Bits of signal are not used: "<<nodep->prettyName() nodep->v3warn(UNUSED, "Bits of signal are not used: "<<nodep->prettyName()
<<bitNames(BN_UNUSED)); <<bitNames(BN_UNUSED));
} }

View File

@ -22,6 +22,8 @@ module t (/*AUTOARG*/
reg sysused; reg sysused;
initial $bboxed(sysused); initial $bboxed(sysused);
wire _unused_ok;
endmodule endmodule
module sub; module sub;