小言_互联网的博客

System Verilog——C语言调用SV对象中的方法

282人阅读  评论(0)

本文接上一篇文章,即调用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
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场