Fix CASEINCOMPLETE when covers all enum values (#3745) (#3782).

Co-authored-by: "G-A. Kamendje" <gkamendje@gmail.com>
This commit is contained in:
Wilson Snyder 2022-11-30 19:42:21 -05:00
parent 4f4c26383c
commit d87ef8394a
9 changed files with 129 additions and 8 deletions

View File

@ -23,6 +23,7 @@ Verilator 5.003 devel
* Internal AST improvements, also affect XML format (#3721). [Geza Lore]
* Change ENDLABEL from warning into an error.
* Deprecate verilated_fst_sc.cpp and verilated_vcd_sc.cpp.
* Fix CASEINCOMPLETE when covers all enum values (#3745) (#3782). [Guy-Armand Kamendje]
* Fix return type of $countbits functions to int (#3725). [Ryszard Rozak, Antmicro Ltd]
* Fix missing UNUSED warnings with --coverage (#3736). [alejandro-castro-ortegon]
* Fix tracing parameters overridden with -G (#3723). [Iztok Jeras]

View File

@ -36,6 +36,7 @@ Glen Gibb
Graham Rushton
Guokai Chen
Gustav Svensk
G-A. Kamendje
Harald Heckmann
Howard Su
Huang Rui

View File

@ -253,6 +253,12 @@ List Of Warnings
:code:`default: ;` so that any design assumption violations will be
discovered in simulation.
Unique case statements that select on an enumerated variable, where all
of the enumerated values are covered by case items, are considered
complete even if illegal non-enumerated values are not covered by the
case statement. To check that illegal values are not hit, use
:vlopt:`--assert` (see IEEE 1800-2017 12.5.3).
Ignoring this warning will only suppress the lint check, it will
simulate correctly.

View File

@ -139,7 +139,33 @@ private:
std::array<AstNode*, 1 << CASE_OVERLAP_WIDTH> m_valueItem;
// METHODS
bool caseIsEnumComplete(AstCase* nodep, uint32_t numCases) {
// Return true if case is across an enum, and every value in the case
// statement corresponds to one of the enum values
if (!nodep->uniquePragma() && !nodep->unique0Pragma()) return false;
AstEnumDType* const enumDtp
= VN_CAST(nodep->exprp()->dtypep()->skipRefToEnump(), EnumDType);
if (!enumDtp) return false; // Case isn't enum
AstBasicDType* const basicp = enumDtp->subDTypep()->basicp();
if (!basicp) return false; // Not simple type (perhaps IEEE illegal)
if (basicp->width() > 32) return false;
// Find all case values into a set
std::set<uint32_t> caseSet;
for (uint32_t i = 0; i < numCases; ++i) { // All case items
if (m_valueItem[i]) caseSet.emplace(i);
}
// Find all enum values into a set
std::set<uint32_t> enumSet;
for (AstEnumItem* itemp = enumDtp->itemsp(); itemp;
itemp = VN_AS(itemp->nextp(), EnumItem)) {
AstConst* const econstp = VN_AS(itemp->valuep(), Const);
const uint32_t val = econstp->toUInt();
// UINFO(9, "Complete enum item " << val << ": " << itemp << endl);
enumSet.emplace(val);
}
// If sets match, all covered
return (caseSet == enumSet);
}
bool isCaseTreeFast(AstCase* nodep) {
int width = 0;
bool opaque = false;
@ -227,15 +253,18 @@ private:
}
}
}
for (uint32_t i = 0; i < numCases; ++i) {
if (!m_valueItem[i]) {
nodep->v3warn(CASEINCOMPLETE, "Case values incompletely covered "
"(example pattern 0x"
<< std::hex << i << ")");
m_caseNoOverlapsAllCovered = false;
return false;
if (!caseIsEnumComplete(nodep, numCases)) {
for (uint32_t i = 0; i < numCases; ++i) {
if (!m_valueItem[i]) {
nodep->v3warn(CASEINCOMPLETE, "Case values incompletely covered "
"(example pattern 0x"
<< std::hex << i << ")");
m_caseNoOverlapsAllCovered = false;
return false;
}
}
}
if (m_caseItems <= 3
// Avoid e.g. priority expanders from going crazy in expansion
|| (m_caseWidth >= 8 && (m_caseItems <= (m_caseWidth + 1)))) {

View File

@ -0,0 +1,19 @@
#!/usr/bin/env perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003 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.
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
scenarios(linter => 1);
lint(
verilator_flags2 => ["--lint-only -Wwarn-CASEINCOMPLETE"],
fails => 0,
);
ok(1);
1;

View File

@ -0,0 +1,20 @@
// DESCRIPTION: Verilator: SystemVerilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2022 by Wilson Snyder.
// SPDX-License-Identifier: CC0-1.0
module t;
enum logic [2:0] {S0, S1, S2} state;
initial begin
state = S1;
unique case (state)
S0: $stop;
S1: $finish;
S2: $stop;
endcase
end
endmodule

View File

@ -0,0 +1,6 @@
%Warning-CASEINCOMPLETE: t/t_case_enum_incomplete_bad.v:14:14: Case values incompletely covered (example pattern 0x1)
14 | unique case (state)
| ^~~~
... For warning description see https://verilator.org/warn/CASEINCOMPLETE?v=latest
... Use "/* verilator lint_off CASEINCOMPLETE */" and lint_on around source to disable this message.
%Error: Exiting due to

View File

@ -0,0 +1,20 @@
#!/usr/bin/env perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2022 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.
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
scenarios(linter => 1);
lint(
verilator_flags2 => ['--assert'],
fails => 1,
expect_filename => $Self->{golden_filename},
);
ok(1);
1;

View File

@ -0,0 +1,19 @@
// DESCRIPTION: Verilator: SystemVerilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2022 by Wilson Snyder.
// SPDX-License-Identifier: CC0-1.0
module t;
enum logic [2:0] {S0, S1, S2} state;
initial begin
state = S1;
unique case (state)
S0: $stop;
S2: $stop;
endcase
end
endmodule