Cygwin+ModelSimでDPI

Cygwin環境でのDPIを使ったSystemVerilogのシミュレーション方法。

簡単に、SystemVerilogからCの関数を呼ぶだけのものを試してみる。

SystemVerilogのコードは以下の通り。プログラムの開始メッセージ表示、Cの関数helloCWorldを呼ぶ、プログラムの終了メッセージ表示の、簡単なプログラムだ。

DpiTest.sv:

module DpiTest();

import "DPI-C" pure function int helloCWorld();

initial begin

$display("Dpi Test Start");

#10 ;

helloCWorld();

#10 ;

$display("Dpi Test Finish");

$finish;

end

endmodule

以下がCのプログラム。printfでメッセージを表示するのみ。

helloCWorld.c

#include <stdio.h>

int helloCWorld()

{

printf("Hello Cworld\n");

return 0;

}

modelsimでのコンパイル用のスクリプト。以下の環境を想定している。

    • 本スクリプト実行前に、同ディレクトリで一度はvlib workが実行されている

    • 上記のSystemVerilogのプログラム、Cのプログラム、本スクリプトは同一ディレクトリにある

    • modelsimのインストールディレクトリがc:\altera\10.1\modelsim_aseである

gccのコンパイルオプションの-mno-cygwinで、CygwinのDLLを組み込まないよう指示する。

#!/bin/sh

vlog dpiTest.sv

gcc -c helloCWorld.c

gcc -shared -mno-cygwin -o helloCWorld.dll \

helloCWorld.o /cygdrive/c/altera/10.1/modelsim_ase/win32aloem/mtipli.dll

シミュレーション実行用のスクリプト。コンパイルしたディレクトリで実行。

#!/bin/sh

vsim -sv_root . -sv_lib helloCWorld -c DpiTest -do "run -all;quit"

実行結果。

C関数からの標準出力のタイミングはSystemVerilog側の$display等からの出力とは独立しているようなので、注意が必要そう。

(そもそもDPIではC側で標準出力を使用するべきではないかも?)

# 6.6c

# vsim -do {run -all;quit} -c -sv_root . -sv_lib helloCWorld DpiTest

# Loading sv_std.std

# Loading work.DpiTest

# Loading .\helloCWorld.dll

# run -all

# DPI Test Start

# DPI Test Finish

# ** Note: $finish : dpiTest.sv(10)

# Time: 20 ps Iteration: 0 Instance: /DpiTest

Hello Cworld

参考資料 :

DOS 上で動作するプログラムを作る

技術解説シリーズ「無償ツールで実践する『ハード・ソフト協調検証』」