FPGA開発日記

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

自作CPUにベクトル命令を追加する実装検討 (7. 基本的な算術演算命令)

自作CPUにおいて、ある程度ベクトル移動命令が動作するようになってきた。

ベクトルレジスタにデータを配置できるようになってきたので、次は算術演算命令を実装してみよう。

    {
        "name":"vadd.vv      v[11:7],v[24:20],v[19:15]vm[25:25]",
        "length":"32", "xlen":["32", "64"],
        "field": ["00000", "0X", "XXXXX", "XXXXX", "000", "XXXXX", "10101", "11"],
        "inst_cat":[["inst_cat", "valu"]], "isa_ext": "v",
        "reg": [["rd", "v3"], ["r1", "v1"], ["r2", "v2"]],
        "vec_ctrl":[["op", "add"]]
    },
    {
        "name":"vsub.vv      v[11:7],v[24:20],v[19:15]vm[25:25]",
        "length":"32", "xlen":["32", "64"],
        "field": ["00001", "0X", "XXXXX", "XXXXX", "000", "XXXXX", "10101", "11"],
        "inst_cat":[["inst_cat", "valu"]], "isa_ext": "v",
        "reg": [["rd", "v3"], ["r1", "v1"], ["r2", "v2"]],
        "vec_ctrl":[["op", "sub"]]
    },

命令デコードに基づいて、データパスを追加する。

    OP_ADD : begin
      unique case (i_sew)
        scariv_vec_pkg::EW8 : for (int b = 0; b < 8; b++) w_res.w8 [b] = i_en_mask[b] ? i_vs1[ 7: 0] + i_vs2[ 7: 0] : w_wr_old.w8 [b];
        scariv_vec_pkg::EW16: for (int b = 0; b < 4; b++) w_res.w16[b] = i_en_mask[b] ? i_vs1[15: 0] + i_vs2[15: 0] : w_wr_old.w16[b];
        scariv_vec_pkg::EW32: for (int b = 0; b < 2; b++) w_res.w32[b] = i_en_mask[b] ? i_vs1[31: 0] + i_vs2[31: 0] : w_wr_old.w32[b];
        scariv_vec_pkg::EW64: for (int b = 0; b < 1; b++) w_res.w64[b] = i_en_mask[b] ? i_vs1[63: 0] + i_vs2[63: 0] : w_wr_old.w64[b];
        default             :                             w_res = 'h0;
      endcase // unique case (i_sew)
    end
    OP_SUB : begin
      unique case (i_sew)
        scariv_vec_pkg::EW8 : for (int b = 0; b < 8; b++) w_res.w8 [b] = i_en_mask[b] ? i_vs1[ 7: 0] - i_vs2[ 7: 0] : w_wr_old.w8 [b];
        scariv_vec_pkg::EW16: for (int b = 0; b < 4; b++) w_res.w16[b] = i_en_mask[b] ? i_vs1[15: 0] - i_vs2[15: 0] : w_wr_old.w16[b];
        scariv_vec_pkg::EW32: for (int b = 0; b < 2; b++) w_res.w32[b] = i_en_mask[b] ? i_vs1[31: 0] - i_vs2[31: 0] : w_wr_old.w32[b];
        scariv_vec_pkg::EW64: for (int b = 0; b < 1; b++) w_res.w64[b] = i_en_mask[b] ? i_vs1[63: 0] - i_vs2[63: 0] : w_wr_old.w64[b];
        default             :                             w_res = 'h0;
      endcase // unique case (i_sew)
    end

一応これで簡単に動くようになる。やっぱり算術演算命令は簡単だ。

GPR[14](21) <= 0000000000000024
5147 : 574 : PC=[0000000080002086] (M,23,01) 04077757 vsetvli a4, a4, e8, m1, ta, mu
GPR[14](84) <= 0000000000000020
5149 : 575 : PC=[000000008000208a] (M,24,01) 5e07cc57 vmv.v.x v24, a5
VPR[24](41) <= 40404040_40404040_40404040_40404040_40404040_40404040_40404040_40404040_
5150 : 576 : PC=[000000008000208e] (M,25,01) 5e05ccd7 vmv.v.x v25, a1
VPR[25](42) <= 64646464_64646464_64646464_64646464_64646464_64646464_64646464_64646464_
5153 : 577 : PC=[0000000080002092] (M,26,01) 038c8f57 vadd.vv v30, v24, v25
VPR[30](43) <= a4a4a4a4_a4a4a4a4_a4a4a4a4_a4a4a4a4_a4a4a4a4_a4a4a4a4_a4a4a4a4_a4a4a4a4_
5153 : 578 : PC=[0000000080002096] (M,26,02) 00009fb9 c.addw  a5, a4
GPR[15](4) <= 0000000000000060
5153 : 579 : PC=[0000000080002098] (M,26,04) fef655e3 bge     a2, a5, pc - 22
5154 : 580 : PC=[0000000080002082] (M,27,01) 40f5873b subw    a4, a1, a5
GPR[14](7) <= 0000000000000004
5155 : 581 : PC=[0000000080002086] (M,28,01) 04077757 vsetvli a4, a4, e8, m1, ta, mu
GPR[14](60) <= 0000000000000004
5158 : 582 : PC=[000000008000208a] (M,29,01) 5e07cc57 vmv.v.x v24, a5
VPR[24](44) <= 40404040_40404040_40404040_40404040_40404040_40404040_40404040_60606060_
5159 : 583 : PC=[000000008000208e] (M,30,01) 5e05ccd7 vmv.v.x v25, a1
VPR[25](45) <= 64646464_64646464_64646464_64646464_64646464_64646464_64646464_64646464_
5161 : 584 : PC=[0000000080002092] (M,31,01) 038c8f57 vadd.vv v30, v24, v25
VPR[30](46) <= a4a4a4a4_a4a4a4a4_a4a4a4a4_a4a4a4a4_a4a4a4a4_a4a4a4a4_a4a4a4a4_c4c4c4c4_
5161 : 585 : PC=[0000000080002096] (M,31,02) 00009fb9 c.addw  a5, a4
GPR[15](46) <= 0000000000000064
5161 : 586 : PC=[0000000080002098] (M,31,04) fef655e3 bge     a2, a5, pc - 22