diff --git a/src/V3Begin.cpp b/src/V3Begin.cpp index 5a9ced53c..4bdb4631f 100644 --- a/src/V3Begin.cpp +++ b/src/V3Begin.cpp @@ -427,7 +427,8 @@ AstNode* V3Begin::convertToWhile(AstForeach* nodep) { AstNode* bodyPointp = new AstBegin{nodep->fileline(), "[EditWrapper]", nullptr}; AstNode* newp = nullptr; AstNode* lastp = nodep; - + // subfromp used to traverse each dimension of multi-d queue/dyn-arr's + AstNodeExpr* subfromp = fromp->cloneTreePure(false); // Major dimension first for (AstNode *argsp = loopsp->elementsp(), *next_argsp; argsp; argsp = next_argsp) { next_argsp = argsp->nextp(); @@ -458,7 +459,10 @@ 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, fromp->cloneTreePure(false), "size"}; + = new AstCMethodHard{fl, subfromp->cloneTreePure(false), "size"}; + AstVarRef* varRefp = new AstVarRef{fl, varp, VAccess::READ}; + subfromp = new AstCMethodHard{fl, subfromp, "at", varRefp}; + subfromp->dtypep(fromDtp); rightp->dtypeSetSigned32(); rightp->protect(false); loopp = createForeachLoop(nodep, bodyPointp, varp, leftp, rightp, VNType::atLt); diff --git a/test_regress/t/t_foreach_array.py b/test_regress/t/t_foreach_array.py new file mode 100755 index 000000000..d4f986441 --- /dev/null +++ b/test_regress/t/t_foreach_array.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_foreach_array.v b/test_regress/t/t_foreach_array.v new file mode 100755 index 000000000..0c4f3e64e --- /dev/null +++ b/test_regress/t/t_foreach_array.v @@ -0,0 +1,74 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2024 by PlanV GmbH. +// SPDX-License-Identifier: CC0-1.0 + +module t_foreach_array; + + int dyn_arr[][]; + int queue[$][$]; + int unpacked_arr [3:1][9:8]; + + int count_que; + int exp_count_que; + int count_dyn; + int exp_count_dyn; + int count_unp; + int exp_count_unp; + + initial begin + // Initialize + queue = '{'{1, 2, 3}, '{4, 5}, '{6}}; + dyn_arr = '{'{1, 2, 3}, '{4, 5, 6, 0, 10}, '{6, 7, 8, 9}}; + + count_que = 0; + + foreach(queue[i, j]) begin + count_que++; + end + + exp_count_que = 0; + foreach(queue[i]) begin + foreach(queue[i][j]) begin + exp_count_que++; + end + end + + count_dyn = 0; + + foreach(dyn_arr[i, j]) begin + count_dyn++; + end + + exp_count_dyn = 0; + + foreach(dyn_arr[i]) begin + foreach(dyn_arr[i][j]) begin + exp_count_dyn++; + end + end + + count_unp = 0; + + foreach(unpacked_arr[i, j]) begin + count_unp++; + end + + exp_count_unp = 0; + + foreach(unpacked_arr[i]) begin + foreach(unpacked_arr[i][j]) begin + exp_count_unp++; + end + end + + 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; + + $write("*-* All Finished *-*\\n"); + $finish; + end + +endmodule