Verilog Procedural Interface
The Verilog Procedural Interface (VPI) is an interface primarily intended for the C programming language. It allows behavioral Verilog code to invoke C functions, and C functions to invoke standard Verilog system tasks. The IEEE 1364-2005 standard defines the Verilog Procedural Interface. VPI is sometimes also referred to as PLI 2, since it replaces the deprecated Program Language Interface (PLI).
Example
As an example, consider the following Verilog code fragment:
val = 41;
$increment(val);
$display("After $increment, val=%d", val);
Suppose the increment
system task increments its first parameter by one. Using C and the VPI mechanism, the increment
task can be implemented as follows:
// Implements the increment system task
static int increment(char *userdata) {
vpiHandle systfref, args_iter, argh;
struct t_vpi_value argval;
int value;
// Obtain a handle to the argument list
systfref = vpi_handle(vpiSysTfCall, NULL);
args_iter = vpi_iterate(vpiArgument, systfref);
// Grab the value of the first argument
argh = vpi_scan(args_iter);
argval.format = vpiIntVal;
vpi_get_value(argh, &argval);
value = argval.value.integer;
vpi_printf("VPI routine received %d\n", value);
// Increment the value and put it back as first argument
argval.value.integer = value + 1;
vpi_put_value(argh, &argval, NULL, vpiNoDelay);
// Cleanup and return
vpi_free_object(args_iter);
return 0;
}
Also, a function that registers this system task is necessary. This function is invoked prior to elaboration or resolution of references when it is placed in the externally visible vlog_startup_routines[]
array.
// Registers the increment system task
void register_increment() {
s_vpi_systf_data data = {vpiSysTask, 0, "$increment", increment, 0, 0, 0};
vpi_register_systf(&data);
}
// Contains a zero-terminated list of functions that have to be called at startup
void (*vlog_startup_routines[])() = {
register_increment,
0
};
The C code is compiled into a shared object that will be used by the Verilog simulator. A simulation of the earlier mentioned Verilog fragment will now result in the following output:
VPI routine received 41 After $increment, val=42
Sources
External links
- Verilog PLI primer
- Verilog VPI tutorial
- Ruby-VPI - Verilog VPI interface for the Ruby programming language
- JOVE - Verilog VPI interface for the Java programming language
- Teal - Verilog VPI interface for the C++ programming language
- ScriptEDA - Verilog VPI interface for the Perl programming language, Python programming language, and Tcl programming language