admin管理员组文章数量:1572326
在2003年IEEE 1800 SV LRM 3.1a中提出了一种直接编程语言接口DPI(Direct Programming Interface),SystemVerilog DPI(直接编程接口)是将SystemVerilog与外部语言连接的一个接口;DPI能够更简洁的连接C/C++或者其他非verilog编程语言,只要使用 import 声明和使用,导入一个C子程序,就可以像调用SystemVerilog中的子程序一样来调用该C子程序;
DPI由两层组成:SystemVerilog层和外部语言层,两层都彼此隔离,实际使用哪种编程语言作为外语是透明的,与此接口的SystemVerilog端无关;理论上外部语言可以是C,C ++,SystemC以及其他语言。但是现在,SystemVerilog仅为C语言定义了一个外部语言层,也就是说目前 DPI 只支持 C;
来看下面一个简单的例子:
module test;
import "DPI-C" pure function void from_c();//导入外部c
initial begin
$display("Entering in sv initial block");
#20;
from_c();
#5;
$display("Exiting from sv initial block");
end
endmodule
外部的C :
#include <stdio.h>
#include "svdpi.h"
void from_c()
{
printf("C scope: +++++++++++++++\n");
}
在VCS编译选项中直接加入 C 文件会直接进行编译 ,运行结果如下:
通过DPI可以在SystemVerilog中调用C语言中的function(C语言中没有task),当然,也可以通过DPI调用SystemVerilog中的task和function;
上面提到过,DPI 由两个 layer 组成,即 SV层和其他语言层,并且这二者的编译 也是独立的;在 DPI 的这种分层结构中,遵循的是一种 “黑盒” 规则:组件的规范和实现明确分开,实际实现对该语言编写代码的其余部分是透明的,而对于通过DPI使用其方法的语言为不透明的。例如,C语言编写的方法,对于通过DPI使用其的SystemVerilog来说是一个黑盒子但是SystemVerilog无需更改即可对其进行调用;
如何实现DPI?
1.在 sv 中导入 c
语法:
import "DPI-C" [from_c_name =] [pure][context] function type to_sv_name(args);
import "DPI-C" [from_c_name =] [context] task to_sv_ame (args);
// from_c_name 为 c 侧的function 名字
// to_sv_name 为 c function 在 sv 中修改后的使用名字,这可以防止 from_c_name 与 sv 中的 function 出现同名的情况
经过 DPI-C 导入的 c 函数可以在 sv 的function 或 task 中直接调用,但是只在DPI 被声明的空间内有效;
从上述语法结构我们可以看出,import使用方式主要有三种,下面将示例import的三种用法;
这里需要注意,pure和context仅能在import时使用,并且pure不能用于task;
1.1 context 方式
在导入方法时,有时需要知道被调用的环境的上下文信息,简单来说就是 import 的方法中除了访问 sv 中传入的形参之外,还调用了sv 中的其他数据或者方法,此时就必须在DPI 声明之前加上 context 修饰;
使用context导入方法的方式,因为需要记录import方法调用时上写文环境,会带来一些额外的开销导致仿真的效率变低,所以一般情况下不要使用context方式;看下面例子:
module test;
import "DPI-C" context function void from_c();
export "DPI-C" function from_sv;//export 不需要加任何参数,也不用加 void 修饰
function void from_sv();
$display("SV scope: ***************");
endfunction
initial begin
$display("Entering in sv initial block");
#20;
from_c();
#5;
$display("Exiting from sv initial block");
end
endmodule
#include <stdio.h>
#include "svdpi.h"
extern void from_sv();
void from_c()
{
printf("C scope: +++++++++++++++\n");
from_sv();
}
上面的例子中, from_c 函数中调用了来自 sv export 的function from_sv,所以在 sv 中 import 时必须加 context 修饰,结果如下:
版权声明:本文标题:DPI基础知识 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://www.elefans.com/dianzi/1727724836a1127104.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论