Apply 'make format'
This commit is contained in:
parent
69dce205d3
commit
bb871728c9
|
@ -3369,14 +3369,16 @@ void VerilatedScope::exportInsert(int finalize, const char* namep, void* cb) VL_
|
|||
}
|
||||
|
||||
void VerilatedScope::varInsert(int finalize, const char* namep, void* datap, bool isParam,
|
||||
VerilatedVarType vltype, int vlflags, int udims, int pdims ...) VL_MT_UNSAFE {
|
||||
VerilatedVarType vltype, int vlflags, int udims,
|
||||
int pdims...) VL_MT_UNSAFE {
|
||||
// Grab dimensions
|
||||
// In the future we may just create a large table at emit time and
|
||||
// statically construct from that.
|
||||
if (!finalize) return;
|
||||
|
||||
if (!m_varsp) m_varsp = new VerilatedVarNameMap;
|
||||
VerilatedVar var(namep, datap, vltype, static_cast<VerilatedVarFlags>(vlflags), udims, pdims, isParam);
|
||||
VerilatedVar var(namep, datap, vltype, static_cast<VerilatedVarFlags>(vlflags), udims, pdims,
|
||||
isParam);
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, pdims);
|
||||
|
|
|
@ -76,7 +76,7 @@ class VerilatedVarProps VL_NOT_FINAL {
|
|||
const VerilatedVarFlags m_vlflags; // Direction
|
||||
std::vector<VerilatedRange> m_unpacked; // Unpacked array ranges
|
||||
std::vector<VerilatedRange> m_packed; // Packed array ranges
|
||||
VerilatedRange m_packedDpi; // Flattened packed array range
|
||||
VerilatedRange m_packedDpi; // Flattened packed array range
|
||||
void initUnpacked(int udims, const int* ulims) {
|
||||
for (int i = 0; i < udims; ++i) {
|
||||
const int uleft = ulims ? ulims[2 * i + 0] : 0;
|
||||
|
@ -152,8 +152,7 @@ public:
|
|||
uint32_t entSize() const VL_MT_SAFE;
|
||||
uint32_t entBits() const VL_MT_SAFE {
|
||||
uint32_t bits = 1;
|
||||
for (auto it : m_packed)
|
||||
bits *= it.elements();
|
||||
for (auto it : m_packed) bits *= it.elements();
|
||||
return bits;
|
||||
}
|
||||
bool isPublicRW() const { return ((m_vlflags & VLVF_PUB_RW) != 0); }
|
||||
|
|
|
@ -172,9 +172,7 @@ protected:
|
|||
const VerilatedScope* m_scopep = nullptr;
|
||||
std::string m_fullname;
|
||||
int32_t m_indexedDim = -1;
|
||||
const VerilatedRange* get_range() const {
|
||||
return m_varp->range(m_indexedDim + 1);
|
||||
}
|
||||
const VerilatedRange* get_range() const { return m_varp->range(m_indexedDim + 1); }
|
||||
|
||||
public:
|
||||
VerilatedVpioVarBase(const VerilatedVar* varp, const VerilatedScope* scopep)
|
||||
|
@ -272,8 +270,8 @@ class VerilatedVpioRangeIter final : public VerilatedVpio {
|
|||
public:
|
||||
explicit VerilatedVpioRangeIter(const std::vector<VerilatedRange>& ranges)
|
||||
: m_ranges{ranges} {
|
||||
m_iter = m_ranges.begin();
|
||||
}
|
||||
m_iter = m_ranges.begin();
|
||||
}
|
||||
~VerilatedVpioRangeIter() override = default;
|
||||
static VerilatedVpioRangeIter* castp(vpiHandle h) {
|
||||
return dynamic_cast<VerilatedVpioRangeIter*>(reinterpret_cast<VerilatedVpio*>(h));
|
||||
|
@ -326,6 +324,7 @@ class VerilatedVpioVar VL_NOT_FINAL : public VerilatedVpioVarBase {
|
|||
} m_mask; // memoized variable mask
|
||||
uint32_t m_entSize = 0; // memoized variable size
|
||||
uint32_t m_bitOffset = 0;
|
||||
|
||||
protected:
|
||||
void* m_varDatap = nullptr; // varp()->datap() adjusted for array entries
|
||||
std::vector<int32_t> m_index;
|
||||
|
@ -361,8 +360,7 @@ public:
|
|||
uint32_t entSize() const { return m_entSize; }
|
||||
const std::vector<int32_t>& index() const { return m_index; }
|
||||
VerilatedVpioVar* withIndex(int32_t index) const {
|
||||
if (VL_UNLIKELY(indexedDim() + 1 >= varp()->dims()))
|
||||
return nullptr;
|
||||
if (VL_UNLIKELY(indexedDim() + 1 >= varp()->dims())) return nullptr;
|
||||
|
||||
auto ret = new VerilatedVpioVar{this};
|
||||
ret->m_index.push_back(index);
|
||||
|
@ -373,7 +371,8 @@ public:
|
|||
chunkSize *= varp()->range(dim)->elements();
|
||||
|
||||
if (isIndexedDimUnpacked())
|
||||
ret->m_varDatap = (static_cast<uint8_t*>(ret->m_varDatap)) + entSize() * chunkSize * (index - get_range()->low());
|
||||
ret->m_varDatap = (static_cast<uint8_t*>(ret->m_varDatap))
|
||||
+ entSize() * chunkSize * (index - get_range()->low());
|
||||
else
|
||||
ret->m_bitOffset += chunkSize * (index - get_range()->low());
|
||||
|
||||
|
@ -394,9 +393,7 @@ public:
|
|||
const char* fullname() const override {
|
||||
static thread_local std::string t_out;
|
||||
t_out = std::string{scopep()->name()} + "." + name();
|
||||
for (auto idx : index()) {
|
||||
t_out += "[" + std::to_string(idx) + "]";
|
||||
}
|
||||
for (auto idx : index()) { t_out += "[" + std::to_string(idx) + "]"; }
|
||||
return t_out.c_str();
|
||||
}
|
||||
void* prevDatap() const { return m_prevDatap; }
|
||||
|
@ -478,11 +475,10 @@ public:
|
|||
explicit VerilatedVpioRegIter(const VerilatedVpioVar* vop)
|
||||
: m_var{new VerilatedVpioVar(vop)}
|
||||
, m_maxDim{vop->varp()->udims() - 1} {
|
||||
for (auto it = vop->indexedDim() + 1; it <= m_maxDim; it++)
|
||||
m_ranges.push_back(*vop->varp()->range(it));
|
||||
for (auto it : m_ranges)
|
||||
m_nextIndex.push_back(it.right());
|
||||
}
|
||||
for (auto it = vop->indexedDim() + 1; it <= m_maxDim; it++)
|
||||
m_ranges.push_back(*vop->varp()->range(it));
|
||||
for (auto it : m_ranges) m_nextIndex.push_back(it.right());
|
||||
}
|
||||
~VerilatedVpioRegIter() override = default;
|
||||
static VerilatedVpioRegIter* castp(vpiHandle h) {
|
||||
return dynamic_cast<VerilatedVpioRegIter*>(reinterpret_cast<VerilatedVpio*>(h));
|
||||
|
@ -494,22 +490,21 @@ public:
|
|||
delete this;
|
||||
return nullptr;
|
||||
}
|
||||
if (m_nextIndex.front() > m_ranges.front().high() ||
|
||||
m_nextIndex.front() < m_ranges.front().low()) {
|
||||
if (m_nextIndex.front() > m_ranges.front().high()
|
||||
|| m_nextIndex.front() < m_ranges.front().low()) {
|
||||
// Finished iterating
|
||||
delete this;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
VerilatedVpioVar* ret = m_var;
|
||||
for (auto it : m_nextIndex)
|
||||
ret = ret->withIndex(it);
|
||||
for (auto it : m_nextIndex) ret = ret->withIndex(it);
|
||||
|
||||
// Increase the index, pretending the dimensions are flattened
|
||||
for (int32_t it = m_ranges.size() - 1; it >= 0; it--) {
|
||||
m_nextIndex.at(it) += m_ranges.at(it).increment();
|
||||
if (m_nextIndex.at(it) <= m_ranges.at(it).high() &&
|
||||
m_nextIndex.at(it) >= m_ranges.at(it).low())
|
||||
if (m_nextIndex.at(it) <= m_ranges.at(it).high()
|
||||
&& m_nextIndex.at(it) >= m_ranges.at(it).low())
|
||||
break;
|
||||
else if (it > 0)
|
||||
m_nextIndex.at(it) = m_ranges.at(it).right();
|
||||
|
@ -2104,8 +2099,7 @@ vpiHandle vpi_handle_by_index(vpiHandle object, PLI_INT32 indx) {
|
|||
const VerilatedVpioVar* const varop = VerilatedVpioVar::castp(object);
|
||||
if (VL_LIKELY(varop)) {
|
||||
// Case: no dimensions left to index
|
||||
if (VL_UNLIKELY(varop->indexedDim() + 1 > varop->varp()->dims() - 1))
|
||||
return nullptr;
|
||||
if (VL_UNLIKELY(varop->indexedDim() + 1 > varop->varp()->dims() - 1)) return nullptr;
|
||||
|
||||
// Case: index out of range
|
||||
if (VL_UNLIKELY(indx < varop->rangep()->low() || indx > varop->rangep()->high()))
|
||||
|
@ -2194,8 +2188,7 @@ vpiHandle vpi_iterate(PLI_INT32 type, vpiHandle object) {
|
|||
ranges.emplace_back(*vop->varp()->range(dim));
|
||||
|
||||
// allow one more range layer (regbit)
|
||||
if (ranges.empty())
|
||||
ranges.emplace_back(VerilatedRange(0, 0));
|
||||
if (ranges.empty()) ranges.emplace_back(VerilatedRange(0, 0));
|
||||
return ((new VerilatedVpioRangeIter{ranges})->castVpiHandle());
|
||||
}
|
||||
case vpiReg: {
|
||||
|
@ -2423,19 +2416,20 @@ static void vl_strprintf(std::string& buffer, char const* fmt, ...) {
|
|||
}
|
||||
|
||||
// Information about how to access packed array data.
|
||||
// If underlying type is multi-word (VLVT_WDATA), the packed element might straddle word boundaries,
|
||||
// in which case m_maskHi != 0.
|
||||
template<typename T>
|
||||
// If underlying type is multi-word (VLVT_WDATA), the packed element might straddle word
|
||||
// boundaries, in which case m_maskHi != 0.
|
||||
template <typename T>
|
||||
struct VarAccessInfo final {
|
||||
T* m_datap; // Typed pointer to packed array base address
|
||||
size_t m_bitOffset; // Data start location (bit offset)
|
||||
size_t m_wordOffset; // Data start location (word offset, VLVT_WDATA only)
|
||||
T m_maskLo; // Access mask for m_datap[m_wordOffset]
|
||||
T m_maskHi; // Access mask for m_datap[m_wordOffset + 1] (VLVT_WDATA only)
|
||||
T* m_datap; // Typed pointer to packed array base address
|
||||
size_t m_bitOffset; // Data start location (bit offset)
|
||||
size_t m_wordOffset; // Data start location (word offset, VLVT_WDATA only)
|
||||
T m_maskLo; // Access mask for m_datap[m_wordOffset]
|
||||
T m_maskHi; // Access mask for m_datap[m_wordOffset + 1] (VLVT_WDATA only)
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
VarAccessInfo<T> vl_vpi_var_access_info(const VerilatedVpioVarBase* vop, size_t bitCount, size_t addOffset) {
|
||||
template <typename T>
|
||||
VarAccessInfo<T> vl_vpi_var_access_info(const VerilatedVpioVarBase* vop, size_t bitCount,
|
||||
size_t addOffset) {
|
||||
// VarAccessInfo generation
|
||||
// vop - variable to access (already indexed)
|
||||
// bitCount - how many bits to write/read
|
||||
|
@ -2444,8 +2438,7 @@ VarAccessInfo<T> vl_vpi_var_access_info(const VerilatedVpioVarBase* vop, size_t
|
|||
const size_t wordBits = sizeof(T) * 8;
|
||||
uint32_t varBits = vop->bitSize();
|
||||
|
||||
if (vop->varp()->vltype() == VLVT_REAL)
|
||||
varBits *= sizeof(double) * 8;
|
||||
if (vop->varp()->vltype() == VLVT_REAL) varBits *= sizeof(double) * 8;
|
||||
|
||||
// make sure we're not trying to write outside var bounds
|
||||
assert(varBits > addOffset);
|
||||
|
@ -2487,42 +2480,45 @@ VarAccessInfo<T> vl_vpi_var_access_info(const VerilatedVpioVarBase* vop, size_t
|
|||
return info;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
T vl_vpi_get_word_gen(const VerilatedVpioVarBase* vop, size_t bitCount, size_t addOffset) {
|
||||
const size_t wordBits = sizeof(T) * 8;
|
||||
const VarAccessInfo<T> info = vl_vpi_var_access_info<T>(vop, bitCount, addOffset);
|
||||
if (info.m_maskHi)
|
||||
return ((info.m_datap[info.m_wordOffset] & info.m_maskLo) >> info.m_bitOffset) |
|
||||
((info.m_datap[info.m_wordOffset + 1] & info.m_maskHi) << (wordBits - info.m_bitOffset));
|
||||
return ((info.m_datap[info.m_wordOffset] & info.m_maskLo) >> info.m_bitOffset)
|
||||
| ((info.m_datap[info.m_wordOffset + 1] & info.m_maskHi)
|
||||
<< (wordBits - info.m_bitOffset));
|
||||
else
|
||||
return (info.m_datap[info.m_wordOffset] & info.m_maskLo) >> info.m_bitOffset;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
void vl_vpi_put_word_gen(const VerilatedVpioVar* vop, T word, size_t bitCount, size_t addOffset) {
|
||||
const size_t wordBits = sizeof(T) * 8;
|
||||
const VarAccessInfo<T> info = vl_vpi_var_access_info<T>(vop, bitCount, addOffset);
|
||||
|
||||
if (info.m_maskHi) {
|
||||
info.m_datap[info.m_wordOffset + 1] = (info.m_datap[info.m_wordOffset+1] & ~info.m_maskHi) |
|
||||
((word >> (wordBits - info.m_bitOffset)) & info.m_maskHi);
|
||||
info.m_datap[info.m_wordOffset + 1]
|
||||
= (info.m_datap[info.m_wordOffset + 1] & ~info.m_maskHi)
|
||||
| ((word >> (wordBits - info.m_bitOffset)) & info.m_maskHi);
|
||||
}
|
||||
info.m_datap[info.m_wordOffset] = (info.m_datap[info.m_wordOffset] & ~info.m_maskLo) |
|
||||
((word << info.m_bitOffset) & info.m_maskLo);
|
||||
info.m_datap[info.m_wordOffset] = (info.m_datap[info.m_wordOffset] & ~info.m_maskLo)
|
||||
| ((word << info.m_bitOffset) & info.m_maskLo);
|
||||
}
|
||||
|
||||
// bitCount: maximum number of bits to read, will stop earlier if it reaches the var bounds
|
||||
// addOffset: additional read bitoffset
|
||||
QData vl_vpi_get_word(const VerilatedVpioVarBase* vop, size_t bitCount, size_t addOffset) {
|
||||
switch (vop->varp()->vltype()) {
|
||||
case VLVT_UINT8: return vl_vpi_get_word_gen<CData>(vop, bitCount, addOffset);
|
||||
case VLVT_UINT16: return vl_vpi_get_word_gen<SData>(vop, bitCount, addOffset);
|
||||
case VLVT_UINT32: return vl_vpi_get_word_gen<IData>(vop, bitCount, addOffset);
|
||||
case VLVT_UINT64: return vl_vpi_get_word_gen<QData>(vop, bitCount, addOffset);
|
||||
case VLVT_WDATA: return vl_vpi_get_word_gen<EData>(vop, bitCount, addOffset);
|
||||
default:
|
||||
VL_VPI_ERROR_(__FILE__, __LINE__, "%s: Unsupported vltype (%d)", __func__, vop->varp()->vltype());
|
||||
return 0;
|
||||
case VLVT_UINT8: return vl_vpi_get_word_gen<CData>(vop, bitCount, addOffset);
|
||||
case VLVT_UINT16: return vl_vpi_get_word_gen<SData>(vop, bitCount, addOffset);
|
||||
case VLVT_UINT32: return vl_vpi_get_word_gen<IData>(vop, bitCount, addOffset);
|
||||
case VLVT_UINT64: return vl_vpi_get_word_gen<QData>(vop, bitCount, addOffset);
|
||||
case VLVT_WDATA: return vl_vpi_get_word_gen<EData>(vop, bitCount, addOffset);
|
||||
default:
|
||||
VL_VPI_ERROR_(__FILE__, __LINE__, "%s: Unsupported vltype (%d)", __func__,
|
||||
vop->varp()->vltype());
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2531,13 +2527,14 @@ QData vl_vpi_get_word(const VerilatedVpioVarBase* vop, size_t bitCount, size_t a
|
|||
// addOffset: additional write bitoffset
|
||||
void vl_vpi_put_word(const VerilatedVpioVar* vop, QData word, size_t bitCount, size_t addOffset) {
|
||||
switch (vop->varp()->vltype()) {
|
||||
case VLVT_UINT8: vl_vpi_put_word_gen<CData>(vop, word, bitCount, addOffset); break;
|
||||
case VLVT_UINT16: vl_vpi_put_word_gen<SData>(vop, word, bitCount, addOffset); break;
|
||||
case VLVT_UINT32: vl_vpi_put_word_gen<IData>(vop, word, bitCount, addOffset); break;
|
||||
case VLVT_UINT64: vl_vpi_put_word_gen<QData>(vop, word, bitCount, addOffset); break;
|
||||
case VLVT_WDATA: vl_vpi_put_word_gen<EData>(vop, word, bitCount, addOffset); break;
|
||||
default:
|
||||
VL_VPI_ERROR_(__FILE__, __LINE__, "%s: Unsupported vltype (%d)", __func__, vop->varp()->vltype());
|
||||
case VLVT_UINT8: vl_vpi_put_word_gen<CData>(vop, word, bitCount, addOffset); break;
|
||||
case VLVT_UINT16: vl_vpi_put_word_gen<SData>(vop, word, bitCount, addOffset); break;
|
||||
case VLVT_UINT32: vl_vpi_put_word_gen<IData>(vop, word, bitCount, addOffset); break;
|
||||
case VLVT_UINT64: vl_vpi_put_word_gen<QData>(vop, word, bitCount, addOffset); break;
|
||||
case VLVT_WDATA: vl_vpi_put_word_gen<EData>(vop, word, bitCount, addOffset); break;
|
||||
default:
|
||||
VL_VPI_ERROR_(__FILE__, __LINE__, "%s: Unsupported vltype (%d)", __func__,
|
||||
vop->varp()->vltype());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2732,8 +2729,8 @@ vpiHandle vpi_put_value(vpiHandle object, p_vpi_value valuep, p_vpi_time /*time_
|
|||
vl_vpi_put_word(vop, valuep->value.vector[i].aval, 32, i * 32);
|
||||
return object;
|
||||
} else if (vop->varp()->vltype() == VLVT_UINT64 && varBits > 32) {
|
||||
const QData val = (static_cast<QData>(valuep->value.vector[1].aval) << 32) |
|
||||
static_cast<QData>(valuep->value.vector[0].aval);
|
||||
const QData val = (static_cast<QData>(valuep->value.vector[1].aval) << 32)
|
||||
| static_cast<QData>(valuep->value.vector[0].aval);
|
||||
vl_vpi_put_word(vop, val, 64, 0);
|
||||
return object;
|
||||
} else {
|
||||
|
|
|
@ -960,7 +960,6 @@ void EmitCSyms::emitSymImp() {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
putns(scopep, protect("__Vscope_" + it->second.m_scopeName));
|
||||
putns(varp, ".varInsert(__Vfinal,");
|
||||
putsQuoted(protect(it->second.m_varBasePretty));
|
||||
|
|
|
@ -89,7 +89,8 @@ static int _mon_check_props(TestVpiHandle& handle, int size, int direction, int
|
|||
int vpidir = vpi_get(vpiDirection, handle);
|
||||
// Don't check port directions in verilator
|
||||
// See issue #681
|
||||
if (!TestSimulator::is_verilator() && !TestSimulator::is_questa()) CHECK_RESULT(vpidir, direction);
|
||||
if (!TestSimulator::is_verilator() && !TestSimulator::is_questa())
|
||||
CHECK_RESULT(vpidir, direction);
|
||||
}
|
||||
|
||||
// check type of object
|
||||
|
@ -120,25 +121,25 @@ int mon_check_props() {
|
|||
// the code that sets up the VerilatedAssertOneThread() check in
|
||||
// verilated_vpi.cc, it was causing the check to falsely fail
|
||||
// (due to m_threadid within the check not being initted yet.)
|
||||
static struct params values[]
|
||||
= {{"onebit", {1, vpiNoDirection, 1, vpiReg}, {0, 0, 0, 0}},
|
||||
{"twoone", {2, vpiNoDirection, 0, vpiReg}, {0, 0, 0, 0}},
|
||||
{"onetwo", {2, vpiNoDirection, 1, vpiRegArray}, {0, 0, 0, 0}},
|
||||
{"fourthreetwoone",
|
||||
{2, vpiNoDirection, 0, vpiRegArray},
|
||||
{2, vpiNoDirection, 0, vpiReg}},
|
||||
{"theint", {32, vpiNoDirection, 0, TestSimulator::is_verilator() ? vpiReg : vpiIntVar}, {0, 0, 0, 0}},
|
||||
{"clk", {1, vpiInput, 1, vpiPort}, {0, 0, 0, 0}},
|
||||
{"testin", {16, vpiInput, 0, vpiPort}, {0, 0, 0, 0}},
|
||||
{"testout", {24, vpiOutput, 0, vpiPort}, {0, 0, 0, 0}},
|
||||
{"sub.subin", {1, vpiInput, 1, vpiPort}, {0, 0, 0, 0}},
|
||||
{"sub.subout", {1, vpiOutput, 1, vpiPort}, {0, 0, 0, 0}},
|
||||
{"sub.subparam", {32, vpiNoDirection, 0, vpiParameter}, {0, 0, 0, 0}},
|
||||
{"sub.the_intf.bytesig", {8, vpiNoDirection, 0, vpiReg}, {0, 0, 0, 0}},
|
||||
{"sub.the_intf.param", {32, vpiNoDirection, 0, vpiParameter}, {0, 0, 0, 0}},
|
||||
{"sub.the_intf.lparam", {32, vpiNoDirection, 0, vpiParameter}, {0, 0, 0, 0}},
|
||||
{"twobytwo", {4, vpiNoDirection, 0, vpiReg}, {0, 0, 0, 0}},
|
||||
{NULL, {0, 0, 0, 0}, {0, 0, 0, 0}}};
|
||||
static struct params values[] = {
|
||||
{"onebit", {1, vpiNoDirection, 1, vpiReg}, {0, 0, 0, 0}},
|
||||
{"twoone", {2, vpiNoDirection, 0, vpiReg}, {0, 0, 0, 0}},
|
||||
{"onetwo", {2, vpiNoDirection, 1, vpiRegArray}, {0, 0, 0, 0}},
|
||||
{"fourthreetwoone", {2, vpiNoDirection, 0, vpiRegArray}, {2, vpiNoDirection, 0, vpiReg}},
|
||||
{"theint",
|
||||
{32, vpiNoDirection, 0, TestSimulator::is_verilator() ? vpiReg : vpiIntVar},
|
||||
{0, 0, 0, 0}},
|
||||
{"clk", {1, vpiInput, 1, vpiPort}, {0, 0, 0, 0}},
|
||||
{"testin", {16, vpiInput, 0, vpiPort}, {0, 0, 0, 0}},
|
||||
{"testout", {24, vpiOutput, 0, vpiPort}, {0, 0, 0, 0}},
|
||||
{"sub.subin", {1, vpiInput, 1, vpiPort}, {0, 0, 0, 0}},
|
||||
{"sub.subout", {1, vpiOutput, 1, vpiPort}, {0, 0, 0, 0}},
|
||||
{"sub.subparam", {32, vpiNoDirection, 0, vpiParameter}, {0, 0, 0, 0}},
|
||||
{"sub.the_intf.bytesig", {8, vpiNoDirection, 0, vpiReg}, {0, 0, 0, 0}},
|
||||
{"sub.the_intf.param", {32, vpiNoDirection, 0, vpiParameter}, {0, 0, 0, 0}},
|
||||
{"sub.the_intf.lparam", {32, vpiNoDirection, 0, vpiParameter}, {0, 0, 0, 0}},
|
||||
{"twobytwo", {4, vpiNoDirection, 0, vpiReg}, {0, 0, 0, 0}},
|
||||
{NULL, {0, 0, 0, 0}, {0, 0, 0, 0}}};
|
||||
struct params* value = values;
|
||||
while (value->signal) {
|
||||
TestVpiHandle h = VPI_HANDLE(value->signal);
|
||||
|
|
|
@ -28,10 +28,10 @@
|
|||
#endif
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <random>
|
||||
#include <cstdlib>
|
||||
|
||||
// These require the above. Comment prevents clang-format moving them
|
||||
#include "TestCheck.h"
|
||||
|
@ -42,8 +42,8 @@ int errors = 0;
|
|||
|
||||
// TEST START
|
||||
|
||||
void _arr_type_check(TestVpiHandle& arr_h, int expType, int expSize, int expRangeHigh, int expRangeLow)
|
||||
{
|
||||
void _arr_type_check(TestVpiHandle& arr_h, int expType, int expSize, int expRangeHigh,
|
||||
int expRangeLow) {
|
||||
const int vpitype = vpi_get(vpiType, arr_h);
|
||||
TEST_CHECK_EQ(vpitype, expType);
|
||||
const int vpisize = vpi_get(vpiSize, arr_h);
|
||||
|
@ -64,7 +64,8 @@ void _arr_type_check(TestVpiHandle& arr_h, int expType, int expSize, int expRang
|
|||
}
|
||||
|
||||
void _arr_iter_check(const char* name, int wordSize, const int* lows) {
|
||||
TestVpiHandle arr_h = vpi_handle_by_name(const_cast<PLI_BYTE8*>(TestSimulator::rooted(name)), NULL);
|
||||
TestVpiHandle arr_h
|
||||
= vpi_handle_by_name(const_cast<PLI_BYTE8*>(TestSimulator::rooted(name)), NULL);
|
||||
TEST_CHECK_NZ(arr_h);
|
||||
|
||||
_arr_type_check(arr_h, vpiRegArray, 4, lows[0] + 1, lows[0]);
|
||||
|
@ -118,13 +119,15 @@ void _arr_iter_check(const char* name, int wordSize, const int* lows) {
|
|||
TEST_CHECK_NZ(arr_elem2_h);
|
||||
|
||||
// first indexing yields wordSize / 2 Regs
|
||||
_arr_type_check(arr_elem2_h, vpiReg, wordSize / 2, lows[3] + wordSize / 2 - 1, lows[3]);
|
||||
_arr_type_check(arr_elem2_h, vpiReg, wordSize / 2, lows[3] + wordSize / 2 - 1,
|
||||
lows[3]);
|
||||
|
||||
for (int idx3 = lows[3]; idx3 < lows[3] + wordSize / 2; idx3++) {
|
||||
TestVpiHandle arr_elem3_h = vpi_handle_by_index(arr_elem2_h, idx3);
|
||||
TEST_CHECK_NZ(arr_elem3_h);
|
||||
{
|
||||
// second indexing yields size-1 RegBits (no support for RegBit VPI type yet)
|
||||
// second indexing yields size-1 RegBits (no support for RegBit VPI type
|
||||
// yet)
|
||||
const int vpitype = vpi_get(vpiType, arr_elem3_h);
|
||||
if (TestSimulator::is_verilator()) {
|
||||
TEST_CHECK_EQ(vpitype, vpiReg);
|
||||
|
@ -202,8 +205,8 @@ void _arr_iter_check(const char* name, int wordSize, const int* lows) {
|
|||
}
|
||||
}
|
||||
|
||||
void _arr_access_format_check(TestVpiHandle ®_h, int wordSize, const int* lows, const char *octVal_s, PLI_INT32 format)
|
||||
{
|
||||
void _arr_access_format_check(TestVpiHandle& reg_h, int wordSize, const int* lows,
|
||||
const char* octVal_s, PLI_INT32 format) {
|
||||
const int spanSize = wordSize / 2;
|
||||
s_vpi_value value_in;
|
||||
s_vpi_value value_out;
|
||||
|
@ -230,7 +233,7 @@ void _arr_access_format_check(TestVpiHandle ®_h, int wordSize, const int* low
|
|||
uint64_t intVal;
|
||||
t_vpi_vecval vecVal[2];
|
||||
sscanf(octSpan_s, "%" SCNo64, &intVal);
|
||||
char strVal_s[spanSize + 1]; // max length of the string happens for binary
|
||||
char strVal_s[spanSize + 1]; // max length of the string happens for binary
|
||||
|
||||
if (format == vpiIntVal) {
|
||||
value_in.value.integer = intVal;
|
||||
|
@ -269,23 +272,20 @@ void _arr_access_format_check(TestVpiHandle ®_h, int wordSize, const int* low
|
|||
|
||||
vpi_get_value(subreg_h, &value_out);
|
||||
switch (format) {
|
||||
case vpiIntVal:
|
||||
TEST_CHECK_EQ(value_out.value.integer, value_in.value.integer);
|
||||
break;
|
||||
case vpiVectorVal:
|
||||
if (spanSize > 32)
|
||||
TEST_CHECK_EQ(value_out.value.vector[1].aval, value_in.value.vector[1].aval);
|
||||
TEST_CHECK_EQ(value_out.value.vector[0].aval, value_in.value.vector[0].aval);
|
||||
break;
|
||||
case vpiStringVal:
|
||||
TEST_CHECK_EQ(value_out.value.str[0], value_in.value.str[0] ? value_in.value.str[0] : ' ');
|
||||
break;
|
||||
case vpiBinStrVal:
|
||||
case vpiDecStrVal:
|
||||
case vpiHexStrVal:
|
||||
case vpiOctStrVal:
|
||||
TEST_CHECK_CSTR(value_out.value.str, value_in.value.str);
|
||||
break;
|
||||
case vpiIntVal: TEST_CHECK_EQ(value_out.value.integer, value_in.value.integer); break;
|
||||
case vpiVectorVal:
|
||||
if (spanSize > 32)
|
||||
TEST_CHECK_EQ(value_out.value.vector[1].aval, value_in.value.vector[1].aval);
|
||||
TEST_CHECK_EQ(value_out.value.vector[0].aval, value_in.value.vector[0].aval);
|
||||
break;
|
||||
case vpiStringVal:
|
||||
TEST_CHECK_EQ(value_out.value.str[0],
|
||||
value_in.value.str[0] ? value_in.value.str[0] : ' ');
|
||||
break;
|
||||
case vpiBinStrVal:
|
||||
case vpiDecStrVal:
|
||||
case vpiHexStrVal:
|
||||
case vpiOctStrVal: TEST_CHECK_CSTR(value_out.value.str, value_in.value.str); break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -298,22 +298,23 @@ void _arr_access_format_check(TestVpiHandle ®_h, int wordSize, const int* low
|
|||
std::default_random_engine rng;
|
||||
|
||||
void _arr_access_check(const char* name, int wordSize, const int* lows) {
|
||||
TestVpiHandle arr_h = vpi_handle_by_name(const_cast<PLI_BYTE8*>(TestSimulator::rooted(name)), NULL);
|
||||
TestVpiHandle arr_h
|
||||
= vpi_handle_by_name(const_cast<PLI_BYTE8*>(TestSimulator::rooted(name)), NULL);
|
||||
TEST_CHECK_NZ(arr_h);
|
||||
|
||||
std::uniform_int_distribution<uint64_t> rand64(
|
||||
std::numeric_limits<uint64_t>::min(),
|
||||
std::numeric_limits<uint64_t>::max()
|
||||
);
|
||||
std::uniform_int_distribution<uint64_t> rand64(std::numeric_limits<uint64_t>::min(),
|
||||
std::numeric_limits<uint64_t>::max());
|
||||
|
||||
char octVal_s[wordSize / 3 + 1];
|
||||
|
||||
// fill octVal_s with random octal digits
|
||||
if (wordSize < 64) {
|
||||
sprintf(octVal_s, "%0*" PRIo64, wordSize / 3, rand64(rng) % (static_cast<uint64_t>(1) << wordSize));
|
||||
sprintf(octVal_s, "%0*" PRIo64, wordSize / 3,
|
||||
rand64(rng) % (static_cast<uint64_t>(1) << wordSize));
|
||||
} else {
|
||||
sprintf(octVal_s, "%0*" PRIo64, 63 / 3, rand64(rng));
|
||||
sprintf(octVal_s + 63 / 3, "%0*" PRIo64, (wordSize - 63) / 3, rand64(rng) % (static_cast<uint64_t>(1) << (wordSize - 63)));
|
||||
sprintf(octVal_s + 63 / 3, "%0*" PRIo64, (wordSize - 63) / 3,
|
||||
rand64(rng) % (static_cast<uint64_t>(1) << (wordSize - 63)));
|
||||
}
|
||||
|
||||
// Assume that reading/writing to the "flattened" packed register is already tested,
|
||||
|
@ -355,14 +356,10 @@ struct params {
|
|||
};
|
||||
|
||||
void _multidim_check() {
|
||||
static struct params values[] = {
|
||||
{"arr_cdata", 6, {0, 1, 2, 3}},
|
||||
{"arr_sdata", 12, {4, 5, 6, 7}},
|
||||
{"arr_idata", 30, {8, 9, 10, 11}},
|
||||
{"arr_qdata", 60, {12, 13, 14, 15}},
|
||||
{"arr_wdata", 126, {16, 17, 18, 19}},
|
||||
{nullptr, 0, {0, 0, 0, 0}}
|
||||
};
|
||||
static struct params values[]
|
||||
= {{"arr_cdata", 6, {0, 1, 2, 3}}, {"arr_sdata", 12, {4, 5, 6, 7}},
|
||||
{"arr_idata", 30, {8, 9, 10, 11}}, {"arr_qdata", 60, {12, 13, 14, 15}},
|
||||
{"arr_wdata", 126, {16, 17, 18, 19}}, {nullptr, 0, {0, 0, 0, 0}}};
|
||||
struct params* value = values;
|
||||
while (value->name) {
|
||||
_arr_iter_check(value->name, value->wordSize, value->lows);
|
||||
|
@ -411,7 +408,7 @@ void (*vlog_startup_routines[])() = {vpi_compat_bootstrap, 0};
|
|||
int main(int argc, char** argv) {
|
||||
const std::unique_ptr<VerilatedContext> contextp{new VerilatedContext};
|
||||
|
||||
uint64_t sim_time = 1100; // TODO
|
||||
uint64_t sim_time = 1100; // TODO
|
||||
contextp->debug(0);
|
||||
contextp->commandArgs(argc, argv);
|
||||
|
||||
|
|
Loading…
Reference in New Issue