vpi: $left and $right functions for arrays and strings.
This commit is contained in:
parent
288ebf011c
commit
961d6a8f3b
|
|
@ -52,6 +52,47 @@ static PLI_INT32 one_array_arg_compiletf(ICARUS_VPI_CONST PLI_BYTE8*name)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Checks if a function is passed an array and optionally an integer.
|
||||||
|
static PLI_INT32 array_int_opt_arg_compiletf(ICARUS_VPI_CONST PLI_BYTE8*name)
|
||||||
|
{
|
||||||
|
const int MAX_ARGC = 3; // one more is to verify there are at most 2 args
|
||||||
|
vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
|
||||||
|
vpiHandle argv, arg[MAX_ARGC];
|
||||||
|
PLI_INT32 arg_type[MAX_ARGC];
|
||||||
|
int argc;
|
||||||
|
|
||||||
|
argv = vpi_iterate(vpiArgument, callh);
|
||||||
|
argc = 0;
|
||||||
|
|
||||||
|
if(argv) {
|
||||||
|
for(int i = 0; i < MAX_ARGC; ++i) {
|
||||||
|
arg[i] = vpi_scan(argv);
|
||||||
|
if(arg[i]) {
|
||||||
|
arg_type[i] = vpi_get(vpiType, arg[i]);
|
||||||
|
++argc;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!argv || argc == MAX_ARGC || (arg_type[0] != vpiRegArray && arg_type[0] != vpiStringVar) ||
|
||||||
|
(argc == 2 && arg_type[1] != vpiIntegerVar &&
|
||||||
|
!(arg_type[1] == vpiConstant && vpi_get(vpiConstType, arg[1]) == vpiBinaryConst))) {
|
||||||
|
vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
|
||||||
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
|
vpi_printf("%s expects an array and optionally an integer.\n", name);
|
||||||
|
|
||||||
|
if(argc == MAX_ARGC)
|
||||||
|
vpi_free_object(argv);
|
||||||
|
|
||||||
|
vpi_control(vpiFinish, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static PLI_INT32 func_not_implemented_compiletf(ICARUS_VPI_CONST PLI_BYTE8* name)
|
static PLI_INT32 func_not_implemented_compiletf(ICARUS_VPI_CONST PLI_BYTE8* name)
|
||||||
{
|
{
|
||||||
vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
|
vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
|
||||||
|
|
@ -63,6 +104,47 @@ static PLI_INT32 func_not_implemented_compiletf(ICARUS_VPI_CONST PLI_BYTE8* name
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PLI_INT32 array_get_property(int property, ICARUS_VPI_CONST PLI_BYTE8*name)
|
||||||
|
{
|
||||||
|
vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
|
||||||
|
vpiHandle argv, array, dim;
|
||||||
|
s_vpi_value value;
|
||||||
|
|
||||||
|
argv = vpi_iterate(vpiArgument, callh);
|
||||||
|
if (argv == 0) {
|
||||||
|
vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
|
||||||
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
|
vpi_printf("%s requires an array argument.\n", name);
|
||||||
|
vpi_control(vpiFinish, 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
array = vpi_scan(argv);
|
||||||
|
dim = vpi_scan(argv);
|
||||||
|
|
||||||
|
if(dim != 0) {
|
||||||
|
vpi_printf("SORRY: %s:%d: multiple dimensions are not handled yet.\n",
|
||||||
|
vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh));
|
||||||
|
vpi_control(vpiFinish, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
value.format = vpiIntVal;
|
||||||
|
value.value.integer = vpi_get(property, array);
|
||||||
|
vpi_put_value(callh, &value, 0, vpiNoDelay);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PLI_INT32 left_calltf(ICARUS_VPI_CONST PLI_BYTE8*name)
|
||||||
|
{
|
||||||
|
return array_get_property(vpiLeftRange, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
static PLI_INT32 right_calltf(ICARUS_VPI_CONST PLI_BYTE8*name)
|
||||||
|
{
|
||||||
|
return array_get_property(vpiRightRange, name);
|
||||||
|
}
|
||||||
|
|
||||||
static void high_array(const char*name, vpiHandle callh, vpiHandle arg)
|
static void high_array(const char*name, vpiHandle callh, vpiHandle arg)
|
||||||
{
|
{
|
||||||
s_vpi_value value;
|
s_vpi_value value;
|
||||||
|
|
@ -178,32 +260,6 @@ void v2009_array_register(void)
|
||||||
tf_data.compiletf = func_not_implemented_compiletf;;
|
tf_data.compiletf = func_not_implemented_compiletf;;
|
||||||
tf_data.sizetf = 0;
|
tf_data.sizetf = 0;
|
||||||
|
|
||||||
/* These functions are not currently implemented. */
|
|
||||||
tf_data.tfname = "$dimensions";
|
|
||||||
tf_data.user_data = "$dimensions";
|
|
||||||
res = vpi_register_systf(&tf_data);
|
|
||||||
vpip_make_systf_system_defined(res);
|
|
||||||
|
|
||||||
tf_data.tfname = "$unpacked_dimensions";
|
|
||||||
tf_data.user_data = "$unpacked_dimensions";
|
|
||||||
res = vpi_register_systf(&tf_data);
|
|
||||||
vpip_make_systf_system_defined(res);
|
|
||||||
|
|
||||||
tf_data.tfname = "$left";
|
|
||||||
tf_data.user_data = "$left";
|
|
||||||
res = vpi_register_systf(&tf_data);
|
|
||||||
vpip_make_systf_system_defined(res);
|
|
||||||
|
|
||||||
tf_data.tfname = "$right";
|
|
||||||
tf_data.user_data = "$right";
|
|
||||||
res = vpi_register_systf(&tf_data);
|
|
||||||
vpip_make_systf_system_defined(res);
|
|
||||||
|
|
||||||
tf_data.tfname = "$increment";
|
|
||||||
tf_data.user_data = "$increment";
|
|
||||||
res = vpi_register_systf(&tf_data);
|
|
||||||
vpip_make_systf_system_defined(res);
|
|
||||||
|
|
||||||
tf_data.tfname = "$high";
|
tf_data.tfname = "$high";
|
||||||
tf_data.user_data = "$high";
|
tf_data.user_data = "$high";
|
||||||
tf_data.compiletf = one_array_arg_compiletf;
|
tf_data.compiletf = one_array_arg_compiletf;
|
||||||
|
|
@ -217,4 +273,34 @@ void v2009_array_register(void)
|
||||||
tf_data.calltf = low_calltf;
|
tf_data.calltf = low_calltf;
|
||||||
res = vpi_register_systf(&tf_data);
|
res = vpi_register_systf(&tf_data);
|
||||||
vpip_make_systf_system_defined(res);
|
vpip_make_systf_system_defined(res);
|
||||||
|
|
||||||
|
tf_data.tfname = "$left";
|
||||||
|
tf_data.user_data = "$left";
|
||||||
|
tf_data.compiletf = array_int_opt_arg_compiletf;
|
||||||
|
tf_data.calltf = left_calltf;
|
||||||
|
res = vpi_register_systf(&tf_data);
|
||||||
|
vpip_make_systf_system_defined(res);
|
||||||
|
|
||||||
|
tf_data.tfname = "$right";
|
||||||
|
tf_data.user_data = "$right";
|
||||||
|
tf_data.compiletf = array_int_opt_arg_compiletf;
|
||||||
|
tf_data.calltf = right_calltf;
|
||||||
|
res = vpi_register_systf(&tf_data);
|
||||||
|
vpip_make_systf_system_defined(res);
|
||||||
|
|
||||||
|
/* These functions are not currently implemented. */
|
||||||
|
tf_data.tfname = "$dimensions";
|
||||||
|
tf_data.user_data = "$dimensions";
|
||||||
|
res = vpi_register_systf(&tf_data);
|
||||||
|
vpip_make_systf_system_defined(res);
|
||||||
|
|
||||||
|
tf_data.tfname = "$unpacked_dimensions";
|
||||||
|
tf_data.user_data = "$unpacked_dimensions";
|
||||||
|
res = vpi_register_systf(&tf_data);
|
||||||
|
vpip_make_systf_system_defined(res);
|
||||||
|
|
||||||
|
tf_data.tfname = "$increment";
|
||||||
|
tf_data.user_data = "$increment";
|
||||||
|
res = vpi_register_systf(&tf_data);
|
||||||
|
vpip_make_systf_system_defined(res);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -221,10 +221,16 @@ int __vpiDarrayVar::vpi_get(int code)
|
||||||
switch (code) {
|
switch (code) {
|
||||||
case vpiArrayType:
|
case vpiArrayType:
|
||||||
return vpiDynamicArray;
|
return vpiDynamicArray;
|
||||||
|
case vpiLeftRange:
|
||||||
|
return 0;
|
||||||
|
case vpiRightRange:
|
||||||
|
return get_size() - 1;
|
||||||
case vpiSize:
|
case vpiSize:
|
||||||
return get_size();
|
return get_size();
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
fprintf(stderr, "vpi sorry: property is not implemented");
|
||||||
|
assert(false);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,13 @@ int __vpiStringVar::vpi_get(int code)
|
||||||
// The vpiSize of a string variable is the number of
|
// The vpiSize of a string variable is the number of
|
||||||
// bytes (characters) in that string.
|
// bytes (characters) in that string.
|
||||||
return str.size();
|
return str.size();
|
||||||
|
case vpiLeftRange:
|
||||||
|
return 0;
|
||||||
|
case vpiRightRange:
|
||||||
|
return str.size() - 1;
|
||||||
default:
|
default:
|
||||||
|
fprintf(stderr, "vpi sorry: property is not implemented");
|
||||||
|
assert(false);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue