CverのPLIで浮動小数点入力(Linux)

設計

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).

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

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