自作CPUのFPUは、外部IPを使用している。FPNewというIPを使っている。
FPNewは、簡単に浮動小数点演算を実装できるのだが、これをインテグレートした後に問題を見つけた。
Some compliance issues with IEEE 754-2008 are currently known to exist for the PULP DivSqrt unit (Rounding mismatches have been reported in GitHub issues. This can lead to results being off by 1ulp, and the inexact flag not being properly raised in these cases as well)
つまり、いくつかの演算についてはDivSqrtユニットに問題がありミスマッチが発生する可能性があるということだ。 実際この問題に直結するケースがあり、これを今のところ解決する手段はないので、検証環境側を変更する必要がある。
つまり、当該div命令やsqrt命令が実行された場合は、結果に1ビットの誤差があるときはそれを認め、ISS側にRTLの値を伝搬することで検証を継続させることにする。
int64_t iss_wr_val = p->get_state()->FPR[rtl_wr_gpr_addr].v[0]; if (!is_equal_flen(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_flen / 4, rtl_wr_val, g_rv_flen / 4, iss_wr_val); if (abs(iss_wr_val - rtl_wr_val) == 1) { float128_t f128_rtl_val; f128_rtl_val.v[0] = rtl_wr_val; f128_rtl_val.v[1] = 0; fprintf(compare_log_fp, "Small Approximation error. Backpropagating to ISS\n"); p->get_state()->FPR.write(rtl_wr_gpr_addr, f128_rtl_val); fprintf(compare_log_fp, "==========================================\n"); return; } fprintf(compare_log_fp, "==========================================\n"); fail_count ++; if (fail_count >= fail_max) { stop_sim(100, rtl_time); } return; } else { fprintf(compare_log_fp, "FPR[%02d](%d) <= %0*llx\n", rtl_wr_gpr_addr, rtl_wr_gpr_rnid, g_rv_flen / 4, rtl_wr_val); }
こんな感じで、1ビットの誤差があればそれを認めて、SpikeのレジスタにRTLの値を上書きする。
float128_t f128_rtl_val; f128_rtl_val.v[0] = rtl_wr_val; f128_rtl_val.v[1] = 0; p->get_state()->FPR.write(rtl_wr_gpr_addr, f128_rtl_val);
これで、とりあえず浮動小数点の検証を継続できるようになった。
GPR[10](109) <= 0000000080002f10 336061 : 371660 : PC=[0000000080002f14] (M,41,02) 4b050513 addi a0, a0, 1200 GPR[10](135) <= 00000000800033c0 336061 : 371661 : PC=[0000000080002f18] (M,41,04) 1aa477d3 fdiv.d fa5, fs0, fa0 ========================================== Wrong FPR[15](126): RTL = 40a9114a6e7937b4, ISS = 40a9114a6e7937b5 Small Approximation error. Backpropagating to ISS ========================================== 336061 : 371662 : PC=[0000000080002f1c] (M,41,08) e20785d3 fmv.x.d a1, fa5 GPR[11](126) <= 40a9114a6e7937b4 336061 : 371663 : PC=[0000000080002f20] (M,41,16) 9b5ff0ef jal pc - 0x64c GPR[01](87) <= 0000000080002f24 336062 : 371664 : PC=[00000000800028d4] (M,42,01) 0000711d c.addi16sp sp, -96 GPR[02](83) <= 0000000080024130 336062 : 371665 : PC=[00000000800028d6] (M,42,02) 02810313 addi t1, sp, 40 GPR[06](132) <= 0000000080024158