diff --git a/docs/CONTRIBUTORS b/docs/CONTRIBUTORS index 30c0e86dc..fa4645414 100644 --- a/docs/CONTRIBUTORS +++ b/docs/CONTRIBUTORS @@ -60,6 +60,7 @@ Jeremy Bennett Jevin Sweval Jiacheng Qian Jiuyang Liu +Joey Liu John Coiner John Demme Jonathan Drolet diff --git a/src/V3EmitCFunc.h b/src/V3EmitCFunc.h index 1e39db840..7f1078505 100644 --- a/src/V3EmitCFunc.h +++ b/src/V3EmitCFunc.h @@ -358,7 +358,7 @@ public: // Wide functions assign into the array directly, don't need separate assign statement m_wideTempRefp = VN_AS(nodep->lhsp(), VarRef); paren = false; - } else if (nodep->isWide()) { + } else if (nodep->isWide() && !VN_IS(nodep->dtypep()->skipRefp(), UnpackArrayDType)) { putbs("VL_ASSIGN_W("); puts(cvtToStr(nodep->widthMin()) + ","); iterateAndNextNull(nodep->lhsp()); diff --git a/src/V3Expand.cpp b/src/V3Expand.cpp index 874759e6c..a34660a7d 100644 --- a/src/V3Expand.cpp +++ b/src/V3Expand.cpp @@ -848,6 +848,10 @@ private: } void visit(AstNodeAssign* nodep) override { if (nodep->user1SetOnce()) return; // Process once + if (VN_IS(nodep->dtypep()->skipRefp(), UnpackArrayDType)) { + return; // Skip for UnpackArrayDType + } + VL_RESTORER(m_stmtp); m_stmtp = nodep; iterateChildren(nodep); diff --git a/test_regress/t/t_unpack_array_direct_assignment.pl b/test_regress/t/t_unpack_array_direct_assignment.pl new file mode 100755 index 000000000..29a73f42a --- /dev/null +++ b/test_regress/t/t_unpack_array_direct_assignment.pl @@ -0,0 +1,24 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2023 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 + +scenarios(simulator => 1); + +top_filename("t/t_unpack_array_no_expand.v"); + +compile( + verilator_flags2 => ['-fno-expand'], + ); + +execute( + check_finished => 1, + ); + +ok(1); +1; diff --git a/test_regress/t/t_unpack_array_no_expand.pl b/test_regress/t/t_unpack_array_no_expand.pl new file mode 100755 index 000000000..859050d63 --- /dev/null +++ b/test_regress/t/t_unpack_array_no_expand.pl @@ -0,0 +1,21 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2023 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 + +scenarios(simulator => 1); + +compile( + ); + +execute( + check_finished => 1, + ); + +ok(1); +1; diff --git a/test_regress/t/t_unpack_array_no_expand.v b/test_regress/t/t_unpack_array_no_expand.v new file mode 100644 index 000000000..04e83813d --- /dev/null +++ b/test_regress/t/t_unpack_array_no_expand.v @@ -0,0 +1,42 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2023 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +module t + ( + output logic [255:0] data_out + ); + localparam int NUM_STAGES = 3; + + /* verilator lint_off ALWCOMBORDER */ + /* verilator lint_off UNOPTFLAT */ + +`define INPUT 256'hbabecafe + + logic [255:0] stage_data [NUM_STAGES+1]; + + genvar stage; + generate + always_comb begin + stage_data[0] = `INPUT; + end + for (stage = 0; stage < NUM_STAGES; ++stage) begin : stage_gen + always_comb begin + stage_data[stage+1] = stage_data[stage]; + end + end + endgenerate + + /* verilator lint_on UNOPTFLAT */ + /* verilator lint_on ALWCOMBORDER */ + + always_comb begin + data_out = stage_data[NUM_STAGES]; + if (data_out !== `INPUT) $stop; + $write("*-* All Finished *-*\n"); + $finish; + end + +endmodule