Preserve C++ widths in V3Expand (#5975)

During V3Expand, some w32/1 (width == 32, widthMin == 1), nodes (e.g.:
RedOr) are replaced with w1 nodes (width == widthMin == 1) (e.g.: Neq).
However, V3Expand runs after V3Clean, when we are in C++ width world,
so we need to preserve the width/widthMin distinction, otherwise a later
constant folding can eliminate e.g. a necessary AstAnd used clear an
intermediate result (isAllOnes is true for a Const 1 with w1, but false
for a Const 1 with w32/1).

Attempting to fix by preserving all width/widthMin during a replacement
in V3Expand.

DFG itself is fine, but the transformed code hits the above.

Fixes #5953
This commit is contained in:
Geza Lore 2025-05-04 16:31:27 +01:00 committed by GitHub
parent ea65bcd86b
commit 70c84d3abd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 91 additions and 0 deletions

View File

@ -123,6 +123,11 @@ class ExpandVisitor final : public VNVisitor {
}
static void replaceWithDelete(AstNode* nodep, AstNode* newp) {
newp->user1(1); // Already processed, don't need to re-iterate
if (newp->width() != nodep->width()) {
UASSERT_OBJ(newp->widthMin() == nodep->widthMin(), nodep,
"Replacement width mismatch");
newp->dtypeChgWidth(nodep->width(), nodep->widthMin());
}
nodep->replaceWith(newp);
VL_DO_DANGLING(nodep->deleteTree(), nodep);
}

View File

@ -0,0 +1,7 @@
[0] in5=0 clock_10=0 clock_12=0 out18=1
[5] in5=0 clock_10=0 clock_12=1 out18=1
[10] in5=0 clock_10=0 clock_12=0 out18=1
[15] in5=0 clock_10=1 clock_12=0 out18=1
[15] in5=0 clock_10=1 clock_12=0 out18=0
[20] in5=0 clock_10=0 clock_12=0 out18=0
*-* All Finished *-*

View File

@ -0,0 +1,18 @@
#!/usr/bin/env python3
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2025 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(verilator_flags2=['--binary'])
test.execute(expect_filename=test.golden_filename)
test.passes()

View File

@ -0,0 +1,61 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2025 by Wilson Snyder.
// SPDX-License-Identifier: CC0-1.0
module gymhnulbvj (in5, clock_10, clock_12, out18);
input wire [23:22] in5;
wire [29:1] wire_4;
reg reg_35;
output wire out18;
input wire clock_10;
input wire clock_12;
// verilator lint_off WIDTH
assign wire_4 = ~ in5[22];
assign out18 = reg_35 ? 0 : !(!(~(wire_4[6:5] | 8'hc6)));
// verilator lint_on WIDTH
always @(posedge clock_10 or posedge clock_12) begin
if (clock_12) begin
reg_35 <= 0;
end
else begin
// verilator lint_off WIDTH
reg_35 <= wire_4;
// verilator lint_on WIDTH
end
end
endmodule
module t;
reg [23:22] in5;
reg clock_10 = 0;
reg clock_12 = 0;
wire out18;
gymhnulbvj uut (
.in5(in5),
.clock_10(clock_10),
.clock_12(clock_12),
.out18(out18)
);
initial begin
$monitor("[%0t] in5=%d clock_10=%d clock_12=%d out18=%d", $time, in5, clock_10, clock_12, out18);
in5 = 2'b00;
#5 clock_12 = 1;
#5 clock_12 = 0;
#5 clock_10 = 1;
#5 clock_10 = 0;
#10;
$write("*-* All Finished *-*\n");
$finish;
end
endmodule