B.1 PLI子程序分类总览
PLI子程序按功能分为三大类:
| 类别 | 前缀 | 功能 | 典型用途 |
|---|---|---|---|
| 任务/函数子程序 | tf_ |
处理用户自定义任务的参数、返回值、回调等 | 自定义系统任务 |
| 存取子程序 | acc_ |
读写设计对象(信号、模块、端口等) | 设计信息提取 |
| VPI子程序 | vpi_ |
TF/ACC的超集,统一接口 | 新设计推荐使用 |
B.2 TF子程序(任务/函数子程序)
一、参数获取与设置
| 子程序 | 功能 | 示例 |
|---|---|---|
tf_getp(n) |
获取第n个输入参数的整数值 | int a = tf_getp(1); |
tf_putp(n, val) |
设置第n个输出参数的整数值 | tf_putp(1, 42); |
tf_getlongp(h, n) |
获取长整数参数(高32位) | tf_getlongp(&h, 1); |
tf_putlongp(n, h, l) |
设置长整数参数 | tf_putlongp(1, hi, lo); |
tf_getrealp(n) |
获取实数参数 | double r = tf_getrealp(1); |
tf_putrealp(n, val) |
设置实数参数 | tf_putrealp(1, 3.14); |
tf_gettime() |
获取当前仿真时间 | time_t t = tf_gettime(); |
tf_getinstance() |
获取当前任务实例的句柄 | handle h = tf_getinstance(); |
二、字符串参数
| 子程序 | 功能 |
|---|---|
tf_getcstringp(n) |
获取第n个参数的字符串 |
tf_putcstringp(n, str) |
设置第n个参数的字符串 |
tf_getstringp(n) |
获取字符串参数(旧版) |
tf_putstringp(n, str) |
设置字符串参数(旧版) |
三、错误与信息输出
| 子程序 | 功能 | 示例 |
|---|---|---|
tf_error(fmt, ...) |
输出错误信息 | tf_error("Value out of range"); |
tf_warning(fmt, ...) |
输出警告信息 | tf_warning("Signal is x"); |
tf_message(level, fmt, ...) |
输出指定级别的信息 | tf_message(1, "Info: %d", val); |
io_printf(fmt, ...) |
格式化输出(最常用) | io_printf("Hello %s\n", name); |
io_scanf(fmt, ...) |
从输入读取格式化数据 | io_scanf("%d", &num); |
vpi_printf(fmt, ...) |
VPI版本的格式化输出 | vpi_printf("Value = %d\n", val); |
四、仿真控制
| 子程序 | 功能 |
|---|---|
tf_dostop() |
暂停仿真(相当于 $stop) |
tf_dofinish() |
结束仿真(相当于 $finish) |
tf_gettime() |
获取当前仿真时间 |
tf_settime(t) |
设置当前仿真时间(慎用) |
五、回调(Callback)相关
| 子程序 | 功能 |
|---|---|
tf_add_long(&val, inc) |
长整数加法 |
tf_sub_long(&val, dec) |
长整数减法 |
tf_getlongtime() |
获取长整数格式的仿真时间 |
tf_setlongtime(t) |
设置长整数格式的仿真时间 |
tf_scale_long() |
时间缩放 |
tf_compare_long(a, b) |
长整数比较 |
B.3 ACC子程序(存取子程序)
一、初始化与关闭
| 子程序 | 功能 |
|---|---|
acc_initialize() |
初始化ACC环境(必须首先调用) |
acc_close() |
关闭ACC环境,释放资源 |
二、句柄与遍历
| 子程序 | 功能 | 示例 |
|---|---|---|
vpi_handle(type, ref) |
获取句柄 | vpiHandle h = vpi_handle(vpiTop, NULL); |
vpi_handle_by_name(name, scope) |
根据名字获取句柄 | vpiHandle h = vpi_handle_by_name("top.clk", NULL); |
vpi_iterate(type, ref) |
创建迭代器 | vpiHandle it = vpi_iterate(vpiModule, top); |
vpi_scan(it) |
遍历下一个对象 | vpiHandle obj = vpi_scan(it); |
vpi_get_value(obj, val) |
获取信号值 | s_vpi_value val; vpi_get_value(h, &val); |
vpi_put_value(obj, val, delay, flags) |
设置信号值 | vpi_put_value(h, &val, NULL, vpiNoDelay); |
三、注册回调
| 子程序 | 功能 |
|---|---|
vpi_register_cb(cb_data) |
注册回调函数 |
vpi_remove_cb(cb_handle) |
移除回调 |
vpi_register_systf(systf_data) |
注册系统任务/函数 |
vpi_get_cb_info(obj, cb_data) |
获取回调信息 |
四、常用回调类型
| 回调类型 | 触发时机 |
|---|---|
cbValueChange |
信号值变化时 |
cbAfterDelay |
延迟指定时间后 |
cbReadWriteSynch |
读写同步时 |
cbEndOfSimulation |
仿真结束时 |
cbStartOfSimulation |
仿真开始时 |
cbNextSimTime |
下一个仿真时间步 |
cbSignal |
信号事件 |
五、VPI对象类型(常用)
| 类型 | 含义 |
|---|---|
vpiModule |
模块 |
vpiPort |
端口 |
vpiNet |
线网 |
vpiReg |
寄存器 |
vpiIntegerVar |
整数变量 |
vpiParameter |
参数 |
vpiPrimitive |
原语 |
vpiTop |
顶层模块 |
vpiScope |
作用域 |
B.5 完整示例:用ACC子程序读取信号值
下面是一个使用ACC子程序读取信号值并打印的C程序示例:
// ============================================================
// 文件名:read_signal.c
// 功能:用ACC子程序读取信号值并打印
// ============================================================
#include <stdio.h>
#include "acc_user.h" // ACC子程序头文件
// 用户自定义系统任务:$read_signal
int read_signal() {
handle signal_handle;
char value_str[256];
// 初始化ACC环境(必须首先调用)
acc_initialize();
// 获取信号句柄(假设信号名为 top.data)
signal_handle = acc_handle_object("top.data");
if (signal_handle == NULL) {
io_printf("Error: Signal not found!\n");
acc_close();
return 1;
}
// 获取信号值,格式为二进制字符串
acc_fetch_value(signal_handle, "%b", value_str);
// 打印信号名和值
io_printf("Signal %s = %s\n",
acc_fetch_fullname(signal_handle),
value_str);
// 关闭ACC环境
acc_close();
return 0;
}
对应的Verilog调用:
module test;
reg [7:0] data;
initial begin
data = 8'hA5;
#10 $read_signal; // 调用用户自定义任务
$finish;
end
endmodule
仿真输出:
Signal top.data = 10100101
B.6 使用注意事项
| 注意事项 | 说明 |
|---|---|
| 仿真器差异 | 不同仿真器的PLI实现略有不同,具体以文档为准 |
| 头文件 | TF/ACC用 veriuser.h 和 acc_user.h,VPI用 vpi_user.h |
| 初始化 | 使用ACC前必须调用 acc_initialize(),结束时调用 acc_close() |
| 编译链接 | 需要将C代码编译为共享库,并在仿真时指定库路径 |
| 综合不支持 | PLI仅用于仿真,综合工具不支持PLI |