forked from github/verilator
Co-authored-by: "G-A. Kamendje" <gkamendje@gmail.com>
This commit is contained in:
parent
4f4c26383c
commit
d87ef8394a
1
Changes
1
Changes
@ -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]
|
||||
|
@ -36,6 +36,7 @@ Glen Gibb
|
||||
Graham Rushton
|
||||
Guokai Chen
|
||||
Gustav Svensk
|
||||
G-A. Kamendje
|
||||
Harald Heckmann
|
||||
Howard Su
|
||||
Huang Rui
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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)))) {
|
||||
|
19
test_regress/t/t_case_enum_complete.pl
Executable file
19
test_regress/t/t_case_enum_complete.pl
Executable 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;
|
20
test_regress/t/t_case_enum_complete.v
Normal file
20
test_regress/t/t_case_enum_complete.v
Normal 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
|
6
test_regress/t/t_case_enum_incomplete_bad.out
Normal file
6
test_regress/t/t_case_enum_incomplete_bad.out
Normal 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
|
20
test_regress/t/t_case_enum_incomplete_bad.pl
Executable file
20
test_regress/t/t_case_enum_incomplete_bad.pl
Executable 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;
|
19
test_regress/t/t_case_enum_incomplete_bad.v
Normal file
19
test_regress/t/t_case_enum_incomplete_bad.v
Normal 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
|
Loading…
Reference in New Issue
Block a user