sv中义引入了直接编程接口dpi(direct programming interface),他能更简单的连接C,C++,或者其他非verilog语言。一旦声明或者使用import语句导入了一个C子程序,就可以调用它。C代码也可以很方便的调用verilog中的子程序。应用场景主要体现在:
(1)我们知道,在模块级乃至子系统级的验证,使用SV就完全够用了,而在更上面的层级,例如系统级,多采用大量的C代码组成。那么为了完成测试用例从子系统到系统级的复用,我们最好在子系统级开始就有意识地建立支持C测试的环境,并且使用一些基于C的测试用例,这样才能使得整体具有更好的复用性。
(2)处理器的需要。子系统测试时,不一定本身自带了处理器的硬件实例(Verilog编写的),因此在构建子系统时还要考虑如何模拟外部处理器对子系统的访问行为。
1.1 传递数值
1.1.1 传递整数与实数
sv与c之间传递的最基本的数据类型就是int类型,他是一个双状态,32位的数据类型。下面举一个例子怎么在sv中调用C的子程序。
例:调用factory()函数
import "DPI-C" function int factory(input int i);
program automatic test;
initial begin
for(int i =1;i<10;i++) begin
$display("%0d = %0d ",i,factory(i));
end
end
endprogram
- 首先要声明import语句,表明factory函数使用其他语言C或C++实现,修饰符DPI-C表明这是一个dpi子程序
- 然后在sv中使用这个函数的时候直接用就好,会返回数值给sv
- 其中import声明中将带有返回值的C函数会被映射成sv函数,void类型的会被映射成一个sv任务或void函数
- 可以更改C中函数的名字,修改语句为import “DPI-C” test=function void my_test();此时将test修改为my_test
使用时的注意事项有:
- 需要注意的是,被导入的子程序只在有定义的地方在使用,多个地方用可以设置一个包 ,每次导入即可
- 导入的C子程序可以有多个参数或者没有参数。缺省情况下,参数的方向是input(sv流向C),但是也可以定义为output以及inout,不支持ref类型,函数也可以返回一个简单的值。
- 为了减少C代码中的漏洞,可以将任意输入参数定义为const。这样一旦对输入变量进行写操作,就会报错
1.1.2 数据类型
SV和C之间的数据类型不是完全一致的,所以肯定需要转换,对应关系如下:
值得注意的是有些映射关系并不完全准确,例如bit映射的svbit,而svbit又会映射为unsigned char类型,但这样一来容易在变量的高位写入非法的数据值 。
在C的一侧,如果需要引用sv中的函数,则只需要extern void sv_function();就可以了