iverilog/ivtest/vpi/pr2314742.c

159 lines
3.5 KiB
C

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <vpi_user.h>
/*
* This file exercises an error
*/
static int chkvpierr(void)
{
s_vpi_error_info info;
int level;
if ((level = vpi_chk_error(&info)) != 0) {
fprintf(stderr, "+++ VPI ERROR +++ level %d\n", level);
fprintf(stderr, "+++ MESS: %s\n", info.message);
fprintf(stderr, "+++ PROD: %s\n", info.product);
fprintf(stderr, "+++ CODE: %s\n", info.code);
fprintf(stderr, "+++ FILE: %s\n", info.file);
fprintf(stderr, "+++\n");
}
return level;
}
#ifdef IVERILOG_V0_8
static PLI_INT32 xxx_compiletf(char *user_data)
#else
static PLI_INT32 xxx_compiletf(PLI_BYTE8 *user_data)
#endif
{
(void)user_data; /* Parameter is not used. */
return 0;
}
char charbuf[100];
#ifdef IVERILOG_V0_8
static PLI_INT32 xxx_calltf(char *user_data)
#else
static PLI_INT32 xxx_calltf(PLI_BYTE8 *user_data)
#endif
{
vpiHandle systf_h;
s_vpi_value vpival; /* get/set register values */
s_vpi_time t;
vpiHandle arg_iterator;
int i;
vpiHandle argi[100];
(void)user_data; /* Parameter is not used. */
/* Get handle to this instance, look up our workarea */
systf_h = vpi_handle(vpiSysTfCall, NULL);
chkvpierr();
arg_iterator = vpi_iterate(vpiArgument, systf_h);
chkvpierr();
i = 0;
if (arg_iterator == NULL) {
fprintf(stderr, "ERROR: missing argument list to $example(...)");
}
/* Copy args pointers into argi array */
while ((argi[i] = vpi_scan(arg_iterator)) != NULL) {
chkvpierr();
i++;
}
/* iterator is exhausted, no need to free */
/* Fill in the time struct */
t.type = vpiScaledRealTime;
t.high = 0;
t.low = 0;
t.real = 10.0;
/* Fill in the value struct */
vpival.format = vpiBinStrVal;
vpival.value.str = charbuf;
/*
* This is where the real work happens. We are called in an intial
* block and we schedule three "set-values" at times 10, 20 and 30
* to args 0, 1 and 2. The charbuf gets shared among the three
* calls, even though it shouldn't and the values are not distinct.
*/
/* Write this value to argi[0] at time 10.0 */
strcpy(charbuf, "01010101");
vpi_put_value(argi[0], &vpival, &t, vpiTransportDelay);
/* Write this value to argi[1] at time 20.0 */
strcpy(charbuf, "x1x1x1x1");
t.real = 20.0;
vpi_put_value(argi[1], &vpival, &t, vpiTransportDelay);
/* Write this value to argi[2] at time 30.0 */
strcpy(charbuf, "0xz101xz");
t.real = 30.0;
vpi_put_value(argi[2], &vpival, &t, vpiTransportDelay);
return 0;
}
static void xxx_register(void)
{
s_vpi_systf_data tfdata;
vpi_printf("+++ in XXX_REGISTER\n");
tfdata.type = vpiSysFunc;
/*
* TOM: sysfunctype field seems to be problematic for different simulators!
* some simulators simply don't register callback if subtype missing.
*
* Icarus - doesn't implement vpiSizedFunc, so use vpiIntFunct.
* CVER - use vpiIntFunc
* MTI - use vpiSizedFunc or vpiIntFunc.
* XL/NC - doesn't matter
* VCS - doesn't matter
*
*/
tfdata.sysfunctype = vpiIntFunc;
/* tfdata.sysfunctype = vpiSizedFunc; */
tfdata.tfname = "$example";
tfdata.calltf = xxx_calltf;
tfdata.compiletf = xxx_compiletf;
/* tfdata.sizetf = xxx_sizetf; */
tfdata.sizetf = 0;
tfdata.user_data = 0;
vpi_register_systf(&tfdata);
chkvpierr();
}
static void xxx_startup(void)
{
vpi_printf("*** Registering XXX PLI functions.\n");
xxx_register();
}
/**
*
*
**/
void (*vlog_startup_routines[])(void) = {
xxx_startup,
0
};