Verilog PLIで浮動小数点の値をバイナリ値に変換する方法を紹介します。シミュレータはCver、動作環境はLinux(ubuntu 14.04LTE 64bit)です。
ステップ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" #include "cv_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); // バイナリ値を返すレジスタのハンドル float val = acc_fetch_tfarg(2); // taskの引数から値を取得 // set floating-point binary value _uf.f = val; value_s.value.integer = _uf.u; // 共用体を利用してバイナリ値をセット acc_set_value(reg,&value_s,&delay_s); } p_tfcell my_bootstrap () { static s_tfcell my_tfs[] = { { usertask, 0, 0, 0, to_float32, 0, "$to_float32",1 }, {0} }; io_printf("*** Registering user PLI 1.0 task\n"); return(my_tfs); }
ステップ2:Cファイルのコンパイル
CverのPLI用インクルードファイルのディレクトリにパスを通して Cファイルのコンパイルを行います。64bit環境でコンパイルを行う場合には-m32オプションが必要です。またリンク時には-melf_i386オプションが必要です。
#!/bin/sh #Cver directory CVER_DIR="/opt/gplcver-2.12a.src" # check Cver availability if [ ! -e ${CVER_DIR} ]; then echo "Cver not found.Please set CVER_DIR." exit 1 fi # PLI compile CFLAGS="-fPIC -Wall -g -m32 -I${CVER_DIR}/pli_incs" LFLAGS="-G -shared -export-dynamic -melf_i386" if [ ! -e my_pli.so ]; then echo "PLI compile" gcc ${CFLAGS} -c ../pli/my_pli.c ld ${LFLAGS} my_pli.o ${LFLAGS} -o my_pli.so 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用シェアードライブラリを+loadpli1オプションで指定してcverを実行します。
# run cver cver \ +loadpli1=./my_pli.so:my_bootstrap \ +notimingchecks \ -y ${RTL_DIR} \ +incdir+${RTL_DIR}/+ \ +libext+.v+ \ ${sim_file}
実行ログです。
GPLCVER_2.12a of 05/16/07 (Linux-elf). Copyright (c) 1991-2007 Pragmatic C Software Corp. All Rights reserved. Licensed under the GNU General Public License (GPL). See the 'COPYING' file for details. NO WARRANTY provided. Today is Sun Feb 8 07:50:32 2015. *** Registering user PLI 1.0 task Compiling source file "../scenario/test_1.v" Highest level modules: test_module 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 Halted at location **../scenario/test_1.v(78) time 410 from call to $finish. There were 0 error(s), 9 warning(s), and 9 inform(s).
簡単なモジュールをつかったプロジェクト・サンプルはこちら。