diff --git a/include/verilated_vpi.cpp b/include/verilated_vpi.cpp index 6554acba2..57087fa63 100644 --- a/include/verilated_vpi.cpp +++ b/include/verilated_vpi.cpp @@ -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(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; } diff --git a/test_regress/t/t_vpi_var.cpp b/test_regress/t/t_vpi_var.cpp index 364968244..10a0c75e8 100644 --- a/test_regress/t/t_vpi_var.cpp +++ b/test_regress/t/t_vpi_var.cpp @@ -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); diff --git a/test_regress/t/t_vpi_var.v b/test_regress/t/t_vpi_var.v index df59e4e89..66cd97c8b 100644 --- a/test_regress/t/t_vpi_var.v +++ b/test_regress/t/t_vpi_var.v @@ -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 diff --git a/test_regress/t/t_vpi_var2.v b/test_regress/t/t_vpi_var2.v index 14dd8f7f2..db78f8842 100644 --- a/test_regress/t/t_vpi_var2.v +++ b/test_regress/t/t_vpi_var2.v @@ -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 diff --git a/test_regress/t/t_vpi_var3.v b/test_regress/t/t_vpi_var3.v index e87bc8f68..c7442ecb3 100644 --- a/test_regress/t/t_vpi_var3.v +++ b/test_regress/t/t_vpi_var3.v @@ -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