本文接上一篇文章,即调用System Verilog 任务的C 任务,简介如下
https://blog.csdn.net/qq_31348733/article/details/101000399
如何在C语言中调用SV方法呢,显然定义在类中的方法我们无法直接调用,因为当SV编译器编译代码时,对象还不存在。为了解决这个问题,我们可以在SV和C之间传递一个对象引用。但是跟C指针不同的是,SV句柄不能通过DPI传递,不过可以定义一个句柄数据组,然后在两种语言之间传递数组的索引。
下面是一个实例:
带有内存模型类的System Verilog模块
//tb_top.sv
`timescale 1ns/1ns
module tb_top;
//=====================================================================\
// ********** Define Parameter and Internal Signals *************
//=====================================================================/
//======================================================================
// *************** Main Code ****************
//======================================================================
import "DPI-C" context task readFile(string fname);
export "DPI-C" task memRead;
export "DPI-C" task memWrite;
export "DPI-C" function memBuild;
initial begin
readFile("mem.dat");
end
//类中的方法不能导出
class Memory;
int mem[];
function new(input int mSize);
mem = new[mSize];
endfunction:new
task memRead(input int addr, output int data);
#20
data = mem[addr];
$display("reading data.----time:%0t", $time);
endtask:memRead
task memWrite(input int addr, input int data);
#10
mem[addr] = data;
$display("write successfully!----addr = %0d, data = %0d----time:%0t", addr, data, $time);
endtask:memWrite
endclass:Memory
Memory memq[$];
//创建一个新的内存实例并将其压入队列
function int memBuild(input int size);
Memory m;
m = new(size);
memq.push_back(m);
$display("SV:M%0d allocate memory----size = %0d----time:%0t", memq.size()-1, size, $time);
return memq.size()-1;
endfunction:memBuild
task memRead(input int idx, addr, output int data);
$write("M%0d: ",idx) ;
memq[idx].memRead(addr, data);
endtask:memRead
task memWrite(input int idx, addr, data);
$write("M%0d: ",idx) ;
memq[idx].memWrite(addr, data);
endtask:memWrite
endmodule
下面是调用带OOP内存的导出任务的C代码:
#include <stdio.h>
extern int memBuild(int);
extern void memRead(int idx, int addr, int *data);
extern void memWrite(int idx, int addr, int data);
int readFile(char *fname){
int cmd, idx;
FILE *file;
int addr, data, exp;
file = fopen(fname, "r");
while(!feof(file)){
cmd = fgetc(file);
fscanf(file, "%d", &idx);
switch(cmd){
//分配内存
case 'M':{
int hi, qidx;
fscanf(file, "%d", &hi);
qidx = memBuild(hi);
break;
}
//读内存
case 'R':{
fscanf(file, "%c %d %d",&cmd, &addr, &data);
memRead(idx, addr, &exp);
if(exp == data){
io_printf("read successfully!----addr = %d data = %d\n", addr, data);
}
else{
io_printf("read error!---- addr = %d data should be %d, but it is %d now.\n", addr, exp, data);
}
break;
}
//写内存
case 'W':{
fscanf(file, "%c %d %d",&cmd, &addr, &data);
memWrite(idx, addr, data);
break;
}
}
}
fclose(file);
}
下面是命令文件:
M0 1000
M1 2000
M2 3000
W0 1 1
W0 2 2
W0 3 3
W1 1 2
W1 2 3
W1 3 4
W2 1 3
W2 2 4
W2 3 5
R0 1 1
R0 1 2
R1 2 2
R1 2 3
R2 3 2
R2 3 5
程序运行结果:
# SV:M0 allocate memory----size = 1000----time:0
# SV:M1 allocate memory----size = 2000----time:0
# SV:M2 allocate memory----size = 3000----time:0
# M0: write successfully!----addr = 1, data = 1----time:10
# M0: write successfully!----addr = 2, data = 2----time:20
# M0: write successfully!----addr = 3, data = 3----time:30
# M1: write successfully!----addr = 1, data = 2----time:40
# M1: write successfully!----addr = 2, data = 3----time:50
# M1: write successfully!----addr = 3, data = 4----time:60
# M2: write successfully!----addr = 1, data = 3----time:70
# M2: write successfully!----addr = 2, data = 4----time:80
# M2: write successfully!----addr = 3, data = 5----time:90
# M0: reading data.----time:110
# read successfully!----addr = 1 data = 1
# M0: reading data.----time:130
# read error!---- addr = 1 data should be 1, but it is 2 now.
# M1: reading data.----time:150
# read error!---- addr = 2 data should be 3, but it is 2 now.
# M1: reading data.----time:170
# read successfully!----addr = 2 data = 3
# M2: reading data.----time:190
# read error!---- addr = 3 data should be 5, but it is 2 now.
# M2: reading data.----time:210
# read successfully!----addr = 3 data = 5
转载:https://blog.csdn.net/qq_31348733/article/details/101033155
查看评论