Fix VPI access to multidimensional packed arrays with ascending indices (#7275)

This commit is contained in:
Christian Hecken 2026-03-18 04:30:05 +01:00 committed by GitHub
parent 3bb0ea63ad
commit 612d1611b6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 48 additions and 31 deletions

View File

@ -376,13 +376,14 @@ public:
m_entSize = varp->entSize();
m_varDatap = varp->datap();
}
explicit VerilatedVpioVar(const VerilatedVpioVar* varp)
: VerilatedVpioVarBase{varp} {
if (varp) {
m_entSize = varp->m_entSize;
m_varDatap = varp->m_varDatap;
m_index = varp->m_index;
m_partselBits = varp->m_partselBits;
explicit VerilatedVpioVar(const VerilatedVpioVar* vop)
: VerilatedVpioVarBase{vop} {
if (vop) {
m_entSize = vop->m_entSize;
m_varDatap = vop->m_varDatap;
m_index = vop->m_index;
m_partselBits = vop->m_partselBits;
m_bitOffset = vop->m_bitOffset;
// Not copying m_prevDatap, must be nullptr
}
}
@ -451,7 +452,8 @@ public:
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());
// Packed arrays are stored left-to-right, not high index to low index
ret->m_bitOffset += chunkSize * std::abs(index - get_range()->right());
return ret;
}

View File

@ -1288,28 +1288,37 @@ int _mon_check_multi_index() {
CHECK_RESULT_Z(vh_oob);
}
// Multiple packed dimensions: multi_packed is [15:0][7:0] multi_packed[2:0]
// Multiple packed dimensions: multi_packed is [0:15][0:3][7:0] multi_packed[2:0]
{
TestVpiHandle vh1 = vpi_handle_by_name((PLI_BYTE8*)"t.multi_packed[1]", nullptr);
CHECK_RESULT_NZ(vh1);
CHECK_RESULT(vpi_get(vpiSize, vh1), 128); // 16*8
CHECK_RESULT(vpi_get(vpiSize, vh1), 512); // 16*8*4
// Index into first packed dim
TestVpiHandle vh2 = vpi_handle_by_index(vh1, 2);
CHECK_RESULT_NZ(vh2);
CHECK_RESULT(vpi_get(vpiSize, vh2), 32); // 8*4
// Index into second packed dim -> 8-bit word
TestVpiHandle vh3 = vpi_handle_by_index(vh2, 2);
CHECK_RESULT_NZ(vh3);
CHECK_RESULT(vpi_get(vpiSize, vh3), 8);
vpi_get_value(vh3, &v);
CHECK_RESULT(v.value.integer, 74); // 1*64 + 2*4 + 2
// Further into bit level
TestVpiHandle vh4 = vpi_handle_by_index(vh3, 3);
CHECK_RESULT_NZ(vh4);
CHECK_RESULT(vpi_get(vpiSize, vh4), 1);
// Write last 32 bits of the packed vector in the specified unpacked dimension,
// i.e. the four 8-bit elements in multi_packed[1][3:0]
// i.e. the four 8-bit elements in multi_packed[1][15][0:3]
v.value.integer = 0xAABBCCDD;
vpi_put_value(vh1, &v, nullptr, vpiNoDelay);
// Index into first packed dim -> 8-bit sub-word
TestVpiHandle vh2 = vpi_handle_by_index(vh1, 2);
CHECK_RESULT_NZ(vh2);
CHECK_RESULT(vpi_get(vpiSize, vh2), 8);
// Further into bit level
TestVpiHandle vh3 = vpi_handle_by_index(vh2, 3);
CHECK_RESULT_NZ(vh3);
CHECK_RESULT(vpi_get(vpiSize, vh3), 1);
// Index into the last bits of the packed array and check value
TestVpiHandle vh_last = vpi_handle_by_index(vh1, 0);
// Index into the last element of the packed array and check value
TestVpiHandle vh_last
= vpi_handle_by_name((PLI_BYTE8*)"t.multi_packed[1][15][3]", nullptr);
CHECK_RESULT_NZ(vh_last);
vpi_get_value(vh_last, &v);
CHECK_RESULT(v.value.integer, 0xDD);

View File

@ -48,9 +48,9 @@ extern "C" int mon_check();
reg [7:0] mem_2d[3:0][7:0] /*verilator public_flat_rw */; // Descending indices
// verilator lint_off ASCRANGE
reg [0:95] mem_3d[0:1][1:0][0:1] /*verilator public_flat_rw */; // Mixed: asc, desc, asc
// verilator lint_on ASCRANGE
reg [15:0] [7:0] multi_packed[2:0] /*verilator public_flat_rw */;
reg [0:15][0:3][7:0] multi_packed[2:0] /*verilator public_flat_rw */;
// verilator lint_on ASCRANGE
reg unpacked_only[7:0];
reg [7:0] text_byte /*verilator public_flat_rw @(posedge clk) */;
@ -125,7 +125,9 @@ extern "C" int mon_check();
for (int i = 0; i < 3; i++) begin
for (int j = 0; j < 16; j++) begin
multi_packed[i][j] = 8'((i * 16) + j);
for (int k = 0; k < 4; k++) begin
multi_packed[i][j][k] = 8'(((i * 64) + (j * 4) + k));
end
end
end

View File

@ -63,10 +63,10 @@ extern "C" int mon_check();
reg [7:0] mem_2d[3:0][7:0]; // Descending indices
// verilator lint_off ASCRANGE
reg [0:95] mem_3d[0:1][1:0][0:1]; // Mixed: asc, desc, asc
// verilator lint_on ASCRANGE
// Signal with multiple packed dimensions
reg [15:0] [7:0] multi_packed[2:0];
reg [0:15][0:3][7:0] multi_packed[2:0];
// verilator lint_on ASCRANGE
reg unpacked_only[7:0];
/*verilator public_off*/
reg invisible2;
@ -143,7 +143,9 @@ extern "C" int mon_check();
for (int i = 0; i < 3; i++) begin
for (int j = 0; j < 16; j++) begin
multi_packed[i][j] = 8'((i * 16) + j);
for (int k = 0; k < 4; k++) begin
multi_packed[i][j][k] = 8'(((i * 64) + (j * 4) + k));
end
end
end

View File

@ -48,10 +48,10 @@ extern "C" int mon_check();
reg [7:0] mem_2d[3:0][7:0]; // Descending indices
// verilator lint_off ASCRANGE
reg [0:95] mem_3d[0:1][1:0][0:1]; // Mixed: asc, desc, asc
// verilator lint_on ASCRANGE
// Signal with multiple packed dimensions
reg [15:0] [7:0] multi_packed[2:0];
reg [0:15][0:3][7:0] multi_packed[2:0];
// verilator lint_on ASCRANGE
reg unpacked_only[7:0];
reg [7:0] text_byte;
@ -123,7 +123,9 @@ extern "C" int mon_check();
for (int i = 0; i < 3; i++) begin
for (int j = 0; j < 16; j++) begin
multi_packed[i][j] = 8'((i * 16) + j);
for (int k = 0; k < 4; k++) begin
multi_packed[i][j][k] = 8'(((i * 64) + (j * 4) + k));
end
end
end