Support multidimensional array access via VPI (#2812) (#5573)

This commit is contained in:
Krzysztof Starecki
2025-01-09 19:04:26 -05:00
committed by GitHub
parent 052812bb87
commit 69dce205d3
15 changed files with 1101 additions and 493 deletions
+14 -18
View File
@@ -3289,7 +3289,7 @@ uint32_t VerilatedVarProps::entSize() const VL_MT_SAFE {
case VLVT_UINT16: size = sizeof(SData); break;
case VLVT_UINT32: size = sizeof(IData); break;
case VLVT_UINT64: size = sizeof(QData); break;
case VLVT_WDATA: size = VL_WORDS_I(packed().elements()) * sizeof(IData); break;
case VLVT_WDATA: size = VL_WORDS_I(entBits()) * sizeof(IData); break;
default: size = 0; break; // LCOV_EXCL_LINE
}
return size;
@@ -3308,7 +3308,7 @@ void* VerilatedVarProps::datapAdjustIndex(void* datap, int dim, int indx) const
uint8_t* bytep = reinterpret_cast<uint8_t*>(datap);
// If on index 1 of a 2 index array, then each index 1 is index2sz*entsz
size_t slicesz = entSize();
for (int d = dim + 1; d <= m_udims; ++d) slicesz *= elements(d);
for (int d = dim + 1; d <= udims(); ++d) slicesz *= elements(d);
bytep += indxAdj * slicesz;
return bytep;
}
@@ -3369,32 +3369,28 @@ 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 dims, ...) 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), dims, isParam);
VerilatedVar var(namep, datap, vltype, static_cast<VerilatedVarFlags>(vlflags), udims, pdims, isParam);
va_list ap;
va_start(ap, dims);
for (int i = 0; i < dims; ++i) {
va_start(ap, pdims);
for (int i = 0; i < udims; ++i) {
const int msb = va_arg(ap, int);
const int lsb = va_arg(ap, int);
if (i == 0) {
var.m_packed.m_left = msb;
var.m_packed.m_right = lsb;
} else if (i >= 1 && i <= var.udims()) {
var.m_unpacked[i - 1].m_left = msb;
var.m_unpacked[i - 1].m_right = lsb;
} else {
// We could have a linked list of ranges, but really this whole thing needs
// to be generalized to support structs and unions, etc.
const std::string msg = "Unsupported multi-dimensional public varInsert: "s + namep;
VL_FATAL_MT(__FILE__, __LINE__, "", msg.c_str());
}
var.m_unpacked[i].m_left = msb;
var.m_unpacked[i].m_right = lsb;
}
for (int i = 0; i < pdims; ++i) {
const int msb = va_arg(ap, int);
const int lsb = va_arg(ap, int);
var.m_packed[i].m_left = msb;
var.m_packed[i].m_right = lsb;
}
va_end(ap);