学习记录23(DPI-C)
1.什么是DPI?
DPI(Direct Programming Interface),全称直接编程接口,是SV与其它语言(C/C++)交互的接口,基本上是唯一接口了。
2.为什么要用DPI?
大部分的模块级或者子系统级直接使用SV就能完成,但是更高一层就不行了,所以需要通过DPI来接入c语言,建立支持c语言的的测试环境,最好在子系统阶段就开始建立。
3.SV和c的调用关系
相互调用,sv调用c和sv,c调用sv和c,注意c不能调用sv中含有延时/耗时操作的那部分。
在调用时的主体依然是对应的语言,例如在sv中调用c,那么被调用的c仍然是在c环境下实现的,sv通过import进行导入。同理,c调用sv,那么s被调用的sv函数仍然是在sv中实现,通过export导出供c使用。下面演示sv中导入c函数,import就是让 SV 能调用 C 的函数,export就是让 C 能调用 SV 的函数


第二张图的逻辑是,sv调用c,在c函数内部调用sv把流程打通了。
4.sv和c数据类型的对应关系?
SV DPI-C接口:https://zhuanlan.zhihu.com/p/258390406
这个链接里的04知识点一定要知道,多语言调用:https://zhuanlan.zhihu.com/p/404764885
| sv | c | 位宽(字节) |
|---|---|---|
| byte | char | 8bit(1) |
| shortint | short int | 16bit(2) |
| int | int | 32bit(4) |
| longint | long long | 64bit(8) |
| shortreal | float | 32bit(4) |
| real | double | 64bit(8) |
| chandle(指针) | void* | 64bit(8) |
| string(指针) | char* | 64bit(8) |
调用的时候要注意四值逻辑还是二值逻辑,在调用时如果sv中的四值逻辑需要在c中调用,SV 的 logic 在 C 语言中会被映射为特定的结构体或数组,从而完整地保留其 0、1、X(未知)和 Z(高阻)四种状态。
标量 logic (单bit)--->C 语言的 svLogic 结构体(它实际上是一个包含两个 unsigned char 的结构体,aval (Actual Value): 存放实际的 0/1 值。bval (Bad Value): 用于表示 X 或 Z 状态)
向量 logic[N:0] (多位宽)--->C 语言的 svLogicVecVal 结构体数组(同上)
5.VPI与DPI的接口区别?
谈谈Verilog/System Verilog 和C的几种交互方式:cnblogs.com/Alfred-HOO/artickes/17470174.html
Verilog PLI 简介:https://www.runoob.com/w3cnote/verilog2-pli-intro.html
6.对寄存器的访问行为
只读/写,读,写
7.sv与c相互调用的写法
sv调用c
注意:调用时要声明import “DPI” context task c_test这里的函数名要与c中一致。

c调用sv
注意:
1)要写头文件include <svdpi.h> 。
2)要写外部调用关键字extern对函数名进行声明。

8.Makefile的改动
分成三步,分别是编译comp以及链接elab和运行run,也可以一步完成-R就是让仿真编译后直接执行(一步执行),编译后的文件默认是simv,可以通过-o来指定可执行文件名
增量编译:第一次编译很慢,后续修改某一个或者多个文件只编译修改的文件,不再编译未修改的文件
10.$test$plusargs()和$value$plusargs()
DPI最重要的一点就是可以调用外部其他由c底层构建的语言,例如python或者perl等,此外还能调用system()任务,也就是linux的一些命令行.如果需要返回值可以调用linux的system()或者wexitstatus任务(需要#include <wait.h>)
perl主要用处理文本,是日本基于c开发的一种脚本语言,下面展示用DPI调用c间接调用perl

$test$plusargs() —— 检查“开关”是否存在
作用:检查命令行中是否指定了某个“字符串标志”。它不关注值,只关注“有没有出现”。
语法:int found = $test$plusargs("字符串");
返回值:如果命令行中存在该字符串,返回 1(真);否则返回 0(假)。
常见用法:控制调试信息的开关(比如是否打印波形、是否开启详细日志)。
用法
initial begin
if ($test$plusargs("DEBUG")) begin
$display("调试模式已开启,将打印详细信息");
// 开启 verbose 打印
end else begin
$display("正常运行模式");
end
end
//命令行调用
./simv +DEBUG # 传入开关,触发调试模式
./simv # 不传入,进入正常运行模式
用法
initial begin
int test_seed;
string test_name;
// 获取整型参数 +seed
if ($value$plusargs("seed=%d", test_seed)) begin
$display("传入随机种子: %0d", test_seed);
end else begin
test_seed = 0; // 默认值
end
// 获取字符串参数 +test_name
if ($value$plusargs("test_name=%s", test_name)) begin
$display("运行测试用例: %s", test_name);
end else begin
test_name = "default_test";
end
end
//命令行调用
./simv +seed=12345 +test_name=reset_test
# 输出:传入随机种子: 12345
# 输出:运行测试用例: reset_test
上面两个方法就是常用于设置关键词,你加关键词和不加关键词会决定以什么方式编译执行
浙公网安备 33010602011771号