ModelSimのPLIで浮動小数点入力(cygwin)

設計

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

簡単なモジュールをつかったプロジェクト・サンプルはこちら

タイトルとURLをコピーしました