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
簡単なモジュールをつかったプロジェクト・サンプルはこちら。

