Internals: Cleanup some VPI messages and fix test coverage

This commit is contained in:
Wilson Snyder 2026-08-14 19:47:45 -04:00
parent edd4cd4faf
commit d6b206cc7d
29 changed files with 213 additions and 151 deletions

View File

@ -2489,7 +2489,7 @@ vpiHandle vpi_register_cb(p_cb_data cb_data_p) {
return vop->castVpiHandle();
}
default:
VL_VPI_WARNING_(__FILE__, __LINE__, "%s: Unsupported callback type %s", __func__,
VL_VPI_WARNING_(__FILE__, __LINE__, "%s: Unsupported callback type '%s'", __func__,
VerilatedVpiError::strFromVpiCallbackReason(reason));
return nullptr;
}
@ -2935,7 +2935,7 @@ vpiHandle vpi_handle(PLI_INT32 type, vpiHandle object) {
return (new VerilatedVpioConst{vop->rangep()->left()})->castVpiHandle();
}
VL_VPI_WARNING_(__FILE__, __LINE__,
"%s: Unsupported vpiHandle (%p) for type %s, nothing will be returned",
"%s: Unsupported vpiHandle '%p' for type '%s', nothing will be returned",
__func__, object, VerilatedVpiError::strFromVpiMethod(type));
return nullptr;
}
@ -2949,7 +2949,7 @@ vpiHandle vpi_handle(PLI_INT32 type, vpiHandle object) {
return (new VerilatedVpioConst{vop->rangep()->right()})->castVpiHandle();
}
VL_VPI_WARNING_(__FILE__, __LINE__,
"%s: Unsupported vpiHandle (%p) for type %s, nothing will be returned",
"%s: Unsupported vpiHandle '%p' for type '%s', nothing will be returned",
__func__, object, VerilatedVpiError::strFromVpiMethod(type));
return nullptr;
}
@ -3110,8 +3110,9 @@ PLI_INT32 vpi_get(PLI_INT32 property, vpiHandle object) {
[[fallthrough]];
}
default:
VL_VPI_ERROR_(__FILE__, __LINE__, "%s: Unsupported property %s, nothing will be returned",
__func__, VerilatedVpiError::strFromVpiProp(property));
VL_VPI_ERROR_(__FILE__, __LINE__,
"%s: Unsupported property '%s', nothing will be returned", __func__,
VerilatedVpiError::strFromVpiProp(property));
return vpiUndefined;
}
}
@ -3577,7 +3578,7 @@ void vpi_get_value(vpiHandle object, p_vpi_value valuep) {
VerilatedVpiError::strFromVpiVal(valuep->format), vop->fullname());
return;
}
VL_VPI_ERROR_(__FILE__, __LINE__, "%s: Unsupported vpiHandle (%p)", __func__, object);
VL_VPI_ERROR_(__FILE__, __LINE__, "%s: Unsupported vpiHandle '%p'", __func__, object);
}
vpiHandle vpi_put_value(vpiHandle object, p_vpi_value valuep, p_vpi_time /*time_p*/,
@ -3918,7 +3919,7 @@ vpiHandle vpi_put_value(vpiHandle object, p_vpi_value valuep, p_vpi_time /*time_
__func__, vop->fullname());
return nullptr;
}
VL_VPI_ERROR_(__FILE__, __LINE__, "%s: Unsupported vpiHandle (%p)", __func__, object);
VL_VPI_ERROR_(__FILE__, __LINE__, "%s: Unsupported vpiHandle '%p'", __func__, object);
return nullptr;
}
@ -4313,13 +4314,13 @@ void vpi_get_value_array(vpiHandle object, p_vpi_arrayvalue arrayvalue_p, PLI_IN
const VerilatedVpioVar* const vop = VerilatedVpioVar::castp(object);
if (VL_UNLIKELY(!vop)) {
VL_VPI_ERROR_(__FILE__, __LINE__, "%s: Unsupported vpiHandle (%p)", __func__, object);
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()));
VL_VPI_ERROR_(__FILE__, __LINE__, "%s: Unsupported type '%s' for '%s'", __func__,
VerilatedVpiError::strFromVpiObjType(vop->type()), vop->name());
return;
}
@ -4495,13 +4496,13 @@ void vpi_put_value_array(vpiHandle object, p_vpi_arrayvalue arrayvalue_p, PLI_IN
const VerilatedVpioVar* const vop = VerilatedVpioVar::castp(object);
if (VL_UNLIKELY(!vop)) {
VL_VPI_ERROR_(__FILE__, __LINE__, "%s: Unsupported vpiHandle (%p)", __func__, object);
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()));
VL_VPI_ERROR_(__FILE__, __LINE__, "%s: Unsupported vpiHandle type '%s' for '%s'", __func__,
VerilatedVpiError::strFromVpiObjType(vop->type()), vop->name());
return;
}

View File

@ -2523,6 +2523,7 @@ class VlTest:
line = re.sub(r'CPU Time: +[0-9.]+ seconds[^\n]+', 'CPU Time: ###', line)
line = re.sub(r'\?v=[0-9.]+', '?v=latest', line) # warning URL
line = re.sub(r'_h[0-9a-f]{8}_', '_h########_', line)
line = re.sub(r'vpiHandle \'0x[0-9a-f]+\'', 'vpiHandle \'0x#\'', line)
# Avoid absolute paths
line = re.sub(r'%Error: /[^: ]+/([^/:])', r'%Error: .../\1', line)
line = re.sub(r'("file://)/[^: ]+/([^/:])', r'\1/.../\2', line)

View File

@ -12,6 +12,9 @@
#ifndef TEST_CHECK_H_
#define TEST_CHECK_H_
#include "sv_vpi_user.h"
#include "vpi_user.h"
#include <iostream>
extern int errors;
@ -84,6 +87,15 @@ static const bool verbose = false;
} \
} while (0)
inline bool _test_check_error() {
t_vpi_error_info errorInfo{};
const PLI_INT32 gotError = vpi_chk_error(&errorInfo);
if (gotError) vpi_printf((PLI_BYTE8*)"vpi_chk_error: %s\n", errorInfo.message);
return gotError;
}
#define TEST_CHECK_ERROR(expectError) TEST_CHECK_HEX_EQ(_test_check_error(), expectError)
//======================================================================
#define TEST_VERBOSE_PRINTF(format, ...) \

View File

@ -28,49 +28,25 @@ for s in [
'Syntax error: Range \':\', \'+:\' etc are not allowed in the instance', # Instead get syntax error
'dynamic new() not expected in this context (expected under an assign)', # Instead get syntax error
'exited with', # Is hit; driver.py filters out
'expected non-complex non-double', # V3Width warns and repairs earlier
'loading non-variable', # Instead 'storing to parameter' or syntax error
# Tested in t_vpi_force.cpp, but not picked up by pattern matching in this script yet
'%s: Trailing garbage \'%s\' in \'%s\' as value %s for \'%s\'',
'%s: Non hex character \'%c\' in \'%s\' as value %s for \'%s\'',
'%s: Non octal character \'%c\' in \'%s\' as value %s for \'%s\'',
# Not yet analyzed
'--pipe-filter protocol error, unexpected:',
'--pipe-filter returned bad status',
'--pipe-filter: stdin/stdout closed before pipe opened',
'--pipe-filter: write to closed file',
'Assigning >32 bit to unranged parameter (defaults to 32 bits)',
'Assignment pattern with no members',
'%s: Ignoring vpi_put_value to vpiConstant \'%s\'',
'%s: Ignoring vpi_put_value to vpiParameter \'%s\'',
'%s: Index %u for object \'%s\' is out of bounds [%u,%u]',
'%s: Parsing failed for \'%s\' as value %s for \'%s\'',
'%s: Requested elements (%u) exceed array size (%u)',
'%s: Requested elements to set (%u) exceed array size (%u)',
'%s: Unsupported callback type %s',
'%s: Unsupported flags (%x)',
'%s: Unsupported format (%s) as requested for \'%s\'',
'%s: Unsupported format (%s) for \'%s\'',
'%s: Unsupported p_vpi_value as requested for \'%s\' with vpiInertialDelay',
'%s: Unsupported property %s, nothing will be returned',
'%s: Unsupported callback type \'%s\'',
'%s: Unsupported type %s, ignoring',
'%s: Unsupported type %s, nothing will be returned',
'%s: Unsupported type (%d)',
'%s: Unsupported type (%p, %s)',
'%s: Unsupported vltype (%d)',
'%s: Unsupported vpiHandle (%p)',
'%s: Unsupported vpiHandle (%p) for type %s, nothing will be returned',
'%s: Unsupported vpiUserAllocFlag (%x)',
'%s: Unsupported vpiHandle \'%p\' for type \'%s\', nothing will be returned',
'%s: VPI callback data pointer is null',
'Assigning >32 bit to unranged parameter (defaults to 32 bits)',
'Assignment pattern with no members',
'Ignoring vpi_get_time with nullptr value pointer',
'Ignoring vpi_get_value_array with null index pointer',
'Ignoring vpi_get_value_array with null value pointer',
'Ignoring vpi_put_value with nullptr value pointer',
'Ignoring vpi_put_value_array to signal marked read-only,',
'Ignoring vpi_put_value_array with null index pointer',
'Ignoring vpi_put_value_array with null value pointer',
'vpi_put_value was used on signal marked read-only,',
'Can\'t find varpin scope of',
'Can\'t read annotation file:',
'Can\'t resolve module reference: \'',
@ -143,7 +119,6 @@ for s in [
'Unsupported: static cast to',
'Unsupported: super',
'Unsupported: with[] stream expression',
'expected non-complex non-double',
'loading other than unpacked-array variable',
'loading other than unpacked/associative-array variable',
# These are safety limits requiring >1000 bins or >10000 members to trigger

View File

@ -32,9 +32,12 @@
#include <iostream>
// These require the above. Comment prevents clang-format moving them
#include "TestCheck.h"
#include "TestSimulator.h"
#include "TestVpi.h"
int errors = 0;
extern "C" {
int mon_check() {
#ifdef TEST_VERBOSE
@ -74,10 +77,10 @@ int mon_check() {
vpi_value.format = vpiIntVal;
vpi_value.value.integer = 1;
vpi_put_value(sigHandle, &vpi_value, NULL, vpiNoDelay);
CHECK_RESULT(vpi_chk_error(nullptr), vpiError);
TEST_CHECK_ERROR(true);
// and an intertial write
vpi_put_value(sigHandle, &vpi_value, NULL, vpiInertialDelay);
CHECK_RESULT(vpi_chk_error(nullptr), vpiError);
TEST_CHECK_ERROR(true);
// t.signal_rw is not constant
sigHandle = vpi_handle_by_name((PLI_BYTE8*)"t.signal_rw", NULL);
@ -98,7 +101,7 @@ int mon_check() {
PLI_INT32 timeConstType = vpi_get(vpiConstType, timeHandle);
CHECK_RESULT(timeConstType, vpiDecConst)
return 0; // Ok
return errors; // Ok
}
}
//======================================================================

View File

@ -0,0 +1,3 @@
vpi_chk_error: vpi_put_value was used on signal marked read-only, use public_flat_rw instead for 't.signal_rd'
vpi_chk_error: vpi_put_value was used on signal marked read-only, use public_flat_rw instead for 't.signal_rd'
*-* All Finished *-*

View File

@ -16,6 +16,6 @@ test.compile(make_top_shell=False,
make_pli=True,
verilator_flags2=["--exe --vpi --no-l2name", test.pli_filename])
test.execute(use_libvpi=True)
test.execute(use_libvpi=True, expect_filename=test.golden_filename)
test.passes()

View File

@ -20,6 +20,8 @@
#include <algorithm>
#include <memory> // For std::unique_ptr
int errors = 0;
namespace {
constexpr int maxAllowedErrorLevel = vpiWarning;
@ -705,6 +707,8 @@ int expectVpiPutError(const std::string& signalName, s_vpi_value value_s, const
const std::string receivedErrorMessage = receivedError.first;
CHECK_RESULT_NZ(errorOccurred); // NOLINT(concurrency-mt-unsafe)
VL_PRINTF("vpi_chk_error: %s\n", receivedErrorMessage.c_str());
// NOLINTNEXTLINE(concurrency-mt-unsafe,performance-avoid-endl)
CHECK_RESULT(receivedErrorMessage, expectedErrorMessage);
return 0;

View File

@ -0,0 +1,9 @@
vpi_chk_error: vpi_put_value used with vpiForceFlag on non-forceable signal 't.test.str1'
vpi_chk_error: vpi_put_value: Non octal character 'A' in '123A' as value vpiOctStrVal for 't.test.octString__VforceVal'
vpi_chk_error: vpi_put_value: Parsing failed for 'A123' as value vpiDecStrVal for 't.test.decStringC__VforceVal'
vpi_chk_error: vpi_put_value: Trailing garbage 'A' in '123A' as value vpiDecStrVal for 't.test.decStringC__VforceVal'
vpi_chk_error: vpi_put_value: Non hex character 'G' in '12AG' as value vpiHexStrVal for 't.test.hexString__VforceVal'
vpi_chk_error: vl_check_format: Unsupported format (vpiRawFourStateVal) for 't.test.onebit'
vpi_chk_error: vpi_put_value: Unsupported format (vpiSuppressVal) as requested for 't.test.onebit__VforceVal'
vpi_chk_error: vpi_put_value: Unsupported p_vpi_value as requested for 't.test.onebit' with vpiInertialDelay
*-* All Finished *-*

View File

@ -25,6 +25,9 @@ test.compile(
],
v_flags2=["+define+USE_VPI_NOT_DPI"])
test.execute(xrun_flags2=["+define+USE_VPI_NOT_DPI"], use_libvpi=True, check_finished=True)
test.execute(xrun_flags2=["+define+USE_VPI_NOT_DPI"],
use_libvpi=True,
check_finished=True,
expect_filename=test.golden_filename)
test.passes()

View File

@ -13,10 +13,13 @@
#include "verilated.h"
#include "TestCheck.h"
#include "TestSimulator.h" // For is_verilator()
#include "TestVpi.h" // For CHECK_RESULT_NZ
#include "vpi_user.h"
int errors = 0;
extern "C" int forceValue(void) {
if (!TestSimulator::is_verilator()) {
#ifdef VERILATOR
@ -33,10 +36,9 @@ extern "C" int forceValue(void) {
value_s.format = vpiIntVal;
value_s.value.integer = 0;
vpi_put_value(signal, &value_s, nullptr, vpiForceFlag);
// NOLINTNEXTLINE(concurrency-mt-unsafe);
CHECK_RESULT_Z(vpi_chk_error(nullptr))
TEST_CHECK_ERROR(false);
return 0;
return errors;
}
#ifdef IS_VPI

View File

@ -0,0 +1,2 @@
SOMESTRING = foo
*-* All Finished *-*

View File

@ -18,6 +18,6 @@ test.compile(make_top_shell=False,
iv_flags2=["-g2005-sv -D USE_VPI_NOT_DPI"],
v_flags2=["+define+USE_VPI_NOT_DPI +define+VERILATOR_COMMENTS"])
test.execute(use_libvpi=True)
test.execute(use_libvpi=True, expect_filename=test.golden_filename)
test.passes()

View File

@ -19,11 +19,14 @@
#endif
// These require the above. Comment prevents clang-format moving them
#include "TestCheck.h"
#include "TestSimulator.h"
#include "TestVpi.h"
#include <vector>
int errors = 0;
//======================================================================
int test_vpiRawFourStateVal(char* name, PLI_BYTE8* test_data, int index, const unsigned low,
@ -46,7 +49,7 @@ int test_vpiRawFourStateVal(char* name, PLI_BYTE8* test_data, int index, const u
arrayvalue.flags = 0;
arrayvalue.value.vectors = 0;
vpi_get_value_array(arrayhandle, &arrayvalue, index_arr, num);
CHECK_RESULT_NZ(!vpi_chk_error(0));
TEST_CHECK_ERROR(false);
// compare to test data
index -= low;
@ -87,7 +90,7 @@ int test_vpiRawTwoStateVal(char* name, PLI_BYTE8* test_data, int index, const un
arrayvalue.flags = 0;
arrayvalue.value.vectors = 0;
vpi_get_value_array(arrayhandle, &arrayvalue, index_arr, num);
CHECK_RESULT_NZ(!vpi_chk_error(0));
TEST_CHECK_ERROR(false);
// compare to test data
index -= low;
@ -142,7 +145,7 @@ int test_vpiVectorVal(char* name, PLI_BYTE8* test_data, int index, const unsigne
arrayvalue.flags = 0;
arrayvalue.value.vectors = 0;
vpi_get_value_array(arrayhandle, &arrayvalue, index_arr, num);
CHECK_RESULT_NZ(!vpi_chk_error(0));
TEST_CHECK_ERROR(false);
#ifdef TEST_VERBOSE
for (unsigned i = 0; i < vec_size; i++) {
@ -198,7 +201,7 @@ int test_vpiIntVal(char* name, PLI_BYTE8* test_data, int index, const unsigned l
arrayvalue.flags = 0;
arrayvalue.value.integers = 0;
vpi_get_value_array(arrayhandle, &arrayvalue, index_arr, num);
CHECK_RESULT_NZ(!vpi_chk_error(0));
TEST_CHECK_ERROR(false);
#ifdef TEST_VERBOSE
for (unsigned i = 0; i < size; i++) {
@ -250,7 +253,7 @@ int test_vpiShortIntVal(char* name, PLI_BYTE8* test_data, int index, const unsig
arrayvalue.flags = 0;
arrayvalue.value.shortints = 0;
vpi_get_value_array(arrayhandle, &arrayvalue, index_arr, num);
CHECK_RESULT_NZ(!vpi_chk_error(0));
TEST_CHECK_ERROR(false);
#ifdef TEST_VERBOSE
for (unsigned i = 0; i < size; i++) {
@ -301,7 +304,7 @@ int test_vpiLongIntVal(char* name, PLI_BYTE8* test_data, int index, const unsign
arrayvalue.flags = 0;
arrayvalue.value.longints = 0;
vpi_get_value_array(arrayhandle, &arrayvalue, index_arr, num);
CHECK_RESULT_NZ(!vpi_chk_error(0));
TEST_CHECK_ERROR(false);
// compare to test data
index -= low;
@ -492,7 +495,7 @@ int mon_check_props() {
PLI_INT32 indexp[1] = {0};
vpi_get_value_array(object, &arrayvalue, indexp, NUM_ELEMENTS);
CHECK_RESULT_NZ(vpi_chk_error(0));
TEST_CHECK_ERROR(true);
}
{
@ -507,7 +510,7 @@ int mon_check_props() {
PLI_INT32 indexp[1] = {0};
vpi_get_value_array(object, &arrayvalue, indexp, NUM_ELEMENTS);
CHECK_RESULT_NZ(vpi_chk_error(0));
TEST_CHECK_ERROR(true);
}
{
@ -521,7 +524,7 @@ int mon_check_props() {
arrayvalue.value.integers = 0;
PLI_INT32 indexp[1] = {0};
vpi_get_value_array(object, &arrayvalue, indexp, NUM_ELEMENTS);
CHECK_RESULT_NZ(vpi_chk_error(0));
TEST_CHECK_ERROR(true);
}
{
@ -536,7 +539,7 @@ int mon_check_props() {
PLI_INT32 indexp[1] = {0};
vpi_get_value_array(object, &arrayvalue, indexp, NUM_ELEMENTS);
CHECK_RESULT_NZ(vpi_chk_error(0));
TEST_CHECK_ERROR(true);
}
{
@ -551,7 +554,7 @@ int mon_check_props() {
PLI_INT32 indexp[1] = {0};
vpi_get_value_array(object, &arrayvalue, indexp, NUM_ELEMENTS);
CHECK_RESULT_NZ(vpi_chk_error(0));
TEST_CHECK_ERROR(true);
}
{
@ -566,11 +569,11 @@ int mon_check_props() {
PLI_INT32 indexp[1] = {4};
vpi_get_value_array(object, &arrayvalue, indexp, NUM_ELEMENTS);
CHECK_RESULT_NZ(vpi_chk_error(0));
TEST_CHECK_ERROR(true);
indexp[0] = 0;
vpi_get_value_array(object, &arrayvalue, indexp, NUM_ELEMENTS);
CHECK_RESULT_NZ(vpi_chk_error(0));
TEST_CHECK_ERROR(true);
}
{
@ -585,7 +588,7 @@ int mon_check_props() {
PLI_INT32 indexp[1] = {0};
vpi_get_value_array(object, &arrayvalue, indexp, NUM_ELEMENTS);
CHECK_RESULT_NZ(vpi_chk_error(0));
TEST_CHECK_ERROR(true);
}
{
@ -600,7 +603,7 @@ int mon_check_props() {
PLI_INT32 indexp[1] = {0};
vpi_get_value_array(object, &arrayvalue, indexp, NUM_ELEMENTS);
CHECK_RESULT_NZ(vpi_chk_error(0));
TEST_CHECK_ERROR(true);
}
{
@ -615,7 +618,7 @@ int mon_check_props() {
PLI_INT32 indexp[1] = {0};
vpi_get_value_array(object, &arrayvalue, indexp, 5);
CHECK_RESULT_NZ(vpi_chk_error(0));
TEST_CHECK_ERROR(true);
}
{
@ -626,7 +629,7 @@ int mon_check_props() {
PLI_INT32 indexp[1] = {0};
vpi_get_value_array(object, 0, indexp, 0);
CHECK_RESULT_NZ(vpi_chk_error(0));
TEST_CHECK_ERROR(true);
}
{
@ -640,10 +643,10 @@ int mon_check_props() {
arrayvalue.value.integers = 0;
vpi_get_value_array(object, &arrayvalue, 0, 0);
CHECK_RESULT_NZ(vpi_chk_error(0));
TEST_CHECK_ERROR(true);
}
return 0;
return errors;
}
extern "C" int mon_check(void) { return mon_check_props(); }

View File

@ -0,0 +1,13 @@
vpi_chk_error: vl_check_array_format: Unsupported format (vpiRealVal) as requested for 'test.read_longs'
vpi_chk_error: vl_check_array_format: Unsupported format (vpiShortRealVal) as requested for 'test.read_words'
vpi_chk_error: vl_check_array_format: Unsupported format (vpiTimeVal) as requested for 'test.read_longs'
vpi_chk_error: vpi_get_value_array: Unsupported vpiHandle '0x#'
vpi_chk_error: vpi_get_value_array: Unsupported type 'vpiReg' for 'read_scalar'
vpi_chk_error: vpi_get_value_array: Index 4 for object 'test.read_bounds' is out of bounds [1,3]
vpi_chk_error: vpi_get_value_array: Index 0 for object 'test.read_bounds' is out of bounds [1,3]
vpi_chk_error: vpi_get_value_array: Unsupported vpiUserAllocFlag (2000)
vpi_chk_error: vl_check_array_format: Unsupported format (vpiShortIntVal) as requested for 'test.read_words'
vpi_chk_error: vl_get_value_array: Requested elements (5) exceed array size (4)
vpi_chk_error: Ignoring vpi_get_value_array with null value pointer
vpi_chk_error: Ignoring vpi_get_value_array with null index pointer
*-* All Finished *-*

View File

@ -18,6 +18,6 @@ test.compile(make_top_shell=False,
iv_flags2=["-g2005-sv -D USE_VPI_NOT_DPI"],
v_flags2=["+define+USE_VPI_NOT_DPI +define+VERILATOR_COMMENTS"])
test.execute(use_libvpi=True)
test.execute(use_libvpi=True, expect_filename=test.golden_filename)
test.passes()

View File

@ -78,7 +78,6 @@ void _mon_check_range(const TestVpiHandle& handle, int size, int left, int right
void _mem_check(const char* name, int size, int left, int right, int words) {
s_vpi_value value;
s_vpi_error_info e;
vpi_printf((PLI_BYTE8*)"Check memory vpi (%s) ...\n", name);
TestVpiHandle mem_h = vpi_handle_by_name((PLI_BYTE8*)TestSimulator::rooted(name), NULL);
@ -106,7 +105,7 @@ void _mem_check(const char* name, int size, int left, int right, int words) {
value.format = vpiIntVal;
value.value.integer = ++cnt;
vpi_put_value(lcl_h, &value, NULL, vpiNoDelay);
TEST_CHECK_Z(vpi_chk_error(&e));
TEST_CHECK_ERROR(false);
// check size and range
_mon_check_range(lcl_h, size, left, right);
}
@ -118,7 +117,7 @@ void _mem_check(const char* name, int size, int left, int right, int words) {
value.format = vpiBinStrVal;
value.value.str = const_cast<char*>(binStr.c_str());
vpi_put_value(mem_h, &value, NULL, vpiNoDelay);
TEST_CHECK_Z(vpi_chk_error(&e));
TEST_CHECK_ERROR(false);
}
if (vpitype == vpiRegArray) {
// iterate and accumulate
@ -128,7 +127,7 @@ void _mem_check(const char* name, int size, int left, int right, int words) {
++cnt;
value.format = vpiIntVal;
vpi_get_value(lcl_h, &value);
TEST_CHECK_Z(vpi_chk_error(&e));
TEST_CHECK_ERROR(false);
TEST_CHECK_EQ(value.value.integer, cnt);
}
iter_h.freed(); // IEEE 37.2.2 vpi_scan at end does a vpi_release_handle
@ -136,7 +135,7 @@ void _mem_check(const char* name, int size, int left, int right, int words) {
} else {
value.format = vpiBinStrVal;
vpi_get_value(mem_h, &value);
TEST_CHECK_Z(vpi_chk_error(&e));
TEST_CHECK_ERROR(false);
TEST_CHECK_EQ(std::string{value.value.str}, binStr);
}
@ -183,7 +182,7 @@ void _mem_check(const char* name, int size, int left, int right, int words) {
TEST_CHECK_EQ(value.value.integer, 1);
// check writing to vpiConstant
vpi_put_value(side_h, &value, NULL, vpiNoDelay);
TEST_CHECK_NZ(vpi_chk_error(&e));
TEST_CHECK_ERROR(true);
}
{
// iterator should exhaust after 1 dimension

View File

@ -0,0 +1,7 @@
Check memory vpi (mem0) ...
vpi_chk_error: vpi_put_value: Ignoring vpi_put_value to vpiConstant '<null>'
Check memory vpi (memp32) ...
Check memory vpi (memp31) ...
Check memory vpi (memp33) ...
Check memory vpi (memw) ...
*-* All Finished *-*

View File

@ -18,6 +18,6 @@ test.compile(make_top_shell=False,
v_flags2=["+define+USE_VPI_NOT_DPI"],
verilator_flags2=["--exe --vpi --no-l2name", test.pli_filename])
test.execute(use_libvpi=True)
test.execute(use_libvpi=True, expect_filename=test.golden_filename)
test.passes()

View File

@ -214,14 +214,13 @@ void _arr_access_format_check(TestVpiHandle& reg_h, int wordSize, const int* low
assert(spanSize <= MAX_SPANSIZE);
s_vpi_value value_in;
s_vpi_value value_out;
s_vpi_error_info e;
char zero_s[2] = "0";
// zero out the vector
value_in.format = vpiOctStrVal;
value_in.value.str = zero_s;
vpi_put_value(reg_h, &value_in, NULL, vpiNoDelay);
TEST_CHECK_Z(vpi_chk_error(&e));
TEST_CHECK_ERROR(false);
value_in.format = format;
value_out.format = format;
@ -272,7 +271,7 @@ void _arr_access_format_check(TestVpiHandle& reg_h, int wordSize, const int* low
}
vpi_put_value(subreg_h, &value_in, NULL, vpiNoDelay);
TEST_CHECK_Z(vpi_chk_error(&e));
TEST_CHECK_ERROR(false);
vpi_get_value(subreg_h, &value_out);
switch (format) {
@ -324,13 +323,12 @@ void _arr_access_check(const char* name, int wordSize, const int* lows) {
while (TestVpiHandle reg_h = vpi_scan(arr_iter_h)) {
s_vpi_value value_in;
s_vpi_value value_out;
s_vpi_error_info e;
value_out.format = vpiOctStrVal;
value_in.format = vpiOctStrVal;
value_in.value.str = octVal_s;
vpi_put_value(reg_h, &value_in, NULL, vpiNoDelay);
TEST_CHECK_Z(vpi_chk_error(&e));
TEST_CHECK_ERROR(false);
vpi_get_value(reg_h, &value_out);
TEST_CHECK_CSTR(value_out.value.str, octVal_s);

View File

@ -39,16 +39,18 @@
#include <iostream>
// These require the above. Comment prevents clang-format moving them
#include "TestCheck.h"
#include "TestSimulator.h"
#include "TestVpi.h"
int errors = 0;
int check_param_int(std::string name, PLI_INT32 format, int exp_value, bool verbose) {
int vpi_type;
TestVpiHandle param_h;
s_vpi_value value;
value.format = format;
value.value.integer = 0;
s_vpi_error_info e;
const char* p;
vpi_printf((PLI_BYTE8*)"Check parameter %s vpi ...\n", name.c_str());
@ -68,32 +70,23 @@ int check_param_int(std::string name, PLI_INT32 format, int exp_value, bool verb
p = vpi_get_str(vpiType, param_h);
CHECK_RESULT_CSTR(p, "vpiParameter");
vpi_type = vpi_get(vpiLocalParam, param_h);
CHECK_RESULT_NZ(vpi_chk_error(&e));
if (verbose && vpi_chk_error(&e)) {
vpi_printf((PLI_BYTE8*)" vpi_chk_error: %s\n", e.message);
}
TEST_CHECK_ERROR(true);
// values
if (verbose) vpi_printf((PLI_BYTE8*)" Try writing value to %s ...\n", name.c_str());
value.value.integer = exp_value;
vpi_put_value(param_h, &value, NULL, vpiNoDelay);
CHECK_RESULT_NZ(vpi_chk_error(&e));
if (verbose && vpi_chk_error(&e)) {
vpi_printf((PLI_BYTE8*)" vpi_chk_error: %s\n", e.message);
}
TEST_CHECK_ERROR(true);
if (verbose) vpi_printf((PLI_BYTE8*)" Try reading value of %s ...\n", name.c_str());
vpi_get_value(param_h, &value);
CHECK_RESULT_NZ(!vpi_chk_error(&e));
if (verbose && vpi_chk_error(&e)) {
vpi_printf((PLI_BYTE8*)" vpi_chk_error: %s\n", e.message);
}
TEST_CHECK_ERROR(false);
if (verbose) {
vpi_printf((PLI_BYTE8*)" value of %s: %d\n", name.c_str(), value.value.integer);
}
CHECK_RESULT(value.value.integer, exp_value);
return 0;
return errors;
}
int check_param_str(std::string name, PLI_INT32 format, std::string exp_value, bool verbose) {
@ -102,7 +95,6 @@ int check_param_str(std::string name, PLI_INT32 format, std::string exp_value, b
s_vpi_value value;
value.format = format;
value.value.integer = 0;
s_vpi_error_info e;
const char* p;
vpi_printf((PLI_BYTE8*)"Check parameter %s vpi ...\n", name.c_str());
@ -122,32 +114,23 @@ int check_param_str(std::string name, PLI_INT32 format, std::string exp_value, b
p = vpi_get_str(vpiType, param_h);
CHECK_RESULT_CSTR(p, "vpiParameter");
vpi_type = vpi_get(vpiLocalParam, param_h);
CHECK_RESULT_NZ(vpi_chk_error(&e));
if (verbose && vpi_chk_error(&e)) {
vpi_printf((PLI_BYTE8*)" vpi_chk_error: %s\n", e.message);
}
TEST_CHECK_ERROR(true);
// values
if (verbose) vpi_printf((PLI_BYTE8*)" Try writing value to %s ...\n", name.c_str());
value.value.str = (PLI_BYTE8*)exp_value.c_str();
vpi_put_value(param_h, &value, NULL, vpiNoDelay);
CHECK_RESULT_NZ(vpi_chk_error(&e));
if (verbose && vpi_chk_error(&e)) {
vpi_printf((PLI_BYTE8*)" vpi_chk_error: %s\n", e.message);
}
TEST_CHECK_ERROR(true);
if (verbose) vpi_printf((PLI_BYTE8*)" Try reading value of %s ...\n", name.c_str());
vpi_get_value(param_h, &value);
CHECK_RESULT_NZ(!vpi_chk_error(&e));
if (verbose && vpi_chk_error(&e)) {
vpi_printf((PLI_BYTE8*)" vpi_chk_error: %s\n", e.message);
}
TEST_CHECK_ERROR(false);
if (verbose) {
vpi_printf((PLI_BYTE8*)" value of %s: %s\n", name.c_str(), value.value.str);
}
CHECK_RESULT_CSTR(value.value.str, exp_value.c_str());
return 0;
return errors;
}
int _mon_check_param() {

View File

@ -0,0 +1,13 @@
Check parameter WIDTH vpi ...
vpi_chk_error: vpi_get: Unsupported property 'vpiLocalParam', nothing will be returned
vpi_chk_error: vpi_put_value: Ignoring vpi_put_value to vpiParameter 't.WIDTH'
Check parameter DEPTH vpi ...
vpi_chk_error: vpi_get: Unsupported property 'vpiLocalParam', nothing will be returned
vpi_chk_error: vpi_put_value: Ignoring vpi_put_value to vpiParameter 't.DEPTH'
Check parameter PARAM_LONG vpi ...
vpi_chk_error: vpi_get: Unsupported property 'vpiLocalParam', nothing will be returned
vpi_chk_error: vpi_put_value: Ignoring vpi_put_value to vpiParameter 't.PARAM_LONG'
Check parameter PARAM_STR vpi ...
vpi_chk_error: vpi_get: Unsupported property 'vpiLocalParam', nothing will be returned
vpi_chk_error: vpi_put_value: Ignoring vpi_put_value to vpiParameter 't.PARAM_STR'
*-* All Finished *-*

View File

@ -18,6 +18,6 @@ test.compile(make_top_shell=False,
v_flags2=["+define+USE_VPI_NOT_DPI"],
verilator_flags2=["--exe --vpi --no-l2name", test.pli_filename])
test.execute(use_libvpi=True)
test.execute(use_libvpi=True, expect_filename=test.golden_filename)
test.passes()

View File

@ -19,11 +19,14 @@
#endif
// These require the above. Comment prevents clang-format moving them
#include "TestCheck.h"
#include "TestSimulator.h"
#include "TestVpi.h"
#include <vector>
int errors = 0;
//======================================================================
int test_vpiRawFourStateVal(char* name, PLI_BYTE8* test_data, int index, const unsigned num,
@ -56,12 +59,12 @@ int test_vpiRawFourStateVal(char* name, PLI_BYTE8* test_data, int index, const u
arrayvalue.flags = 0;
arrayvalue.value.rawvals = test_data_four_state.data();
vpi_put_value_array(arrayhandle, &arrayvalue, index_arr, num);
CHECK_RESULT_NZ(!vpi_chk_error(0));
TEST_CHECK_ERROR(false);
// get value to nu
arrayvalue.value.rawvals = 0;
vpi_get_value_array(arrayhandle, &arrayvalue, index_arr, size);
CHECK_RESULT_NZ(!vpi_chk_error(0));
TEST_CHECK_ERROR(false);
#ifdef TEST_VERBOSE
for (unsigned i = 0; i < (2 * size * elem_size); i++) {
@ -107,12 +110,12 @@ int test_vpiRawTwoStateVal(char* name, PLI_BYTE8* test_data, int index, const un
arrayvalue.flags = 0;
arrayvalue.value.rawvals = test_data;
vpi_put_value_array(arrayhandle, &arrayvalue, index_arr, num);
CHECK_RESULT_NZ(!vpi_chk_error(0));
TEST_CHECK_ERROR(false);
// get value to check
arrayvalue.value.rawvals = 0;
vpi_get_value_array(arrayhandle, &arrayvalue, index_arr, size);
CHECK_RESULT_NZ(!vpi_chk_error(0));
TEST_CHECK_ERROR(false);
#ifdef TEST_VERBOSE
for (unsigned i = 0; i < (size * elem_size); i++) {
@ -172,12 +175,12 @@ int test_vpiVectorVal(char* name, PLI_BYTE8* test_data, int index, const unsigne
arrayvalue.flags = 0;
arrayvalue.value.vectors = test_data_vectors.data();
vpi_put_value_array(arrayhandle, &arrayvalue, index_arr, num);
CHECK_RESULT_NZ(!vpi_chk_error(0));
TEST_CHECK_ERROR(false);
// get value to check
arrayvalue.value.vectors = 0;
vpi_get_value_array(arrayhandle, &arrayvalue, index_arr, size);
CHECK_RESULT_NZ(!vpi_chk_error(0));
TEST_CHECK_ERROR(false);
#ifdef TEST_VERBOSE
for (unsigned i = 0; i < vec_size; i++) {
@ -233,12 +236,12 @@ int test_vpiIntVal(char* name, PLI_BYTE8* test_data, int index, const unsigned n
arrayvalue.flags = 0;
arrayvalue.value.integers = test_data_integers.data();
vpi_put_value_array(arrayhandle, &arrayvalue, index_arr, num);
CHECK_RESULT_NZ(!vpi_chk_error(0));
TEST_CHECK_ERROR(false);
// get value to check
arrayvalue.value.vectors = 0;
vpi_get_value_array(arrayhandle, &arrayvalue, index_arr, size);
CHECK_RESULT_NZ(!vpi_chk_error(0));
TEST_CHECK_ERROR(false);
#ifdef TEST_VERBOSE
for (unsigned i = 0; i < size; i++) {
@ -288,12 +291,12 @@ int test_vpiShortIntVal(char* name, PLI_BYTE8* test_data, int index, const unsig
arrayvalue.flags = 0;
arrayvalue.value.shortints = test_data_shortints.data();
vpi_put_value_array(arrayhandle, &arrayvalue, index_arr, num);
CHECK_RESULT_NZ(!vpi_chk_error(0));
TEST_CHECK_ERROR(false);
// get value to check
arrayvalue.value.vectors = 0;
vpi_get_value_array(arrayhandle, &arrayvalue, index_arr, size);
CHECK_RESULT_NZ(!vpi_chk_error(0));
TEST_CHECK_ERROR(false);
#ifdef TEST_VERBOSE
for (unsigned i = 0; i < size; i++) {
@ -342,12 +345,12 @@ int test_vpiLongIntVal(char* name, PLI_BYTE8* test_data, int index, const unsign
arrayvalue.flags = 0;
arrayvalue.value.longints = test_data_longints.data();
vpi_put_value_array(arrayhandle, &arrayvalue, index_arr, num);
CHECK_RESULT_NZ(!vpi_chk_error(0));
TEST_CHECK_ERROR(false);
// get value to check
arrayvalue.value.vectors = 0;
vpi_get_value_array(arrayhandle, &arrayvalue, index_arr, size);
CHECK_RESULT_NZ(!vpi_chk_error(0));
TEST_CHECK_ERROR(false);
// compare to test data
for (unsigned i = 0; i < num; i++) {
@ -534,15 +537,15 @@ int mon_check_props(void) {
PLI_INT32 indexp[1] = {0};
vpi_put_value_array(object, &arrayvalue, indexp, 4);
CHECK_RESULT_NZ(vpi_chk_error(0));
TEST_CHECK_ERROR(true);
arrayvalue.format = vpiShortRealVal;
vpi_put_value_array(object, &arrayvalue, indexp, 4);
CHECK_RESULT_NZ(vpi_chk_error(0));
TEST_CHECK_ERROR(true);
arrayvalue.format = vpiTimeVal;
vpi_put_value_array(object, &arrayvalue, indexp, 4);
CHECK_RESULT_NZ(vpi_chk_error(0));
TEST_CHECK_ERROR(true);
}
{
@ -553,7 +556,7 @@ int mon_check_props(void) {
PLI_INT32 indexp[1] = {0};
vpi_put_value_array(object, 0, indexp, 4);
CHECK_RESULT_NZ(vpi_chk_error(0));
TEST_CHECK_ERROR(true);
}
{
@ -569,7 +572,7 @@ int mon_check_props(void) {
PLI_INT32 indexp[1] = {0};
vpi_put_value_array(object, &arrayvalue, indexp, 4);
CHECK_RESULT_NZ(vpi_chk_error(0));
TEST_CHECK_ERROR(true);
}
{
@ -585,7 +588,7 @@ int mon_check_props(void) {
PLI_INT32 indexp[1] = {0};
vpi_put_value_array(object, &arrayvalue, indexp, 4);
CHECK_RESULT_NZ(vpi_chk_error(0));
TEST_CHECK_ERROR(true);
}
{
@ -601,11 +604,11 @@ int mon_check_props(void) {
PLI_INT32 indexp[1] = {4};
vpi_put_value_array(object, &arrayvalue, indexp, 4);
CHECK_RESULT_NZ(vpi_chk_error(0));
TEST_CHECK_ERROR(true);
indexp[0] = 0;
vpi_put_value_array(object, &arrayvalue, indexp, 4);
CHECK_RESULT_NZ(vpi_chk_error(0));
TEST_CHECK_ERROR(true);
}
{
@ -621,7 +624,7 @@ int mon_check_props(void) {
PLI_INT32 indexp[1] = {0};
vpi_put_value_array(object, &arrayvalue, indexp, 4);
CHECK_RESULT_NZ(vpi_chk_error(0));
TEST_CHECK_ERROR(true);
}
{
@ -637,11 +640,11 @@ int mon_check_props(void) {
PLI_INT32 indexp[1] = {0};
vpi_put_value_array(object, &arrayvalue, indexp, 4);
CHECK_RESULT_NZ(vpi_chk_error(0));
TEST_CHECK_ERROR(true);
arrayvalue.flags = vpiOneValue;
vpi_put_value_array(object, &arrayvalue, indexp, 4);
CHECK_RESULT_NZ(vpi_chk_error(0));
TEST_CHECK_ERROR(true);
}
{
@ -657,11 +660,11 @@ int mon_check_props(void) {
PLI_INT32 indexp[1] = {0};
vpi_put_value_array(object, &arrayvalue, indexp, 4);
CHECK_RESULT_NZ(vpi_chk_error(0));
TEST_CHECK_ERROR(true);
arrayvalue.flags = vpiOneValue;
vpi_put_value_array(object, &arrayvalue, indexp, 4);
CHECK_RESULT_NZ(vpi_chk_error(0));
TEST_CHECK_ERROR(true);
}
{
@ -677,7 +680,7 @@ int mon_check_props(void) {
PLI_INT32 indexp[1] = {0};
vpi_put_value_array(object, &arrayvalue, indexp, 5);
CHECK_RESULT_NZ(~vpi_chk_error(0));
TEST_CHECK_ERROR(true);
}
{
@ -688,7 +691,7 @@ int mon_check_props(void) {
PLI_INT32 indexp[1] = {0};
vpi_get_value_array(object, 0, indexp, 0);
CHECK_RESULT_NZ(vpi_chk_error(0));
TEST_CHECK_ERROR(true);
}
{
@ -703,10 +706,10 @@ int mon_check_props(void) {
arrayvalue.value.integers = datap;
vpi_get_value_array(object, &arrayvalue, 0, 0);
CHECK_RESULT_NZ(vpi_chk_error(0));
TEST_CHECK_ERROR(true);
}
return 0;
return errors;
}
extern "C" int mon_check(void) { return mon_check_props(); }

View File

@ -0,0 +1,17 @@
vpi_chk_error: vl_check_array_format: Unsupported format (vpiRealVal) as requested for 'test.write_longs'
vpi_chk_error: vl_check_array_format: Unsupported format (vpiShortRealVal) as requested for 'test.write_longs'
vpi_chk_error: vl_check_array_format: Unsupported format (vpiTimeVal) as requested for 'test.write_longs'
vpi_chk_error: Ignoring vpi_put_value_array with null value pointer
vpi_chk_error: vpi_put_value_array: Unsupported vpiHandle '0x#'
vpi_chk_error: vpi_put_value_array: Unsupported vpiHandle type 'vpiReg' for 'write_scalar'
vpi_chk_error: vpi_put_value_array: Index 4 for object 'test.write_bounds' is out of bounds [1,3]
vpi_chk_error: vpi_put_value_array: Index 0 for object 'test.write_bounds' is out of bounds [1,3]
vpi_chk_error: Ignoring vpi_put_value_array to signal marked read-only, use public_flat_rw instead: 'test.write_inaccessible'
vpi_chk_error: vl_check_array_format: Unsupported format (*undefined*) as requested for 'test.write_words'
vpi_chk_error: vpi_put_value_array: Unsupported flags (4000)
vpi_chk_error: vl_check_array_format: Unsupported format (vpiShortIntVal) as requested for 'test.write_words'
vpi_chk_error: vpi_put_value_array: Unsupported flags (4000)
vpi_chk_error: vl_put_value_array: Requested elements to set (5) exceed array size (4)
vpi_chk_error: Ignoring vpi_get_value_array with null value pointer
vpi_chk_error: Ignoring vpi_get_value_array with null index pointer
*-* All Finished *-*

View File

@ -18,6 +18,6 @@ test.compile(make_top_shell=False,
iv_flags2=["-g2005-sv -D USE_VPI_NOT_DPI"],
v_flags2=["+define+USE_VPI_NOT_DPI +define+VERILATOR_COMMENTS"])
test.execute(use_libvpi=True)
test.execute(use_libvpi=True, expect_filename=test.golden_filename)
test.passes()

View File

@ -486,12 +486,11 @@ int _mon_check_big() {
Verilated::fatalOnVpiError(false);
vpi_get_value(h, &v);
Verilated::fatalOnVpiError(true);
s_vpi_error_info info;
CHECK_RESULT_Z(vpi_chk_error(&info));
TEST_CHECK_ERROR(false);
v.format = vpiStringVal;
vpi_get_value(h, &v);
CHECK_RESULT_Z(vpi_chk_error(nullptr));
TEST_CHECK_ERROR(false);
CHECK_RESULT_CSTR_STRIP(v.value.str, "some text");
#endif
@ -1710,7 +1709,7 @@ int _mon_check_delayed() {
v.format = vpiIntVal;
v.value.integer = 123;
vpi_put_value(vh, &v, &t, vpiInertialDelay);
CHECK_RESULT_Z(vpi_chk_error(nullptr));
TEST_CHECK_ERROR(false);
vpi_get_value(vh, &v);
CHECK_RESULT(v.value.integer, 0);
@ -1720,19 +1719,24 @@ int _mon_check_delayed() {
CHECK_RESULT_NZ(vhMemWord);
v.value.integer = 456;
vpi_put_value(vhMemWord, &v, &t, vpiInertialDelay);
CHECK_RESULT_Z(vpi_chk_error(nullptr));
TEST_CHECK_ERROR(false);
// test unsupported vpiInertialDelay cases
// - should these also throw vpi errors?
v.format = vpiStringVal;
v.value.str = nullptr;
vpi_put_value(vh, &v, &t, vpiInertialDelay);
CHECK_RESULT_NZ(vpi_chk_error(nullptr));
TEST_CHECK_ERROR(true);
v.format = vpiVectorVal;
v.value.vector = nullptr;
vpi_put_value(vh, &v, &t, vpiInertialDelay);
CHECK_RESULT_NZ(vpi_chk_error(nullptr));
TEST_CHECK_ERROR(true);
// Test null value in put
v.format = vpiVectorVal;
vpi_put_value(vh, nullptr, &t, 0);
TEST_CHECK_ERROR(true);
// This format throws an error now
#ifdef VERILATOR

View File

@ -0,0 +1,5 @@
vpi_chk_error: vpi_put_value: Unsupported p_vpi_value as requested for 't.delayed' with vpiInertialDelay
vpi_chk_error: vpi_put_value: Unsupported p_vpi_value as requested for 't.delayed' with vpiInertialDelay
vpi_chk_error: Ignoring vpi_put_value with nullptr value pointer
%Info: Checking results
*-* All Finished *-*

View File

@ -19,6 +19,8 @@ test.compile(make_top_shell=False,
v_flags2=["+define+USE_VPI_NOT_DPI"],
verilator_flags2=["-Wno-SYMRSVDWORD --exe --vpi --no-l2name", test.pli_filename])
test.execute(use_libvpi=True, all_run_flags=['+PLUS +INT=1234 +STRSTR'])
test.execute(use_libvpi=True,
all_run_flags=['+PLUS +INT=1234 +STRSTR'],
expect_filename=test.golden_filename)
test.passes()