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

Lei Yang
Lei Yang
PhD candidate

My research interests include visual speech recognition and semantics segmentation.