RISC-V Tortureは、生成したテストパタンをシミュレータで実行し、最後にシグニチャを出力する。 シグニチャを他の実装(Rocket-Chipなど)との結果と比較して正しく実行できたかを判定している。
SpikeおよびRocket-Chipでシグニチャを生成するためには+signature=<filename>
とすればよいというのは前回解析した。
次にこのシグニチャが具体的にどのような方法で生成されているのかについて調査する。
RISC-V Tortureのシグニチャは生成されたテストパタンのbegin_signature
とend_signature
の間メモリの内容がダンプされている。
また、テストパタンの最後に`レジスタの値をすべて比較該メモリ領域にダンプすることでレジスタの中身を一致比較させるようになっている。
まあ、これだと計算の最後しか見ることができないな。。。
reg_dump: la x1, loop_count lw x2, 0(x1) addi x3, x2, -1 sw x3, 0(x1) bnez x2, pseg_0 la x1, xreg_output_data sd x0, 0(x1) sd x2, 16(x1) sd x3, 24(x1) sd x4, 32(x1) sd x5, 40(x1) sd x6, 48(x1) sd x7, 56(x1) ...
従って、同じような仕組みで自作RISC-Vシミュレータにもシグニチャを生成する仕組みを入れると、Spikeとのランダムテストの一致比較ができるはずだ。早速やってみよう。
for (Addr_t addr = m_sig_addr_start; addr <= ((m_sig_addr_end-1) | 0xf); addr += 0x10) { for (Addr_t b_addr = addr + 0xf; b_addr >= addr; b_addr--) { UByte_t b_data; LoadMemory<UByte_t> (b_addr, &b_data); fprintf (fp, "%02x", b_data); } fprintf (fp, "\n"); }
追加したものをテストしてみる。同じパタンで、Spikeの生成したtest.spike.sig
と自作シミュレータで生成したシグニチャを比較する。
$ diff $ diff test.forest.sig test.spike.sig 22c22 < d6bd427500000006ffffffffffff8008 --- > d6bd4275000000067ff8000000000000 26c26 < 7ff0000000000000ffffffffffff8008 --- > 7ff00000000000007ff8000000000000 29c29 < 0000000000000000ffffffffffffffff --- > 00000000000000007ff8000000000000
ありゃ!差分がある。解析が必要だなあ。