DPI-C
環境構築には、以下のサイトを参考にしました。
- http://www.kumikomi.net/archives/2009/12/_1systemverilogdpi-c.php?page=2
- http://dora.bk.tsukuba.ac.jp/~takeuchi/index.php?%C5%C5%B5%A4%B2%F3%CF%A9%2FHDL%2FModelSim%20XE%20%A4%F2%BB%C8%A4%C3%A4%BF%20SystemVerilog%20DPI- C%20%A5%C6%A5%B9%A5%C8#vc235973
※このページにはSVの添付ファイルがあります
DPI-Cは、CからSVのtask/functionを、SVからCの関数を、簡単な定義だけで呼び出す手法です。
DPI-C環境への移行にあたり、以下のように進めていこうと思います。
- 変更は、master_bfmのみ
- トランザクション発行task、write_issueとread_issueをCからcallできるようにする
- Cでtest()という関数を定義して、これをSV側から呼び出すようにする
DPI-Cの定義を、master_bfmの記述に追加します。class定義の下に、
/// Define for DPI-C ////////////////////////////
export "DPI-C" task write_issue;
export "DPI-C" task read_issue;
export "DPI-C" task wait_cycle;
import "DPI-C" context task test();
/////////////////////////////////////////////////
を追加します。
export宣言は、SVのtask/functionをCから呼び出すときに使います。
import宣言は、Cの関数をSVから呼び出すときに使います。
今回は、「Cでテストベクタを記述」するのが目的ですので、Cにtestという関数を定義して、
その中でwrite_issue、read_issueが実行出来ればOKです。
さて、コードをコンパイルするか…というところで、気をつけることがあります。
それは、Cコードに読ませるヘッダファイルの生成をすること。ModelSimでは、以下のように記述します。
vlog $SV_File -dpiheader dpi.h
こうすると、カレントにdpi.hが生成されます。
次にテストベクタを記述します。
--- test.c ---
#include "dpi.h"
int test() {
write_issue(0x00000000, 0x00112233);
read_issue (0x00000000);
}
gccでコンパイルをしますが、その前にModelSimでobjectファイルを生成する必要があります。
vsim -dpiexportobj cexports -c tb_top
このとき、cexportsは生成するobjectファイル名を表します。-c の後ろはテストベンチトップの
module名です。次にgccでコンパイルし、dpi.oを生成し、そのあとModelSimに読み込ませる
DLLファイルを生成します。
gcc -c -g test.c -I$INC_PATH -I. -o dpi.o
gcc -shared -o cimports.dll dpi.o cexports.obj -L$LIB_PATH -lmtipli
ここで、$INC_PATH、$LIB_PATHは以下のようになっています。
/c/altera/10.1/modelsim_ase/include
/c/altera/10.1/modelsim_ase/win32aloem
上記手順でDLLファイルを作成したら、vsimでSimulationをします。
vsim -c tb_top -sv_lib cimports -do "run -all;quit"
DLLファイルは、-sv_libオプションで指定します。
実行結果は
# [1200] write cmd. addr=00000000h, data=00112233h
# [1900] read cmd. addr=00000000h
# [2900] read data. data=00112233h
# ** Note: $finish : master_bfm.sv(129)
となりました。
補足
SystemVerilogにDPI-C対応記述を入れてから、他にも少し修正したところがあります。
それは、task write_issue, read_issueの引数です。引数の型をbit型にしていましたが、
これだとうまくいかなかったので、int unsigned型にしています。
本当はどうするのがいいのかなぁ…誰か教えてくださいm(_ _)m