mirror of
https://github.com/verilator/verilator.git
synced 2024-12-29 10:47:34 +00:00
parent
e9a1c75b7f
commit
a64660a530
@ -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[,,,])"
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user