DPI-C

環境構築には、以下のサイトを参考にしました。

※このページには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