Vengineerの妄想(準備期間)

人生は短いけど、長いです。人生を楽しみましょう!

DPI-CとBFM、その1

Verification Engineerの戯言

http://blogs.yahoo.co.jp/verification_engineer/10950264.html

で、BFMについて書きました。そのとき、DPI-CをBFMに利用できることを示しました。

今回から数回に分けて、どのようにすればいいかを説明していきます。

DPI-Cは、SystemVerilogのmoduleとprogramで利用できます。
moduleとprogram内からDPI-Cを使って、C言語の関数を呼び出せます。
また、C言語からmoduleとprogramのtask/functionが呼び出せます。

BFMへに応用するときは、次のようにします。

1)、C言語へのエントリポイント(ここでは、c_mainとします)をimportで宣言する。
2)、SystemVerilogのinitial文内で、C言語へのエントリポイント(c_main)をコールする。
3)、C言語で呼ばれた関数(c_main)がBFMに対するプログラムになります。
4)、C言語からSystemVerilogでexportしたタスク(bus_cycle)を使って、BFMの外部バスにアクセスします。
5)、プログラムが終了したら、エントリポイントの関数を終了します。
6)、C言語へのエントリポイントを終了したら、SystemVerilog側で$finish(2)を
呼んで、シミュレータを終了します。

ポイントは、2点、

A)、SystemVerilog側からC言語側を呼び出すとき、
  B)、C言語の関数からBFMの外部バスにアクセスするとき、

です。

A)に対しては、

import "DPI-C" task c_main();

initial begin
c_main();
$finish(2);
end

とします。c_mainはC言語の関数です。
次のように、c_main関数に引数を持たせることも可能です。

SystemVerilog側

int opt_a;
string opt_b;

opt_a = 1; opt_b = "test";
c_main( opt_a, opt_b );

C言語

int c_main( int opt_a, char *opt_b ) {

printf("opt_a = %d, opt_b = %s\n", opt_a, opt_b );

return 0;
}

SystemVerilog側からopt_aにint型(値は:1)、opt_bに文字列型(値は:test")を
c_main関数の引数に渡します。
C言語側では、引数のopt_a, opt_bを表示し、関数を終了します。

ここで注意です。C言語側の関数をSystemVerilog側でtaskと定義したときは、
C言語側の関数の戻り値の型は、int型で、通常の戻り値は"0"です。
(なぜ、このようになるかは、とりあえず、おまじないということにしておいてください)。

次回は、B)について説明します。

お楽しみに!