在仿真驗(yàn)證中,SV語(yǔ)言不能很好的描述復(fù)雜的計(jì)算或者流程關(guān)系,使用軟件語(yǔ)言(比如C)就比較方便。那么當(dāng)我們使用C描述了這些關(guān)系后,如何在基于SV的仿真環(huán)境中使用呢?有兩種方式,一種是將C編譯為可執(zhí)行文件,利用系統(tǒng)函數(shù)進(jìn)行調(diào)用。另外一種方式利用SV提供的 DPI-C接口。第一種方式并不是嚴(yán)格意義上的SV和C的對(duì)接,只是通過(guò)命令行執(zhí)行了C程序。比如我們寫(xiě)了一個(gè)hello world的c程序:
int main(){
printf(“hello world!/n”);
return 0;
}
我們將其編譯為可執(zhí)行文件gcc -o hello hello.c
我們就可以在我們的SV函數(shù)中直接執(zhí)行:
function void exe();
$system(“./hello”);
Endfunction
除了這個(gè)方式,SV還提供了和C/C++直接的接口DPI。DPI接口允許用戶用C編寫(xiě)程序,并和SV實(shí)現(xiàn)對(duì)接,也可以用SV寫(xiě)程序,將SV程序?qū)С龅絚中。二者實(shí)現(xiàn)了相互調(diào)用。如何要在SV中使用自己定義的C函數(shù),需要在SV中導(dǎo)入函數(shù)。比如:
module Bus(input In1, output Out1);
import "DPI" function void slave_write(input int address,
input int data);
export "DPI" function write; // Note – not a function prototype
// This SystemVerilog function could be called from C
function void write(int address, int data);
// Call C function
slave_write(address, data); // Arguments passed by copy
endfunction
...
endmodule
C中為:
#include "svdpi.h"
extern void write(int, int); // Imported from SystemVerilog
void slave_write(const int I1, const int I2)
{
buff[I1] = I2;
...
}
C函數(shù)slave_write在SV中被調(diào)用,其有兩個(gè)參量 address和data。在C函數(shù)中通常要包含兩個(gè)頭文件:svdpi.h和svdpi_src.h。
C和SV的數(shù)據(jù)類型有以下幾種對(duì)應(yīng)關(guān)系:
我們需要注意SV和C之間參量傳遞有兩種方式,一種是值傳遞,比如byte-char,shortint-short int等,另外一種方式是通過(guò)指針傳遞,比如在SV中packed和unpacked的數(shù)組,是通過(guò)引用傳遞到C的,那么C中就使用指針來(lái)進(jìn)行接收。比如bit[n:0]作為packed數(shù)組,傳遞到C中是用svBitVecVal*來(lái)接收的,svBitVecVal是一個(gè)宏定義,實(shí)際上就是32bit數(shù)據(jù)。在這里需要注意的是,n bit的SV數(shù)據(jù)在C中是以32bit數(shù)據(jù)存放的,按照小端排列。比如bit[127:0] a,對(duì)應(yīng)的C中數(shù)據(jù)svBitVecVal* b,有以下對(duì)應(yīng)關(guān)系:
a[31:0] = b[0]
a[63:32] = b[1]
…
這點(diǎn)初學(xué)者很容易掉坑里,我一開(kāi)始在傳遞這個(gè)變量的時(shí)候以為是一個(gè)svBitVecVal存儲(chǔ)1bit數(shù)據(jù)。在SV測(cè)的多維數(shù)據(jù)也都可以在C中使用1維指針接收,比如有以下函數(shù):
Void write(svBitVecVal* data){
}
SV中可以為:
Import “DPI-C” function void write(bit[127:0] data[16][16]);
這樣在C中讀寫(xiě)data數(shù)據(jù)的時(shí)候就需要通過(guò)指針來(lái)確認(rèn)數(shù)據(jù)位置。指針指向了數(shù)據(jù)data的第一個(gè)32bit數(shù)據(jù),即data[0][0][31:0],之后數(shù)據(jù)往后增加指針即可得到。
對(duì)于unpacked的數(shù)組數(shù)據(jù),在C中可以使用指針直接訪問(wèn),但是在packed中的數(shù)據(jù),卻只允許使用定義的函數(shù)來(lái)讀寫(xiě)。這些函數(shù)有:
svBit svGetSelectBit(const svBitPackedArrRef s, int i);
svLogic svGetSelectLogic(const svLogicPackedArrRef s, int i);
void svPutSelectBit(svBitPackedArrRef d, int i, svBit s);
void svPutSelectLogic(svLogicPackedArrRef d, int i, svLogic s);
/* canonical
void svGetPartSelectBit(svBitVec32* d, const svBitPackedArrRef s, int i,
int w);
svBitVec32 svGetBits(const svBitPackedArrRef s, int i, int w);
svBitVec32 svGet32Bits(const svBitPackedArrRef s, int i); // 32-bits
unsigned long long svGet64Bits(const svBitPackedArrRef s, int i); // 64-bits
void svGetPartSelectLogic(svLogicVec32* d, const svLogicPackedArrRef s, int i,
int w);
/* actual
void svPutPartSelectBit(svBitPackedArrRef d, const svBitVec32 s, int i,
int w);
void svPutPartSelectLogic(svLogicPackedArrRef d, const svLogicVec32 s, int i,
int w);
除了可以向C中傳遞固定維度數(shù)組,還可以傳遞不固定維度數(shù)組,即動(dòng)態(tài)數(shù)據(jù)。在C中通過(guò)svOpenArrayHandle來(lái)獲取這些數(shù)據(jù),這些數(shù)據(jù)的操作也需要通過(guò)一些函數(shù),不能直接操作。比如以下函數(shù)可以獲得動(dòng)態(tài)數(shù)組的位置:
int svLeft(const svOpenArrayHandle h, int d);
int svRight(const svOpenArrayHandle h, int d);
int svLow(const svOpenArrayHandle h, int d);
int svHigh(const svOpenArrayHandle h, int d);
比如定義一個(gè)數(shù)組bit[3:0] data[3:9],那么
svLeft(data, 1)是3,svRight(data, 1)是9。
在SV中有如下形式:
Import “DPI-C” function void write(bit[3:0] data[])
C中為:
Void write(svOpenArrayHandle data)
C函數(shù)
-
函數(shù)
+關(guān)注
關(guān)注
3文章
4285瀏覽量
62333 -
SV
+關(guān)注
關(guān)注
0文章
6瀏覽量
13925 -
仿真驗(yàn)證
+關(guān)注
關(guān)注
0文章
25瀏覽量
8121
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論