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:
parent
ea65bcd86b
commit
70c84d3abd
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 *-*
|
|
@ -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()
|
|
@ -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
|
Loading…
Reference in New Issue