Verilog PLIで浮動小数点の値をバイナリ値に変換する方法を紹介します。シミュレータはModelSim、動作環境はWindows上のcygwinです。
手順は次の4ステップです。
ステップ1: PLI用Cファイルの準備
ステップ2: Cファイルのコンパイル
ステップ3: テストベンチからの呼び出し
ステップ4: シミュレーションの実行
ステップ1:PLI用Cファイルの準備
$to_float32というtaskを追加します。
$to_float32は、第2引数で指定された浮動小数点値を、バイナリ値に変換して第1引数のレジスタにセットします。例えば、1.0という値は$to_float32で0x3f800000に変換されます。実際のコードは次の通りです。浮動小数点値のバイナリ変換は共用体で行っています。
#include "acc_user.h" #include "veriuser.h" int to_float32() { union { float f; unsigned int u; } _uf; // initialize tasks acc_initialize(); static s_setval_delay delay_s = {accRealTime, accNoDelay}; static s_setval_value value_s = {accIntVal}; delay_s.time.real = 0; handle reg = acc_handle_tfarg(1); // get register handle float val = acc_fetch_tfarg(2); // get floating number // set floating-point binary value _uf.f = val; value_s.value.integer = _uf.u; acc_set_value(reg,&value_s,&delay_s); } s_tfcell veriusertfs[] = { { usertask, 0, 0, 0, to_float32, 0, "$to_float32",1 }, {0} };
ステップ2:Cファイルのコンパイル
Cファイルのコンパイルは、cygwinのgccではなくModelSimディレクトリに格納されているgccで行います。次の例では、taskを記述したCファイルmy_pli.cをコンパイルしてmy_pli.slを生成しています。
#!/bin/sh #ModelSim directory MDELSIM_DIR="g:/altera/13.1/modelsim_ase" GCC=${MDELSIM_DIR}/gcc-4.2.1-mingw32vc9/bin/gcc # check ModelSim availability if [ ! -e ${MDELSIM_DIR} ]; then echo "ModelSim not found.Please set MODELSIM_DIR." exit 1 fi # PLI compile if [ ! -e my_pli.sl ]; then echo "PLI compile" ${GCC} -c -g -I ${MDELSIM_DIR}/include ../pli/my_pli.c ${GCC} -shared -Bsymbolic -L ${MDELSIM_DIR}/win32aloem -lmtipli -o my_pli.sl my_pli.o fi
ステップ3:テストベンチからの呼び出し
テストベンチでPLI taskを呼び出します。次の例では0.0から9.0の浮動小数点値を$to_float32でバイナリに変換し、レジスタf32にセットしています。
integer i; reg [31:0] f32; // 浮動小数点値の変換結果を格納するレジスタ initial begin $dumpvars; reset; repeat (10) @(posedge clk); for (i=0;i<10;i=i+1) begin $to_float32(f32,i); // iをバイナリ値に変換してf32にセット $display("float %f %x\n",i,f32); @(posedge clk); end repeat (10) @(posedge clk); $finish; end
ステップ4:シミュレーションの実行
pliライブラリを指定してvsimを実行します。
# simulation vsim test_module -pli my_pli.sl <<EOF run -all EOF
実行ログ
# vsim -pli my_pli.sl test_module # Loading ./my_pli.sl # Loading sv_std.std # Loading work.test_module # Loading work.mod_top # Loading work.mod_a # Loading work.mod_b run -all # float 0.000000 00000000 # # float 1.000000 3f800000 # # float 2.000000 40000000 # # float 3.000000 40400000 # # float 4.000000 40800000 # # float 5.000000 40a00000 # # float 6.000000 40c00000 # # float 7.000000 40e00000 # # float 8.000000 41000000 # # float 9.000000 41100000 # # ** Note: $finish : ../scenario/test_1.v(78) # Time: 410 ps Iteration: 1 Instance: /test_module
簡単なモジュールをつかったプロジェクト・サンプルはこちら。