La interfaz procedimental Verilog (VPI), conocida originalmente como PLI 2.0, es una interfaz pensada principalmente para el lenguaje de programación C. Permite que el código Verilog de comportamiento invoque funciones C, y que las funciones C invoquen tareas estándar del sistema Verilog. La interfaz procedimental Verilog forma parte del estándar IEEE 1364 Programming Language Interface; la edición más reciente del estándar es de 2005. A veces, a VPI también se la denomina PLI 2, ya que reemplaza a la obsoleta Program Language Interface (PLI) .
Si bien PLI 1 quedó obsoleto en favor de VPI (también conocido como PLI 2), PLI 1 aún se usa comúnmente en lugar de VPI debido a su interfaz de función tf_put, tf_get mucho más ampliamente documentada que se describe en muchos libros de referencia de verilog.
Uso de C++
C++ se puede integrar 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 Verilog:
valor = 41;
$incremento(val);
$display("Después de $incremento, val=%d", val);
Supongamos que la incrementtarea del sistema incrementa su primer parámetro en uno. Utilizando C y el mecanismo VPI, la incrementtarea 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 ; int value ;
// 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.format = vpiIntVal ; vpi_get_value ( argh , & argval ); value = argval.value.integer ; vpi_printf ( " La rutina VPI recibió % d \ n " , value ) ;
// Incrementa el valor y vuelve a colocarlo como primer argumento
argval . value . entire = value + 1 ; vpi_put_value ( argh , & argval , NULL , vpiNoDelay );
// Limpieza y retorno
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 ( & data ); }
// Contiene una lista terminada en cero de funciones que deben llamarse al inicio
void ( * vlog_startup_routines [])() = { register_increment , 0 };
El código C se compila en un objeto compartido que utilizará el simulador Verilog. Una simulación del fragmento Verilog mencionado anteriormente dará como resultado lo siguiente:
Rutina VPI recibida 41 Después de $increment, val=42
Véase también
Fuentes
- Exploración del IEEE
Fuentes para la interfaz VPI de Verilog
- Teal, para C++
- JOVE, para Java
- Ruby-VPI, para Ruby
- ScriptEDA, para Perl , Python y Tcl
- Cocotb [1], para Python
- OrigenSim, para Ruby
Enlaces externos
- Imprimación Verilog PLI
- Tutorial de Verilog VPI