diff --git a/Changes b/Changes index d8a560704..ece562e22 100644 --- a/Changes +++ b/Changes @@ -146,6 +146,9 @@ Verilator 5.030 2024-10-27 * Fix build on gcc when using the Spack wrapper (#5555). [Eric Müller] * Fix enum name method (#5563). [Todd Strader] * Fix `$countbits` in assert with non-tristates (#5566). [Shou-Li Hsu] +* Fix missing VlProcess handle in coroutines with splits (#5623) (#5650). [Bartłomiej Chmiel, Antmicro Ltd.] +* Fix imported array assignment literals (#5642) (#5648). [Todd Strader] +* Fix foreach mixed array (#5655) (#5656). [Yilou Wang] Verilator 5.028 2024-08-21 diff --git a/docs/guide/simulating.rst b/docs/guide/simulating.rst index f62bada5c..6a3484c7f 100644 --- a/docs/guide/simulating.rst +++ b/docs/guide/simulating.rst @@ -224,14 +224,6 @@ at branches). At each such branch, a counter is incremented. At the end of a test, the counters, filename, and line number corresponding to each counter are written into the coverage file. -Verilator automatically disables coverage of branches with a $stop in -them, as it is assumed that $stop branches contain an error check that should -not occur. A :option:`/*verilator&32;coverage_block_off*/` metacomment -will perform a similar function on any code in that block or below, or -:option:`/*verilator&32;coverage_off*/` and -:option:`/*verilator&32;coverage_on*/` will disable and enable coverage -respectively around a block of code. - Verilator may over-count combinatorial (non-clocked) blocks when those blocks receive signals which have had the :option:`UNOPTFLAT` warning disabled; for the most accurate results, do not disable this warning when @@ -278,6 +270,22 @@ A :option:`/*verilator&32;coverage_off*/` signals that do not need toggle analysis, such as RAMs and register files. +.. _Suppressing Coverage: + +Suppressing Coverage +-------------------- + +Using :option:`/*verilator&32;coverage_off*/` and +:option:`/*verilator&32;coverage_on*/` around a block of code will disable +and enable coverage respectively around that block. Or, use the +:option:`coverage_block_off` configuration file option. + +Verilator automatically disables coverage of lines and branches with a +$stop in them, as it is assumed that $stop branches contain an error check +that should not occur. A :option:`/*verilator&32;coverage_block_off*/` +metacomment will perform a similar function on any code in that block or +below. + .. _Coverage Collection: Coverage Collection diff --git a/src/V3AstNodeOther.h b/src/V3AstNodeOther.h index ec8c777e3..da584d4ef 100644 --- a/src/V3AstNodeOther.h +++ b/src/V3AstNodeOther.h @@ -2121,9 +2121,9 @@ public: bool isScBigUint() const VL_MT_STABLE; bool isScSensitive() const { return m_scSensitive; } bool isSigPublic() const; - bool isSigModPublic() const { return m_sigModPublic; } - bool isSigUserRdPublic() const { return m_sigUserRdPublic; } - bool isSigUserRWPublic() const { return m_sigUserRWPublic; } + bool isSigModPublic() const { return m_sigModPublic && !isIfaceRef(); } + bool isSigUserRdPublic() const { return m_sigUserRdPublic && !isIfaceRef(); } + bool isSigUserRWPublic() const { return m_sigUserRWPublic && !isIfaceRef(); } bool isTrace() const { return m_trace; } bool isRand() const { return m_rand.isRand(); } bool isRandC() const { return m_rand.isRandC(); } diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp index 1106c25fc..2490fda10 100644 --- a/src/V3AstNodes.cpp +++ b/src/V3AstNodes.cpp @@ -437,7 +437,8 @@ void AstNetlist::timeprecisionMerge(FileLine*, const VTimescale& value) { } bool AstVar::isSigPublic() const { - return (m_sigPublic || (v3Global.opt.allPublic() && !isTemp() && !isGenVar())); + return (m_sigPublic || (v3Global.opt.allPublic() && !isTemp() && !isGenVar())) + && !isIfaceRef(); } bool AstVar::isScQuad() const { return (isSc() && isQuad() && !isScBv() && !isScBigUint()); } bool AstVar::isScBv() const { diff --git a/src/V3Begin.cpp b/src/V3Begin.cpp index f20ba4f6d..7d23f8489 100644 --- a/src/V3Begin.cpp +++ b/src/V3Begin.cpp @@ -424,6 +424,7 @@ AstNode* V3Begin::convertToWhile(AstForeach* nodep) { AstNode* bodyPointp = new AstBegin{nodep->fileline(), "[EditWrapper]", nullptr}; AstNode* newp = nullptr; AstNode* lastp = nodep; + AstVar* nestedIndexp = nullptr; // subfromp used to traverse each dimension of multi-d variable-sized unpacked array (queue, // dyn-arr and associative-arr) AstNodeExpr* subfromp = fromp->cloneTreePure(false); @@ -456,8 +457,13 @@ AstNode* V3Begin::convertToWhile(AstForeach* nodep) { } } else if (VN_IS(fromDtp, DynArrayDType) || VN_IS(fromDtp, QueueDType)) { AstConst* const leftp = new AstConst{fl, 0}; - AstNodeExpr* const rightp - = new AstCMethodHard{fl, subfromp->cloneTreePure(false), "size"}; + AstNodeExpr* const rightp = new AstCMethodHard{ + fl, + VN_IS(subfromp->dtypep(), NodeArrayDType) + ? new AstArraySel{fl, subfromp->cloneTreePure(false), + new AstVarRef{fl, nestedIndexp, VAccess::READ}} + : subfromp->cloneTreePure(false), + "size"}; AstVarRef* varRefp = new AstVarRef{fl, varp, VAccess::READ}; subfromp = new AstCMethodHard{fl, subfromp, "at", varRefp}; subfromp->dtypep(fromDtp); @@ -508,6 +514,7 @@ AstNode* V3Begin::convertToWhile(AstForeach* nodep) { if (!newp) newp = loopp; } // Prep for next + nestedIndexp = varp; fromDtp = fromDtp->subDTypep(); } // The parser validates we don't have "foreach (array[,,,])" diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index 0cbc5bc79..a18cc8f39 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -280,7 +280,7 @@ public: } else if (foundp->imported()) { // From package // We don't throw VARHIDDEN as if the import is later the symbol // table's import wouldn't warn - } else if (VN_IS(nodep, Begin) && VN_IS(fnodep, Begin) + } else if (forPrimary() && VN_IS(nodep, Begin) && VN_IS(fnodep, Begin) && VN_AS(nodep, Begin)->generate()) { // Begin: ... blocks often replicate under genif/genfor, so // suppress duplicate checks. See t_gen_forif.v for an example. @@ -2779,7 +2779,10 @@ class LinkDotResolveVisitor final : public VNVisitor { if (AstVar* const varp = VN_CAST(foundp->nodep(), Var)) { if (varp->isParam() || varp->isGenVar()) { // Attach found Text reference to PatMember - nodep->varrefp(new AstVarRef{nodep->fileline(), varp, VAccess::READ}); + nodep->varrefp( + new AstVarRef{nodep->fileline(), + foundp->imported() ? foundp->classOrPackagep() : nullptr, + varp, VAccess::READ}); UINFO(9, indent() << " new " << nodep->varrefp() << endl); } } diff --git a/src/V3LinkParse.cpp b/src/V3LinkParse.cpp index 238d9dd49..07ea7cc14 100644 --- a/src/V3LinkParse.cpp +++ b/src/V3LinkParse.cpp @@ -430,23 +430,20 @@ class LinkParseVisitor final : public VNVisitor { VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); } else if (nodep->attrType() == VAttrType::VAR_PUBLIC) { UASSERT_OBJ(m_varp, nodep, "Attribute not attached to variable"); - // Public ifacerefs aren't supported - be compatible with older parser that ignored it - if (!m_varp->isIfaceRef()) { - m_varp->sigUserRWPublic(true); - m_varp->sigModPublic(true); - } + m_varp->sigUserRWPublic(true); + m_varp->sigModPublic(true); VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); } else if (nodep->attrType() == VAttrType::VAR_PUBLIC_FLAT) { UASSERT_OBJ(m_varp, nodep, "Attribute not attached to variable"); - if (!m_varp->isIfaceRef()) m_varp->sigUserRWPublic(true); + m_varp->sigUserRWPublic(true); VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); } else if (nodep->attrType() == VAttrType::VAR_PUBLIC_FLAT_RD) { UASSERT_OBJ(m_varp, nodep, "Attribute not attached to variable"); - if (!m_varp->isIfaceRef()) m_varp->sigUserRdPublic(true); + m_varp->sigUserRdPublic(true); VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); } else if (nodep->attrType() == VAttrType::VAR_PUBLIC_FLAT_RW) { UASSERT_OBJ(m_varp, nodep, "Attribute not attached to variable"); - if (!m_varp->isIfaceRef()) m_varp->sigUserRWPublic(true); + m_varp->sigUserRWPublic(true); VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); } else if (nodep->attrType() == VAttrType::VAR_ISOLATE_ASSIGNMENTS) { UASSERT_OBJ(m_varp, nodep, "Attribute not attached to variable"); diff --git a/test_regress/t/t_duplicated_gen_blocks_bad.out b/test_regress/t/t_duplicated_gen_blocks_bad.out new file mode 100644 index 000000000..5d14ab424 --- /dev/null +++ b/test_regress/t/t_duplicated_gen_blocks_bad.out @@ -0,0 +1,15 @@ +%Error: t/t_duplicated_gen_blocks_bad.v:11:12: Duplicate declaration of block: 'block' + : ... note: In instance 't' + 11 | begin : block + | ^~~~~ + t/t_duplicated_gen_blocks_bad.v:9:12: ... Location of original declaration + 9 | begin : block + | ^~~~~ +%Error: t/t_duplicated_gen_blocks_bad.v:15:23: Duplicate declaration of block: 'block1' + : ... note: In instance 't' + 15 | if (X > 1) begin : block1 + | ^~~~~~ + t/t_duplicated_gen_blocks_bad.v:13:23: ... Location of original declaration + 13 | if (X > 0) begin : block1 + | ^~~~~~ +%Error: Exiting due to diff --git a/test_regress/t/t_duplicated_gen_blocks_bad.py b/test_regress/t/t_duplicated_gen_blocks_bad.py new file mode 100755 index 000000000..31228c9a7 --- /dev/null +++ b/test_regress/t/t_duplicated_gen_blocks_bad.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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('linter') + +test.lint(fails=True, expect_filename=test.golden_filename) + +test.passes() diff --git a/test_regress/t/t_duplicated_gen_blocks_bad.v b/test_regress/t/t_duplicated_gen_blocks_bad.v new file mode 100644 index 000000000..43f7742a9 --- /dev/null +++ b/test_regress/t/t_duplicated_gen_blocks_bad.v @@ -0,0 +1,17 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2024 by Antmicro. +// SPDX-License-Identifier: CC0-1.0 + +module t (/*AUTOARG*/); + parameter X = 2; + begin : block + end + begin : block + end + if (X > 0) begin : block1 + end + if (X > 1) begin : block1 + end +endmodule diff --git a/test_regress/t/t_foreach_array.v b/test_regress/t/t_foreach_array.v index 7b4a8eca6..2f4297c14 100755 --- a/test_regress/t/t_foreach_array.v +++ b/test_regress/t/t_foreach_array.v @@ -5,19 +5,30 @@ // SPDX-License-Identifier: CC0-1.0 module t_foreach_array; - + // Define various structures to test foreach behavior int dyn_arr[][]; int queue[$][$]; int unpacked_arr [3:1][9:8]; int associative_array_3d[string][string][string]; - int count_que; - int exp_count_que; - int count_dyn; - int exp_count_dyn; - int count_unp; - int exp_count_unp; + int queue_unp[$][3]; // Outer dynamic queue with fixed-size inner arrays + int unp_queue[3][$]; // Fixed-size outer array with dynamic inner queues + int dyn_queue[][]; // Fully dynamic 2D array + int queue_dyn[$][]; // Outer dynamic queue with dynamic inner queues + int dyn_unp[][3]; // Dynamic outer array with fixed-size inner arrays + int unp_dyn[3][]; // Fixed-size outer array with dynamic inner arrays + + // Define counter for various structures of array + int count_que, exp_count_que; + int count_dyn, exp_count_dyn; + int count_unp, exp_count_unp; int count_assoc; + int count_queue_unp, exp_count_queue_unp; + int count_unp_queue, exp_count_unp_queue; + int count_dyn_queue, exp_count_dyn_queue; + int count_queue_dyn, exp_count_queue_dyn; + int count_dyn_unp, exp_count_dyn_unp; + int count_unp_dyn, exp_count_unp_dyn; string k1, k2, k3; @@ -35,57 +46,77 @@ module t_foreach_array; associative_array_3d["key2"]["subkey1"]["subsubkey2"] = 8; associative_array_3d["key2"]["subkey3"]["subsubkey1"] = 9; + queue_unp = '{'{1, 2, 3}, '{4, 5, 6}, '{7, 8, 9}}; + unp_queue[0] = '{10, 11}; + unp_queue[1] = '{12, 13, 14}; + unp_queue[2] = '{15}; + dyn_queue = '{'{16, 17}, '{18, 19, 20}}; + queue_dyn = '{'{21, 22}, '{23, 24, 25}}; + dyn_unp = '{'{26, 27, 28}, '{29, 30, 31}}; + unp_dyn[0] = '{32, 33}; + unp_dyn[1] = '{34, 35, 36}; + unp_dyn[2] = '{37}; + + // Perform foreach loop counting and expected value calculation count_que = 0; - - foreach(queue[i, j]) begin - count_que++; - end - + foreach(queue[i, j]) count_que++; exp_count_que = 0; - foreach(queue[i]) begin - foreach(queue[i][j]) begin - exp_count_que++; - end - end + foreach(queue[i]) foreach(queue[i][j]) exp_count_que++; count_dyn = 0; - - foreach(dyn_arr[i, j]) begin - count_dyn++; - end - + foreach(dyn_arr[i, j]) count_dyn++; exp_count_dyn = 0; - - foreach(dyn_arr[i]) begin - foreach(dyn_arr[i][j]) begin - exp_count_dyn++; - end - end + foreach(dyn_arr[i]) foreach(dyn_arr[i][j]) exp_count_dyn++; count_unp = 0; - - foreach(unpacked_arr[i, j]) begin - count_unp++; - end - + foreach(unpacked_arr[i, j]) count_unp++; exp_count_unp = 0; - - foreach(unpacked_arr[i]) begin - foreach(unpacked_arr[i][j]) begin - exp_count_unp++; - end - end + foreach(unpacked_arr[i]) foreach(unpacked_arr[i][j]) exp_count_unp++; count_assoc = 0; + foreach(associative_array_3d[k1, k2, k3]) count_assoc++; - foreach(associative_array_3d[k1, k2, k3]) begin - count_assoc++; - end + count_queue_unp = 0; + foreach (queue_unp[i, j]) count_queue_unp++; + exp_count_queue_unp = 0; + foreach (queue_unp[i]) foreach (queue_unp[i][j]) exp_count_queue_unp++; + count_unp_queue = 0; + foreach (unp_queue[i, j]) count_unp_queue++; + exp_count_unp_queue = 0; + foreach (unp_queue[i]) foreach (unp_queue[i][j]) exp_count_unp_queue++; + + count_dyn_queue = 0; + foreach (dyn_queue[i, j]) count_dyn_queue++; + exp_count_dyn_queue = 0; + foreach (dyn_queue[i]) foreach (dyn_queue[i][j]) exp_count_dyn_queue++; + + count_queue_dyn = 0; + foreach (queue_dyn[i, j]) count_queue_dyn++; + exp_count_queue_dyn = 0; + foreach (queue_dyn[i]) foreach (queue_dyn[i][j]) exp_count_queue_dyn++; + + count_dyn_unp = 0; + foreach (dyn_unp[i, j]) count_dyn_unp++; + exp_count_dyn_unp = 0; + foreach (dyn_unp[i]) foreach (dyn_unp[i][j]) exp_count_dyn_unp++; + + count_unp_dyn = 0; + foreach (unp_dyn[i, j]) count_unp_dyn++; + exp_count_unp_dyn = 0; + foreach (unp_dyn[i]) foreach (unp_dyn[i][j]) exp_count_unp_dyn++; + + // Verification checks if (count_que != 6 || count_que != exp_count_que) $stop; if (count_dyn != 12 || count_dyn != exp_count_dyn) $stop; if (count_unp != 6 || count_unp != exp_count_unp) $stop; if (count_assoc != 9) $stop; + if (count_queue_unp != exp_count_queue_unp) $stop; + if (count_unp_queue != exp_count_unp_queue) $stop; + if (count_dyn_queue != exp_count_dyn_queue) $stop; + if (count_queue_dyn != exp_count_queue_dyn) $stop; + if (count_dyn_unp != exp_count_dyn_unp) $stop; + if (count_unp_dyn != exp_count_unp_dyn) $stop; $write("*-* All Finished *-*\\n"); $finish; diff --git a/test_regress/t/t_interface_hidden.py b/test_regress/t/t_interface_hidden.py new file mode 100755 index 000000000..d4f986441 --- /dev/null +++ b/test_regress/t/t_interface_hidden.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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() + +test.execute() + +test.passes() diff --git a/test_regress/t/t_interface_hidden.v b/test_regress/t/t_interface_hidden.v new file mode 100644 index 000000000..04b460d92 --- /dev/null +++ b/test_regress/t/t_interface_hidden.v @@ -0,0 +1,76 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2013 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +module t (/*AUTOARG*/ + // Inputs + clk + ); + + input clk; + integer cyc=1; + + ifc ifc(); // Cell name hides interface's name + assign ifc.ifi = 55; + + sub sub (.isub(ifc)); // Cell name hides module's name + + int om; + + mod_or_type mot (.*); + + hides_with_type hides_type(); + hides_with_decl hides_decl(); + + always @ (posedge clk) begin + cyc <= cyc + 1; + if (cyc == 20) begin + if (om != 22) $stop; + if (mot.LOCAL != 22) $stop; + if (ifc.ifo != 55) $stop; + $write("*-* All Finished *-*\n"); + $finish; + end + end +endmodule + +module sub + ( + ifc isub + ); + always @* begin + isub.ifo = isub.ifi; + end +endmodule + +module mod_or_type(output int om); + localparam LOCAL = 22; + initial om = 22; +endmodule + +module hides_with_type(); + typedef int ifc; // Hides interface + typedef int mod_or_type; // Hides module + + ifc /*=int*/ hides_ifc; + mod_or_type /*=int*/ hides_mod; + + initial hides_ifc = 33; + initial hides_mod = 44; +endmodule + +module hides_with_decl(); + int ifc; // Hides interface + int mod_or_type; // Hides module + + initial ifc = 66; + initial mod_or_type = 77; +endmodule + +interface ifc; + localparam LOCAL = 12; + int ifi; + int ifo; +endinterface diff --git a/test_regress/t/t_param_pattern_init.v b/test_regress/t/t_param_pattern_init.v index f175e4bcf..69fefffec 100644 --- a/test_regress/t/t_param_pattern_init.v +++ b/test_regress/t/t_param_pattern_init.v @@ -7,6 +7,15 @@ `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); +package some_pkg; + localparam FOO = 5; + localparam BAR = 6; + + typedef enum int { + QUX = 7 + } pkg_enum_t; +endpackage + module t (/*AUTOARG*/ // Inputs clk @@ -69,6 +78,22 @@ module t (/*AUTOARG*/ `checkh(enum_array[2], 32'ha5a5); end + logic [31:0] package_array [8]; + + import some_pkg::*; + always_comb package_array = '{ + FOO: 32'h9876, + BAR: 32'h1212, + QUX: 32'h5432, + default: 0 + }; + + always_ff @(posedge clk) begin + `checkh(package_array[5], 32'h9876); + `checkh(package_array[6], 32'h1212); + `checkh(package_array[7], 32'h5432); + end + always_ff @(posedge clk) begin cyc <= cyc + 1; if (cyc == 2) begin diff --git a/test_regress/t/t_scoped_param_pattern_init_unsup.out b/test_regress/t/t_scoped_param_pattern_init_unsup.out new file mode 100644 index 000000000..377634d74 --- /dev/null +++ b/test_regress/t/t_scoped_param_pattern_init_unsup.out @@ -0,0 +1,4 @@ +%Error: t/t_scoped_param_pattern_init_unsup.v:30:22: syntax error, unexpected ':', expecting ',' or '}' + 30 | some_pkg::FOO: 32'h9876, + | ^ +%Error: Exiting due to diff --git a/test_regress/t/t_scoped_param_pattern_init_unsup.py b/test_regress/t/t_scoped_param_pattern_init_unsup.py new file mode 100755 index 000000000..efe8cc01c --- /dev/null +++ b/test_regress/t/t_scoped_param_pattern_init_unsup.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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.lint(fails=True, expect_filename=test.golden_filename) + +test.passes() diff --git a/test_regress/t/t_scoped_param_pattern_init_unsup.v b/test_regress/t/t_scoped_param_pattern_init_unsup.v new file mode 100644 index 000000000..ebaa9cd89 --- /dev/null +++ b/test_regress/t/t_scoped_param_pattern_init_unsup.v @@ -0,0 +1,50 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2010 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); + +package some_pkg; + localparam FOO = 5; + localparam BAR = 6; + + typedef enum int { + QUX = 7 + } pkg_enum_t; +endpackage + +module t (/*AUTOARG*/ + // Inputs + clk + ); + + input clk; + int cyc = 0; + + logic [31:0] package_array [8]; + + always_comb package_array = '{ + some_pkg::FOO: 32'h9876, + some_pkg::BAR: 32'h1212, + some_pkg::QUX: 32'h5432, + default: 0 + }; + + always_ff @(posedge clk) begin + `checkh(package_array[5], 32'h9876); + `checkh(package_array[6], 32'h1212); + `checkh(package_array[7], 32'h5432); + end + + always_ff @(posedge clk) begin + cyc <= cyc + 1; + if (cyc == 2) begin + $write("*-* All Finished *-*\n"); + $finish; + end + end + +endmodule diff --git a/test_regress/t/t_unpacked_concat.v b/test_regress/t/t_unpacked_concat.v index 468518ab2..f1ca793b5 100644 --- a/test_regress/t/t_unpacked_concat.v +++ b/test_regress/t/t_unpacked_concat.v @@ -6,90 +6,90 @@ module t (/*AUTOARG*/); - typedef int AI3[1:3]; - AI3 A3; - int A9[1:9]; + typedef int ai3_t[1:3]; + ai3_t a3; + int a9[1:9]; logic [2:0] s0; logic [2:0] s1[1:3]; - logic [2:0] s2[3:1]; + logic [2:0] s1b[3:1]; logic [2:0] s3[2:8]; - logic [2:0] s4[8:2]; + logic [2:0] s3b[8:2]; initial begin s0 = 3'd1; s1[1] = 3'd2; s1[2] = 3'd3; s1[3] = 3'd4; - s2[1] = 3'd5; - s2[2] = 3'd6; - s2[3] = 3'd7; + s1b[1] = 3'd5; + s1b[2] = 3'd6; + s1b[3] = 3'd7; - A3 = '{1, 2, 3}; - A9 = {A3, 4, 5, A3, 6}; - if (A9[1] != 1) $stop; - if (A9[2] != 2) $stop; - if (A9[3] != 3) $stop; - if (A9[4] != 4) $stop; - if (A9[5] != 5) $stop; - if (A9[6] != 1) $stop; - if (A9[7] != 2) $stop; - if (A9[8] != 3) $stop; - if (A9[9] != 6) $stop; + a3 = '{1, 2, 3}; + a9 = {a3, 4, 5, a3, 6}; + if (a9[1] != 1) $stop; + if (a9[2] != 2) $stop; + if (a9[3] != 3) $stop; + if (a9[4] != 4) $stop; + if (a9[5] != 5) $stop; + if (a9[6] != 1) $stop; + if (a9[7] != 2) $stop; + if (a9[8] != 3) $stop; + if (a9[9] != 6) $stop; - s3 = {s0, s1, s2}; + s3 = {s0, s1, s1b}; if (s3[2] != s0) $stop; if (s3[3] != s1[1]) $stop; if (s3[4] != s1[2]) $stop; if (s3[5] != s1[3]) $stop; - if (s3[6] != s2[3]) $stop; - if (s3[7] != s2[2]) $stop; - if (s3[8] != s2[1]) $stop; + if (s3[6] != s1b[3]) $stop; + if (s3[7] != s1b[2]) $stop; + if (s3[8] != s1b[1]) $stop; - s3[2:8] = {s0, s1[1:2], s1[3], s2[3], s2[2:1]}; + s3[2:8] = {s0, s1[1:2], s1[3], s1b[3], s1b[2:1]}; if (s3[2] != s0) $stop; if (s3[3] != s1[1]) $stop; if (s3[4] != s1[2]) $stop; if (s3[5] != s1[3]) $stop; - if (s3[6] != s2[3]) $stop; - if (s3[7] != s2[2]) $stop; - if (s3[8] != s2[1]) $stop; + if (s3[6] != s1b[3]) $stop; + if (s3[7] != s1b[2]) $stop; + if (s3[8] != s1b[1]) $stop; - s3 = {s0, s1[1], s1[2:3], s2[3:2], s2[1]}; + s3 = {s0, s1[1], s1[2:3], s1b[3:2], s1b[1]}; if (s3[2] != s0) $stop; if (s3[3] != s1[1]) $stop; if (s3[4] != s1[2]) $stop; if (s3[5] != s1[3]) $stop; - if (s3[6] != s2[3]) $stop; - if (s3[7] != s2[2]) $stop; - if (s3[8] != s2[1]) $stop; + if (s3[6] != s1b[3]) $stop; + if (s3[7] != s1b[2]) $stop; + if (s3[8] != s1b[1]) $stop; - s4 = {s0, s1, s2}; - if (s4[8] != s0) $stop; - if (s4[7] != s1[1]) $stop; - if (s4[6] != s1[2]) $stop; - if (s4[5] != s1[3]) $stop; - if (s4[4] != s2[3]) $stop; - if (s4[3] != s2[2]) $stop; - if (s4[2] != s2[1]) $stop; + s3b = {s0, s1, s1b}; + if (s3b[8] != s0) $stop; + if (s3b[7] != s1[1]) $stop; + if (s3b[6] != s1[2]) $stop; + if (s3b[5] != s1[3]) $stop; + if (s3b[4] != s1b[3]) $stop; + if (s3b[3] != s1b[2]) $stop; + if (s3b[2] != s1b[1]) $stop; - s4[8:2] = {s0, s1[1:2], s1[3], s2[3], s2[2:1]}; - if (s4[8] != s0) $stop; - if (s4[7] != s1[1]) $stop; - if (s4[6] != s1[2]) $stop; - if (s4[5] != s1[3]) $stop; - if (s4[4] != s2[3]) $stop; - if (s4[3] != s2[2]) $stop; - if (s4[2] != s2[1]) $stop; + s3b[8:2] = {s0, s1[1:2], s1[3], s1b[3], s1b[2:1]}; + if (s3b[8] != s0) $stop; + if (s3b[7] != s1[1]) $stop; + if (s3b[6] != s1[2]) $stop; + if (s3b[5] != s1[3]) $stop; + if (s3b[4] != s1b[3]) $stop; + if (s3b[3] != s1b[2]) $stop; + if (s3b[2] != s1b[1]) $stop; - s4 = {s0, s1[1], s1[2:3], s2[3:2], s2[1]}; - if (s4[8] != s0) $stop; - if (s4[7] != s1[1]) $stop; - if (s4[6] != s1[2]) $stop; - if (s4[5] != s1[3]) $stop; - if (s4[4] != s2[3]) $stop; - if (s4[3] != s2[2]) $stop; - if (s4[2] != s2[1]) $stop; + s3b = {s0, s1[1], s1[2:3], s1b[3:2], s1b[1]}; + if (s3b[8] != s0) $stop; + if (s3b[7] != s1[1]) $stop; + if (s3b[6] != s1[2]) $stop; + if (s3b[5] != s1[3]) $stop; + if (s3b[4] != s1b[3]) $stop; + if (s3b[3] != s1b[2]) $stop; + if (s3b[2] != s1b[1]) $stop; $write("*-* All Finished *-*\n"); $finish; diff --git a/test_regress/t/t_unpacked_init.v b/test_regress/t/t_unpacked_init.v index ae7243ad1..e9d052a51 100644 --- a/test_regress/t/t_unpacked_init.v +++ b/test_regress/t/t_unpacked_init.v @@ -14,6 +14,8 @@ module t (/*AUTOARG*/); int a3[1] = '{16}; int a4[1] = {17}; + int a5[2][3] = '{'{10, 11, 12}, '{13, 14, 15}}; + initial begin `checkh(a1[0], 12); `checkh(a1[1], 13); @@ -25,6 +27,13 @@ module t (/*AUTOARG*/); `checkh(a4[0], 17); + `checkh(a5[0][0], 10); + `checkh(a5[0][1], 11); + `checkh(a5[0][2], 12); + `checkh(a5[1][0], 13); + `checkh(a5[1][1], 14); + `checkh(a5[1][2], 15); + $write("*-* All Finished *-*\n"); $finish; end