FPGA開発日記

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

自作RISC-Vプロセッサでriscv-testsテストパタンセットを流す

RISC-Vにはriscv-testsというテストパタンセットが用意されており、これらを流すことによりRISC-Vのアーキテクチャとして正しく実装されているかどうかをチェックすることができるようになっている。

github.com

自作RISC-Vプロセッサにおいても、このパタンセットは利用することができる。一通り流してみて、どれくらいパスできるか見てみよう。

対象パタンセット

RISC-V のテストパタンセットは以下のように分類される (下記はriscv-tests githubより抜粋)。

TVM Name Description
rv32ui RV32 user-level, integer only
rv32si RV32 supervisor-level, integer only
rv64ui RV64 user-level, integer only
rv64uf RV64 user-level, integer and floating-point
rv64uv RV64 user-level, integer, floating-point, and vector
rv64si RV64 supervisor-level, integer only
rv64sv RV64 supervisor-level, integer and vector

この中で、とりあえず通せそうなのはrv32uiクラスかな。とりあえず以下をターゲットとしてコンパイルして、リグレッションテストとして流してみた。

算術演算系 rv32ui-p-add, rv32ui-p-addi, rv32ui-p-auipc, rv32ui-p-lui, rv32ui-p-sub
論理演算系 rv32ui-p-and, rv32ui-p-andi, rv32ui-p-or, rv32ui-p-ori, rv32ui-p-sra, rv32ui-p-srai, rv32ui-p-srl, rv32ui-p-srli, rv32ui-p-xor, rv32ui-p-xori
分岐命令系 rv32ui-p-beq, rv32ui-p-bge, rv32ui-p-bgeu, rv32ui-p-blt, rv32ui-p-bltu, rv32ui-p-bne, rv32ui-p-jal, rv32ui-p-jalr, rv32ui-p-sll, rv32ui-p-slli
比較命令系 rv32ui-p-slt, rv32ui-p-slti, rv32ui-p-sltiu, rv32ui-p-sltu
制御系 rv32ui-p-fence_i, rv32ui-p-simple
メモリアクセス rv32ui-p-lb, rv32ui-p-lbu, rv32ui-p-lh, rv32ui-p-lhu, rv32ui-p-lw, rv32ui-p-sb, rv32ui-p-sh, rv32ui-p-sw

RISC-V riscv-testsのPass/Fail判定について

これらのテストパタン、どのようにPass/Failを判定しているのだろう?逆アセンブルするとからくりが分かる。

80000180:    00400e93            li  t4,4
80000184:   00700e13            li  t3,7
80000188:   01d29463            bne t0,t4,80000190 <fail>
8000018c:   01c01c63            bne zero,t3,800001a4 <pass> 

80000190 <fail>:
80000190:   0ff0000f            fence
80000194:   000e0063            beqz    t3,80000194 <fail+0x4>
80000198:   001e1e13            slli    t3,t3,0x1
8000019c:   001e6e13            ori t3,t3,1
800001a0:   00000073            ecall

800001a4 <pass>:
800001a4:   0ff0000f            fence
800001a8:   00100e13            li  t3,1
800001ac:   00000073            ecall
800001b0:   c0001073            unimp
800001b4:   0000                    unimp

セルフチェックテストを実行し、結果がPass, Failによって最終分岐先が異なる。この時のt3の値に、その結果が書き込まれる。これがt3=1ならばPass, それ以外ならFailだ。

さて、この判定基準を利用して測定した結果、上記のテストパタンのうち落ちたのは以下の3本だった。たったの3本!

rv32ui-p-fence_i
rv32ui-p-sb
rv32ui-p-jalr

このうち、rv32ui-p-jalrの間違いはすぐに分かった。RISC-VのJALR命令は、オフセットを取ることができるのだ。

f:id:msyksphinz:20170707022024p:plain

これを修正して、残りはsb命令とfence命令だけとなった。これらを修正していく。