diff --git a/src/V3Expand.cpp b/src/V3Expand.cpp index fb348121b..395ba5e04 100644 --- a/src/V3Expand.cpp +++ b/src/V3Expand.cpp @@ -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); } diff --git a/test_regress/t/t_opt_expand_keep_widths.out b/test_regress/t/t_opt_expand_keep_widths.out new file mode 100644 index 000000000..f310ca87a --- /dev/null +++ b/test_regress/t/t_opt_expand_keep_widths.out @@ -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 *-* diff --git a/test_regress/t/t_opt_expand_keep_widths.py b/test_regress/t/t_opt_expand_keep_widths.py new file mode 100755 index 000000000..fa87f0e9d --- /dev/null +++ b/test_regress/t/t_opt_expand_keep_widths.py @@ -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() diff --git a/test_regress/t/t_opt_expand_keep_widths.v b/test_regress/t/t_opt_expand_keep_widths.v new file mode 100644 index 000000000..a19565b00 --- /dev/null +++ b/test_regress/t/t_opt_expand_keep_widths.v @@ -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