自作CPUにベクトル実行エンジンを追加する試行をしている。
実装を検証するために、Spikeの検証環境を構築している。
まず、ベクトル書き込み情報をDPI経由で渡すために、ポインタ経由でのデータ渡しを実装している。 これについては、過去のブログを参照すること。
まずは、書き込みしたベクトル命令の情報をSpike側でダンプできるようにしてみる。
} else if (rtl_wr_valid && (iss_wr_type == 2 || rtl_wr_type == 2)) { // VPR write for (int a = 0; a < 32; a++) { fprintf(compare_log_fp, "VPR[%02d] = ", a); for (int b = g_rv_vlen / 8-1; b >= 0; b--) { fprintf (compare_log_fp, "%02x", static_cast<uint8_t *>(p->VU.reg_file)[a * (g_rv_vlen/8) + b]); if (b % 4 == 0) { fprintf (compare_log_fp, "_"); } } fprintf (compare_log_fp, "\n"); }
以下のように、とりあえずSpikeのベクトルレジスタの情報をダンプする。
GPR[14](17) <= 0000000000000008 4691 : 238 : PC=[0000000080002012] (M,34,01) 5e07cc57 vmv.v.x v24, a5 VPR[00] = 00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_ VPR[01] = 00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_ VPR[21] = 00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_ VPR[22] = 00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_ VPR[23] = 00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_ VPR[24] = 00000000_00000008_00000000_00000008_00000000_00000008_00000000_00000008_00000000_00000008_00000000_00000008_00000000_00000008_00000000_00000008_ VPR[25] = 00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_ VPR[26] = 00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_
とりあえず、RTLとSpikeのレジスタ表示を並べてみる。
} else if (rtl_wr_valid && (iss_wr_type == 2 || rtl_wr_type == 2)) { // VPR write fprintf(compare_log_fp, "ISS[%02d] = ", rtl_wr_gpr_addr); for (int b = g_rv_vlen / 8-1; b >= 0; b--) { fprintf (compare_log_fp, "%02x", static_cast<uint8_t *>(p->VU.reg_file)[rtl_wr_gpr_addr * (g_rv_vlen/8) + b]); if (b % 4 == 0) { fprintf (compare_log_fp, "_"); } } fprintf (compare_log_fp, "\n"); fprintf(compare_log_fp, "RTL[%02d] = ", rtl_wr_gpr_addr); for (int b = g_rv_vlen / 8-1; b >= 0; b--) { fprintf (compare_log_fp, "%02x", rtl_wr_vec_val[b]); if (b % 4 == 0) { fprintf (compare_log_fp, "_"); } }
4691 : 238 : PC=[0000000080002012] (M,34,01) 5e07cc57 vmv.v.x v24, a5 ISS[24] = 00000000_00000008_00000000_00000008_00000000_00000008_00000000_00000008_00000000_00000008_00000000_00000008_00000000_00000008_00000000_00000008_ RTL[24] = 00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000008_ 4691 : 239 : PC=[0000000080002016] (M,34,02) 00009fb9 c.addw a5, a4
一応動くようになった。
検証環境を追加した。こんな感じで比較結果が表示される。
4822 : 306 : PC=[000000008000202e] (M,40,01) 05077757 vsetvli a4, a4, e32, m1, ta, mu GPR[14](159) <= 0000000000000010 4823 : 307 : PC=[0000000080002032] (M,41,01) 5e07cc57 vmv.v.x v24, a5 ========================================== Wrong VPR[24](59): ISS[24] = 00000010_00000010_00000010_00000010_00000010_00000010_00000010_00000010_00000010_00000010_00000010_00000010_00000010_00000010_00000010_00000010_ RTL[24] = 00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000010_ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ =============================== SIMULATION FINISH : FAIL (CODE=100) RUNNING TIME : 4823 ===============================