Support stream operation on unpacked array (#4714) (#5006)

This commit is contained in:
Fuad Ismail 2024-03-22 05:26:42 +07:00 committed by GitHub
parent 248573205b
commit 1c79df8630
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 429 additions and 158 deletions

View File

@ -1578,6 +1578,13 @@ static inline void VL_ASSIGN_DYN_Q(VlQueue<T>& q, int elem_size, int lbits, QDat
for (int i = 0; i < size; ++i) q.at(i) = (T)((from >> (i * elem_size)) & mask);
}
template <typename T, std::size_t T_Depth>
static inline void VL_ASSIGN_UNPACK_Q(VlUnpacked<T, T_Depth>& q, size_t elem_size, QData from) {
const QData mask = VL_MASK_Q(elem_size);
for (size_t i = 0; i < T_Depth; ++i)
q[i] = (T)((from >> ((T_Depth - 1 - i) * elem_size)) & mask);
}
template <typename T>
static inline IData VL_DYN_TO_I(const VlQueue<T>& q, int elem_size) {
IData ret = 0;
@ -1592,6 +1599,20 @@ static inline QData VL_DYN_TO_Q(const VlQueue<T>& q, int elem_size) {
return ret;
}
template <typename T, std::size_t T_Depth>
static inline IData VL_UNPACK_TO_I(const VlUnpacked<T, T_Depth>& 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;
}
template <typename T, std::size_t T_Depth>
static inline QData VL_UNPACK_TO_Q(const VlUnpacked<T, T_Depth>& 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;
}
// Because concats are common and wide, it's valuable to always have a clean output.
// Thus we specify inputs must be clean, so we don't need to clean the output.
// Note the bit shifts are always constants, so the adds in these constify out.

View File

@ -1112,6 +1112,34 @@ public:
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;
string emitVerilog() override { V3ERROR_NA_RETURN(""); }
string emitC() override { V3ERROR_NA_RETURN(""); }
bool cleanOut() const override { return true; }
};
class AstDot final : public AstNodeExpr {
// A dot separating paths in an AstVarXRef, AstFuncRef or AstTaskRef
// These are eliminated in the link stage

View File

@ -2168,6 +2168,21 @@ class ConstVisitor final : public VNVisitor {
"array to a variable of size greater than 64");
}
srcp = new AstCvtDynArrayToPacked{srcp->fileline(), srcp, srcDTypep};
} 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()};
// 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
= 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};
}
nodep->rhsp(srcp);
VL_DO_DANGLING(pushDeletep(streamp), streamp);
@ -2188,10 +2203,17 @@ class ConstVisitor final : public VNVisitor {
} else {
streamp->dtypeSetLogicUnsized(srcp->width(), srcp->widthMin(), VSigning::UNSIGNED);
}
if (dWidth == 0) {
streamp = new AstCvtPackedToDynArray{nodep->fileline(), streamp, dstp->dtypep()};
} else if (sWidth > dWidth) {
streamp = new AstSel{streamp->fileline(), streamp, sWidth - dWidth, dWidth};
if (VN_IS(dstp->dtypep(), UnpackArrayDType)) {
streamp
= new AstCvtPackedToUnpackArray{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()};
} else if (sWidth >= dWidth) {
streamp = new AstSel{streamp->fileline(), streamp, sWidth - dWidth, dWidth};
}
}
nodep->lhsp(dstp);
nodep->rhsp(streamp);
@ -2205,10 +2227,24 @@ class ConstVisitor final : public VNVisitor {
AstNodeExpr* srcp = nodep->rhsp()->unlinkFrBack();
const int sWidth = srcp->width();
const int dWidth = dstp->width();
if (dWidth == 0) {
srcp = new AstCvtPackedToDynArray{nodep->fileline(), srcp, dstp->dtypep()};
} else if (sWidth > dWidth) {
srcp = new AstSel{streamp->fileline(), srcp, sWidth - dWidth, dWidth};
if (VN_IS(dstp->dtypep(), UnpackArrayDType)) {
const int dstBitWidth
= dWidth * VN_AS(dstp->dtypep(), UnpackArrayDType)->arrayUnpackedElements();
// Handling the case where rhs is wider than lhs. StreamL does not require this
// since the combination of the left streaming operation and the implicit
// truncation in VL_ASSIGN_UNPACK automatically selects the left-most bits.
if (sWidth > dstBitWidth) {
srcp
= new AstSel{streamp->fileline(), srcp, sWidth - dstBitWidth, dstBitWidth};
}
srcp = new AstCvtPackedToUnpackArray{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()};
} else if (sWidth >= dWidth) {
srcp = new AstSel{streamp->fileline(), srcp, sWidth - dWidth, dWidth};
}
}
nodep->lhsp(dstp);
nodep->rhsp(srcp);
@ -2228,6 +2264,14 @@ class ConstVisitor final : public VNVisitor {
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});
streamp->dtypeFrom(lhsDtypep);
}
} else if (m_doV && replaceAssignMultiSel(nodep)) {
return true;

View File

@ -380,6 +380,21 @@ public:
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(AstNodeAssign* nodep) override {
bool paren = true;
bool decind = false;
@ -447,6 +462,19 @@ public:
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) //
&& !VN_IS(nodep->rhsp(), CExpr) //
&& !VN_IS(nodep->rhsp(), CMethodHard) //

View File

@ -226,26 +226,30 @@ class SliceVisitor final : public VNVisitor {
m_assignError = false;
if (debug() >= 9) nodep->dumpTree("- Deslice-In: ");
AstNodeDType* const dtp = nodep->lhsp()->dtypep()->skipRefp();
AstNode* stp = nodep->rhsp();
if (const AstUnpackArrayDType* const arrayp = VN_CAST(dtp, UnpackArrayDType)) {
// 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 the
// elements
AstNodeAssign* newlistp = nullptr;
const int elements = arrayp->rangep()->elementsConst();
for (int elemIdx = 0; elemIdx < elements; ++elemIdx) {
AstNodeAssign* const newp
= nodep->cloneType(cloneAndSel(nodep->lhsp(), elements, elemIdx),
cloneAndSel(nodep->rhsp(), elements, elemIdx));
if (debug() >= 9) newp->dumpTree("- new: ");
newlistp = AstNode::addNext(newlistp, newp);
if (!VN_IS(stp, CvtPackedToUnpackArray)) {
// 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
// the elements
AstNodeAssign* newlistp = nullptr;
const int elements = arrayp->rangep()->elementsConst();
for (int elemIdx = 0; elemIdx < elements; ++elemIdx) {
AstNodeAssign* const newp
= nodep->cloneType(cloneAndSel(nodep->lhsp(), elements, elemIdx),
cloneAndSel(nodep->rhsp(), elements, elemIdx));
if (debug() >= 9) newp->dumpTree("- new: ");
newlistp = AstNode::addNext(newlistp, newp);
}
if (debug() >= 9) nodep->dumpTree("- Deslice-Dn: ");
nodep->replaceWith(newlistp);
VL_DO_DANGLING(nodep->deleteTree(), nodep);
// Normal edit iterator will now iterate on all of the expansion assignments
// This will potentially call this function again to resolve next level of
// slicing
return;
}
if (debug() >= 9) nodep->dumpTree("- Deslice-Dn: ");
nodep->replaceWith(newlistp);
VL_DO_DANGLING(nodep->deleteTree(), nodep);
// Normal edit iterator will now iterate on all of the expansion assignments
// This will potentially call this function again to resolve next level of slicing
return;
}
VL_RESTORER(m_assignp);
m_assignp = nodep;

View File

@ -843,9 +843,10 @@ class WidthVisitor final : public VNVisitor {
nodep->v3error("Slice size isn't a constant or basic data type.");
}
const AstNodeDType* const lhsDtypep = nodep->lhsp()->dtypep()->skipRefToEnump();
if (VN_IS(lhsDtypep, DynArrayDType) || VN_IS(lhsDtypep, QueueDType)) {
if (VN_IS(lhsDtypep, DynArrayDType) || VN_IS(lhsDtypep, QueueDType)
|| VN_IS(lhsDtypep, UnpackArrayDType)) {
nodep->dtypeSetStream();
} else if (VN_IS(lhsDtypep, UnpackArrayDType) || lhsDtypep->isCompound()) {
} else if (lhsDtypep->isCompound()) {
nodep->v3warn(E_UNSUPPORTED,
"Unsupported: Stream operation on a variable of a type "
<< lhsDtypep->prettyDTypeNameQ());
@ -4908,6 +4909,32 @@ class WidthVisitor final : public VNVisitor {
return;
}
// Width check for unpacked array stream assignment
if (const AstNodeStream* streamp = VN_CAST(nodep->rhsp(), NodeStream)) {
if (AstUnpackArrayDType* arr = VN_CAST(streamp->lhsp()->dtypep(), UnpackArrayDType)) {
int lwidth = nodep->lhsp()->width();
int rwidth = arr->subDTypep()->width() * arr->arrayUnpackedElements();
if (lwidth != 0 && lwidth < rwidth) {
nodep->v3widthWarn(lwidth, rwidth,
"Target fixed size variable ("
<< lwidth << " bits) is narrower than the stream ("
<< rwidth << " bits) (IEEE 1800-2023 11.4.14)");
}
}
} else if (const AstNodeStream* streamp = VN_CAST(nodep->lhsp(), NodeStream)) {
if (AstUnpackArrayDType* arr = VN_CAST(streamp->lhsp()->dtypep(), UnpackArrayDType)) {
int rwidth = nodep->rhsp()->width();
int lwidth = arr->subDTypep()->width() * arr->arrayUnpackedElements();
if (rwidth != 0 && rwidth < lwidth) {
nodep->v3widthWarn(lwidth, rwidth,
"Stream target requires "
<< lwidth
<< " bits, but source expression only provides "
<< rwidth << " bits (IEEE 1800-2023 11.4.14.3)");
}
}
}
if (nodep->hasDType() && nodep->dtypep()->isEvent()) {
checkEventAssignment(nodep);
v3Global.setAssignsEvents();

View File

@ -6,9 +6,4 @@
: ... note: In instance 't'
12 | initial packed_data_32 = {<<$random{byte_in}};
| ^~
%Error-UNSUPPORTED: t/t_stream_bad.v:12:30: Unsupported: Stream operation on a variable of a type 'byte$[0:3]'
: ... note: In instance 't'
12 | initial packed_data_32 = {<<$random{byte_in}};
| ^~
... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest
%Error: Exiting due to

View File

@ -1,146 +1,42 @@
%Error-UNSUPPORTED: t/t_stream_integer_type_unsup.v:118:31: Unsupported: Stream operation on a variable of a type 'byte$[0:3]'
: ... note: In instance 't'
118 | packed_data_32 = {<<8{byte_in}};
| ^~
... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest
%Error-UNSUPPORTED: t/t_stream_integer_type_unsup.v:119:31: Unsupported: Stream operation on a variable of a type 'shortint$[0:3]'
: ... note: In instance 't'
119 | packed_data_64 = {<<16{shortint_in}};
| ^~
%Error-UNSUPPORTED: t/t_stream_integer_type_unsup.v:120:31: Unsupported: Stream operation on a variable of a type 'int$[0:3]'
%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}};
| ^~
%Error-UNSUPPORTED: t/t_stream_integer_type_unsup.v:121:31: Unsupported: Stream operation on a variable of a type 'integer$[0:3]'
| ^
... 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:31: Unsupported: Stream operation on a variable of a type 'longint$[0:3]'
| ^
%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:31: Unsupported: Stream operation on a variable of a type 'time$[0:3]'
| ^
%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:124:31: Unsupported: Stream operation on a variable of a type 'bit[7:0]$[0:3]'
: ... note: In instance 't'
124 | v_packed_data_32 = {<<8{bit_in}};
| ^~
%Error-UNSUPPORTED: t/t_stream_integer_type_unsup.v:125:31: Unsupported: Stream operation on a variable of a type 'bit[15:0]$[0:3]'
: ... note: In instance 't'
125 | v_packed_data_64 = {<<16{logic_in}};
| ^~
%Error-UNSUPPORTED: t/t_stream_integer_type_unsup.v:126:31: Unsupported: Stream operation on a variable of a type 'bit[31:0]$[0:3]'
| ^
%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:128:11: Unsupported: Stream operation on a variable of a type 'byte$[0:3]'
: ... note: In instance 't'
128 | {<<8{byte_out}} = packed_data_32;
| ^~
%Error-UNSUPPORTED: t/t_stream_integer_type_unsup.v:129:11: Unsupported: Stream operation on a variable of a type 'shortint$[0:3]'
: ... note: In instance 't'
129 | {<<16{shortint_out}} = packed_data_64;
| ^~
%Error-UNSUPPORTED: t/t_stream_integer_type_unsup.v:130:11: Unsupported: Stream operation on a variable of a type 'int$[0:3]'
: ... note: In instance 't'
130 | {<<32{int_out}} = packed_data_128;
| ^~
%Error-UNSUPPORTED: t/t_stream_integer_type_unsup.v:131:11: Unsupported: Stream operation on a variable of a type 'integer$[0:3]'
: ... note: In instance 't'
131 | {<<32{integer_out}} = packed_data_128_i;
| ^~
%Error-UNSUPPORTED: t/t_stream_integer_type_unsup.v:132:11: Unsupported: Stream operation on a variable of a type 'longint$[0:3]'
: ... note: In instance 't'
132 | {<<64{longint_out}} = packed_data_256;
| ^~
%Error-UNSUPPORTED: t/t_stream_integer_type_unsup.v:133:11: Unsupported: Stream operation on a variable of a type 'time$[0:3]'
: ... note: In instance 't'
133 | {<<64{time_out}} = packed_time_256;
| ^~
%Error-UNSUPPORTED: t/t_stream_integer_type_unsup.v:134:11: Unsupported: Stream operation on a variable of a type 'bit[7:0]$[0:3]'
: ... note: In instance 't'
134 | {<<8{bit_out}} = v_packed_data_32;
| ^~
%Error-UNSUPPORTED: t/t_stream_integer_type_unsup.v:135:11: Unsupported: Stream operation on a variable of a type 'bit[15:0]$[0:3]'
: ... note: In instance 't'
135 | {<<16{logic_out}} = v_packed_data_64;
| ^~
%Error-UNSUPPORTED: t/t_stream_integer_type_unsup.v:136:11: Unsupported: Stream operation on a variable of a type 'bit[31:0]$[0:3]'
: ... note: In instance 't'
136 | {<<32{reg_out}} = v_packed_data_128;
| ^~
%Error-UNSUPPORTED: t/t_stream_integer_type_unsup.v:150:31: Unsupported: Stream operation on a variable of a type 'byte$[0:3]'
: ... note: In instance 't'
150 | packed_data_32 = {<<byte{byte_in}};
| ^~
%Error-UNSUPPORTED: t/t_stream_integer_type_unsup.v:151:31: Unsupported: Stream operation on a variable of a type 'shortint$[0:3]'
: ... note: In instance 't'
151 | packed_data_64 = {<<shortint{shortint_in}};
| ^~
%Error-UNSUPPORTED: t/t_stream_integer_type_unsup.v:152:31: Unsupported: Stream operation on a variable of a type 'int$[0:3]'
| ^
%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 = {<<int{int_in}};
| ^~
%Error-UNSUPPORTED: t/t_stream_integer_type_unsup.v:153:31: Unsupported: Stream operation on a variable of a type 'integer$[0:3]'
| ^
%Error-UNSUPPORTED: t/t_stream_integer_type_unsup.v:153:28: Unsupported: Assignment of stream of unpacked array to a variable of size greater than 64
: ... note: In instance 't'
153 | packed_data_128_i = {<<integer{integer_in}};
| ^~
%Error-UNSUPPORTED: t/t_stream_integer_type_unsup.v:154:31: Unsupported: Stream operation on a variable of a type 'longint$[0:3]'
| ^
%Error-UNSUPPORTED: t/t_stream_integer_type_unsup.v:154:28: Unsupported: Assignment of stream of unpacked array to a variable of size greater than 64
: ... note: In instance 't'
154 | packed_data_256 = {<<longint{longint_in}};
| ^~
%Error-UNSUPPORTED: t/t_stream_integer_type_unsup.v:155:31: Unsupported: Stream operation on a variable of a type 'time$[0:3]'
| ^
%Error-UNSUPPORTED: t/t_stream_integer_type_unsup.v:155:28: Unsupported: Assignment of stream of unpacked array to a variable of size greater than 64
: ... note: In instance 't'
155 | packed_time_256 = {<<time{time_in}};
| ^~
%Error-UNSUPPORTED: t/t_stream_integer_type_unsup.v:156:31: Unsupported: Stream operation on a variable of a type 'bit[7:0]$[0:3]'
: ... note: In instance 't'
156 | v_packed_data_32 = {<<test_byte{bit_in}};
| ^~
%Error-UNSUPPORTED: t/t_stream_integer_type_unsup.v:157:31: Unsupported: Stream operation on a variable of a type 'bit[15:0]$[0:3]'
: ... note: In instance 't'
157 | v_packed_data_64 = {<<test_short{logic_in}};
| ^~
%Error-UNSUPPORTED: t/t_stream_integer_type_unsup.v:158:31: Unsupported: Stream operation on a variable of a type 'bit[31:0]$[0:3]'
| ^
%Error-UNSUPPORTED: t/t_stream_integer_type_unsup.v:158:28: Unsupported: Assignment of stream of unpacked array to a variable of size greater than 64
: ... note: In instance 't'
158 | v_packed_data_128 = {<<test_word{reg_in}};
| ^~
%Error-UNSUPPORTED: t/t_stream_integer_type_unsup.v:160:11: Unsupported: Stream operation on a variable of a type 'byte$[0:3]'
: ... note: In instance 't'
160 | {<<byte{byte_out}} = packed_data_32;
| ^~
%Error-UNSUPPORTED: t/t_stream_integer_type_unsup.v:161:11: Unsupported: Stream operation on a variable of a type 'shortint$[0:3]'
: ... note: In instance 't'
161 | {<<shortint{shortint_out}} = packed_data_64;
| ^~
%Error-UNSUPPORTED: t/t_stream_integer_type_unsup.v:162:11: Unsupported: Stream operation on a variable of a type 'int$[0:3]'
: ... note: In instance 't'
162 | {<<int{int_out}} = packed_data_128;
| ^~
%Error-UNSUPPORTED: t/t_stream_integer_type_unsup.v:163:11: Unsupported: Stream operation on a variable of a type 'integer$[0:3]'
: ... note: In instance 't'
163 | {<<integer{integer_out}} = packed_data_128_i;
| ^~
%Error-UNSUPPORTED: t/t_stream_integer_type_unsup.v:164:11: Unsupported: Stream operation on a variable of a type 'longint$[0:3]'
: ... note: In instance 't'
164 | {<<longint{longint_out}} = packed_data_256;
| ^~
%Error-UNSUPPORTED: t/t_stream_integer_type_unsup.v:165:11: Unsupported: Stream operation on a variable of a type 'time$[0:3]'
: ... note: In instance 't'
165 | {<<time{time_out}} = packed_time_256;
| ^~
%Error-UNSUPPORTED: t/t_stream_integer_type_unsup.v:166:11: Unsupported: Stream operation on a variable of a type 'bit[7:0]$[0:3]'
: ... note: In instance 't'
166 | {<<test_byte{bit_out}} = v_packed_data_32;
| ^~
%Error-UNSUPPORTED: t/t_stream_integer_type_unsup.v:167:11: Unsupported: Stream operation on a variable of a type 'bit[15:0]$[0:3]'
: ... note: In instance 't'
167 | {<<test_short{logic_out}} = v_packed_data_64;
| ^~
%Error-UNSUPPORTED: t/t_stream_integer_type_unsup.v:168:11: Unsupported: Stream operation on a variable of a type 'bit[31:0]$[0:3]'
: ... note: In instance 't'
168 | {<<test_word{reg_out}} = v_packed_data_128;
| ^~
| ^
%Error: Exiting due to

View File

@ -0,0 +1,21 @@
#!/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(simulator => 1);
compile(
);
execute(
check_finished => 1,
);
ok(1);
1;

View File

@ -0,0 +1,83 @@
// 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);
`define checks(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='%s' exp='%s'\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0);
typedef enum bit [5:0] {
A = 6'b111000,
B = 6,b111111
} enum_t;
module t (/*AUTOARG*/);
initial begin
bit arr[6];
bit [1:0] arr2[3];
bit [5:0] arr6[1];
string v;
bit [5:0] bit6 = 6'b111000;
bit [5:0] ans;
enum_t ans_enum;
{ >> bit {arr}} = bit6;
v = $sformatf("%p", arr); `checks(v, "'{'h1, 'h1, 'h1, 'h0, 'h0, 'h0} ");
ans = { >> bit {arr} };
`checkh(ans, bit6);
ans_enum = enum_t'({ >> bit {arr} });
`checkh(ans_enum, bit6);
{ << bit {arr}} = bit6;
v = $sformatf("%p", arr); `checks(v, "'{'h0, 'h0, 'h0, 'h1, 'h1, 'h1} ");
ans = { << bit {arr} };
`checkh(ans, bit6);
ans_enum = enum_t'({ << bit {arr} });
`checkh(ans_enum, bit6);
{ >> bit[1:0] {arr2}} = bit6;
v = $sformatf("%p", arr2); `checks(v, "'{'h3, 'h2, 'h0} ");
ans = { >> bit[1:0] {arr2} };
`checkh(ans, bit6);
ans_enum = enum_t'({ >> bit[1:0] {arr2} });
`checkh(ans_enum, bit6);
{ << bit[1:0] {arr2}} = bit6;
v = $sformatf("%p", arr2); `checks(v, "'{'h0, 'h2, 'h3} ");
ans = { << bit[1:0] {arr2} };
`checkh(ans, bit6);
ans_enum = enum_t'({ << bit[1:0] {arr2} });
`checkh(ans_enum, bit6);
{ >> bit [5:0] {arr6} } = bit6;
v = $sformatf("%p", arr6); `checks(v, "'{'h38} ");
ans = { >> bit[5:0] {arr6} };
`checkh(ans, bit6);
ans_enum = enum_t'({ >> bit[5:0] {arr6} });
`checkh(ans_enum, bit6);
{ << bit [5:0] {arr6} } = bit6;
v = $sformatf("%p", arr6); `checks(v, "'{'h38} ");
ans = { << bit[5:0] {arr6} };
`checkh(ans, bit6);
ans_enum = enum_t'({ << bit[5:0] {arr6} });
`checkh(ans_enum, bit6);
$write("*-* All Finished *-*\n");
$finish;
end
endmodule

View File

@ -0,0 +1,11 @@
%Warning-WIDTHEXPAND: t/t_stream_unpack_narrower.v:14:18: Stream target requires 32 bits, but source expression only provides 31 bits (IEEE 1800-2023 11.4.14.3)
: ... note: In instance 't'
14 | {>>{stream}} = packed_data;
| ^
... For warning description see https://verilator.org/warn/WIDTHEXPAND?v=latest
... Use "/* verilator lint_off WIDTHEXPAND */" and lint_on around source to disable this message.
%Warning-WIDTHTRUNC: t/t_stream_unpack_narrower.v:15:17: Target fixed size variable (31 bits) is narrower than the stream (32 bits) (IEEE 1800-2023 11.4.14)
: ... note: In instance 't'
15 | packed_data = {>>{stream}};
| ^
%Error: Exiting due to

View File

@ -0,0 +1,19 @@
#!/usr/bin/env perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003 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(simulator => 1);
lint(
fails => 1,
expect_filename => $Self->{golden_filename},
);
ok(1);
1;

View File

@ -0,0 +1,18 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2022 by Geza Lore.
// SPDX-License-Identifier: CC0-1.0
module t;
logic [30:0] packed_data;
logic [7:0] stream[4];
initial begin
packed_data = 31'h12345678;
{>>{stream}} = packed_data;
packed_data = {>>{stream}};
end
endmodule

View File

@ -0,0 +1,21 @@
#!/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(simulator => 1);
compile(
);
execute(
check_finished => 1,
);
ok(1);
1;

View File

@ -0,0 +1,55 @@
// 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);
`define checks(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='%s' exp='%s'\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0);
module t (/*AUTOARG*/);
initial begin
logic [7:0] src_1 = 8'b1010_0011; // 8 bits wide source
logic [1:0] dst_1 [3]; // 6 bits wide target
logic [1:0] exp_1 [3]; // 6 bits wide target
logic [1:0] src_2 [3] = '{2'b10, 2'b10, 2'b10}; // 6 bits wide source
logic [7:0] dst_2; // 8 bits wide target
logic [7:0] exp_2; // 8 bits wide target
string expv;
string gotv;
// unpack as target, StreamR
{>>{dst_1}} = src_1;
exp_1 = '{2'b10, 2'b10, 2'b00};
expv = $sformatf("%p", exp_1);
gotv = $sformatf("%p", dst_1);
`checks(gotv, expv);
// unpack as target, StreamL
{<<{dst_1}} = src_1;
exp_1 = '{2'b00, 2'b01, 2'b01};
expv = $sformatf("%p", exp_1);
gotv = $sformatf("%p", dst_1);
`checks(gotv, expv);
// unpack as source, StreamR
dst_2 = {>>{src_2}};
exp_2 = 8'b10101000;
expv = $sformatf("%p", exp_2);
gotv = $sformatf("%p", dst_2);
`checks(gotv, expv);
// unpack as source, StreamL
dst_2 = {<<{src_2}};
exp_2 = 8'b01010100;
expv = $sformatf("%p", exp_2);
gotv = $sformatf("%p", dst_2);
`checks(gotv, expv);
$write("*-* All Finished *-*\n");
$finish;
end
endmodule