From 755039d21b3179d3ae1ff742d9d50261466e4923 Mon Sep 17 00:00:00 2001 From: Jaeuk Lee <126692701+skku970412@users.noreply.github.com> Date: Tue, 7 Jul 2026 12:52:21 +0900 Subject: [PATCH 1/2] Fix dynamic array assignment to unpacked arrays (#6907) --- docs/CONTRIBUTORS | 1 + include/verilated_funcs.h | 21 +++++++++++++++++++++ src/V3Slice.cpp | 1 + src/V3Width.cpp | 25 +++++++++++++++++++++++++ test_regress/t/t_dynarray.v | 23 +++++++++++++++++++++++ 5 files changed, 71 insertions(+) diff --git a/docs/CONTRIBUTORS b/docs/CONTRIBUTORS index 24e3ced87..e52f92eb2 100644 --- a/docs/CONTRIBUTORS +++ b/docs/CONTRIBUTORS @@ -110,6 +110,7 @@ Ilya Barkov Iru Cai Ivan Vnučec Iztok Jeras +Jaeuk Lee Jake Merdich Jakub Michalski Jakub Wasilewski diff --git a/include/verilated_funcs.h b/include/verilated_funcs.h index 349fe44da..f7ba3f8b1 100644 --- a/include/verilated_funcs.h +++ b/include/verilated_funcs.h @@ -3086,6 +3086,27 @@ static inline void VL_REVCOPY_Q(VlQueue& q, const VlUnpacked& fro VL_COPY_Q(q, srcQ, lbits, srcElementBits, dstElementBits); } +// Overloads for VlQueue source -> VlUnpacked destination +template +static inline void VL_COPY_Q(VlUnpacked& q, const VlQueue& from, int lbits, + int srcElementBits, int dstElementBits) { + if (srcElementBits == dstElementBits) { + for (size_t i = 0; i < N_Depth; ++i) q[i] = from.at(static_cast(i)); + } else { + VlQueue tmpQ; + VL_COPY_Q(tmpQ, from, lbits, srcElementBits, dstElementBits); + for (size_t i = 0; i < N_Depth; ++i) q[i] = tmpQ.at(static_cast(i)); + } +} + +template +static inline void VL_REVCOPY_Q(VlUnpacked& q, const VlQueue& from, int lbits, + int srcElementBits, int dstElementBits) { + VlQueue tmpQ; + VL_REVCOPY_Q(tmpQ, from, lbits, srcElementBits, dstElementBits); + for (size_t i = 0; i < N_Depth; ++i) q[i] = tmpQ.at(static_cast(i)); +} + //====================================================================== // Expressions needing insert/select diff --git a/src/V3Slice.cpp b/src/V3Slice.cpp index 4331e4015..713628fa0 100644 --- a/src/V3Slice.cpp +++ b/src/V3Slice.cpp @@ -247,6 +247,7 @@ class SliceVisitor final : public VNVisitor { const AstUnpackArrayDType* const arrayp = VN_CAST(dtp, UnpackArrayDType); if (!arrayp) return false; if (VN_IS(stp, CvtPackedToArray)) return false; + if (VN_IS(stp, CvtArrayToArray)) return false; if (VN_IS(stp, CReset)) return false; // Any isSc variables must be expanded regardless of --fno-slice diff --git a/src/V3Width.cpp b/src/V3Width.cpp index 802fe155d..854b01451 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -6439,6 +6439,7 @@ class WidthVisitor final : public VNVisitor { } iterateCheckAssign(nodep, "Assign RHS", nodep->rhsp(), FINAL, lhsDTypep); + convertArrayToUnpackedAssign(nodep); // UINFOTREE(1, nodep, "", "AssignOut"); } if (VN_IS(nodep, AssignForce)) checkForceReleaseLhs(nodep, nodep->lhsp()); @@ -6561,6 +6562,30 @@ class WidthVisitor final : public VNVisitor { checkForceReleaseLhs(nodep, nodep->lhsp()); } + static void convertArrayToUnpackedAssign(AstNodeAssign* nodep) { + AstNodeDType* const lhsDTypep = nodep->lhsp()->dtypep()->skipRefp(); + if (!VN_IS(lhsDTypep, UnpackArrayDType)) return; + + AstNodeExpr* const rhsp = nodep->rhsp(); + AstNodeDType* const rhsDTypep = rhsp->dtypep()->skipRefp(); + if (!VN_IS(rhsDTypep, DynArrayDType) && !VN_IS(rhsDTypep, QueueDType)) return; + + int srcElementBits = 1; + if (const AstNodeDType* const elemDtp = rhsDTypep->subDTypep()->skipRefp()) { + srcElementBits = elemDtp->width(); + } + int dstElementBits = 1; + if (const AstNodeDType* const elemDtp = lhsDTypep->subDTypep()->skipRefp()) { + dstElementBits = elemDtp->width(); + } + + rhsp->unlinkFrBack(); + AstCvtArrayToArray* const newp = new AstCvtArrayToArray{ + rhsp->fileline(), rhsp, lhsDTypep, false, 1, dstElementBits, srcElementBits}; + newp->didWidth(true); + nodep->rhsp(newp); + } + static bool isFormatNonNumericArg(const AstNodeDType* dtypep) { dtypep = dtypep->skipRefp(); return dtypep->isString() // diff --git a/test_regress/t/t_dynarray.v b/test_regress/t/t_dynarray.v index 308f83ffa..914d207ec 100644 --- a/test_regress/t/t_dynarray.v +++ b/test_regress/t/t_dynarray.v @@ -26,6 +26,9 @@ module t ( typedef bit [7:0] byte_t; byte_t a[]; byte_t b[]; + byte_t fixed[256]; + byte_t fixed_rev[1:256]; + byte_t q[$]; // wide data array typedef struct packed { @@ -157,6 +160,26 @@ module t ( p256.delete(); `checkh(p256.size, 0); + // Test assignment from dynamic and queue arrays to fixed unpacked arrays. + a = new[256]; + for (int j = 0; j < 256; j++) begin + a[j] = byte_t'(j + 32'ha0); + q.push_back(byte_t'(j + 32'h40)); + end + fixed = a; + `checkh(fixed[0], 8'ha0); + `checkh(fixed[255], 8'h9f); + fixed = q; + `checkh(fixed[0], 8'h40); + `checkh(fixed[255], 8'h3f); + fixed_rev = a; + `checkh(fixed_rev[1], 8'ha0); + `checkh(fixed_rev[256], 8'h9f); + fixed_rev = q; + `checkh(fixed_rev[1], 8'h40); + `checkh(fixed_rev[256], 8'h3f); + q.delete(); + end $write("*-* All Finished *-*\n"); From 56b379b1506c9dea4902ae92e776291e0a7aab3d Mon Sep 17 00:00:00 2001 From: JAEUK LEE Date: Wed, 8 Jul 2026 17:19:23 +0900 Subject: [PATCH 2/2] Address dynamic array review feedback --- include/verilated_funcs.h | 10 +++------- test_regress/t/t_dynarray.v | 7 +++++++ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/include/verilated_funcs.h b/include/verilated_funcs.h index f7ba3f8b1..60dbcd8f1 100644 --- a/include/verilated_funcs.h +++ b/include/verilated_funcs.h @@ -3090,13 +3090,9 @@ static inline void VL_REVCOPY_Q(VlQueue& q, const VlUnpacked& fro template static inline void VL_COPY_Q(VlUnpacked& q, const VlQueue& from, int lbits, int srcElementBits, int dstElementBits) { - if (srcElementBits == dstElementBits) { - for (size_t i = 0; i < N_Depth; ++i) q[i] = from.at(static_cast(i)); - } else { - VlQueue tmpQ; - VL_COPY_Q(tmpQ, from, lbits, srcElementBits, dstElementBits); - for (size_t i = 0; i < N_Depth; ++i) q[i] = tmpQ.at(static_cast(i)); - } + VlQueue tmpQ; + VL_COPY_Q(tmpQ, from, lbits, srcElementBits, dstElementBits); + for (size_t i = 0; i < N_Depth; ++i) q[i] = tmpQ.at(static_cast(i)); } template diff --git a/test_regress/t/t_dynarray.v b/test_regress/t/t_dynarray.v index 914d207ec..bd9bbbf3a 100644 --- a/test_regress/t/t_dynarray.v +++ b/test_regress/t/t_dynarray.v @@ -27,6 +27,7 @@ module t ( byte_t a[]; byte_t b[]; byte_t fixed[256]; + byte_t fixed_desc[255:0]; byte_t fixed_rev[1:256]; byte_t q[$]; @@ -172,6 +173,12 @@ module t ( fixed = q; `checkh(fixed[0], 8'h40); `checkh(fixed[255], 8'h3f); + fixed_desc = a; + `checkh(fixed_desc[255], 8'h9f); + `checkh(fixed_desc[0], 8'ha0); + fixed_desc = q; + `checkh(fixed_desc[255], 8'h3f); + `checkh(fixed_desc[0], 8'h40); fixed_rev = a; `checkh(fixed_rev[1], 8'ha0); `checkh(fixed_rev[256], 8'h9f);