This repository has been archived by the owner on Dec 29, 2023. It is now read-only.
/
pr2314742.c
158 lines (126 loc) · 3.51 KB
/
pr2314742.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <vpi_user.h>
/*
* This file exercises an error
*/
static int chkvpierr()
{
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()
{
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()
{
vpi_printf("*** Registering XXX PLI functions.\n");
xxx_register();
}
/**
*
*
**/
void (*vlog_startup_routines[])() = {
xxx_startup,
0
};