DPI系列一:指南翻译
[原文链接:http://www.testbench.in/DP_00_INDEX.html]
1. Introductions
1.1 what is Dpi-C
- 长久以来,用户需要一种简单的方式用于verilog和其他语言的通信,然而VPI和PLI用起来过于复杂,即便一个很简单的程序,用户也需深刻理解其底层原理才行。但是大部分时候,用户无需VPI和PLI的复杂、强大功能。基于此,DPI应运而生,其基于synopsys提供的DirectC接口发展而来。DPI支持C语言等待SV语言中的事件,SV也可屏蔽C中的函数或任务。
DPI包含两个独立的层次:SV层和其他语言层,两个层次彼此独立,在两种语言编译时,都互不依赖。
DPI-C遵循黑盒原则,组件的定义和实现分离,真实的实现对于系统来说是透传的。其独立性是基于C将函数封装成SV可识别的函数单元。
2. Layers
- TODO
3. Import
3.1 Import methods
- C中实现的方法在SV中import后,可直接由SV调用,这类方法就称为import method。导入的task、function和SV自定义的方法类似,仍然可以有0个或多个常规的input、output、inout参数。
作为DPI-C禁用协议的一类,导入的task总是返回int型,因此在C中需定义为int函数。接下来我们将讨论DPI-C的禁用协议。
导入函数可以返回结果,或可以被定义为void函数。
导入函数的语法如下:
import {“DPI” | “DPI-C”} [context | pure] [c_identifier =] [function|task] [function_identifier|task_identifier] ([tf_port_list]);
3.2 Steps to write import methods
- In SV Code
a、导入C函数(可在module、program、package中导入,可在class外导入,不能在class中导入)
b、调用导入的C函数
program main;
string str;
import "DPI-C" string_sv2c=task string_sv2c();
initial
begin
string_sv2c();
end
endprogram
- IN C Code: c_code.c
定义上述导入的C函数
#include "svdpi.h"
void string_sv2c(){
printf(" C: Hellow from C ");
}
- **Simulation
step1:GCC编译C代码为so库
gcc c_code.c -nostartfiles -fPIC -shared -I /eda/synopsys/vcsmx_2016.06/include -o lib.so
step2:VCS编译SV代码
不依赖C代码,常规编译即可
step3:VCS仿真
用参数-sv_lib调用步骤1生成的lib.so: -sv_lib lib(不加lib.so的后缀)
Result
C: Hellow from C
3.3 Standard C Functions
- 用户也可以调用标准C函数,例如
import "DPI" function chandle malloc(int size);
import "DPI" function void free(chandle ptr);
4. Naming
- TODO
5. Export
5.1 Export methods
- 在SV中定义并声明为export的方法可以被C调用,称这些方法为export methos。
5.2 Steps to write export method
- In SV Code
program main;
export "DPI-C" function export_func;
import "DPI-C" function void import_func;
function void export_func();
$display("SV: Hello from SV");
endfucntion
initial begin
import_func();
end
endprogram
- In C Code
extern void export_func(void);
void import_func(){
export_func();
}
- Result
SV: Hello from SV
5.3 Blocking Export Dpi Task
- SV DPI允许C调用SV中消耗时间的task
In SV Code
program main;
export "DPI-C" task export_task;
import "DPI-C" context task import_task();
task export_task();
$display("SV: Entered the export function . wait for some time : %0d ",$time);
#100;
$display("SV: After waiting %0d",$time);
endtask
initial begin
$display("SV: Before calling import function %0d",$time);
import_task();
$display("SV: After calling import function %0d",$time);
end
endprogram
In SV Code
extern void export_task();
void import_task() {
printf(" C: Before calling export function\n");
export_task();
printf(" C: After calling export function\n");
}
- Result
SV: Before calling import function 0
C: Before calling export function
SV: Entered the export function . wait for some time : 0
SV: After waiting 100
C: After calling export function
SV: After calling import function 100