浮動小数点命令をサポートするためには、まずはレジスタファイル、そして検証環境の更新が必要だ。
まず、SpikeにおけるFPU命令のトレースログの取り扱いについては、浮動小数点命令レジスタへの書き込みが行われると、レジスタの種類のビットが変更される。
spike_dpi/riscv-isa-sim/riscv/decode.h
# define WRITE_FREG(reg, value) ({ \ freg_t wdata = freg(value); /* value may have side effects */ \ STATE.log_reg_write[((reg) << 4) | 1] = wdata; \ DO_WRITE_FREG(reg, wdata); \ })
log_reg_write
の書き込みは、浮動小数点演算の場合には下位ビットに1が設定される。これを使って判定する。
まずはISSとRTLで書き込みレジスタタイプが異なればエラーを出力します。
if (rtl_wr_valid && (iss_wr_type == 0 || iss_wr_type == 1) && (rtl_wr_type == 0 || rtl_wr_type == 1) && iss_wr_type != rtl_wr_type) { fprintf(compare_log_fp, "==========================================\n"); fprintf(compare_log_fp, "RTL/ISS Write Register Type different.\n"); fprintf(compare_log_fp, "ISS = %s, RTL = %s\n", iss_wr_type == 0 ? "GPR" : iss_wr_type == 1 ? "FPR" : "Others", rtl_wr_type == 0 ? "GPR" : iss_wr_type == 1 ? "FPR" : "Others"); fprintf(compare_log_fp, "==========================================\n"); stop_sim(100); }
FPRレジスタ書き込み命令であれば、FPRレジスタ同士を比較して、エラーがあれば出力する。
} else if (rtl_wr_valid && iss_wr_type == 1) { // FPR write int64_t iss_wr_val = p->get_state()->FPR[rtl_wr_gpr_addr].v[0]; if (!is_equal_xlen(iss_wr_val, rtl_wr_val)) { fprintf(compare_log_fp, "==========================================\n"); fprintf(compare_log_fp, "Wrong FPR[%02d](%d): RTL = %0*llx, ISS = %0*lx\n", rtl_wr_gpr_addr, rtl_wr_gpr_rnid, g_rv_xlen / 4, rtl_wr_val, g_rv_xlen / 4, iss_wr_val); fprintf(compare_log_fp, "==========================================\n"); fail_count ++; if (fail_count >= fail_max) { stop_sim(100); } return; } else { fprintf(compare_log_fp, "FPR[%02d](%d) <= %0*llx\n", rtl_wr_gpr_addr, rtl_wr_gpr_rnid, g_rv_xlen / 4, rtl_wr_val); } }
これで、まずはFMV.D.X
命令の動作を確認する。FMV.D.X
命令は、整数レジスタのデータを、データ型変換することなく、そのまま浮動小数点レジスタに転送する命令だ。
make rv64_tiny && ./msrh_tb_rv64_tiny-debug -d -e ../tests/riscv-tests/isa/rv64ud-p-move -o rv64ud-p-move.tiny.log | spike-dasm
あれ、リネーム機能のアサーションで落ちてしまった。
CSR_MCYCLE written 00000000 CSR_MCYCLE written 00000000 [10254] %Error: msrh_rename.sv:495: Assertion failed in TOP.msrh_tb.u_msrh_tile_wrapper.u_msrh_tile.u_msrh_int_rename.unnamedblk4.list_check1_loop.unnamedblk5.list_check2_loop: Index 55( 1, 23) and 75( 2, 11) are same ID: 1 %Error: ../src/../src/msrh_rename.sv:495: Verilog $stop
命令自体は何となく動いているように見える。デバッグしていく。
GPR[11](65) <= 000091a2b3c4d5e7 2555 : 77 : PC=[000000008000019c] (U,03,01) 00d59593 slli a1, a1, 13 GPR[11](6) <= 123456789abce000 2556 : 78 : PC=[00000000800001a0] (U,04,01) ef058593 addi a1, a1, -272 GPR[11](1) <= 123456789abcdef0 2561 : 79 : PC=[00000000800001a4] (U,05,01) 00000613 li a2, 0 GPR[12](9) <= 0000000000000000 2561 : 80 : PC=[00000000800001a8] (U,05,02) f20580d3 fmv.d.x ft1, a1 FPR[01](64) <= 123456789abcdef0 2562 : 81 : PC=[00000000800001ac] (U,06,01) f2060153 fmv.d.x ft2, a2 FPR[02](32) <= 0000000000000000