diff --git a/Changes b/Changes index cf53af706..b0bacebaf 100644 --- a/Changes +++ b/Changes @@ -23,6 +23,7 @@ Verilator 5.007 devel * Support static function variables (#3830). [Ryszard Rozak, Antmicro Ltd] * Fix real parameters of infinity and NaN. * Fix pattern assignment to unpacked structs (#3510). [Mostafa Garnal] +* Fix single-element replication to dynarray/unpacked/queue (#3548). [Gustav Svensk] Verilator 5.006 2023-01-22 diff --git a/src/V3Width.cpp b/src/V3Width.cpp index 0b739d092..e901ae869 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -714,12 +714,24 @@ private: << vdtypep->prettyDTypeNameQ() << " data type"); } - // Don't iterate lhsp as SELF, the potential Concat below needs - // the adtypep passed down to recognize the QueueDType - userIterateAndNext(nodep->lhsp(), WidthVP{vdtypep, BOTH}.p()); - nodep->replaceWith(nodep->lhsp()->unlinkFrBack()); - VL_DO_DANGLING(pushDeletep(nodep), nodep); - return; + if (VN_IS(nodep->lhsp(), Concat)) { + // Convert to concat directly, and visit(AstConst) will convert. + // Don't iterate lhsp as SELF, the potential Concat below needs + // the adtypep passed down to recognize the QueueDType + userIterateAndNext(nodep->lhsp(), WidthVP{vdtypep, BOTH}.p()); + nodep->replaceWith(nodep->lhsp()->unlinkFrBack()); + VL_DO_DANGLING(pushDeletep(nodep), nodep); + return; + } else { // int a[] = {lhs} -> same as '{lhs} + auto* const newp = new AstPattern{ + nodep->fileline(), + new AstPatMember{nodep->lhsp()->fileline(), nodep->lhsp()->unlinkFrBack(), + nullptr, nullptr}}; + nodep->replaceWith(newp); + VL_DO_DANGLING(pushDeletep(nodep), nodep); + userIterate(newp, m_vup); + return; + } } if (VN_IS(vdtypep, AssocArrayDType)) { nodep->v3warn(E_UNSUPPORTED, "Unsupported: Replication to form " diff --git a/test_regress/t/t_dynarray_init.pl b/test_regress/t/t_dynarray_init.pl new file mode 100755 index 000000000..9a15dd2cc --- /dev/null +++ b/test_regress/t/t_dynarray_init.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 2019 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_dynarray_init.v b/test_regress/t/t_dynarray_init.v new file mode 100644 index 000000000..756792b45 --- /dev/null +++ b/test_regress/t/t_dynarray_init.v @@ -0,0 +1,36 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2020 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +`define stop $stop +`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0) + +module t (/*AUTOARG*/); + + int a1[] = '{12, 13}; + int a2[] = {14, 15}; + int a3[] = '{16}; + int a4[] = {17}; + + initial begin + `checkh(a1.size, 2); + `checkh(a1[0], 12); + `checkh(a1[1], 13); + + `checkh(a2.size, 2); + `checkh(a2[0], 14); + `checkh(a2[1], 15); + + `checkh(a3.size, 1); + `checkh(a3[0], 16); + + `checkh(a4.size, 1); + `checkh(a4[0], 17); + + $write("*-* All Finished *-*\n"); + $finish; + end + +endmodule diff --git a/test_regress/t/t_queue_init.pl b/test_regress/t/t_queue_init.pl new file mode 100755 index 000000000..9a15dd2cc --- /dev/null +++ b/test_regress/t/t_queue_init.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 2019 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_queue_init.v b/test_regress/t/t_queue_init.v new file mode 100644 index 000000000..cc22d9747 --- /dev/null +++ b/test_regress/t/t_queue_init.v @@ -0,0 +1,36 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2020 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +`define stop $stop +`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0) + +module t (/*AUTOARG*/); + + int a1[$] = '{12, 13}; + int a2[$] = {14, 15}; + int a3[$] = '{16}; + int a4[$] = {17}; + + initial begin + `checkh(a1.size, 2); + `checkh(a1[0], 12); + `checkh(a1[1], 13); + + `checkh(a2.size, 2); + `checkh(a2[0], 14); + `checkh(a2[1], 15); + + `checkh(a3.size, 1); + `checkh(a3[0], 16); + + `checkh(a4.size, 1); + `checkh(a4[0], 17); + + $write("*-* All Finished *-*\n"); + $finish; + end + +endmodule diff --git a/test_regress/t/t_unpacked_concat_bad.out b/test_regress/t/t_unpacked_concat_bad.out index 1482e7507..0f7ec60dd 100644 --- a/test_regress/t/t_unpacked_concat_bad.out +++ b/test_regress/t/t_unpacked_concat_bad.out @@ -3,4 +3,8 @@ 17 | localparam bit_int_t count_bits [1:0] = {2{$bits(count_t)}}; | ^ ... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest +%Error: t/t_unpacked_concat_bad.v:17:46: Assignment pattern missed initializing elements: 0 + : ... In instance t + 17 | localparam bit_int_t count_bits [1:0] = {2{$bits(count_t)}}; + | ^ %Error: Exiting due to diff --git a/test_regress/t/t_unpacked_init.pl b/test_regress/t/t_unpacked_init.pl new file mode 100755 index 000000000..9a15dd2cc --- /dev/null +++ b/test_regress/t/t_unpacked_init.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 2019 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_unpacked_init.v b/test_regress/t/t_unpacked_init.v new file mode 100644 index 000000000..ae7243ad1 --- /dev/null +++ b/test_regress/t/t_unpacked_init.v @@ -0,0 +1,32 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2020 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +`define stop $stop +`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0) + +module t (/*AUTOARG*/); + + int a1[2] = '{12, 13}; + int a2[2] = {14, 15}; + int a3[1] = '{16}; + int a4[1] = {17}; + + initial begin + `checkh(a1[0], 12); + `checkh(a1[1], 13); + + `checkh(a2[0], 14); + `checkh(a2[1], 15); + + `checkh(a3[0], 16); + + `checkh(a4[0], 17); + + $write("*-* All Finished *-*\n"); + $finish; + end + +endmodule