Fix foreach with 2-D queues and dynamic arrays (#5525) (#5529)

This commit is contained in:
Yilou Wang 2024-10-10 16:50:37 +02:00 committed by GitHub
parent 2a905c1d6e
commit f3cc32554c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 98 additions and 2 deletions

View File

@ -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);

View File

@ -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()

View File

@ -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