一、什么是DPI?
DPI即Direct Programming Interface,就是system verliog与C\C++语言的交互接口。
- 允许SystemVerilog调用C函数像SystemVerilog调用SV的任务或者函数一样。
- sv与c/c++变量直接相互传递,SystemVerilog可以调用C,C可以调用SV。
- 使用者想用C/C++能够复用到SV,DPI很容易实现C/C++代码连接到SV的复用。
1、利用DPI实现SV与C的相互调用
import "DPI" context task c_test(input int base_addr);//SV文件中加入import
program automatic top;
semaphore bus_sem = new(1);
export "DPI" task apb_write; //SV文件中加入export
task apb_write(input int addr, data);
bus_sem.get(1);
#10
$display("VLOG : APB Write : time = %0t,Addr = 0x%0x, Data = 0x%0x ", $time,addr, data);
bus_sem.put(1);
endtask
initial begin
fork
c_test(32'h1000);
c_test(32'h2000);
join
end
endprogram
#include <svdpi.h> //C文件中加入头文件
extern void abp_write(int, int);//C文件中加入extern
void c_test(int base)
{
int addr, data;
for(addr=base; addr<base+5; addr++) {
data = addr*100;
apb_write(addr, data);
printf("C_TEST: APB_Write: addr = 0x%0x, data = 0x%0x\n",addr, data);
}
}
打印结果:
VLOG : APB Write :time = 10 Addr = 0x2000, Data = 0xc8000
C_TEST: APB_Write: addr = 0x1000, data = 0x64000
VLOG : APB Write :time = 20 Addr = 0x1001, Data = 0x64064
C_TEST: APB_Write: addr = 0x2000, data = 0xc8000
VLOG : APB Write :time = 30 Addr = 0x2001, Data = 0xc8064
C_TEST: APB_Write: addr = 0x1001, data = 0x64064
VLOG : APB Write :time = 40 Addr = 0x1002, Data = 0x640c8
C_TEST: APB_Write: addr = 0x2001, data = 0xc8064
VLOG : APB Write :time = 50 Addr = 0x2002, Data = 0xc80c8
C_TEST: APB_Write: addr = 0x1002, data = 0x640c8
VLOG : APB Write :time = 60 Addr = 0x1003, Data = 0x6412c
C_TEST: APB_Write: addr = 0x2002, data = 0xc80c8
VLOG : APB Write :time = 70 Addr = 0x2003, Data = 0xc812c
C_TEST: APB_Write: addr = 0x1003, data = 0x6412c
VLOG : APB Write :time = 80 Addr = 0x1004, Data = 0x64190
C_TEST: APB_Write: addr = 0x2003, data = 0xc812c
VLOG : APB Write :time = 90 Addr = 0x2004, Data = 0xc8190
C_TEST: APB_Write: addr = 0x1004, data = 0x64190
VLOG : APB Write :time = 100 Addr = 0x2004, Data = 0xc8190
C_TEST: APB_Write: addr = 0x2004, data = 0xc8190
说明:
- 需要在文件中加入头文件和extern、import、export
- 只能用VCS才能编译C文件,不能使用vlogan编译C文件
2、利用DPI调用C语言间接调用perl脚本
import "DPI-C" function int call_perl(string s);
program automatic test;
int ret_val ;
string script;
initial begin
if(!$test$plusargs("script"))begin
$display("NO +script switch found");
$finish;
end
else begin
$value$plusargs("script=%s",script);//匹配字符串
$display("SV: Running '%s'",script);//打印剩余的字符串
ret_val = call_perl(script);
$display("SV: Perl script return %0d",ret_val);
end
end
endprogram : test
//C文件
#include <svdpi.h>
#include <stdlib.h>
#include <wait.h>
int call_perl(const char* command)
{
int result = system(command);//系统函数去调用perl脚本
return WEXITSTATUS(result);
}
//perl文件
#!/usr/bin/perl
print "Perl :Hello World! \n";
exit (5)
打印结果:
SV: Running 'perl hello.pl'
Perl :Hello World!
SV: Perl script return 5
说明:编译脚本RUN中加入了 +script="perl hello.pl"
- 系统函数$test$plusargs (string):用来仿真时外面传入字符串,用于搜索用户指定的字符串这个字符串不包含脚本命令行参数的前导加号(+)。按照+号后面由前向后匹配字符串的顺序,只要匹配到代码中给的字符就匹配成功,匹配成功返回1,否则返回0。
- 系统函数$value$plusargs (string1, variable),string1除了和上述中的string是同样的含义还可以指定一个传数据的格式(一般就是%s,%d等),variable指的是string1和脚本中的指定的字符串匹配完成后剩余的字符串,剩余的字符串会按照string中指定的格式赋值给variable,如果没有剩余的字符串,则存储到变量中的值应该是0或空字符串值。
- DPI调用外部其他语言,最简单的办法就是调用system()任务,如果需要命令的返回值,使用linux的system()函数和WEXITSTATUS任务(需要#include <wait.h>,若要调用tcl、python等其他语言,只要把编译脚本中的+script="改成对应语言文件"。
- SV基础学习基本更新完成拉~