El procedimiento Interface Verilog (VPI), originalmente conocida como PLI 2.0, es una interfaz destinada principalmente para el C lenguaje de programación . Permite que el código de comportamiento de Verilog invoque funciones C y funciones C para invocar tareas estándar del sistema Verilog. La interfaz de procedimiento Verilog es parte del estándar de interfaz de lenguaje de programación IEEE 1364 ; la edición más reciente del estándar es de 2005. VPI a veces también se conoce como PLI 2, ya que reemplaza a la obsoleta Interfaz de lenguaje de programa (PLI) .
Si bien PLI 1 se desaprobó en favor de VPI (también conocido como PLI 2), PLI 1 todavía se usa comúnmente sobre VPI debido a su interfaz de función tf_put, tf_get mucho más documentada que se describe en muchos libros de referencia de Verilog.
Uso de C ++
C ++ es integrable con VPI (PLI 2.0) y PLI 1.0, utilizando la palabra clave "extern C / C ++" incorporada en los compiladores de C ++.
Ejemplo
Como ejemplo, considere el siguiente fragmento de código de Verilog:
val = 41;$ incremento (val);$ display ("Después de $ incremento, val =% d", val);
Suponga que la increment
tarea del sistema incrementa su primer parámetro en uno. Usando C y el mecanismo VPI, la increment
tarea se puede implementar de la siguiente manera:
// Implementa la tarea del sistema de incremento static int increment ( char * userdata ) { vpiHandle systfref , args_iter , argh ; struct t_vpi_value argval ; valor int ; // Obtener un identificador para la lista de argumentos systfref = vpi_handle ( vpiSysTfCall , NULL ); args_iter = vpi_iterate ( vpiArgument , systfref ); // Toma el valor del primer argumento argh = vpi_scan ( args_iter ); argval . formato = vpiIntVal ; vpi_get_value ( argh , & argval ); valor = argval . valor . entero ; vpi_printf ( "Rutina VPI recibida% d \ n " , valor ); // Incrementa el valor y vuelve a colocarlo como primer argumento argval . valor . entero = valor + 1 ; vpi_put_value ( argh , & argval , NULL , vpiNoDelay ); // Limpiar y devolver vpi_free_object ( args_iter ); return 0 ; }
Además, es necesaria una función que registre esta tarea del sistema. Esta función se invoca antes de la elaboración o resolución de referencias cuando se coloca en la vlog_startup_routines[]
matriz visible externamente .
// Registra la tarea del sistema de incremento void register_increment () { s_vpi_systf_data data = { vpiSysTask , 0 , "$ increment" , increment , 0 , 0 , 0 }; vpi_register_systf ( & datos ); }// Contiene una lista de funciones terminadas en cero que deben llamarse al inicio void ( * vlog_startup_routines []) () = { register_increment , 0 };
El código C se compila en un objeto compartido que será utilizado por el simulador Verilog. Una simulación del fragmento de Verilog mencionado anteriormente dará como resultado el siguiente resultado:
Rutina VPI recibida 41Después de $ incremento, val = 42