Fix 'case (_) inside' with x wildcards (#7766)

Found by inspection, case inside used to threat 'x' as a value, not as a
wildcard. Per the standard it should behave as '==?' which treats both
'x' and 'z' as wildcards.
This commit is contained in:
Geza Lore 2026-06-12 07:48:36 +01:00 committed by GitHub
parent 4555c8b23c
commit 60f729639b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 55 additions and 2 deletions

View File

@ -576,8 +576,8 @@ class CaseVisitor final : public VNVisitor {
bool neverItem(const AstCase* casep, const AstConst* itemp) {
// Xs in case or casez are impossible due to two state simulations
if (casep->casex()) {
} else if (casep->casez() || casep->caseInside()) {
if (casep->casex() || casep->caseInside()) {
} else if (casep->casez()) {
if (itemp->num().isAnyX()) return true;
} else {
if (itemp->num().isFourState()) return true;

View File

@ -0,0 +1,18 @@
#!/usr/bin/env python3
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# 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-FileCopyrightText: 2026 Wilson Snyder
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
import vltest_bootstrap
test.scenarios('simulator')
test.compile(verilator_flags2=['--binary'])
test.execute()
test.passes()

View File

@ -0,0 +1,35 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain.
// SPDX-FileCopyrightText: 2026 Wilson Snyder
// SPDX-License-Identifier: CC0-1.0
// verilog_format: off
`define stop $stop
`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0x exp=%0x (%s !== %s)\n", `__FILE__,`__LINE__, (gotv), (expv), `"gotv`", `"expv`"); `stop; end while(0);
// verilog_format: on
module top;
bit clk = 1'b0;
always #1 clk = ~clk;
logic [2:0] cyc = 3'd0;
int count = 0;
always @(posedge clk) begin
// verilator lint_off CASEWITHX
case (cyc) inside
3'b000: begin $display("case inside 000"); ++count; end
3'b001: begin $display("case inside 001"); ++count; end
// Should match z
3'b01?: begin $display("case inside 01?"); ++count; end
// Should match x
3'b1xx: begin $display("case inside 1xx"); ++count; end
endcase
// verilator lint_on CASEWITHX
cyc <= cyc + 3'd1;
if (&cyc) begin
`checkh(count, 8);
$finish;
end
end
endmodule