进行数字设计时,经常会遇到特殊的情况,Verilog 中的任务和函数已经不能满足仿真需求,需要自定义一些系统任务和函数。编程语言接口(PLI, Program Language Interface)提供了一套接口子程序,用于访问设计内部的数据结构,并可以提取仿真环境信息。用户可以调用这些子程序,自定义系统任务和系统函数,与设计内部数据以及 Verilog 仿真器环境进行交互。
通俗来讲,Verilog PLI 提供了一套 C 语言函数, 设计人员可以调用这些集成函数编写软件 C 程序。RTL 编译时,将编写的软件程序也集成到仿真环境中。仿真运行时,通过系统任务调用的方式,就可以动态的去访问仿真中的数据结构。这种访问是双向的,不仅可以从仿真器的数据结构中读取信息, 还能修改数据结构的信息。
PLI 的功能是十分强大的,其用途只局限于设计人员的想象力。
这里总结下 PLI 经常使用的功能:
PLI 的发展主要经历了 3 代。
第一代被称为任务/函数(Task/Function)接口,简称 TF 接口。TF 接口包含一套 C 语言函数库,均以 tf_ 为前缀,定义在 veriuser.h 中。这些 C 函数一般称为 TF 子程序,主要包括用户自定义任务和函数、实用函数、回调机制和数据写输出。
第二代被称为存取(Access)接口,简称 ACC 接口。ACC 接口中的函数均以 acc_ 为前缀,定义在 acc_user.h 中。ACC 子程序主要用于访问和修改 Verilog 描述的多种对象。ACC 库函数是 TF 库函数的叠加,而非替换。
一般 PLI 接口特指是 TF 和 ACC 接口。
第三代被称为过程接口(Verilog Process Interface),简称 VPI 接口。VPI 子程序是 TF 和 ACC 子程序功能的合集,定义在 vpi_user.h 中。
相对于 PLI 子程序又多又乱,VPI 尤显精炼。由于 PLI 诞生之初,没有统一的标准,完全是在实践中发展,导致常用的 PLI 库函数有近百个,写程序时基本都要查手册。
而 VPI 是根据一定的标准统筹规划制定的,融入了很多面向对象的思想,库函数精简度远超 PLI。但是 VPI 结构比较复杂,不容易上手。VPI 最大的弱点还是对仿真器的支持并不友好。
作为 Verilog 的扩展,2003 年 SystemVerilog 标准发布,支持更多形式的仿真。
DPI 接口(Direct Procee Interface)成为软件与 SystemVerilog 交互的接口,目前占主流。
一般情况下,使用 PLI 的 TF 和 ACC 接口就能满足仿真需求了。本章只对 TF 和 ACC 接口进行简单介绍。其他接口待那个少年学成之日,再一一分享给大家。
通过编写系统任务和系统函数, 用户能够用 PLI 和 C 程序扩展 Verilog 语言。这些用户定义的系统任务和函数的名称必须以美元符号 “$” 开头。此时 Verilog 里面的任务相当于一个子程序。当调用任务时,仿真器的执行流程跳转到子程序,完成任务后执行流程返回。Verilog 任务并不返回数值,但是可以有输入、输出和双向的形参。
Verilog 里面的函数跟大多数语言里面的函数一样。 当调用函数时,它运行一套指令,然后返回一个数值给调用它的指令。
使用 PLI 接口完成用户自定义系统任务的基本流程如下所示。
下面以简单的系统任务 $hello_w3cschool 为例进行说明。该系统任务被调用时,会输出一行字符串 “Hello w3cschool!”。
用 C 语言描述的打印程序如下所示,文件命名为 hello_w3cschool.c 。
为说明 PLI 使用的一般流程,此程序并没有调用 TF/ACC 子程序。
#include "stdio.h" //不包含 PLI 库子程序
int hello_w3cschool(){
printf("Hello w3cschool!
");
}
以 VCS 使用为例,编译或创建 VCS 编译时需要的与 C 相关的文件。
对上述 hello_w3cschool.c 进行简单的编译,输出 hello_w3cschool.o 文件。注意相对路径。
gcc -c ../tb/hello_w3cschool.c
创建 VCS 可识别的链接 table 文件,文件命名为 hello_w3cschool.tab, 内容如下。
$hello_w3cschool call=hello_w3cschool
在 Verilog 中以系统任务调用的方式调用 $hello_w3cschool,描述如下。
`timescale 1ns/1ps
module test ;
initial begin
#10 ;
$hello_w3cschool;
end
initial begin
forever begin
#100;
if ($time >= 10000) $finish ;
end
end
endmodule
对 RTL 和 编写的 PLI 中间文件进行编译。表明要链接 PLI 库中的表文件时,需要用 “-P” 参数指定。例如该仿真中应该在 VCS 命令行中增加如下参数(注意相对路径):
-P ../tb/hello_w3cschool.tab hello_w3cschool.o
仿真结果中可以看到打印的信息,截图如下。
点击这里下载源码