学习记录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 的函数

image
image
第二张图的逻辑是,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中一致。
image

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

image

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
image

$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                 # 不传入,进入正常运行模式
**$value$plusargs() —— 获取“键值对”的值** 作用:从命令行中解析一个“键=值”对,并把值赋给一个变量。它不仅能查存在性,还能把值传进来。 语法:int found = $value$plusargs("格式字符串", 变量); 返回值:如果命令行匹配成功并成功赋值,返回 1(真);否则返回 0(假)。 格式字符串:使用 %d(十进制)、%h(十六进制)、%s(字符串)等,与 $display 类似,但要加上 = 号。 -
用法
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

上面两个方法就是常用于设置关键词,你加关键词和不加关键词会决定以什么方式编译执行

posted on 2026-08-05 17:56  tuck0603  阅读(7)  评论(0)    收藏  举报

导航