DPI基础知识

在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 修饰,结果如下:

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值