FPGA開発日記

カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages , English Version https://fpgadevdiary.hatenadiary.com/

RISC-V実装におけるのリグレッションテスト実施方針

RISC-VにおけるテストセットのPass/Fail判定

過去の記事でも少し解説したが、RISC-Vではriscv-testsというテストパタンセットが用意されている。

msyksphinz.hatenablog.com

パタンの説明では、どうやら0x8000_1000への書き込みでもってパタンの終了を判定しなければならないらしい。

RISC-Vのテストパタンセット riscv-tests - FPGA開発日記

このテストパタンにおけるPass/Fail判定の方針だが、特定のアドレスに書き込みを行うことでテストを管理している。 自分でテストパタンを書くときも、この方針に則った方がよさそうだ。

github.com

命令のシーケンスの最後に、0x8000_1000にアクセスするコードを追加している。これをRTL実装が検知すれば、シミュレーションを自動的に停止するという仕組みだ。

ちなみに、上記のスクリプトは以下のようなコードを生成し、各命令のレイテンシとバンド幅を測定するためのコードとなっている。

  for (i = 0; i < 32; i++) {
    asm volatile ("add        %0,%1,%2"
      :"=r"(out0)
      :"r"(in0_0),"r"(in0_1)
      :
      );
    asm volatile ("add        %0,%1,%2"
      :"=r"(out1)
      :"r"(in1_0),"r"(in1_1)
      :
      );
    asm volatile ("add        %0,%1,%2"
      :"=r"(out2)
      :"r"(in2_0),"r"(in2_1)
      :
      );
    asm volatile ("add        %0,%1,%2"
      :"=r"(out3)
      :"r"(in3_0),"r"(in3_1)
      :
      );
    asm volatile ("add        %0,%1,%2"
      :"=r"(out4)
      :"r"(in4_0),"r"(in4_1)
      :
      );
    asm volatile ("add        %0,%1,%2"
      :"=r"(out5)
      :"r"(in5_0),"r"(in5_1)
      :
      );
    asm volatile ("add        %0,%1,%2"
      :"=r"(out6)
      :"r"(in6_0),"r"(in6_1)
      :
      );
    asm volatile ("add        %0,%1,%2"
      :"=r"(out7)
      :"r"(in7_0),"r"(in7_1)
      :
      );
  }

CTestsによるリグレッション環境の構築

CTestsはCMakeなどのビルドシステムのサブセットだが、リグレッションテストを管理することが出来る。これを使って、上記のスクリプトで作成した一連のテストパタンセットを管理してみよう。

リグレッションテストの基本方針として、

  • テストパタンが最後まで完走する
  • ISSと一対一で比較してすべて一致する

ということが求められる。テストパタンが完走したかどうかは、2番目のISSとの一対一比較で実行可能だ。このスクリプトはすでに用意されているため、以下のようなテストパタン実行スクリプトを用意した。

rm -f sim_inst.log sim_pipe.log

sim_result=`./sim_mag_top +HEX=${target}.riscv.hex +MAX=1000 | tail -n 5`
cp sim_inst.log ${target}.sim_inst.log
cp sim_pipe.log ${target}.sim_pipe.log
ruby ../sim/rtl_iss_compare.rb ${target}.sw.log sim_inst.log > ${target}.cmp.log

echo $sim_result | grep -q PASS

if [ $? -eq 0 ]; then
    return 0
else
    return 1
fi

sim_mag_topはiverilogで作成したバイナリだが、このバイナリに対してhexファイルを渡すことでテストパタンを実行している。

そして../sim/rtl_iss_compare.rbを使って、あらかじめISSで実行したテストパタンの実行結果${target}.sw.logとの一致比較をしている。

これをCMakeLists.txtにテストパタンの数だけ登録していく。

# CTest
enable_testing()

add_test (NAME inst_add              COMMAND ./isa_test.sh ./isa_files/inst_add)
add_test (NAME inst_addi             COMMAND ./isa_test.sh ./isa_files/inst_addi)
add_test (NAME inst_addiw            COMMAND ./isa_test.sh ./isa_files/inst_addiw)
add_test (NAME inst_addw             COMMAND ./isa_test.sh ./isa_files/inst_addw)
add_test (NAME inst_amoadd_d         COMMAND ./isa_test.sh ./isa_files/inst_amoadd_d)
add_test (NAME inst_amoadd_w         COMMAND ./isa_test.sh ./isa_files/inst_amoadd_w)
add_test (NAME inst_amoand_d         COMMAND ./isa_test.sh ./isa_files/inst_amoand_d)
add_test (NAME inst_amoand_w         COMMAND ./isa_test.sh ./isa_files/inst_amoand_w)
...

早速自作RISC-Vプロセッサで実行してみた。が、サポートしていない機能が現状多すぎてほとんどのパタンが落ちてしまう。。。実装を改良していかなければ。。。