Report UNUSED on parameters, localparam and genvars (#2627).
This commit is contained in:
parent
251812638d
commit
47eeef485d
4
Changes
4
Changes
|
@ -5,10 +5,14 @@ The contributors that suggested a given feature are shown in []. Thanks!
|
||||||
|
|
||||||
* Verilator 4.107 devel
|
* Verilator 4.107 devel
|
||||||
|
|
||||||
|
** Support randomize() class method and rand (#2607). [Krzysztof Bieganski]
|
||||||
|
|
||||||
*** Support $cast and new CASTCONST warning.
|
*** Support $cast and new CASTCONST warning.
|
||||||
|
|
||||||
*** Add --top option as alias of --top-module.
|
*** Add --top option as alias of --top-module.
|
||||||
|
|
||||||
|
**** Report UNUSED on parameters, localparam and genvars (#2627). [Charles Eric LaForest]
|
||||||
|
|
||||||
**** Fix passing parameter type instantiations by position number.
|
**** Fix passing parameter type instantiations by position number.
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -4973,10 +4973,10 @@ design simulate incorrectly; see the details under --bbox-unsup.
|
||||||
|
|
||||||
=item UNUSED
|
=item UNUSED
|
||||||
|
|
||||||
Warns that the specified signal is never used/consumed. Verilator is
|
Warns that the specified signal or parameter is never used/consumed.
|
||||||
fairly liberal in the usage calculations; making a signal public, a signal
|
Verilator is fairly liberal in the usage calculations; making a signal
|
||||||
matching --unused-regexp ("*unused*") or accessing only a single array
|
public, a signal matching --unused-regexp ("*unused*") or accessing only a
|
||||||
element marks the entire signal as used.
|
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.
|
||||||
|
|
|
@ -330,12 +330,6 @@ private:
|
||||||
if (nodep->isSigPublic()) return false; // Can't elim publics!
|
if (nodep->isSigPublic()) return false; // Can't elim publics!
|
||||||
if (nodep->isIO() || nodep->isClassMember()) return false;
|
if (nodep->isIO() || nodep->isClassMember()) return false;
|
||||||
if (nodep->isTemp() && !nodep->isTrace()) return true;
|
if (nodep->isTemp() && !nodep->isTrace()) return true;
|
||||||
if (nodep->isParam()) {
|
|
||||||
const bool overriddenForHierBlock
|
|
||||||
= m_modp && m_modp->hierBlock() && nodep->overriddenParam();
|
|
||||||
if (!nodep->isTrace() && !overriddenForHierBlock && !v3Global.opt.xmlOnly())
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return m_elimUserVars; // Post-Trace can kill most anything
|
return m_elimUserVars; // Post-Trace can kill most anything
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -105,7 +105,7 @@ private:
|
||||||
|
|
||||||
virtual void visit(AstNodeVarRef* nodep) override {
|
virtual void visit(AstNodeVarRef* nodep) override {
|
||||||
// VarRef: Resolve its reference
|
// VarRef: Resolve its reference
|
||||||
if (nodep->varp()) { nodep->varp()->usedParam(true); }
|
if (nodep->varp()) nodep->varp()->usedParam(true);
|
||||||
iterateChildren(nodep);
|
iterateChildren(nodep);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -149,7 +149,7 @@ public:
|
||||||
void reportViolations() {
|
void reportViolations() {
|
||||||
// Combine bits into overall state
|
// Combine bits into overall state
|
||||||
AstVar* nodep = m_varp;
|
AstVar* nodep = m_varp;
|
||||||
if (!nodep->isParam() && !nodep->isGenVar()) {
|
{
|
||||||
bool allU = true;
|
bool allU = true;
|
||||||
bool allD = true;
|
bool allD = true;
|
||||||
bool anyU = m_wholeFlags[FLAG_USED];
|
bool anyU = m_wholeFlags[FLAG_USED];
|
||||||
|
@ -168,8 +168,12 @@ public:
|
||||||
anyDnotU |= !used && driv;
|
anyDnotU |= !used && driv;
|
||||||
anynotDU |= !used && !driv;
|
anynotDU |= !used && !driv;
|
||||||
}
|
}
|
||||||
|
if ((nodep->isGenVar() || nodep->isParam()) && nodep->isUsedParam())
|
||||||
|
allD = allU = true;
|
||||||
if (allU) m_wholeFlags[FLAG_USED] = true;
|
if (allU) m_wholeFlags[FLAG_USED] = true;
|
||||||
if (allD) m_wholeFlags[FLAG_DRIVEN] = true;
|
if (allD) m_wholeFlags[FLAG_DRIVEN] = true;
|
||||||
|
const char* const what
|
||||||
|
= nodep->isParam() ? "parameter" : nodep->isGenVar() ? "genvar" : "signal";
|
||||||
// Test results
|
// Test results
|
||||||
if (nodep->isIfaceRef()) {
|
if (nodep->isIfaceRef()) {
|
||||||
// For interface top level we don't do any tracking
|
// For interface top level we don't do any tracking
|
||||||
|
@ -181,35 +185,39 @@ public:
|
||||||
// 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.
|
||||||
if (!unusedMatch(nodep)) {
|
if (!unusedMatch(nodep)) {
|
||||||
nodep->v3warn(UNUSED,
|
nodep->v3warn(UNUSED, ucfirst(what) << " is not driven, nor used: "
|
||||||
"Signal is not driven, nor used: " << nodep->prettyNameQ());
|
<< nodep->prettyNameQ());
|
||||||
nodep->fileline()->modifyWarnOff(V3ErrorCode::UNUSED, true); // Warn only once
|
nodep->fileline()->modifyWarnOff(V3ErrorCode::UNUSED, true); // Warn only once
|
||||||
}
|
}
|
||||||
} else if (allD && !anyU) {
|
} else if (allD && !anyU) {
|
||||||
if (!unusedMatch(nodep)) {
|
if (!unusedMatch(nodep)) {
|
||||||
nodep->v3warn(UNUSED, "Signal is not used: " << nodep->prettyNameQ());
|
nodep->v3warn(UNUSED, ucfirst(what)
|
||||||
|
<< " is not used: " << nodep->prettyNameQ());
|
||||||
nodep->fileline()->modifyWarnOff(V3ErrorCode::UNUSED, true); // Warn only once
|
nodep->fileline()->modifyWarnOff(V3ErrorCode::UNUSED, true); // Warn only once
|
||||||
}
|
}
|
||||||
} else if (!anyD && allU) {
|
} else if (!anyD && allU) {
|
||||||
nodep->v3warn(UNDRIVEN, "Signal is not driven: " << nodep->prettyNameQ());
|
nodep->v3warn(UNDRIVEN, ucfirst(what)
|
||||||
|
<< " is not driven: " << nodep->prettyNameQ());
|
||||||
nodep->fileline()->modifyWarnOff(V3ErrorCode::UNDRIVEN, true); // Warn only once
|
nodep->fileline()->modifyWarnOff(V3ErrorCode::UNDRIVEN, true); // Warn only once
|
||||||
} else {
|
} else {
|
||||||
// Bits have different dispositions
|
// Bits have different dispositions
|
||||||
bool setU = false;
|
bool setU = false;
|
||||||
bool setD = false;
|
bool setD = false;
|
||||||
if (anynotDU && !unusedMatch(nodep)) {
|
if (anynotDU && !unusedMatch(nodep)) {
|
||||||
nodep->v3warn(UNUSED, "Bits of signal are not driven, nor used: "
|
nodep->v3warn(UNUSED, "Bits of " << what << " are not driven, nor used: "
|
||||||
<< nodep->prettyNameQ() << bitNames(BN_BOTH));
|
<< nodep->prettyNameQ() << bitNames(BN_BOTH));
|
||||||
setU = true;
|
setU = true;
|
||||||
}
|
}
|
||||||
if (anyDnotU && !unusedMatch(nodep)) {
|
if (anyDnotU && !unusedMatch(nodep)) {
|
||||||
nodep->v3warn(UNUSED, "Bits of signal are not used: " << nodep->prettyNameQ()
|
nodep->v3warn(UNUSED, "Bits of " << what
|
||||||
<< bitNames(BN_UNUSED));
|
<< " are not used: " << nodep->prettyNameQ()
|
||||||
|
<< bitNames(BN_UNUSED));
|
||||||
setU = true;
|
setU = true;
|
||||||
}
|
}
|
||||||
if (anyUnotD) {
|
if (anyUnotD) {
|
||||||
nodep->v3warn(UNDRIVEN, "Bits of signal are not driven: "
|
nodep->v3warn(UNDRIVEN,
|
||||||
<< nodep->prettyNameQ() << bitNames(BN_UNDRIVEN));
|
"Bits of " << what << " are not driven: " << nodep->prettyNameQ()
|
||||||
|
<< bitNames(BN_UNDRIVEN));
|
||||||
setD = true;
|
setD = true;
|
||||||
}
|
}
|
||||||
if (setU) { // Warn only once
|
if (setU) { // Warn only once
|
||||||
|
|
|
@ -8,7 +8,6 @@ module t (/*AUTOARG*/
|
||||||
// Inputs
|
// Inputs
|
||||||
clk
|
clk
|
||||||
);
|
);
|
||||||
parameter PAR = 3;
|
|
||||||
|
|
||||||
input clk;
|
input clk;
|
||||||
integer cyc=1;
|
integer cyc=1;
|
||||||
|
|
|
@ -1,26 +1,26 @@
|
||||||
%Warning-ASSIGNDLY: t/t_delay.v:23:13: Unsupported: Ignoring delay on this assignment/primitive.
|
%Warning-ASSIGNDLY: t/t_delay.v:22:13: Unsupported: Ignoring delay on this assignment/primitive.
|
||||||
23 | assign #(1.2000000000000000) dly1 = dly0 + 32'h1;
|
22 | assign #(1.2000000000000000) dly1 = dly0 + 32'h1;
|
||||||
| ^~~~~~~~~~~~~~~~~~
|
| ^~~~~~~~~~~~~~~~~~
|
||||||
... Use "/* verilator lint_off ASSIGNDLY */" and lint_on around source to disable this message.
|
... Use "/* verilator lint_off ASSIGNDLY */" and lint_on around source to disable this message.
|
||||||
%Warning-ASSIGNDLY: t/t_delay.v:28:19: Unsupported: Ignoring delay on this assignment/primitive.
|
%Warning-ASSIGNDLY: t/t_delay.v:27:19: Unsupported: Ignoring delay on this assignment/primitive.
|
||||||
28 | dly0 <= #0 32'h11;
|
27 | dly0 <= #0 32'h11;
|
||||||
| ^
|
| ^
|
||||||
%Warning-ASSIGNDLY: t/t_delay.v:31:19: Unsupported: Ignoring delay on this assignment/primitive.
|
%Warning-ASSIGNDLY: t/t_delay.v:30:19: Unsupported: Ignoring delay on this assignment/primitive.
|
||||||
31 | dly0 <= #0.12 dly0 + 32'h12;
|
30 | dly0 <= #0.12 dly0 + 32'h12;
|
||||||
| ^~~~
|
| ^~~~
|
||||||
%Warning-ASSIGNDLY: t/t_delay.v:39:25: Unsupported: Ignoring delay on this assignment/primitive.
|
%Warning-ASSIGNDLY: t/t_delay.v:38:25: Unsupported: Ignoring delay on this assignment/primitive.
|
||||||
39 | dly0 <= #(dly_s.dly) 32'h55;
|
38 | dly0 <= #(dly_s.dly) 32'h55;
|
||||||
| ^
|
| ^
|
||||||
%Warning-STMTDLY: t/t_delay.v:44:11: Unsupported: Ignoring delay on this delayed statement.
|
%Warning-STMTDLY: t/t_delay.v:43:11: Unsupported: Ignoring delay on this delayed statement.
|
||||||
: ... In instance t
|
: ... In instance t
|
||||||
44 | #100 $finish;
|
43 | #100 $finish;
|
||||||
| ^~~
|
| ^~~
|
||||||
%Warning-UNUSED: t/t_delay.v:21:12: Signal is not used: 'dly_s'
|
%Warning-UNUSED: t/t_delay.v:20:12: Signal is not used: 'dly_s'
|
||||||
: ... In instance t
|
: ... In instance t
|
||||||
21 | dly_s_t dly_s;
|
20 | dly_s_t dly_s;
|
||||||
| ^~~~~
|
| ^~~~~
|
||||||
%Warning-BLKSEQ: t/t_delay.v:38:20: Blocking assignments (=) in sequential (flop or latch) block
|
%Warning-BLKSEQ: t/t_delay.v:37:20: Blocking assignments (=) in sequential (flop or latch) block
|
||||||
: ... Suggest delayed assignments (<=)
|
: ... Suggest delayed assignments (<=)
|
||||||
38 | dly_s.dly = 55;
|
37 | dly_s.dly = 55;
|
||||||
| ^
|
| ^
|
||||||
%Error: Exiting due to
|
%Error: Exiting due to
|
||||||
|
|
|
@ -13,4 +13,5 @@ endmodule
|
||||||
|
|
||||||
module sub;
|
module sub;
|
||||||
parameter P = 6;
|
parameter P = 6;
|
||||||
|
if (P != 0) ; // Prevent unused
|
||||||
endmodule
|
endmodule
|
||||||
|
|
|
@ -44,8 +44,6 @@ module sub;
|
||||||
|
|
||||||
wire pub /*verilator public*/; // Ignore publics
|
wire pub /*verilator public*/; // Ignore publics
|
||||||
|
|
||||||
localparam THREE = 3;
|
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
primitive udp_mux2 (q, a, b, s);
|
primitive udp_mux2 (q, a, b, s);
|
||||||
|
|
|
@ -23,4 +23,16 @@
|
||||||
: ... In instance t.sub
|
: ... In instance t.sub
|
||||||
28 | wire [3:0] mixed;
|
28 | wire [3:0] mixed;
|
||||||
| ^~~~~
|
| ^~~~~
|
||||||
|
%Warning-UNUSED: t/t_lint_unused_bad.v:37:14: Parameter is not used: 'UNUSED_P'
|
||||||
|
: ... In instance t.sub
|
||||||
|
37 | parameter UNUSED_P = 1;
|
||||||
|
| ^~~~~~~~
|
||||||
|
%Warning-UNUSED: t/t_lint_unused_bad.v:38:15: Parameter is not used: 'UNUSED_LP'
|
||||||
|
: ... In instance t.sub
|
||||||
|
38 | localparam UNUSED_LP = 2;
|
||||||
|
| ^~~~~~~~~
|
||||||
|
%Warning-UNUSED: t/t_lint_unused_bad.v:40:15: Genvar is not driven, nor used: 'unused_gv'
|
||||||
|
: ... In instance t.sub
|
||||||
|
40 | genvar unused_gv;
|
||||||
|
| ^~~~~~~~~
|
||||||
%Error: Exiting due to
|
%Error: Exiting due to
|
||||||
|
|
|
@ -34,9 +34,21 @@ module sub;
|
||||||
|
|
||||||
localparam THREE = 3;
|
localparam THREE = 3;
|
||||||
|
|
||||||
|
parameter UNUSED_P = 1;
|
||||||
|
localparam UNUSED_LP = 2;
|
||||||
|
|
||||||
|
genvar unused_gv;
|
||||||
|
genvar ok_gv;
|
||||||
|
|
||||||
initial begin
|
initial begin
|
||||||
if (0 && assunu1[0] != 0 && udrb2 != 0) begin end
|
if (0 && assunu1[0] != 0 && udrb2 != 0) begin end
|
||||||
if (0 && assunub2[THREE] && assunub2[1:0]!=0) begin end
|
if (0 && assunub2[THREE] && assunub2[1:0]!=0) begin end
|
||||||
if (0 && mixed[1:0] != 0) begin end
|
if (0 && mixed[1:0] != 0) begin end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
generate
|
||||||
|
if (0)
|
||||||
|
for (ok_gv = 0; ok_gv < 1; ++ok_gv) begin end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
Loading…
Reference in New Issue