diff --git a/include/verilated_vpi.cpp b/include/verilated_vpi.cpp index 0ca223349..6554acba2 100644 --- a/include/verilated_vpi.cpp +++ b/include/verilated_vpi.cpp @@ -2779,7 +2779,8 @@ VarAccessInfo vl_vpi_var_access_info(const VerilatedVpioVarBase* vop, size_t // make sure we're not trying to write outside var bounds assert(varBits > addOffset); - bitCount = std::min(bitCount, varBits - addOffset); + bitCount = std::min({wordBits, // For VLWide, varBits can exceed wordBits + bitCount, varBits - addOffset}); VarAccessInfo info; info.m_datap = reinterpret_cast(vop->varDatap()); diff --git a/test_regress/t/t_vpi_var.cpp b/test_regress/t/t_vpi_var.cpp index 9c1686c2d..364968244 100644 --- a/test_regress/t/t_vpi_var.cpp +++ b/test_regress/t/t_vpi_var.cpp @@ -1288,11 +1288,17 @@ int _mon_check_multi_index() { CHECK_RESULT_Z(vh_oob); } - // Multiple packed dimensions: multi_packed is [3:0][7:0] multi_packed[2:0] + // Multiple packed dimensions: multi_packed is [15:0][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), 32); // 4*8 + CHECK_RESULT(vpi_get(vpiSize, vh1), 128); // 16*8 + + // 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] + 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); @@ -1301,6 +1307,12 @@ int _mon_check_multi_index() { 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); + CHECK_RESULT_NZ(vh_last); + vpi_get_value(vh_last, &v); + CHECK_RESULT(v.value.integer, 0xDD); } // Partial indexing (not all unpacked dimensions) diff --git a/test_regress/t/t_vpi_var.v b/test_regress/t/t_vpi_var.v index 553371661..df59e4e89 100644 --- a/test_regress/t/t_vpi_var.v +++ b/test_regress/t/t_vpi_var.v @@ -50,7 +50,7 @@ extern "C" int mon_check(); reg [0:95] mem_3d[0:1][1:0][0:1] /*verilator public_flat_rw */; // Mixed: asc, desc, asc // verilator lint_on ASCRANGE - reg [3:0] [7:0] multi_packed[2:0] /*verilator public_flat_rw */; + reg [15:0] [7:0] multi_packed[2:0] /*verilator public_flat_rw */; reg unpacked_only[7:0]; reg [7:0] text_byte /*verilator public_flat_rw @(posedge clk) */; @@ -124,8 +124,8 @@ extern "C" int mon_check(); end for (int i = 0; i < 3; i++) begin - for (int j = 0; j < 4; j++) begin - multi_packed[i][j] = 8'((i * 4) + j); + for (int j = 0; j < 16; j++) begin + multi_packed[i][j] = 8'((i * 16) + j); end end diff --git a/test_regress/t/t_vpi_var2.v b/test_regress/t/t_vpi_var2.v index 5d1d0136d..14dd8f7f2 100644 --- a/test_regress/t/t_vpi_var2.v +++ b/test_regress/t/t_vpi_var2.v @@ -66,7 +66,7 @@ extern "C" int mon_check(); // verilator lint_on ASCRANGE // Signal with multiple packed dimensions - reg [3:0] [7:0] multi_packed[2:0]; + reg [15:0] [7:0] multi_packed[2:0]; reg unpacked_only[7:0]; /*verilator public_off*/ reg invisible2; @@ -142,8 +142,8 @@ extern "C" int mon_check(); end for (int i = 0; i < 3; i++) begin - for (int j = 0; j < 4; j++) begin - multi_packed[i][j] = 8'((i * 4) + j); + for (int j = 0; j < 16; j++) begin + multi_packed[i][j] = 8'((i * 16) + j); end end diff --git a/test_regress/t/t_vpi_var3.v b/test_regress/t/t_vpi_var3.v index 930c6c14e..e87bc8f68 100644 --- a/test_regress/t/t_vpi_var3.v +++ b/test_regress/t/t_vpi_var3.v @@ -51,7 +51,7 @@ extern "C" int mon_check(); // verilator lint_on ASCRANGE // Signal with multiple packed dimensions - reg [3:0] [7:0] multi_packed[2:0]; + reg [15:0] [7:0] multi_packed[2:0]; reg unpacked_only[7:0]; reg [7:0] text_byte; @@ -122,8 +122,8 @@ extern "C" int mon_check(); end for (int i = 0; i < 3; i++) begin - for (int j = 0; j < 4; j++) begin - multi_packed[i][j] = 8'((i * 4) + j); + for (int j = 0; j < 16; j++) begin + multi_packed[i][j] = 8'((i * 16) + j); end end