diff --git a/include/verilated_funcs.h b/include/verilated_funcs.h index 0d1ecbf3b..3b1b5fd33 100644 --- a/include/verilated_funcs.h +++ b/include/verilated_funcs.h @@ -1586,46 +1586,68 @@ static inline WDataOutP VL_STREAML_WWI(int lbits, WDataOutP owp, WDataInP const } template -static inline void VL_ASSIGN_DYN_Q(VlQueue& q, int elem_size, int lbits, QData from) { - const int size = (lbits + elem_size - 1) / elem_size; - q.renew(size); - const QData mask = VL_MASK_Q(elem_size); - for (int i = 0; i < size; ++i) q.at(i) = (T)((from >> (i * elem_size)) & mask); +static inline IData VL_PACK_II(int obits, int lbits, const VlQueue& q) { + IData ret = 0; + for (size_t i = 0; i < q.size(); ++i) ret |= q.at(i) << (i * lbits); + return ret; } template -static inline void VL_ASSIGN_UNPACK_Q(VlUnpacked& q, size_t elem_size, QData from) { - const QData mask = VL_MASK_Q(elem_size); +static inline IData VL_PACK_II(int obits, int lbits, const VlUnpacked& q) { + IData ret = 0; + for (size_t i = 0; i < T_Depth; ++i) ret |= q[T_Depth - 1 - i] << (i * lbits); + return ret; +} + +#define VL_PACK_QI VL_PACK_QQ + +template +static inline QData VL_PACK_QQ(int obits, int lbits, const VlQueue& q) { + QData ret = 0; + for (size_t i = 0; i < q.size(); ++i) ret |= static_cast(q.at(i)) << (i * lbits); + return ret; +} + +template +static inline QData VL_PACK_QQ(int obits, int lbits, const VlUnpacked& q) { + QData ret = 0; for (size_t i = 0; i < T_Depth; ++i) - q[i] = (T)((from >> ((T_Depth - 1 - i) * elem_size)) & mask); -} - -template -static inline IData VL_DYN_TO_I(const VlQueue& q, int elem_size) { - IData ret = 0; - for (int i = 0; i < q.size(); ++i) ret |= q.at(i) << (i * elem_size); + ret |= static_cast(q[T_Depth - 1 - i]) << (i * lbits); return ret; } template -static inline QData VL_DYN_TO_Q(const VlQueue& q, int elem_size) { - QData ret = 0; - for (int i = 0; i < q.size(); ++i) ret |= q.at(i) << (i * elem_size); - return ret; +static inline WDataOutP VL_PACK_WI(int obits, int lbits, WDataOutP owp, const VlQueue& q) { + VL_MEMSET_ZERO_W(owp + 1, VL_WORDS_I(obits) - 1); + for (size_t i = 0; i < q.size(); ++i) + _vl_insert_WI(owp, q.at(i), i * lbits + lbits - 1, i * lbits); + return owp; } template -static inline IData VL_UNPACK_TO_I(const VlUnpacked& q, size_t elem_size) { - IData ret = 0; - for (size_t i = 0; i < T_Depth; ++i) ret |= q[T_Depth - 1 - i] << (i * elem_size); - return ret; +static inline WDataOutP VL_PACK_WI(int obits, int lbits, WDataOutP owp, + const VlUnpacked& q) { + VL_MEMSET_ZERO_W(owp + 1, VL_WORDS_I(obits) - 1); + for (size_t i = 0; i < T_Depth; ++i) + _vl_insert_WI(owp, q[T_Depth - 1 - i], i * lbits + lbits - 1, i * lbits); + return owp; +} + +template +static inline WDataOutP VL_PACK_WQ(int obits, int lbits, WDataOutP owp, const VlQueue& q) { + VL_MEMSET_ZERO_W(owp + 1, VL_WORDS_I(obits) - 1); + for (size_t i = 0; i < q.size(); ++i) + _vl_insert_WQ(owp, q.at(i), i * lbits + lbits - 1, i * lbits); + return owp; } template -static inline QData VL_UNPACK_TO_Q(const VlUnpacked& q, size_t elem_size) { - QData ret = 0; - for (size_t i = 0; i < T_Depth; ++i) ret |= q[T_Depth - 1 - i] << (i * elem_size); - return ret; +static inline WDataOutP VL_PACK_WQ(int obits, int lbits, WDataOutP owp, + const VlUnpacked& q) { + VL_MEMSET_ZERO_W(owp + 1, VL_WORDS_I(obits) - 1); + for (size_t i = 0; i < T_Depth; ++i) + _vl_insert_WQ(owp, q[T_Depth - 1 - i], i * lbits + lbits - 1, i * lbits); + return owp; } // Because concats are common and wide, it's valuable to always have a clean output. @@ -2067,6 +2089,70 @@ static inline WDataOutP VL_SEL_WWII(int obits, int lbits, WDataOutP owp, WDataIn //====================================================================== // Expressions needing insert/select +template +static inline void VL_UNPACK_II(int lbits, int rbits, VlQueue& q, IData from) { + const size_t size = (rbits + lbits - 1) / lbits; + q.renew(size); + const IData mask = VL_MASK_I(lbits); + for (size_t i = 0; i < size; ++i) q.at(i) = static_cast((from >> (i * lbits)) & mask); +} + +#define VL_UNPACK_IQ VL_UNPACK_QQ + +template +static inline void VL_UNPACK_QQ(int lbits, int rbits, VlQueue& q, QData from) { + const size_t size = (rbits + lbits - 1) / lbits; + q.renew(size); + const QData mask = VL_MASK_Q(lbits); + for (size_t i = 0; i < size; ++i) q.at(i) = static_cast((from >> (i * lbits)) & mask); +} + +template +static inline void VL_UNPACK_IW(int lbits, int rbits, VlQueue& q, WDataInP rwp) { + const int size = (rbits + lbits - 1) / lbits; + q.renew(size); + const IData mask = VL_MASK_I(lbits); + for (size_t i = 0; i < size; ++i) + q.at(i) = static_cast(VL_SEL_IWII(rbits, rwp, i * lbits, lbits) & mask); +} + +template +static inline void VL_UNPACK_QW(int lbits, int rbits, VlQueue& q, WDataInP rwp) { + const int size = (rbits + lbits - 1) / lbits; + q.renew(size); + const QData mask = VL_MASK_Q(lbits); + for (size_t i = 0; i < size; ++i) + q.at(i) = static_cast(VL_SEL_QWII(rbits, rwp, i * lbits, lbits) & mask); +} + +template +static inline void VL_UNPACK_II(int lbits, int rbits, VlUnpacked& q, QData from) { + const IData mask = VL_MASK_I(lbits); + for (size_t i = 0; i < T_Depth; ++i) + q[i] = static_cast((from >> ((T_Depth - 1 - i) * lbits)) & mask); +} + +template +static inline void VL_UNPACK_QQ(int lbits, int rbits, VlUnpacked& q, QData from) { + const QData mask = VL_MASK_Q(lbits); + for (size_t i = 0; i < T_Depth; ++i) + q[i] = static_cast((from >> ((T_Depth - 1 - i) * lbits)) & mask); +} + +template +static inline void VL_UNPACK_IW(int lbits, int rbits, VlUnpacked& q, WDataInP rwp) { + const IData mask = VL_MASK_I(lbits); + for (size_t i = 0; i < T_Depth; ++i) + q[i] = static_cast(VL_SEL_IWII(rbits, rwp, (T_Depth - 1 - i) * lbits, lbits) & mask); +} + +template +static inline void VL_UNPACK_QW(int lbits, int rbits, VlUnpacked& q, WDataInP rwp) { + const QData mask = VL_MASK_Q(lbits); + for (size_t i = 0; i < T_Depth; ++i) + q[i] = static_cast(VL_SEL_QWII(rbits, rwp, (T_Depth - 1 - i) * lbits, lbits) & mask); +} + // Return QData from double (numeric) // EMIT_RULE: VL_RTOIROUND_Q_D: oclean=dirty; lclean==clean/real static inline QData VL_RTOIROUND_Q_D(double lhs) VL_PURE { diff --git a/src/V3AstNodeExpr.h b/src/V3AstNodeExpr.h index 5538298e5..8f7680bc8 100644 --- a/src/V3AstNodeExpr.h +++ b/src/V3AstNodeExpr.h @@ -1124,58 +1124,30 @@ public: string emitC() final override { V3ERROR_NA_RETURN(""); } bool cleanOut() const final override { V3ERROR_NA_RETURN(true); } }; -class AstCvtDynArrayToPacked final : public AstNodeExpr { +class AstCvtArrayToPacked final : public AstNodeExpr { // Cast from dynamic queue data type to packed array // @astgen op1 := fromp : AstNodeExpr public: - AstCvtDynArrayToPacked(FileLine* fl, AstNodeExpr* fromp, AstNodeDType* dtp) - : ASTGEN_SUPER_CvtDynArrayToPacked(fl) { + AstCvtArrayToPacked(FileLine* fl, AstNodeExpr* fromp, AstNodeDType* dtp) + : ASTGEN_SUPER_CvtArrayToPacked(fl) { this->fromp(fromp); dtypeFrom(dtp); } - ASTGEN_MEMBERS_AstCvtDynArrayToPacked; + ASTGEN_MEMBERS_AstCvtArrayToPacked; string emitVerilog() override { V3ERROR_NA_RETURN(""); } - string emitC() override { V3ERROR_NA_RETURN(""); } + string emitC() override { return "VL_PACK_%nq%rq(%nw, %rw, %P, %li)"; } bool cleanOut() const override { return true; } }; -class AstCvtPackedToDynArray final : public AstNodeExpr { - // Cast from packed array to dynamic queue data type +class AstCvtPackedToArray final : public AstNodeExpr { + // Cast from packed array to dynamic/unpacked queue data type // @astgen op1 := fromp : AstNodeExpr public: - AstCvtPackedToDynArray(FileLine* fl, AstNodeExpr* fromp, AstNodeDType* dtp) - : ASTGEN_SUPER_CvtPackedToDynArray(fl) { + AstCvtPackedToArray(FileLine* fl, AstNodeExpr* fromp, AstNodeDType* dtp) + : ASTGEN_SUPER_CvtPackedToArray(fl) { this->fromp(fromp); dtypeFrom(dtp); } - ASTGEN_MEMBERS_AstCvtPackedToDynArray; - string emitVerilog() override { V3ERROR_NA_RETURN(""); } - string emitC() override { V3ERROR_NA_RETURN(""); } - bool cleanOut() const override { return true; } -}; -class AstCvtPackedToUnpackArray final : public AstNodeExpr { - // Cast from packed array to dynamic queue data type - // @astgen op1 := fromp : AstNodeExpr -public: - AstCvtPackedToUnpackArray(FileLine* fl, AstNodeExpr* fromp, AstNodeDType* dtp) - : ASTGEN_SUPER_CvtPackedToUnpackArray(fl) { - this->fromp(fromp); - dtypeFrom(dtp); - } - ASTGEN_MEMBERS_AstCvtPackedToUnpackArray; - string emitVerilog() override { V3ERROR_NA_RETURN(""); } - string emitC() override { V3ERROR_NA_RETURN(""); } - bool cleanOut() const override { return true; } -}; -class AstCvtUnpackArrayToPacked final : public AstNodeExpr { - // Cast from dynamic queue data type to packed array - // @astgen op1 := fromp : AstNodeExpr -public: - AstCvtUnpackArrayToPacked(FileLine* fl, AstNodeExpr* fromp, AstNodeDType* dtp) - : ASTGEN_SUPER_CvtUnpackArrayToPacked(fl) { - this->fromp(fromp); - dtypeFrom(dtp); - } - ASTGEN_MEMBERS_AstCvtUnpackArrayToPacked; + ASTGEN_MEMBERS_AstCvtPackedToArray; string emitVerilog() override { V3ERROR_NA_RETURN(""); } string emitC() override { V3ERROR_NA_RETURN(""); } bool cleanOut() const override { return true; } @@ -4284,7 +4256,7 @@ public: bool cleanOut() const override { return true; } bool cleanLhs() const override { return true; } bool cleanRhs() const override { return true; } - bool sizeMattersLhs() const override { return true; } + bool sizeMattersLhs() const override { return false; } bool sizeMattersRhs() const override { return false; } int instrCount() const override { return widthInstrs() * 2; } }; @@ -4305,7 +4277,7 @@ public: bool cleanOut() const override { return false; } bool cleanLhs() const override { return false; } bool cleanRhs() const override { return false; } - bool sizeMattersLhs() const override { return true; } + bool sizeMattersLhs() const override { return false; } bool sizeMattersRhs() const override { return false; } int instrCount() const override { return widthInstrs() * 2; } }; diff --git a/src/V3Const.cpp b/src/V3Const.cpp index 403148bf8..b5dce4457 100644 --- a/src/V3Const.cpp +++ b/src/V3Const.cpp @@ -2171,26 +2171,17 @@ class ConstVisitor final : public VNVisitor { AstNodeExpr* srcp = streamp->lhsp()->unlinkFrBack(); AstNodeDType* const srcDTypep = srcp->dtypep(); if (VN_IS(srcDTypep, QueueDType) || VN_IS(srcDTypep, DynArrayDType)) { - if (nodep->lhsp()->widthMin() > 64) { - nodep->v3warn(E_UNSUPPORTED, "Unsupported: Assignment of stream of dynamic " - "array to a variable of size greater than 64"); - } - srcp = new AstCvtDynArrayToPacked{srcp->fileline(), srcp, srcDTypep}; + srcp = new AstCvtArrayToPacked{srcp->fileline(), srcp, nodep->dtypep()}; } else if (VN_IS(srcDTypep, UnpackArrayDType)) { - if (nodep->lhsp()->widthMin() > 64) { - nodep->v3warn(E_UNSUPPORTED, "Unsupported: Assignment of stream of dynamic " - "array to a variable of size greater than 64"); - } - srcp = new AstCvtUnpackArrayToPacked{srcp->fileline(), srcp, - nodep->lhsp()->dtypep()}; + srcp = new AstCvtArrayToPacked{srcp->fileline(), srcp, srcDTypep}; // Handling the case where lhs is wider than rhs by inserting zeros. StreamL does // not require this, since the left streaming operator implicitly handles this. - const uint32_t packedBits = nodep->lhsp()->widthMin(); - const uint32_t unpackBits + const int packedBits = nodep->lhsp()->widthMin(); + const int unpackBits = srcDTypep->arrayUnpackedElements() * srcDTypep->subDTypep()->widthMin(); const uint32_t offset = packedBits > unpackBits ? packedBits - unpackBits : 0; srcp = new AstShiftL{srcp->fileline(), srcp, - new AstConst{srcp->fileline(), offset}, 64}; + new AstConst{srcp->fileline(), offset}, packedBits}; } nodep->rhsp(srcp); VL_DO_DANGLING(pushDeletep(streamp), streamp); @@ -2212,19 +2203,18 @@ class ConstVisitor final : public VNVisitor { streamp->dtypeSetLogicUnsized(srcp->width(), srcp->widthMin(), VSigning::UNSIGNED); } if (VN_IS(dstp->dtypep(), UnpackArrayDType)) { - streamp - = new AstCvtPackedToUnpackArray{nodep->fileline(), streamp, dstp->dtypep()}; + streamp = new AstCvtPackedToArray{nodep->fileline(), streamp, dstp->dtypep()}; } else { UASSERT(sWidth >= dWidth, "sWidth >= dWidth should have caused an error earlier"); if (dWidth == 0) { - streamp - = new AstCvtPackedToDynArray{nodep->fileline(), streamp, dstp->dtypep()}; + streamp = new AstCvtPackedToArray{nodep->fileline(), streamp, dstp->dtypep()}; } else if (sWidth >= dWidth) { streamp = new AstSel{streamp->fileline(), streamp, sWidth - dWidth, dWidth}; } } nodep->lhsp(dstp); nodep->rhsp(streamp); + nodep->dtypep(dstp->dtypep()); return true; } else if (m_doV && VN_IS(nodep->lhsp(), StreamR)) { // The right stream operator on lhs of assignment statement does @@ -2245,17 +2235,18 @@ class ConstVisitor final : public VNVisitor { srcp = new AstSel{streamp->fileline(), srcp, sWidth - dstBitWidth, dstBitWidth}; } - srcp = new AstCvtPackedToUnpackArray{nodep->fileline(), srcp, dstp->dtypep()}; + srcp = new AstCvtPackedToArray{nodep->fileline(), srcp, dstp->dtypep()}; } else { UASSERT(sWidth >= dWidth, "sWidth >= dWidth should have caused an error earlier"); if (dWidth == 0) { - srcp = new AstCvtPackedToDynArray{nodep->fileline(), srcp, dstp->dtypep()}; + srcp = new AstCvtPackedToArray{nodep->fileline(), srcp, dstp->dtypep()}; } else if (sWidth >= dWidth) { srcp = new AstSel{streamp->fileline(), srcp, sWidth - dWidth, dWidth}; } } nodep->lhsp(dstp); nodep->rhsp(srcp); + nodep->dtypep(dstp->dtypep()); VL_DO_DANGLING(pushDeletep(streamp), streamp); // Further reduce, any of the nodes may have more reductions. return true; @@ -2264,21 +2255,10 @@ class ConstVisitor final : public VNVisitor { AstStreamL* streamp = VN_AS(nodep->rhsp(), StreamL); AstNodeExpr* const srcp = streamp->lhsp(); const AstNodeDType* const srcDTypep = srcp->dtypep(); - if (VN_IS(srcDTypep, QueueDType) || VN_IS(srcDTypep, DynArrayDType)) { - if (lhsDtypep->widthMin() > 64) { - nodep->v3warn(E_UNSUPPORTED, "Unsupported: Assignment of stream of dynamic " - "array to a variable of size greater than 64"); - } - srcp->unlinkFrBack(); - streamp->lhsp(new AstCvtDynArrayToPacked{srcp->fileline(), srcp, lhsDtypep}); - streamp->dtypeFrom(lhsDtypep); - } else if (VN_IS(srcDTypep, UnpackArrayDType)) { - if (lhsDtypep->widthMin() > 64) { - nodep->v3warn(E_UNSUPPORTED, "Unsupported: Assignment of stream of unpacked " - "array to a variable of size greater than 64"); - } - srcp->unlinkFrBack(); - streamp->lhsp(new AstCvtUnpackArrayToPacked{srcp->fileline(), srcp, lhsDtypep}); + if (VN_IS(srcDTypep, QueueDType) || VN_IS(srcDTypep, DynArrayDType) + || VN_IS(srcDTypep, UnpackArrayDType)) { + streamp->lhsp(new AstCvtArrayToPacked{srcp->fileline(), srcp->unlinkFrBack(), + nodep->dtypep()}); streamp->dtypeFrom(lhsDtypep); } } else if (m_doV && replaceAssignMultiSel(nodep)) { diff --git a/src/V3EmitCFunc.h b/src/V3EmitCFunc.h index 722b63726..2265ead4d 100644 --- a/src/V3EmitCFunc.h +++ b/src/V3EmitCFunc.h @@ -385,32 +385,9 @@ public: emitVarDecl(nodep); } - void visit(AstCvtDynArrayToPacked* nodep) override { - putns(nodep, "VL_DYN_TO_"); - emitIQW(nodep); - const AstNodeDType* const elemDTypep = nodep->fromp()->dtypep()->subDTypep(); - putns(elemDTypep, "<"); - putbs(elemDTypep->cType("", false, false)); - puts(">("); - iterateAndNextConstNull(nodep->fromp()); - puts(", "); - putns(elemDTypep, cvtToStr(elemDTypep->widthMin())); - puts(")"); - } - - void visit(AstCvtUnpackArrayToPacked* nodep) override { - putns(nodep, "VL_UNPACK_TO_"); - emitIQW(nodep); - const AstNodeDType* const elemDTypep = nodep->fromp()->dtypep()->subDTypep(); - putns(elemDTypep, "<"); - putbs(elemDTypep->cType("", false, false)); - puts(","); - puts(cvtToStr(nodep->fromp()->dtypep()->arrayUnpackedElements())); - puts(">("); - iterateAndNextConstNull(nodep->fromp()); - puts(", "); - putns(elemDTypep, cvtToStr(elemDTypep->widthMin())); - puts(")"); + void visit(AstCvtArrayToPacked* nodep) override { + AstNodeDType* const elemDTypep = nodep->fromp()->dtypep()->subDTypep(); + emitOpName(nodep, nodep->emitC(), nodep->fromp(), elemDTypep, nullptr); } void visit(AstNodeAssign* nodep) override { @@ -467,30 +444,24 @@ public: puts(cvtToStr(nodep->widthMin()) + ","); iterateAndNextConstNull(nodep->lhsp()); puts(", "); - } else if (const AstCvtPackedToDynArray* const castp - = VN_CAST(nodep->rhsp(), CvtPackedToDynArray)) { - putns(castp, "VL_ASSIGN_DYN_Q<"); + } else if (const AstCvtPackedToArray* const castp + = VN_CAST(nodep->rhsp(), CvtPackedToArray)) { + putns(castp, "VL_UNPACK_"); + emitIQW(nodep->dtypep()->subDTypep()); + emitIQW(castp->fromp()); + puts("<"); putbs(castp->dtypep()->subDTypep()->cType("", false, false)); + if (VN_IS(castp->dtypep(), UnpackArrayDType)) { + puts(", "); + puts(cvtToStr(castp->dtypep()->arrayUnpackedElements())); + } puts(">("); - iterateAndNextConstNull(nodep->lhsp()); - puts(", "); putns(castp->dtypep(), cvtToStr(castp->dtypep()->subDTypep()->widthMin())); puts(", "); puts(cvtToStr(castp->fromp()->widthMin())); puts(", "); - rhs = false; - iterateAndNextConstNull(castp->fromp()); - } else if (const AstCvtPackedToUnpackArray* const castp - = VN_CAST(nodep->rhsp(), CvtPackedToUnpackArray)) { - putns(castp, "VL_ASSIGN_UNPACK_Q<"); - putbs(castp->dtypep()->subDTypep()->cType("", false, false)); - puts(", "); - puts(cvtToStr(castp->dtypep()->arrayUnpackedElements())); - puts(">("); iterateAndNextConstNull(nodep->lhsp()); puts(", "); - putns(castp->dtypep(), cvtToStr(castp->dtypep()->subDTypep()->widthMin())); - puts(", "); rhs = false; iterateAndNextConstNull(castp->fromp()); } else if (nodep->isWide() && VN_IS(nodep->lhsp(), VarRef) // @@ -1298,8 +1269,7 @@ public: return; } } - emitOpName(nodep, "VL_STREAML_%nq%lq%rq(%lw, %P, %li, %ri)", nodep->lhsp(), nodep->rhsp(), - nullptr); + emitOpName(nodep, nodep->emitC(), nodep->lhsp(), nodep->rhsp(), nullptr); } void visit(AstCastDynamic* nodep) override { putnbs(nodep, "VL_CAST_DYNAMIC("); diff --git a/src/V3Premit.cpp b/src/V3Premit.cpp index 310876d8f..14106e86b 100644 --- a/src/V3Premit.cpp +++ b/src/V3Premit.cpp @@ -274,6 +274,10 @@ class PremitVisitor final : public VNVisitor { iterateChildren(nodep); checkNode(nodep); } + void visit(AstCvtArrayToPacked* nodep) override { + iterateChildren(nodep); + checkNode(nodep); + } void visit(AstSel* nodep) override { iterateAndNextNull(nodep->fromp()); { // Only the 'from' is part of the assignment LHS diff --git a/src/V3Slice.cpp b/src/V3Slice.cpp index 618cbaa13..434f09e81 100644 --- a/src/V3Slice.cpp +++ b/src/V3Slice.cpp @@ -228,7 +228,7 @@ class SliceVisitor final : public VNVisitor { AstNodeDType* const dtp = nodep->lhsp()->dtypep()->skipRefp(); AstNode* stp = nodep->rhsp(); if (const AstUnpackArrayDType* const arrayp = VN_CAST(dtp, UnpackArrayDType)) { - if (!VN_IS(stp, CvtPackedToUnpackArray)) { + if (!VN_IS(stp, CvtPackedToArray)) { // Left and right could have different ascending/descending range, // but #elements is common and all variables are realigned to start at zero // Assign of an ascending range slice to a descending range one must reverse diff --git a/test_regress/t/t_stream_dynamic.v b/test_regress/t/t_stream_dynamic.v index eae28813c..c3c7514dc 100644 --- a/test_regress/t/t_stream_dynamic.v +++ b/test_regress/t/t_stream_dynamic.v @@ -20,6 +20,12 @@ module t (/*AUTOARG*/); bit [5:0] arr6[$]; bit [5:0] bit6 = 6'b111000; bit [5:0] ans; + bit [3:0] arr4[] = '{25{4'b1000}}; + bit [7:0] arr8[] = '{8{8'b00110011}}; + bit [63:0] arr64[] = '{5{64'h0123456789abcdef}}; + bit [63:0] bit64; + bit [99:0] bit100; + bit [319:0] bit320; enum_t ans_enum; { >> bit {arr}} = bit6; @@ -76,6 +82,35 @@ module t (/*AUTOARG*/); ans_enum = enum_t'({ << bit[5:0] {arr6} }); `checkh(ans_enum, bit6); + bit64 = { >> bit {arr8} }; + `checkh(bit64[7:0], 8'b00110011); + bit64 = { << bit {arr8} }; + `checkh(bit64[7:0], 8'b11001100); + + { >> bit {arr8} } = bit64; + `checkh(arr8[0], 8'b11001100); + { << bit {arr8} } = bit64; + `checkh(arr8[0], 8'b00110011); + + bit100 = { >> bit {arr4} }; + `checkh(bit100[3:0], 4'b1000); + bit100 = { << bit {arr4} }; + `checkh(bit100[3:0], 4'b0001); + + bit320 = { >> byte {arr64} }; + `checkh(bit320[63:0], 64'h0123456789abcdef); + bit320 = { << byte {arr64} }; + `checkh(bit320[63:0], 64'hefcdab8967452301); + + { >> bit {arr4} } = bit100; + `checkh(arr4[0], 4'b0001); + { << bit {arr4} } = bit100; + `checkh(arr4[0], 4'b1000); + + { >> byte {arr64} } = bit320; + `checkh(arr64[0], 64'hefcdab8967452301); + { << byte {arr64} } = bit320; + `checkh(arr64[0], 64'h0123456789abcdef); $write("*-* All Finished *-*\n"); $finish; end diff --git a/test_regress/t/t_stream_dynamic_wide_unsup.out b/test_regress/t/t_stream_dynamic_wide_unsup.out deleted file mode 100644 index 1edcffc16..000000000 --- a/test_regress/t/t_stream_dynamic_wide_unsup.out +++ /dev/null @@ -1,10 +0,0 @@ -%Error-UNSUPPORTED: t/t_stream_dynamic_wide_unsup.v:15:14: Unsupported: Assignment of stream of dynamic array to a variable of size greater than 64 - : ... note: In instance 't' - 15 | bit100 = { >> bit {arr} }; - | ^ - ... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest -%Error-UNSUPPORTED: t/t_stream_dynamic_wide_unsup.v:17:14: Unsupported: Assignment of stream of dynamic array to a variable of size greater than 64 - : ... note: In instance 't' - 17 | bit100 = { << bit {arr} }; - | ^ -%Error: Exiting due to diff --git a/test_regress/t/t_stream_dynamic_wide_unsup.pl b/test_regress/t/t_stream_dynamic_wide_unsup.pl deleted file mode 100755 index 7be596e0f..000000000 --- a/test_regress/t/t_stream_dynamic_wide_unsup.pl +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/env perl -if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } -# DESCRIPTION: Verilator: Verilog Test driver/expect definition -# -# Copyright 2020 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 - -scenarios(linter => 1); - -lint( - fails => 1, - expect_filename => $Self->{golden_filename}, - ); - -ok(1); -1; diff --git a/test_regress/t/t_stream_dynamic_wide_unsup.v b/test_regress/t/t_stream_dynamic_wide_unsup.v deleted file mode 100644 index 7059484c3..000000000 --- a/test_regress/t/t_stream_dynamic_wide_unsup.v +++ /dev/null @@ -1,23 +0,0 @@ -// DESCRIPTION: Verilator: Verilog Test module -// -// This file ONLY is placed under the Creative Commons Public Domain, for -// any use, without warranty, 2023 by Antmicro Ltd. -// SPDX-License-Identifier: CC0-1.0 - -`define stop $stop -`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0); - -module t (/*AUTOARG*/); - initial begin - bit[3:0] arr[] = '{25{4'b1000}}; - bit [99:0] bit100; - - bit100 = { >> bit {arr} }; - `checkh(bit100[3:0], 4'b1000); - bit100 = { << bit {arr} }; - `checkh(bit100[3:0], 4'b0001); - - $write("*-* All Finished *-*\n"); - $finish; - end -endmodule diff --git a/test_regress/t/t_stream_integer_type_unsup.pl b/test_regress/t/t_stream_integer_type.pl similarity index 83% rename from test_regress/t/t_stream_integer_type_unsup.pl rename to test_regress/t/t_stream_integer_type.pl index be66c40e6..b46d46042 100755 --- a/test_regress/t/t_stream_integer_type_unsup.pl +++ b/test_regress/t/t_stream_integer_type.pl @@ -11,13 +11,11 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di scenarios(simulator => 1); compile( - fails => $Self->{vlt_all}, - expect_filename => $Self->{golden_filename}, ); execute( check_finished => 1, - ) if !$Self->{vlt_all}; + ); ok(1); 1; diff --git a/test_regress/t/t_stream_integer_type_unsup.v b/test_regress/t/t_stream_integer_type.v similarity index 100% rename from test_regress/t/t_stream_integer_type_unsup.v rename to test_regress/t/t_stream_integer_type.v diff --git a/test_regress/t/t_stream_integer_type_unsup.out b/test_regress/t/t_stream_integer_type_unsup.out deleted file mode 100644 index d752b12ff..000000000 --- a/test_regress/t/t_stream_integer_type_unsup.out +++ /dev/null @@ -1,42 +0,0 @@ -%Error-UNSUPPORTED: t/t_stream_integer_type_unsup.v:120:28: Unsupported: Assignment of stream of unpacked array to a variable of size greater than 64 - : ... note: In instance 't' - 120 | packed_data_128 = {<<32{int_in}}; - | ^ - ... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest -%Error-UNSUPPORTED: t/t_stream_integer_type_unsup.v:121:28: Unsupported: Assignment of stream of unpacked array to a variable of size greater than 64 - : ... note: In instance 't' - 121 | packed_data_128_i = {<<32{integer_in}}; - | ^ -%Error-UNSUPPORTED: t/t_stream_integer_type_unsup.v:122:28: Unsupported: Assignment of stream of unpacked array to a variable of size greater than 64 - : ... note: In instance 't' - 122 | packed_data_256 = {<<64{longint_in}}; - | ^ -%Error-UNSUPPORTED: t/t_stream_integer_type_unsup.v:123:28: Unsupported: Assignment of stream of unpacked array to a variable of size greater than 64 - : ... note: In instance 't' - 123 | packed_time_256 = {<<64{time_in}}; - | ^ -%Error-UNSUPPORTED: t/t_stream_integer_type_unsup.v:126:28: Unsupported: Assignment of stream of unpacked array to a variable of size greater than 64 - : ... note: In instance 't' - 126 | v_packed_data_128 = {<<32{reg_in}}; - | ^ -%Error-UNSUPPORTED: t/t_stream_integer_type_unsup.v:152:28: Unsupported: Assignment of stream of unpacked array to a variable of size greater than 64 - : ... note: In instance 't' - 152 | packed_data_128 = {<