diff --git a/src/V3Begin.cpp b/src/V3Begin.cpp index 4bdb4631f..d6e881f40 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 + // subfromp used to traverse each dimension of multi-d variable-sized unpacked array (queue, + // dyn-arr and associative-arr) AstNodeExpr* subfromp = fromp->cloneTreePure(false); // Major dimension first for (AstNode *argsp = loopsp->elementsp(), *next_argsp; argsp; argsp = next_argsp) { @@ -477,13 +478,16 @@ AstNode* V3Begin::convertToWhile(AstForeach* nodep) { first_varp->usedLoopIdx(true); first_varp->lifetime(VLifetime::AUTOMATIC); AstNodeExpr* const firstp - = new AstCMethodHard{fl, fromp->cloneTreePure(false), "first", + = new AstCMethodHard{fl, subfromp->cloneTreePure(false), "first", new AstVarRef{fl, varp, VAccess::READWRITE}}; firstp->dtypeSetSigned32(); AstNodeExpr* const nextp - = new AstCMethodHard{fl, fromp->cloneTreePure(false), "next", + = new AstCMethodHard{fl, subfromp->cloneTreePure(false), "next", new AstVarRef{fl, varp, VAccess::READWRITE}}; nextp->dtypeSetSigned32(); + AstVarRef* varRefp = new AstVarRef{fl, varp, VAccess::READ}; + subfromp = new AstCMethodHard{fl, subfromp, "at", varRefp}; + subfromp->dtypep(fromDtp); AstNode* const first_clearp = new AstAssign{fl, new AstVarRef{fl, first_varp, VAccess::WRITE}, new AstConst{fl, AstConst::BitFalse{}}}; diff --git a/test_regress/t/t_foreach_array.v b/test_regress/t/t_foreach_array.v index 0c4f3e64e..7b4a8eca6 100755 --- a/test_regress/t/t_foreach_array.v +++ b/test_regress/t/t_foreach_array.v @@ -9,6 +9,7 @@ module t_foreach_array; 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; @@ -16,11 +17,23 @@ module t_foreach_array; int exp_count_dyn; int count_unp; int exp_count_unp; + int count_assoc; + + string k1, k2, k3; initial begin // Initialize queue = '{'{1, 2, 3}, '{4, 5}, '{6}}; dyn_arr = '{'{1, 2, 3}, '{4, 5, 6, 0, 10}, '{6, 7, 8, 9}}; + associative_array_3d["key1"]["subkey1"]["subsubkey1"] = 1; + associative_array_3d["key1"]["subkey1"]["subsubkey2"] = 2; + associative_array_3d["key1"]["subkey2"]["subsubkey1"] = 3; + associative_array_3d["key1"]["subkey3"]["subsubkey1"] = 4; + associative_array_3d["key1"]["subkey3"]["subsubkey2"] = 5; + associative_array_3d["key1"]["subkey3"]["subsubkey3"] = 6; + associative_array_3d["key2"]["subkey1"]["subsubkey1"] = 7; + associative_array_3d["key2"]["subkey1"]["subsubkey2"] = 8; + associative_array_3d["key2"]["subkey3"]["subsubkey1"] = 9; count_que = 0; @@ -63,9 +76,16 @@ module t_foreach_array; end end + count_assoc = 0; + + foreach(associative_array_3d[k1, k2, k3]) begin + count_assoc++; + 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; + if (count_assoc != 9) $stop; $write("*-* All Finished *-*\\n"); $finish; diff --git a/test_regress/t/t_randomize_array.v b/test_regress/t/t_randomize_array.v index bd165adc0..ac2f3015f 100755 --- a/test_regress/t/t_randomize_array.v +++ b/test_regress/t/t_randomize_array.v @@ -108,33 +108,60 @@ endclass class unconstrained_associative_array_test; - rand int associative_array[string]; + rand int associative_array_1d[string]; + rand int associative_array_3d[string][string][string]; + string key1, key2, key3; function new(); - associative_array["key1"] = 0; - associative_array["key2"] = 0; + associative_array_1d["key1"] = 1; + associative_array_1d["key2"] = 2; + + associative_array_3d["key1"]["subkey1"]["subsubkey1"] = 1; + associative_array_3d["key1"]["subkey1"]["subsubkey2"] = 2; + associative_array_3d["key1"]["subkey2"]["subsubkey1"] = 3; + associative_array_3d["key1"]["subkey3"]["subsubkey1"] = 4; + associative_array_3d["key1"]["subkey3"]["subsubkey2"] = 5; + associative_array_3d["key1"]["subkey3"]["subsubkey3"] = 6; + associative_array_3d["key2"]["subkey1"]["subsubkey1"] = 7; + associative_array_3d["key2"]["subkey1"]["subsubkey2"] = 8; + associative_array_3d["key2"]["subkey2"]["subsubkey1"] = 9; + associative_array_3d["key2"]["subkey3"]["subsubkey1"] = 10; + associative_array_3d["key2"]["subkey3"]["subsubkey2"] = 11; endfunction function void check_randomization(); - `check_rand(this, associative_array["key1"]); - `check_rand(this, associative_array["key2"]); + `check_rand(this, associative_array_1d["key1"]); + `check_rand(this, associative_array_1d["key2"]); + + foreach(associative_array_3d[key1, key2, key3]) begin + `check_rand(this, associative_array_3d[key1][key2][key3]); + end endfunction endclass class unconstrained_queue_test; - rand int queue_array[$]; + rand int queue_array_1d[$]; + rand int queue_array_2d[$][$]; function new(); - for (int i = 0; i < 3; i++) begin - queue_array.push_back('h0 + i); + queue_array_1d = {}; + for (int i = 0; i < 8; i++) begin + queue_array_1d.push_back('h0 + i); end + queue_array_2d = {}; + queue_array_2d[0] = '{1, 2, 3}; + queue_array_2d[1] = '{4, 5, 6, 0, 10}; + queue_array_2d[2] = '{6, 7, 8, 9}; endfunction function void check_randomization(); - foreach (queue_array[i]) begin - `check_rand(this, queue_array[i]); + foreach (queue_array_1d[i]) begin + `check_rand(this, queue_array_1d[i]); + end + foreach(queue_array_2d[i, j]) begin + `check_rand(this, queue_array_2d[i][j]); end endfunction