parent
248573205b
commit
1c79df8630
|
|
@ -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);
|
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>
|
template <typename T>
|
||||||
static inline IData VL_DYN_TO_I(const VlQueue<T>& q, int elem_size) {
|
static inline IData VL_DYN_TO_I(const VlQueue<T>& q, int elem_size) {
|
||||||
IData ret = 0;
|
IData ret = 0;
|
||||||
|
|
@ -1592,6 +1599,20 @@ static inline QData VL_DYN_TO_Q(const VlQueue<T>& q, int elem_size) {
|
||||||
return ret;
|
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.
|
// 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.
|
// 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.
|
// Note the bit shifts are always constants, so the adds in these constify out.
|
||||||
|
|
|
||||||
|
|
@ -1112,6 +1112,34 @@ public:
|
||||||
string emitC() override { V3ERROR_NA_RETURN(""); }
|
string emitC() override { V3ERROR_NA_RETURN(""); }
|
||||||
bool cleanOut() const override { return true; }
|
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 {
|
class AstDot final : public AstNodeExpr {
|
||||||
// A dot separating paths in an AstVarXRef, AstFuncRef or AstTaskRef
|
// A dot separating paths in an AstVarXRef, AstFuncRef or AstTaskRef
|
||||||
// These are eliminated in the link stage
|
// These are eliminated in the link stage
|
||||||
|
|
|
||||||
|
|
@ -2168,6 +2168,21 @@ class ConstVisitor final : public VNVisitor {
|
||||||
"array to a variable of size greater than 64");
|
"array to a variable of size greater than 64");
|
||||||
}
|
}
|
||||||
srcp = new AstCvtDynArrayToPacked{srcp->fileline(), srcp, srcDTypep};
|
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);
|
nodep->rhsp(srcp);
|
||||||
VL_DO_DANGLING(pushDeletep(streamp), streamp);
|
VL_DO_DANGLING(pushDeletep(streamp), streamp);
|
||||||
|
|
@ -2188,10 +2203,17 @@ class ConstVisitor final : public VNVisitor {
|
||||||
} else {
|
} else {
|
||||||
streamp->dtypeSetLogicUnsized(srcp->width(), srcp->widthMin(), VSigning::UNSIGNED);
|
streamp->dtypeSetLogicUnsized(srcp->width(), srcp->widthMin(), VSigning::UNSIGNED);
|
||||||
}
|
}
|
||||||
if (dWidth == 0) {
|
if (VN_IS(dstp->dtypep(), UnpackArrayDType)) {
|
||||||
streamp = new AstCvtPackedToDynArray{nodep->fileline(), streamp, dstp->dtypep()};
|
streamp
|
||||||
} else if (sWidth > dWidth) {
|
= new AstCvtPackedToUnpackArray{nodep->fileline(), streamp, dstp->dtypep()};
|
||||||
streamp = new AstSel{streamp->fileline(), streamp, sWidth - dWidth, dWidth};
|
} 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->lhsp(dstp);
|
||||||
nodep->rhsp(streamp);
|
nodep->rhsp(streamp);
|
||||||
|
|
@ -2205,10 +2227,24 @@ class ConstVisitor final : public VNVisitor {
|
||||||
AstNodeExpr* srcp = nodep->rhsp()->unlinkFrBack();
|
AstNodeExpr* srcp = nodep->rhsp()->unlinkFrBack();
|
||||||
const int sWidth = srcp->width();
|
const int sWidth = srcp->width();
|
||||||
const int dWidth = dstp->width();
|
const int dWidth = dstp->width();
|
||||||
if (dWidth == 0) {
|
if (VN_IS(dstp->dtypep(), UnpackArrayDType)) {
|
||||||
srcp = new AstCvtPackedToDynArray{nodep->fileline(), srcp, dstp->dtypep()};
|
const int dstBitWidth
|
||||||
} else if (sWidth > dWidth) {
|
= dWidth * VN_AS(dstp->dtypep(), UnpackArrayDType)->arrayUnpackedElements();
|
||||||
srcp = new AstSel{streamp->fileline(), srcp, sWidth - dWidth, dWidth};
|
// 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->lhsp(dstp);
|
||||||
nodep->rhsp(srcp);
|
nodep->rhsp(srcp);
|
||||||
|
|
@ -2228,6 +2264,14 @@ class ConstVisitor final : public VNVisitor {
|
||||||
srcp->unlinkFrBack();
|
srcp->unlinkFrBack();
|
||||||
streamp->lhsp(new AstCvtDynArrayToPacked{srcp->fileline(), srcp, lhsDtypep});
|
streamp->lhsp(new AstCvtDynArrayToPacked{srcp->fileline(), srcp, lhsDtypep});
|
||||||
streamp->dtypeFrom(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)) {
|
} else if (m_doV && replaceAssignMultiSel(nodep)) {
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -380,6 +380,21 @@ public:
|
||||||
puts(")");
|
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 {
|
void visit(AstNodeAssign* nodep) override {
|
||||||
bool paren = true;
|
bool paren = true;
|
||||||
bool decind = false;
|
bool decind = false;
|
||||||
|
|
@ -447,6 +462,19 @@ public:
|
||||||
puts(", ");
|
puts(", ");
|
||||||
rhs = false;
|
rhs = false;
|
||||||
iterateAndNextConstNull(castp->fromp());
|
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) //
|
} else if (nodep->isWide() && VN_IS(nodep->lhsp(), VarRef) //
|
||||||
&& !VN_IS(nodep->rhsp(), CExpr) //
|
&& !VN_IS(nodep->rhsp(), CExpr) //
|
||||||
&& !VN_IS(nodep->rhsp(), CMethodHard) //
|
&& !VN_IS(nodep->rhsp(), CMethodHard) //
|
||||||
|
|
|
||||||
|
|
@ -226,26 +226,30 @@ class SliceVisitor final : public VNVisitor {
|
||||||
m_assignError = false;
|
m_assignError = false;
|
||||||
if (debug() >= 9) nodep->dumpTree("- Deslice-In: ");
|
if (debug() >= 9) nodep->dumpTree("- Deslice-In: ");
|
||||||
AstNodeDType* const dtp = nodep->lhsp()->dtypep()->skipRefp();
|
AstNodeDType* const dtp = nodep->lhsp()->dtypep()->skipRefp();
|
||||||
|
AstNode* stp = nodep->rhsp();
|
||||||
if (const AstUnpackArrayDType* const arrayp = VN_CAST(dtp, UnpackArrayDType)) {
|
if (const AstUnpackArrayDType* const arrayp = VN_CAST(dtp, UnpackArrayDType)) {
|
||||||
// Left and right could have different ascending/descending range,
|
if (!VN_IS(stp, CvtPackedToUnpackArray)) {
|
||||||
// but #elements is common and all variables are realigned to start at zero
|
// Left and right could have different ascending/descending range,
|
||||||
// Assign of an ascending range slice to a descending range one must reverse the
|
// but #elements is common and all variables are realigned to start at zero
|
||||||
// elements
|
// Assign of an ascending range slice to a descending range one must reverse
|
||||||
AstNodeAssign* newlistp = nullptr;
|
// the elements
|
||||||
const int elements = arrayp->rangep()->elementsConst();
|
AstNodeAssign* newlistp = nullptr;
|
||||||
for (int elemIdx = 0; elemIdx < elements; ++elemIdx) {
|
const int elements = arrayp->rangep()->elementsConst();
|
||||||
AstNodeAssign* const newp
|
for (int elemIdx = 0; elemIdx < elements; ++elemIdx) {
|
||||||
= nodep->cloneType(cloneAndSel(nodep->lhsp(), elements, elemIdx),
|
AstNodeAssign* const newp
|
||||||
cloneAndSel(nodep->rhsp(), elements, elemIdx));
|
= nodep->cloneType(cloneAndSel(nodep->lhsp(), elements, elemIdx),
|
||||||
if (debug() >= 9) newp->dumpTree("- new: ");
|
cloneAndSel(nodep->rhsp(), elements, elemIdx));
|
||||||
newlistp = AstNode::addNext(newlistp, newp);
|
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);
|
VL_RESTORER(m_assignp);
|
||||||
m_assignp = nodep;
|
m_assignp = nodep;
|
||||||
|
|
|
||||||
|
|
@ -843,9 +843,10 @@ class WidthVisitor final : public VNVisitor {
|
||||||
nodep->v3error("Slice size isn't a constant or basic data type.");
|
nodep->v3error("Slice size isn't a constant or basic data type.");
|
||||||
}
|
}
|
||||||
const AstNodeDType* const lhsDtypep = nodep->lhsp()->dtypep()->skipRefToEnump();
|
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();
|
nodep->dtypeSetStream();
|
||||||
} else if (VN_IS(lhsDtypep, UnpackArrayDType) || lhsDtypep->isCompound()) {
|
} else if (lhsDtypep->isCompound()) {
|
||||||
nodep->v3warn(E_UNSUPPORTED,
|
nodep->v3warn(E_UNSUPPORTED,
|
||||||
"Unsupported: Stream operation on a variable of a type "
|
"Unsupported: Stream operation on a variable of a type "
|
||||||
<< lhsDtypep->prettyDTypeNameQ());
|
<< lhsDtypep->prettyDTypeNameQ());
|
||||||
|
|
@ -4908,6 +4909,32 @@ class WidthVisitor final : public VNVisitor {
|
||||||
return;
|
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()) {
|
if (nodep->hasDType() && nodep->dtypep()->isEvent()) {
|
||||||
checkEventAssignment(nodep);
|
checkEventAssignment(nodep);
|
||||||
v3Global.setAssignsEvents();
|
v3Global.setAssignsEvents();
|
||||||
|
|
|
||||||
|
|
@ -6,9 +6,4 @@
|
||||||
: ... note: In instance 't'
|
: ... note: In instance 't'
|
||||||
12 | initial packed_data_32 = {<<$random{byte_in}};
|
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
|
%Error: Exiting due to
|
||||||
|
|
|
||||||
|
|
@ -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]'
|
%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'
|
|
||||||
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]'
|
|
||||||
: ... note: In instance 't'
|
: ... note: In instance 't'
|
||||||
120 | packed_data_128 = {<<32{int_in}};
|
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'
|
: ... note: In instance 't'
|
||||||
121 | packed_data_128_i = {<<32{integer_in}};
|
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'
|
: ... note: In instance 't'
|
||||||
122 | packed_data_256 = {<<64{longint_in}};
|
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'
|
: ... note: In instance 't'
|
||||||
123 | packed_time_256 = {<<64{time_in}};
|
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]'
|
%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'
|
|
||||||
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]'
|
|
||||||
: ... note: In instance 't'
|
: ... note: In instance 't'
|
||||||
126 | v_packed_data_128 = {<<32{reg_in}};
|
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]'
|
%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'
|
|
||||||
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]'
|
|
||||||
: ... note: In instance 't'
|
: ... note: In instance 't'
|
||||||
152 | packed_data_128 = {<<int{int_in}};
|
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'
|
: ... note: In instance 't'
|
||||||
153 | packed_data_128_i = {<<integer{integer_in}};
|
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'
|
: ... note: In instance 't'
|
||||||
154 | packed_data_256 = {<<longint{longint_in}};
|
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'
|
: ... note: In instance 't'
|
||||||
155 | packed_time_256 = {<<time{time_in}};
|
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]'
|
%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'
|
|
||||||
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]'
|
|
||||||
: ... note: In instance 't'
|
: ... note: In instance 't'
|
||||||
158 | v_packed_data_128 = {<<test_word{reg_in}};
|
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
|
%Error: Exiting due to
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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;
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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;
|
||||||
|
|
@ -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
|
||||||
Loading…
Reference in New Issue