mirror of
https://github.com/verilator/verilator.git
synced 2025-01-01 04:07:34 +00:00
Support streams to/from arrays of wide data (#5334)
This commit is contained in:
parent
3426ee5170
commit
e6fe367bdb
@ -1585,71 +1585,184 @@ static inline WDataOutP VL_STREAML_WWI(int lbits, WDataOutP owp, WDataInP const
|
||||
return owp;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static inline IData VL_PACK_II(int obits, int lbits, const VlQueue<T>& q) {
|
||||
static inline IData VL_PACK_II(int obits, int lbits, const VlQueue<CData>& q) {
|
||||
IData ret = 0;
|
||||
for (size_t i = 0; i < q.size(); ++i) ret |= static_cast<IData>(q.at(i)) << (i * lbits);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline IData VL_PACK_II(int obits, int lbits, const VlQueue<SData>& q) {
|
||||
IData ret = 0;
|
||||
for (size_t i = 0; i < q.size(); ++i) ret |= static_cast<IData>(q.at(i)) << (i * lbits);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline IData VL_PACK_II(int obits, int lbits, const VlQueue<IData>& q) {
|
||||
IData ret = 0;
|
||||
for (size_t i = 0; i < q.size(); ++i) ret |= q.at(i) << (i * lbits);
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename T, std::size_t T_Depth>
|
||||
static inline IData VL_PACK_II(int obits, int lbits, const VlUnpacked<T, T_Depth>& q) {
|
||||
template <std::size_t T_Depth>
|
||||
static inline IData VL_PACK_II(int obits, int lbits, const VlUnpacked<CData, T_Depth>& q) {
|
||||
IData ret = 0;
|
||||
for (size_t i = 0; i < T_Depth; ++i)
|
||||
ret |= static_cast<IData>(q[T_Depth - 1 - i]) << (i * lbits);
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <std::size_t T_Depth>
|
||||
static inline IData VL_PACK_II(int obits, int lbits, const VlUnpacked<SData, T_Depth>& q) {
|
||||
IData ret = 0;
|
||||
for (size_t i = 0; i < T_Depth; ++i)
|
||||
ret |= static_cast<IData>(q[T_Depth - 1 - i]) << (i * lbits);
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <std::size_t T_Depth>
|
||||
static inline IData VL_PACK_II(int obits, int lbits, const VlUnpacked<IData, T_Depth>& 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 <typename T>
|
||||
static inline QData VL_PACK_QQ(int obits, int lbits, const VlQueue<T>& q) {
|
||||
static inline QData VL_PACK_QI(int obits, int lbits, const VlQueue<CData>& q) {
|
||||
QData ret = 0;
|
||||
for (size_t i = 0; i < q.size(); ++i) ret |= static_cast<QData>(q.at(i)) << (i * lbits);
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename T, std::size_t T_Depth>
|
||||
static inline QData VL_PACK_QQ(int obits, int lbits, const VlUnpacked<T, T_Depth>& q) {
|
||||
static inline QData VL_PACK_QI(int obits, int lbits, const VlQueue<SData>& q) {
|
||||
QData ret = 0;
|
||||
for (size_t i = 0; i < q.size(); ++i) ret |= static_cast<QData>(q.at(i)) << (i * lbits);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline QData VL_PACK_QI(int obits, int lbits, const VlQueue<IData>& q) {
|
||||
QData ret = 0;
|
||||
for (size_t i = 0; i < q.size(); ++i) ret |= static_cast<QData>(q.at(i)) << (i * lbits);
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <std::size_t T_Depth>
|
||||
static inline QData VL_PACK_QI(int obits, int lbits, const VlUnpacked<CData, T_Depth>& q) {
|
||||
QData ret = 0;
|
||||
for (size_t i = 0; i < T_Depth; ++i)
|
||||
ret |= static_cast<QData>(q[T_Depth - 1 - i]) << (i * lbits);
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static inline WDataOutP VL_PACK_WI(int obits, int lbits, WDataOutP owp, const VlQueue<T>& q) {
|
||||
template <std::size_t T_Depth>
|
||||
static inline QData VL_PACK_QI(int obits, int lbits, const VlUnpacked<SData, T_Depth>& q) {
|
||||
QData ret = 0;
|
||||
for (size_t i = 0; i < T_Depth; ++i)
|
||||
ret |= static_cast<QData>(q[T_Depth - 1 - i]) << (i * lbits);
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <std::size_t T_Depth>
|
||||
static inline QData VL_PACK_QI(int obits, int lbits, const VlUnpacked<IData, T_Depth>& q) {
|
||||
QData ret = 0;
|
||||
for (size_t i = 0; i < T_Depth; ++i)
|
||||
ret |= static_cast<QData>(q[T_Depth - 1 - i]) << (i * lbits);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline QData VL_PACK_QQ(int obits, int lbits, const VlQueue<QData>& q) {
|
||||
QData ret = 0;
|
||||
for (size_t i = 0; i < q.size(); ++i) ret |= q.at(i) << (i * lbits);
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <std::size_t T_Depth>
|
||||
static inline QData VL_PACK_QQ(int obits, int lbits, const VlUnpacked<QData, T_Depth>& q) {
|
||||
QData ret = 0;
|
||||
for (size_t i = 0; i < T_Depth; ++i) ret |= q[T_Depth - 1 - i] << (i * lbits);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline WDataOutP VL_PACK_WI(int obits, int lbits, WDataOutP owp, const VlQueue<CData>& 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 <typename T, std::size_t T_Depth>
|
||||
static inline WDataOutP VL_PACK_WI(int obits, int lbits, WDataOutP owp, const VlQueue<SData>& 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;
|
||||
}
|
||||
|
||||
static inline WDataOutP VL_PACK_WI(int obits, int lbits, WDataOutP owp, const VlQueue<IData>& 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 <std::size_t T_Depth>
|
||||
static inline WDataOutP VL_PACK_WI(int obits, int lbits, WDataOutP owp,
|
||||
const VlUnpacked<T, T_Depth>& q) {
|
||||
const VlUnpacked<CData, T_Depth>& 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 <typename T>
|
||||
static inline WDataOutP VL_PACK_WQ(int obits, int lbits, WDataOutP owp, const VlQueue<T>& q) {
|
||||
template <std::size_t T_Depth>
|
||||
static inline WDataOutP VL_PACK_WI(int obits, int lbits, WDataOutP owp,
|
||||
const VlUnpacked<SData, T_Depth>& 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 <std::size_t T_Depth>
|
||||
static inline WDataOutP VL_PACK_WI(int obits, int lbits, WDataOutP owp,
|
||||
const VlUnpacked<IData, T_Depth>& 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;
|
||||
}
|
||||
|
||||
static inline WDataOutP VL_PACK_WQ(int obits, int lbits, WDataOutP owp, const VlQueue<QData>& 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 <typename T, std::size_t T_Depth>
|
||||
template <std::size_t T_Depth>
|
||||
static inline WDataOutP VL_PACK_WQ(int obits, int lbits, WDataOutP owp,
|
||||
const VlUnpacked<T, T_Depth>& q) {
|
||||
const VlUnpacked<QData, T_Depth>& 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;
|
||||
}
|
||||
|
||||
template <std::size_t N>
|
||||
static inline WDataOutP VL_PACK_WW(int obits, int lbits, WDataOutP owp,
|
||||
const VlQueue<VlWide<N>>& q) {
|
||||
VL_MEMSET_ZERO_W(owp + 1, VL_WORDS_I(obits) - 1);
|
||||
for (size_t i = 0; i < q.size(); ++i)
|
||||
_vl_insert_WW(owp, q.at(i), i * lbits + lbits - 1, i * lbits);
|
||||
return owp;
|
||||
}
|
||||
|
||||
template <std::size_t T_Depth, std::size_t N>
|
||||
static inline WDataOutP VL_PACK_WW(int obits, int lbits, WDataOutP owp,
|
||||
const VlUnpacked<VlWide<N>, T_Depth>& q) {
|
||||
VL_MEMSET_ZERO_W(owp + 1, VL_WORDS_I(obits) - 1);
|
||||
for (size_t i = 0; i < T_Depth; ++i)
|
||||
_vl_insert_WW(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.
|
||||
// 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.
|
||||
@ -2089,68 +2202,169 @@ static inline WDataOutP VL_SEL_WWII(int obits, int lbits, WDataOutP owp, WDataIn
|
||||
//======================================================================
|
||||
// Expressions needing insert/select
|
||||
|
||||
template <typename T>
|
||||
static inline void VL_UNPACK_II(int lbits, int rbits, VlQueue<T>& q, IData from) {
|
||||
static inline void VL_UNPACK_II(int lbits, int rbits, VlQueue<CData>& 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<T>((from >> (i * lbits)) & mask);
|
||||
for (size_t i = 0; i < size; ++i) q.at(i) = (from >> (i * lbits)) & mask;
|
||||
}
|
||||
|
||||
#define VL_UNPACK_IQ VL_UNPACK_QQ
|
||||
static inline void VL_UNPACK_II(int lbits, int rbits, VlQueue<SData>& 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) = (from >> (i * lbits)) & mask;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static inline void VL_UNPACK_QQ(int lbits, int rbits, VlQueue<T>& q, QData from) {
|
||||
static inline void VL_UNPACK_II(int lbits, int rbits, VlQueue<IData>& 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) = (from >> (i * lbits)) & mask;
|
||||
}
|
||||
|
||||
static inline void VL_UNPACK_IQ(int lbits, int rbits, VlQueue<CData>& q, QData 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) = (from >> (i * lbits)) & mask;
|
||||
}
|
||||
|
||||
static inline void VL_UNPACK_IQ(int lbits, int rbits, VlQueue<SData>& q, QData 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) = (from >> (i * lbits)) & mask;
|
||||
}
|
||||
|
||||
static inline void VL_UNPACK_IQ(int lbits, int rbits, VlQueue<IData>& q, QData 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) = (from >> (i * lbits)) & mask;
|
||||
}
|
||||
|
||||
static inline void VL_UNPACK_QQ(int lbits, int rbits, VlQueue<QData>& 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<T>((from >> (i * lbits)) & mask);
|
||||
for (size_t i = 0; i < size; ++i) q.at(i) = (from >> (i * lbits)) & mask;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static inline void VL_UNPACK_IW(int lbits, int rbits, VlQueue<T>& q, WDataInP rwp) {
|
||||
static inline void VL_UNPACK_IW(int lbits, int rbits, VlQueue<CData>& 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<T>(VL_SEL_IWII(rbits, rwp, i * lbits, lbits) & mask);
|
||||
for (size_t i = 0; i < size; ++i) q.at(i) = VL_SEL_IWII(rbits, rwp, i * lbits, lbits) & mask;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static inline void VL_UNPACK_QW(int lbits, int rbits, VlQueue<T>& q, WDataInP rwp) {
|
||||
static inline void VL_UNPACK_IW(int lbits, int rbits, VlQueue<SData>& 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) = VL_SEL_IWII(rbits, rwp, i * lbits, lbits) & mask;
|
||||
}
|
||||
|
||||
static inline void VL_UNPACK_IW(int lbits, int rbits, VlQueue<IData>& 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) = VL_SEL_IWII(rbits, rwp, i * lbits, lbits) & mask;
|
||||
}
|
||||
|
||||
static inline void VL_UNPACK_QW(int lbits, int rbits, VlQueue<QData>& 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<T>(VL_SEL_QWII(rbits, rwp, i * lbits, lbits) & mask);
|
||||
for (size_t i = 0; i < size; ++i) q.at(i) = VL_SEL_QWII(rbits, rwp, i * lbits, lbits) & mask;
|
||||
}
|
||||
|
||||
template <typename T, std::size_t T_Depth>
|
||||
static inline void VL_UNPACK_II(int lbits, int rbits, VlUnpacked<T, T_Depth>& q, QData from) {
|
||||
template <std::size_t N>
|
||||
static inline void VL_UNPACK_WW(int lbits, int rbits, VlQueue<VlWide<N>>& q, WDataInP rwp) {
|
||||
const int size = (rbits + lbits - 1) / lbits;
|
||||
q.renew(size);
|
||||
for (size_t i = 0; i < size; ++i) VL_SEL_WWII(lbits, rbits, q.at(i), rwp, i * lbits, lbits);
|
||||
}
|
||||
|
||||
template <std::size_t T_Depth>
|
||||
static inline void VL_UNPACK_II(int lbits, int rbits, VlUnpacked<CData, T_Depth>& q, IData from) {
|
||||
const IData mask = VL_MASK_I(lbits);
|
||||
for (size_t i = 0; i < T_Depth; ++i) q[i] = (from >> ((T_Depth - 1 - i) * lbits)) & mask;
|
||||
}
|
||||
|
||||
template <std::size_t T_Depth>
|
||||
static inline void VL_UNPACK_II(int lbits, int rbits, VlUnpacked<SData, T_Depth>& q, IData from) {
|
||||
const IData mask = VL_MASK_I(lbits);
|
||||
for (size_t i = 0; i < T_Depth; ++i) q[i] = (from >> ((T_Depth - 1 - i) * lbits)) & mask;
|
||||
}
|
||||
|
||||
template <std::size_t T_Depth>
|
||||
static inline void VL_UNPACK_II(int lbits, int rbits, VlUnpacked<IData, T_Depth>& q, IData from) {
|
||||
const IData mask = VL_MASK_I(lbits);
|
||||
for (size_t i = 0; i < T_Depth; ++i) q[i] = (from >> ((T_Depth - 1 - i) * lbits)) & mask;
|
||||
}
|
||||
|
||||
template <std::size_t T_Depth>
|
||||
static inline void VL_UNPACK_IQ(int lbits, int rbits, VlUnpacked<CData, T_Depth>& q, QData from) {
|
||||
const IData mask = VL_MASK_I(lbits);
|
||||
for (size_t i = 0; i < T_Depth; ++i) q[i] = (from >> ((T_Depth - 1 - i) * lbits)) & mask;
|
||||
}
|
||||
|
||||
template <std::size_t T_Depth>
|
||||
static inline void VL_UNPACK_IQ(int lbits, int rbits, VlUnpacked<SData, T_Depth>& q, QData from) {
|
||||
const IData mask = VL_MASK_I(lbits);
|
||||
for (size_t i = 0; i < T_Depth; ++i) q[i] = (from >> ((T_Depth - 1 - i) * lbits)) & mask;
|
||||
}
|
||||
|
||||
template <std::size_t T_Depth>
|
||||
static inline void VL_UNPACK_IQ(int lbits, int rbits, VlUnpacked<IData, T_Depth>& q, QData from) {
|
||||
const IData mask = VL_MASK_I(lbits);
|
||||
for (size_t i = 0; i < T_Depth; ++i) q[i] = (from >> ((T_Depth - 1 - i) * lbits)) & mask;
|
||||
}
|
||||
|
||||
template <std::size_t T_Depth>
|
||||
static inline void VL_UNPACK_QQ(int lbits, int rbits, VlUnpacked<QData, T_Depth>& q, QData from) {
|
||||
const QData mask = VL_MASK_Q(lbits);
|
||||
for (size_t i = 0; i < T_Depth; ++i) q[i] = (from >> ((T_Depth - 1 - i) * lbits)) & mask;
|
||||
}
|
||||
|
||||
template <std::size_t T_Depth>
|
||||
static inline void VL_UNPACK_IW(int lbits, int rbits, VlUnpacked<CData, T_Depth>& q,
|
||||
WDataInP rwp) {
|
||||
const IData mask = VL_MASK_I(lbits);
|
||||
for (size_t i = 0; i < T_Depth; ++i)
|
||||
q[i] = static_cast<T>((from >> ((T_Depth - 1 - i) * lbits)) & mask);
|
||||
q[i] = VL_SEL_IWII(rbits, rwp, (T_Depth - 1 - i) * lbits, lbits) & mask;
|
||||
}
|
||||
|
||||
template <typename T, std::size_t T_Depth>
|
||||
static inline void VL_UNPACK_QQ(int lbits, int rbits, VlUnpacked<T, T_Depth>& q, QData from) {
|
||||
const QData mask = VL_MASK_Q(lbits);
|
||||
for (size_t i = 0; i < T_Depth; ++i)
|
||||
q[i] = static_cast<T>((from >> ((T_Depth - 1 - i) * lbits)) & mask);
|
||||
}
|
||||
|
||||
template <typename T, std::size_t T_Depth>
|
||||
static inline void VL_UNPACK_IW(int lbits, int rbits, VlUnpacked<T, T_Depth>& q, WDataInP rwp) {
|
||||
template <std::size_t T_Depth>
|
||||
static inline void VL_UNPACK_IW(int lbits, int rbits, VlUnpacked<SData, T_Depth>& q,
|
||||
WDataInP rwp) {
|
||||
const IData mask = VL_MASK_I(lbits);
|
||||
for (size_t i = 0; i < T_Depth; ++i)
|
||||
q[i] = static_cast<T>(VL_SEL_IWII(rbits, rwp, (T_Depth - 1 - i) * lbits, lbits) & mask);
|
||||
q[i] = VL_SEL_IWII(rbits, rwp, (T_Depth - 1 - i) * lbits, lbits) & mask;
|
||||
}
|
||||
|
||||
template <typename T, std::size_t T_Depth>
|
||||
static inline void VL_UNPACK_QW(int lbits, int rbits, VlUnpacked<T, T_Depth>& q, WDataInP rwp) {
|
||||
template <std::size_t T_Depth>
|
||||
static inline void VL_UNPACK_IW(int lbits, int rbits, VlUnpacked<IData, T_Depth>& q,
|
||||
WDataInP rwp) {
|
||||
const IData mask = VL_MASK_I(lbits);
|
||||
for (size_t i = 0; i < T_Depth; ++i)
|
||||
q[i] = VL_SEL_IWII(rbits, rwp, (T_Depth - 1 - i) * lbits, lbits) & mask;
|
||||
}
|
||||
|
||||
template <std::size_t T_Depth>
|
||||
static inline void VL_UNPACK_QW(int lbits, int rbits, VlUnpacked<QData, T_Depth>& q,
|
||||
WDataInP rwp) {
|
||||
const QData mask = VL_MASK_Q(lbits);
|
||||
for (size_t i = 0; i < T_Depth; ++i)
|
||||
q[i] = static_cast<T>(VL_SEL_QWII(rbits, rwp, (T_Depth - 1 - i) * lbits, lbits) & mask);
|
||||
q[i] = VL_SEL_QWII(rbits, rwp, (T_Depth - 1 - i) * lbits, lbits) & mask;
|
||||
}
|
||||
|
||||
template <std::size_t T_Depth, std::size_t N>
|
||||
static inline void VL_UNPACK_WW(int lbits, int rbits, VlUnpacked<VlWide<N>, T_Depth>& q,
|
||||
WDataInP rwp) {
|
||||
for (size_t i = 0; i < T_Depth; ++i)
|
||||
VL_SEL_WWII(lbits, rbits, q[i], rwp, (T_Depth - 1 - i) * lbits, lbits);
|
||||
}
|
||||
|
||||
// Return QData from double (numeric)
|
||||
|
@ -449,13 +449,7 @@ public:
|
||||
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(">(");
|
||||
puts("(");
|
||||
putns(castp->dtypep(), cvtToStr(castp->dtypep()->subDTypep()->widthMin()));
|
||||
puts(", ");
|
||||
puts(cvtToStr(castp->fromp()->widthMin()));
|
||||
|
@ -23,6 +23,7 @@ module t (/*AUTOARG*/);
|
||||
bit [3:0] arr4[] = '{25{4'b1000}};
|
||||
bit [7:0] arr8[] = '{8{8'b00110011}};
|
||||
bit [63:0] arr64[] = '{5{64'h0123456789abcdef}};
|
||||
bit [159:0] arr160[] = '{2{160'h0123456789abcdef0123456789abcdef01234567}};
|
||||
bit [63:0] bit64;
|
||||
bit [99:0] bit100;
|
||||
bit [319:0] bit320;
|
||||
@ -97,20 +98,40 @@ module t (/*AUTOARG*/);
|
||||
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);
|
||||
|
||||
bit320 = { >> byte {arr64} };
|
||||
`checkh(bit320[63:0], 64'h0123456789abcdef);
|
||||
bit320 = { << byte {arr64} };
|
||||
`checkh(bit320[63:0], 64'hefcdab8967452301);
|
||||
|
||||
{ >> byte {arr64} } = bit320;
|
||||
`checkh(arr64[0], 64'hefcdab8967452301);
|
||||
{ << byte {arr64} } = bit320;
|
||||
`checkh(arr64[0], 64'h0123456789abcdef);
|
||||
|
||||
{ >> bit {arr64} } = bit64;
|
||||
`checkh(arr64[0], 64'hcccccccccccccccc);
|
||||
{ << bit {arr64} } = bit64;
|
||||
`checkh(arr64[0], 64'h3333333333333333);
|
||||
|
||||
bit64 = { >> bit {arr64} };
|
||||
`checkh(bit64, 64'h3333333333333333);
|
||||
bit64 = { << bit {arr64} };
|
||||
`checkh(bit64, 64'hcccccccccccccccc);
|
||||
|
||||
bit320 = { >> byte {arr160} };
|
||||
`checkh(bit320[159:0], 160'h0123456789abcdef0123456789abcdef01234567);
|
||||
bit320 = { << byte {arr160} };
|
||||
`checkh(bit320[159:0], 160'h67452301efcdab8967452301efcdab8967452301);
|
||||
|
||||
{ >> byte {arr160} } = bit320;
|
||||
`checkh(arr160[0], 160'h67452301efcdab8967452301efcdab8967452301);
|
||||
{ << byte {arr160} } = bit320;
|
||||
`checkh(arr160[0], 160'h0123456789abcdef0123456789abcdef01234567);
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
|
@ -47,6 +47,9 @@ module t (/*AUTOARG*/
|
||||
|
||||
logic [255:0] packed_time_256;
|
||||
logic [255:0] packed_time_256_ref;
|
||||
|
||||
logic [511:0] v_packed_data_512;
|
||||
logic [511:0] v_packed_data_512_ref;
|
||||
//
|
||||
//integer_atom_type
|
||||
//
|
||||
@ -74,6 +77,7 @@ module t (/*AUTOARG*/
|
||||
typedef bit [15:0] test_short;
|
||||
typedef bit [31:0] test_word;
|
||||
typedef bit [63:0] test_long;
|
||||
typedef bit [127:0] test_wide;
|
||||
//
|
||||
test_byte bit_in[4];
|
||||
test_byte bit_out[4];
|
||||
@ -84,6 +88,9 @@ module t (/*AUTOARG*/
|
||||
test_word reg_in[4];
|
||||
test_word reg_out[4];
|
||||
//
|
||||
test_wide wide_in[4];
|
||||
test_wide wide_out[4];
|
||||
//
|
||||
string error = "";
|
||||
|
||||
initial begin
|
||||
@ -124,6 +131,7 @@ module t (/*AUTOARG*/
|
||||
v_packed_data_32 = {<<8{bit_in}};
|
||||
v_packed_data_64 = {<<16{logic_in}};
|
||||
v_packed_data_128 = {<<32{reg_in}};
|
||||
v_packed_data_512 = {<<32{wide_in}};
|
||||
//unpack
|
||||
{<<8{byte_out}} = packed_data_32;
|
||||
{<<16{shortint_out}} = packed_data_64;
|
||||
@ -134,6 +142,7 @@ module t (/*AUTOARG*/
|
||||
{<<8{bit_out}} = v_packed_data_32;
|
||||
{<<16{logic_out}} = v_packed_data_64;
|
||||
{<<32{reg_out}} = v_packed_data_128;
|
||||
{<<32{wide_out}} = v_packed_data_512;
|
||||
error_ = comp_in_out();
|
||||
end // if (error == "")
|
||||
return error_;
|
||||
@ -234,6 +243,10 @@ module t (/*AUTOARG*/
|
||||
foreach (reg_in[i]) $display("reg_in[%0d]%0h, reg_out=%0h", i, reg_in[i], reg_out[i]);
|
||||
$display("v_packed_data_128=%0h, v_packed_data_128_ref=%0h", v_packed_data_128, v_packed_data_128_ref);
|
||||
end
|
||||
if (error == "integer_vector_type wide") begin
|
||||
foreach (wide_in[i]) $display("wide_in[%0d]%0h, wide_out=%0h", i, wide_in[i], wide_out[i]);
|
||||
$display("v_packed_data_512=%0h, v_packed_data_512_ref=%0h", v_packed_data_512, v_packed_data_512_ref);
|
||||
end
|
||||
endfunction : print_data_error
|
||||
|
||||
function static void print_all_data (string name = "");
|
||||
@ -263,6 +276,9 @@ module t (/*AUTOARG*/
|
||||
|
||||
foreach (reg_in[i]) $display(" %s reg_in[%0d]%0h, reg_out=%0h", name, i, reg_in[i], reg_out[i]);
|
||||
$display(" %s v_packed_data_128=%0h, v_packed_data_128_ref=%0h", name, v_packed_data_128, v_packed_data_128_ref);
|
||||
|
||||
foreach (wide_in[i]) $display(" %s wide_in[%0d]%0h, wide_out=%0h", name, i, wide_in[i], wide_out[i]);
|
||||
$display(" %s v_packed_data_512=%0h, v_packed_data_512_ref=%0h", name, v_packed_data_512, v_packed_data_512_ref);
|
||||
endfunction : print_all_data
|
||||
|
||||
function void init_data();
|
||||
@ -326,6 +342,9 @@ module t (/*AUTOARG*/
|
||||
if (error_ == "") foreach (reg_in[i]) if (reg_in[i] !== reg_out[i]) error_ = "integer_vector_type reg";
|
||||
if (error_ == "") if (v_packed_data_128 !== v_packed_data_128_ref) error_ = "integer_vector_type reg";
|
||||
|
||||
if (error_ == "") foreach (wide_in[i]) if (wide_in[i] !== wide_out[i]) error_ = "integer_vector_type wide";
|
||||
if (error_ == "") if (v_packed_data_128 !== v_packed_data_128_ref) error_ = "integer_vector_type wide";
|
||||
|
||||
return error_;
|
||||
endfunction : comp_in_out
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user