diff --git a/include/verilated_vpi.cpp b/include/verilated_vpi.cpp index 4bec98072..2aa4fccf6 100644 --- a/include/verilated_vpi.cpp +++ b/include/verilated_vpi.cpp @@ -2934,6 +2934,7 @@ void vl_get_value_array(vpiHandle object, p_vpi_arrayvalue arrayvalue_p, if (VL_UNCOVERABLE(num > size)) { VL_VPI_ERROR_(__FILE__, __LINE__, "%s: requested elements (%u) exceed array size (%u)", __func__, num, size); + return; } index -= vop->rangep()->low(); @@ -3217,8 +3218,6 @@ void vl_get_value_array(vpiHandle object, p_vpi_arrayvalue arrayvalue_p, return; } - arrayvalue_p->value.rawvals = nullptr; - VL_VPI_ERROR_(__FILE__, __LINE__, "%s: Unsupported format (%s) as requested for %s", __func__, VerilatedVpiError::strFromVpiVal(arrayvalue_p->format), vop->fullname()); } @@ -3234,20 +3233,17 @@ void vpi_get_value_array(vpiHandle object, p_vpi_arrayvalue arrayvalue_p, const VerilatedVpioVar* const vop = VerilatedVpioVar::castp(object); if (VL_UNLIKELY(!vop)) { VL_VPI_ERROR_(__FILE__, __LINE__, "%s: Unsupported vpiHandle (%p)", __func__, object); + return; } if (vop->type() != vpiRegArray) { VL_VPI_ERROR_(__FILE__, __LINE__, "%s: Unsupported type (%p, %s)", __func__, object, VerilatedVpiError::strFromVpiObjType(vop->type())); + return; } const VerilatedVar* const varp = vop->varp(); - if (varp->dims() != 2) { - VL_VPI_ERROR_(__FILE__, __LINE__, "%s: object %s has unsupported number of indices (%d)", - __func__, vop->fullname(), varp->dims()); - } - if (VL_UNLIKELY(!vop->rangep())) return; int lowRange = vop->rangep()->low(); @@ -3256,11 +3252,13 @@ void vpi_get_value_array(vpiHandle object, p_vpi_arrayvalue arrayvalue_p, if ((index_p[0] > highRange) || (index_p[0] < lowRange)) { VL_VPI_ERROR_(__FILE__, __LINE__, "%s: index %u for object %s is out of bounds [%u,%u]", __func__, index_p[0], vop->fullname(), lowRange, highRange); + return; } if (arrayvalue_p->flags & vpiUserAllocFlag) { VL_VPI_ERROR_(__FILE__, __LINE__, "%s: Unsupported vpiUserAllocFlag (%x)", __func__, arrayvalue_p->flags); + return; } vl_get_value_array(object, arrayvalue_p, index_p, num); @@ -3299,6 +3297,7 @@ void vl_put_value_array(vpiHandle object, p_vpi_arrayvalue arrayvalue_p, if (VL_UNCOVERABLE(num > size)) { VL_VPI_ERROR_(__FILE__, __LINE__, "%s: requested elements to set (%u) exceed array size (%u)", __func__, num, size); + return; } @@ -3482,35 +3481,34 @@ void vpi_put_value_array(vpiHandle object, p_vpi_arrayvalue arrayvalue_p, PLI_INT32* index_p, PLI_UINT32 num) { VL_DEBUG_IF_PLI(VL_DBG_MSGF("- vpi: vpi_put_value_array %p\n", object);); VerilatedVpiImp::assertOneCheck(); - VL_VPI_ERROR_RESET_(); - if (VL_UNLIKELY(!object)) return; + + if(VL_UNLIKELY(!arrayvalue_p)){ + VL_VPI_WARNING_(__FILE__, __LINE__, "Ignoring vpi_put_value_array with nullptr value pointer"); + return; + } const VerilatedVpioVar* const vop = VerilatedVpioVar::castp(object); if (VL_UNLIKELY(!vop)) { VL_VPI_ERROR_(__FILE__, __LINE__, "%s: Unsupported vpiHandle (%p)", __func__, object); + return; } if (vop->type() != vpiRegArray) { VL_VPI_ERROR_(__FILE__, __LINE__, "%s: Unsupported type (%p, %s)", __func__, object, VerilatedVpiError::strFromVpiObjType(vop->type())); + return; } const VerilatedVar* const varp = vop->varp(); - if (varp->dims() != 2) { - VL_VPI_ERROR_(__FILE__, __LINE__, "%s: object %s has unsupported number of indices (%d)", - __func__, vop->fullname(), varp->dims()); - } + int lowRange = vop->rangep()->low(); + int highRange = vop->rangep()->high(); - if (VL_UNLIKELY(!vop->rangep())) return; - - int minRange = std::min(vop->rangep()->left(), vop->rangep()->right()); - int maxRange = std::max(vop->rangep()->left(), vop->rangep()->right()); - - if ((index_p[0] > maxRange) || (index_p[0] < minRange)) { + if ((index_p[0] > highRange) || (index_p[0] < lowRange)) { VL_VPI_ERROR_(__FILE__, __LINE__, "%s: index %u for object %s is out of bounds [%u,%u]", - __func__, index_p[0], vop->fullname(), minRange, maxRange); + __func__, index_p[0], vop->fullname(), lowRange, highRange); + return; } if (VL_UNLIKELY(!vop->varp()->isPublicRW())) { @@ -3518,11 +3516,13 @@ void vpi_put_value_array(vpiHandle object, p_vpi_arrayvalue arrayvalue_p, "Ignoring vpi_put_value_array to signal marked read-only," " use public_flat_rw instead: %s", vop->fullname()); + return; } - if (arrayvalue_p->flags & ~(vpiPropagateOff | vpiOneValue | vpiNoDelay)) { + if (arrayvalue_p->flags & (vpiPropagateOff | vpiOneValue)) { VL_VPI_ERROR_(__FILE__, __LINE__, "%s: Unsupported flags (%x)", __func__, arrayvalue_p->flags); + return; } vl_put_value_array(object, arrayvalue_p, index_p, num); diff --git a/test_regress/t/t_vpi_get_value_array.cpp b/test_regress/t/t_vpi_get_value_array.cpp index 2843d64fa..b6b2cbc8a 100644 --- a/test_regress/t/t_vpi_get_value_array.cpp +++ b/test_regress/t/t_vpi_get_value_array.cpp @@ -216,6 +216,7 @@ int mon_check_props(void) { } { + // test unsupported format vpiHandle object = vpi_handle_by_name((PLI_BYTE8*)"TOP.test.read_longs", NULL); CHECK_RESULT_NZ(object); @@ -227,6 +228,7 @@ int mon_check_props(void) { } { + // test unsupported foramt vpiHandle object = vpi_handle_by_name((PLI_BYTE8*)"TOP.test.read_words", NULL); CHECK_RESULT_NZ(object); @@ -238,6 +240,7 @@ int mon_check_props(void) { } { + // test unsupported format vpiHandle object = vpi_handle_by_name((PLI_BYTE8*)"TOP.test.read_longs", NULL); CHECK_RESULT_NZ(object); @@ -248,6 +251,83 @@ int mon_check_props(void) { CHECK_RESULT_NZ(vpi_chk_error(nullptr)); } + { + // test unsupported vpiHandle + vpiHandle object = vpi_handle_by_name((PLI_BYTE8*)"TOP.test",NULL); + CHECK_RESULT_NZ(object); + + arrayVal.format = vpiIntVal; + + PLI_INT32 indexp[1] = {0}; + vpi_get_value_array(object, &arrayVal, indexp, num); + CHECK_RESULT_NZ(vpi_chk_error(nullptr)); + } + + { + // test unsupported type + vpiHandle object = vpi_handle_by_name((PLI_BYTE8*)"TOP.test.read_scalar",NULL); + CHECK_RESULT_NZ(object); + + arrayVal.format = vpiIntVal; + + PLI_INT32 indexp[1] = {0}; + vpi_get_value_array(object, &arrayVal, indexp, num); + CHECK_RESULT_NZ(vpi_chk_error(nullptr)); + } + + { + // test indexp out of bounds + vpiHandle object = vpi_handle_by_name((PLI_BYTE8*)"TOP.test.read_bounds",NULL); + CHECK_RESULT_NZ(object); + + arrayVal.format = vpiIntVal; + + PLI_INT32 indexp[1] = {4}; + vpi_get_value_array(object, &arrayVal, indexp, num); + CHECK_RESULT_NZ(vpi_chk_error(nullptr)); + + indexp[1] = {0}; + vpi_get_value_array(object, &arrayVal, indexp, num); + CHECK_RESULT_NZ(vpi_chk_error(nullptr)); + } + + { + // test unsupported flags + vpiHandle object = vpi_handle_by_name((PLI_BYTE8*)"TOP.test.read_words",NULL); + CHECK_RESULT_NZ(object); + + s_vpi_arrayvalue arrayvalue = {vpiIntVal,vpiUserAllocFlag,0}; + + PLI_INT32 indexp[1] = {0}; + vpi_get_value_array(object, &arrayvalue, indexp, num); + CHECK_RESULT_NZ(vpi_chk_error(nullptr)); + arrayVal.flags = 0; + } + + { + // test unsupported format & vltype combination + vpiHandle object = vpi_handle_by_name((PLI_BYTE8*)"TOP.test.read_words",NULL); + CHECK_RESULT_NZ(object); + + s_vpi_arrayvalue arrayvalue = {vpiShortIntVal,0,0}; + PLI_INT32 indexp[1] = {0}; + + vpi_get_value_array(object, &arrayvalue, indexp, num); + CHECK_RESULT_NZ(vpi_chk_error(nullptr)); + } + + { + // test num out of bounds + vpiHandle object = vpi_handle_by_name((PLI_BYTE8*)"TOP.test.read_words",NULL); + CHECK_RESULT_NZ(object); + + s_vpi_arrayvalue arrayvalue = {vpiIntVal,0,0}; + PLI_INT32 indexp[1] = {0}; + + vpi_get_value_array(object, &arrayvalue, indexp, 5); + CHECK_RESULT_NZ(vpi_chk_error(nullptr)); + } + return 0; } @@ -272,7 +352,7 @@ int main(int argc, char** argv) { VerilatedVpi::callValueCbs(); } - return 0;//TODO + return 0; } #endif diff --git a/test_regress/t/t_vpi_get_value_array.v b/test_regress/t/t_vpi_get_value_array.v index 5b385a132..daa23be61 100644 --- a/test_regress/t/t_vpi_get_value_array.v +++ b/test_regress/t/t_vpi_get_value_array.v @@ -31,6 +31,8 @@ extern "C" int mon_check(); reg [63:0] read_longs [0:3] `PUBLIC_FLAT_RD; reg [127:0] read_quads [0:3] `PUBLIC_FLAT_RD; integer read_integers [0:3] `PUBLIC_FLAT_RD; + reg [7:0] read_scalar `PUBLIC_FLAT_RD; + reg [7:0] read_bounds [1:3] `PUBLIC_FLAT_RD; integer status; diff --git a/test_regress/t/t_vpi_put_value_array.cpp b/test_regress/t/t_vpi_put_value_array.cpp index 0bb94238d..cce30b58c 100644 --- a/test_regress/t/t_vpi_put_value_array.cpp +++ b/test_regress/t/t_vpi_put_value_array.cpp @@ -243,6 +243,7 @@ int mon_check_props(void) { } { + // test unsupported format vpiHandle object = vpi_handle_by_name((PLI_BYTE8*)"TOP.test.write_longs", NULL); CHECK_RESULT_NZ(object); @@ -254,6 +255,7 @@ int mon_check_props(void) { } { + // test unsupported format vpiHandle object = vpi_handle_by_name((PLI_BYTE8*)"TOP.test.write_words", NULL); CHECK_RESULT_NZ(object); @@ -265,6 +267,7 @@ int mon_check_props(void) { } { + // test unsupported format vpiHandle object = vpi_handle_by_name((PLI_BYTE8*)"TOP.test.write_longs", NULL); CHECK_RESULT_NZ(object); @@ -275,6 +278,120 @@ int mon_check_props(void) { CHECK_RESULT_NZ(vpi_chk_error(nullptr)); } + { + // test null array value + vpiHandle object = vpi_handle_by_name((PLI_BYTE8*)"TOP.test.write_words", NULL); + CHECK_RESULT_NZ(object); + + PLI_INT32 indexp[1] = {0}; + + vpi_put_value_array(object, nullptr, indexp, num); + CHECK_RESULT_NZ(vpi_chk_error(nullptr)); + } + + { + // test unsupported vpiHandle + vpiHandle object = vpi_handle_by_name((PLI_BYTE8*)"TOP.test", NULL); + CHECK_RESULT_NZ(object); + + int datap[4] = {0,0,0,0}; + s_vpi_arrayvalue arrayvalue = {vpiIntVal,0,datap}; + PLI_INT32 indexp[1] = {0}; + + vpi_put_value_array(object, &arrayvalue, indexp, num); + CHECK_RESULT_NZ(vpi_chk_error(nullptr)); + } + + { + // test unsupported type + vpiHandle object = vpi_handle_by_name((PLI_BYTE8*)"TOP.test.write_scalar", NULL); + CHECK_RESULT_NZ(object); + + int datap[4] = {0,0,0,0}; + s_vpi_arrayvalue arrayvalue = {vpiIntVal,0,datap}; + PLI_INT32 indexp[1] = {0}; + + vpi_put_value_array(object, &arrayvalue, indexp, num); + CHECK_RESULT_NZ(vpi_chk_error(nullptr)); + } + + { + // test index out of bounds + vpiHandle object = vpi_handle_by_name((PLI_BYTE8*)"TOP.test.write_bounds", NULL); + CHECK_RESULT_NZ(object); + + int datap[4] = {0,0,0,0}; + s_vpi_arrayvalue arrayvalue = {vpiIntVal,0,datap}; + PLI_INT32 indexp[1] = {0}; + + vpi_put_value_array(object, &arrayvalue, indexp, num); + CHECK_RESULT_NZ(vpi_chk_error(nullptr)); + + indexp[0] = {4}; + vpi_put_value_array(object, &arrayvalue, indexp, num); + CHECK_RESULT_NZ(vpi_chk_error(nullptr)); + } + + { + // test inaccessible + vpiHandle object = vpi_handle_by_name((PLI_BYTE8*)"TOP.test.write_inaccessible", NULL); + CHECK_RESULT_NZ(object); + + int datap[4] = {0,0,0,0}; + s_vpi_arrayvalue arrayvalue = {vpiIntVal,0,datap}; + PLI_INT32 indexp[1] = {0}; + + vpi_put_value_array(object, &arrayvalue, indexp, num); + CHECK_RESULT_NZ(vpi_chk_error(nullptr)); + } + + { + // test unsupported flags + vpiHandle object = vpi_handle_by_name((PLI_BYTE8*)"TOP.test.write_words", NULL); + CHECK_RESULT_NZ(object); + + int datap[4] = {0,0,0,0}; + s_vpi_arrayvalue arrayvalue = {vpiIntVal,vpiPropagateOff,datap}; + PLI_INT32 indexp[1] = {0}; + + vpi_put_value_array(object, &arrayvalue, indexp, num); + CHECK_RESULT_NZ(vpi_chk_error(nullptr)); + + arrayvalue.flags = vpiOneValue; + vpi_put_value_array(object, &arrayvalue, indexp, num); + CHECK_RESULT_NZ(vpi_chk_error(nullptr)); + } + + { + // test unsupported format & type combination + vpiHandle object = vpi_handle_by_name((PLI_BYTE8*)"TOP.test.write_words", NULL); + CHECK_RESULT_NZ(object); + + int datap[4] = {0,0,0,0}; + s_vpi_arrayvalue arrayvalue = {vpiShortIntVal,0,datap}; + PLI_INT32 indexp[1] = {0}; + + vpi_put_value_array(object, &arrayvalue, indexp, num); + CHECK_RESULT_NZ(vpi_chk_error(nullptr)); + + arrayvalue.flags = vpiOneValue; + vpi_put_value_array(object, &arrayvalue, indexp, num); + CHECK_RESULT_NZ(vpi_chk_error(nullptr)); + } + + { + // test num out of bounds + vpiHandle object = vpi_handle_by_name((PLI_BYTE8*)"TOP.test.write_words", NULL); + CHECK_RESULT_NZ(object); + + int datap[4] = {0,0,0,0}; + s_vpi_arrayvalue arrayvalue = {vpiIntVal,0,datap}; + PLI_INT32 indexp[1] = {0}; + + vpi_put_value_array(object, &arrayvalue, indexp, 5); + CHECK_RESULT_NZ(vpi_chk_error(nullptr)); + } + return 0; } diff --git a/test_regress/t/t_vpi_put_value_array.v b/test_regress/t/t_vpi_put_value_array.v index e2168122e..bfa6bfc0c 100644 --- a/test_regress/t/t_vpi_put_value_array.v +++ b/test_regress/t/t_vpi_put_value_array.v @@ -29,7 +29,9 @@ extern "C" int mon_check(); reg [63:0] write_longs [0:3] `PUBLIC_FLAT_RW; reg [127:0] write_quads [0:3] `PUBLIC_FLAT_RW; integer write_integers [0:3] `PUBLIC_FLAT_RW; - // real write_reals [0:3] `PUBLIC_FLAT_RW; //unsupported + reg [7:0] write_scalar `PUBLIC_FLAT_RW; + reg [7:0] write_bounds [1:3] `PUBLIC_FLAT_RW; + reg [7:0] write_inaccessible [0:3] `PUBLIC_FLAT_RD; integer status;