parent
45349990a1
commit
112e1e3752
|
|
@ -595,6 +595,7 @@ class AssertVisitor final : public VNVisitor {
|
|||
AstNodeExpr* propp = nullptr;
|
||||
for (AstCaseItem* itemp = nodep->itemsp(); itemp;
|
||||
itemp = VN_AS(itemp->nextp(), CaseItem)) {
|
||||
AstNodeExpr* itembitp = nullptr;
|
||||
for (AstNodeExpr* icondp = itemp->condsp(); icondp;
|
||||
icondp = VN_AS(icondp->nextp(), NodeExpr)) {
|
||||
AstNodeExpr* onep;
|
||||
|
|
@ -612,17 +613,27 @@ class AssertVisitor final : public VNVisitor {
|
|||
nodep->exprp()->cloneTreePure(false),
|
||||
icondp->cloneTreePure(false));
|
||||
}
|
||||
// OR together all conditions within the same case item
|
||||
if (onep) {
|
||||
if (itembitp) {
|
||||
itembitp = new AstOr{icondp->fileline(), onep, itembitp};
|
||||
} else {
|
||||
itembitp = onep;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (itembitp) {
|
||||
if (propp) {
|
||||
propp = new AstConcat{icondp->fileline(), onep, propp};
|
||||
propp = new AstConcat{itemp->fileline(), itembitp, propp};
|
||||
} else {
|
||||
propp = onep;
|
||||
propp = itembitp;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Empty case means no property
|
||||
if (!propp) propp = new AstConst{nodep->fileline(), AstConst::BitFalse{}};
|
||||
const bool allow_none = has_default || nodep->unique0Pragma();
|
||||
// The following assertion lools as below.
|
||||
// The following assertion looks as below.
|
||||
// if (!$onehot(propp)) begin
|
||||
// if (propp == '0) begin if (!allow_none) $error("none match"); end
|
||||
// else $error("multiple match");
|
||||
|
|
|
|||
|
|
@ -244,9 +244,13 @@ class CaseVisitor final : public VNVisitor {
|
|||
caseItemMap[icondp] = itemp;
|
||||
foundHit = true;
|
||||
} else if (!overlappedCondp) {
|
||||
firstOverlap = i;
|
||||
overlappedCondp = m_valueItem[i];
|
||||
m_caseNoOverlapsAllCovered = false;
|
||||
// Overlapping case item expressions in the
|
||||
// same case item are legal
|
||||
if (caseItemMap[m_valueItem[i]] != itemp) {
|
||||
firstOverlap = i;
|
||||
overlappedCondp = m_valueItem[i];
|
||||
m_caseNoOverlapsAllCovered = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,17 +1,11 @@
|
|||
%Warning-CASEOVERLAP: t/t_case_overlap_bad.v:20:21: Case conditions overlap (example pattern 0x6)
|
||||
20 | 3'b11?, 3'b???: v++;
|
||||
| ^~~~~~
|
||||
t/t_case_overlap_bad.v:20:13: ... Location of overlapping condition
|
||||
20 | 3'b11?, 3'b???: v++;
|
||||
| ^~~~~~
|
||||
... For warning description see https://verilator.org/warn/CASEOVERLAP?v=latest
|
||||
... Use "/* verilator lint_off CASEOVERLAP */" and lint_on around source to disable this message.
|
||||
%Warning-CASEOVERLAP: t/t_case_overlap_bad.v:25:13: Case conditions overlap
|
||||
25 | 3'b001, 3'b000: $stop;
|
||||
| ^~~~~~
|
||||
t/t_case_overlap_bad.v:24:13: ... Location of overlapping condition
|
||||
24 | 3'b00?: $stop;
|
||||
| ^~~~~~
|
||||
... For warning description see https://verilator.org/warn/CASEOVERLAP?v=latest
|
||||
... Use "/* verilator lint_off CASEOVERLAP */" and lint_on around source to disable this message.
|
||||
%Warning-CASEOVERLAP: t/t_case_overlap_bad.v:30:13: Case conditions overlap (example pattern 0x7)
|
||||
30 | 3'b11?: $stop;
|
||||
| ^~~~~~
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
#!/usr/bin/env python3
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2026 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
|
||||
|
||||
import vltest_bootstrap
|
||||
|
||||
test.scenarios('simulator')
|
||||
|
||||
test.compile()
|
||||
|
||||
test.execute()
|
||||
|
||||
test.passes()
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed under the Creative Commons Public Domain, for
|
||||
// any use, without warranty, 2025 by Luca Colagrande.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
module t (/*AUTOARG*/
|
||||
// Inputs
|
||||
clk
|
||||
);
|
||||
|
||||
input clk;
|
||||
|
||||
localparam logic [1:0] INST1 = 2'b0?;
|
||||
localparam logic [1:0] INST2 = 2'b0?;
|
||||
localparam logic [1:0] INST3 = 2'b1?;
|
||||
|
||||
logic [1:0] in, out;
|
||||
|
||||
always_comb begin
|
||||
unique casez (in)
|
||||
INST1, INST2: begin
|
||||
if (in == 2'b00) out = 2'b01;
|
||||
else out = 2'b00;
|
||||
end
|
||||
INST3: begin
|
||||
out = 2'b10;
|
||||
end
|
||||
default: begin
|
||||
out = 2'b11;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
always @ (posedge clk) begin
|
||||
`ifdef TEST_VERBOSE
|
||||
$write("[%0t] in=%x out=%x\n", $time, in, out);
|
||||
`endif
|
||||
if (in == 0) begin
|
||||
if (out != 2'b01) $stop;
|
||||
end
|
||||
else if (in == 1) begin
|
||||
if (out != 2'b00) $stop;
|
||||
end
|
||||
else if (in == 2) begin
|
||||
if (out != 2'b10) $stop;
|
||||
end
|
||||
else if (in == 3) begin
|
||||
if (out != 2'b10) $stop;
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
in <= in + 1;
|
||||
end
|
||||
|
||||
endmodule
|
||||
Loading…
Reference in New Issue