引言
我们在进行RTL仿真时,有时候会遇到HDL工程和C语言工程需要进行数据通信时,使用$readmem()等系统任务会方便很多,但是有时候,实现较复杂功能时,$readmem()就会稍显不足。这时,就需要我们编写特殊的系统任务,来实现。
HDL语言提供的PLI,VPI正是为了解决这个问题而设计的,本小节,我们就熟悉一下VPI。
1,VPI简介
Verilog过程接口(Verilog Procedural Interface, VPI),最初被称为编程语言接口(Program Language Interface, PLI) 2.0,是一个针对C语言的Verilog过程接口。它可以使数字电路的行为级描述代码直接调用C语言的函数,而用到的C语言函数也可以调用标准的Verilog系统任务。Verilog程序结构是IEEE 1364编程语言接口标准的一部分。它最新的版本是2005年更新的。
更多信息请参考:
http://en.wikipedia.org/wiki/Verilog_Procedural_Interface
和
http://www.asic-world.com/verilog/pli6.html#Verilog_Procedural_Interface_(VPI)
2,简单示例
在了解了VPI的含义以及工作原理之后,我们通过下面一个简单的例子来说明VPI的具体使用方法。
针对不同的仿真工具(VCS,modelsim,NC sim),使用VPI有不同的方式。
本实验以modelsim为例。
a,编写C语言实现
hello.c
/*
* vpi simple test
* rill,2014-03-21
*/
#include "vpi_user.h"
static PLI_INT32 hello(PLI_BYTE8 * param) {
vpi_printf("Hello Rill!\n");
return 0;
}
// Associate C Function with a New System Task
void registerHelloSystfs(void) {
s_vpi_systf_data task_data_s;
vpiHandle systf_handle;
task_data_s.type = vpiSysTask;
task_data_s.sysfunctype = vpiSysTask;
task_data_s.tfname = "$hello";
task_data_s.calltf = hello;
task_data_s.compiletf = 0;
task_data_s.sizetf = 0;
task_data_s.user_data = 0;
systf_handle = vpi_register_systf(&task_data_s);
vpi_free_object(systf_handle);
}
// Register the new system task here
void (*vlog_startup_routines[]) () = {
registerHelloSystfs,
0 // last entry must be 0
};