Verilog编程语言接口
在MacOS上使用Icarus Verilog时实现编程语言接口PLI
定义系统函数模块
// Icarus Verilog使用的头文件
# include <vpi_user.h>
// 编译时函数
static int hello_compiletf(char* user_data)
{
return 0;
}
// 调用时函数
static int hello_calltf(char* user_data)
{
vpi_printf("Hello, World!\n");
return 0;
}
// 注册函数,注册编译时函数和调用时函数
void hello_register()
{
s_vpi_systf_data tf_data;
tf_data.type = vpiSysTask;
tf_data.tfname = "$hello";
tf_data.calltf = hello_calltf;
tf_data.compiletf = hello_compiletf;
tf_data.sizetf = 0;
tf_data.user_data = 0;
vpi_register_systf(&tf_data);
}
// 加载模块时运行函数
void (*vlog_startup_routines[])() = {
hello_register,
0
};
仿真加载PLI模块时,首先检查函数指针数组startup,用0作为数据结束符。
接着运行startup中指定的函数,通常为register函数,注册对应的系统函数。
compiletf函数为vvp加载模块自动编译时执行,通常用于监测param参数状态。也可以留空。
calltf指函数为verilog中每次调用PLI执行的结果。
注意 vpi_子程序是存取子程序(acc_)和实用子程序(tf_)的拓展集合。
编译PLI模块
使用GCC编译
# 编译目标文件.o
gcc -c -fpic hello.c
# 编译得到模块文件.vpi
gcc -shared -o hello.vpi hello.o -lvpi
前提:安装有vpi_user.h和vpi的动态链接库
使用Icarus编译
# 编译得到.o和.vpi文件
iverilog-vpi hello.c
调用系统函数
在verilog中调用自定义系统函数
module main;
initial $hello;
endmodule
运行系统仿真
# 编译verilog文件得到仿真文件.vvp
iverilog -ohello.vvp hello.v
# 运行仿真
vvp -M. -mhello hello.vvp
参数-M指定搜索路径 在这里为当前文件夹
参数-m指定系统函数模块名 在这里为hello