FPGA開発日記

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

自作CPUにベクトル命令を追加する実装検討 (2. Spikeによる検証環境の構築)

自作CPUにベクトル実行エンジンを追加する試行をしている。

実装を検証するために、Spikeの検証環境を構築している。

まず、ベクトル書き込み情報をDPI経由で渡すために、ポインタ経由でのデータ渡しを実装している。 これについては、過去のブログを参照すること。

msyksphinz.hatenablog.com

まずは、書き込みしたベクトル命令の情報を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
===============================