FPGA開発日記

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

自作RISC-Vアウトオブオーダコアの実装 (FPUのサイクル数変更)

自作RISC-Vアウトオブオーダコアの実装、FPUを実装している。現在整数側のパイプラインをベースとしてFPUのレイテンシを1としているが、そんなことはあり得ないので、レイテンシを伸ばしていこうと思う。 ただし、すべてのFPU命令のレイテンシを伸ばしていくとそれは問題がある。FPU命令群の中にはFMVFSGNJなどの非常にシンプルな命令が入っており、これらは1サイクルで計算してしまって構わない。 これらを区別するために、パイプライン終了の信号とレジスタの書き込みポートを2つに拡張してしまおうと思う。

このために、まずパイプラインの完了、レジスタの書き込みポートを2つに増やす。

    output msrh_pkg::early_wr_t o_ex1_mv_early_wr,
    output msrh_pkg::phy_wr_t   o_ex3_mv_phy_wr,
    done_if.master              ex3_mv_done_if,

    output msrh_pkg::phy_wr_t   o_fpnew_phy_wr,
    done_if.master              fpnew_done_if

2つのパイプラインは、デコード時にどちらを使うかを指定する。データ移動系命令は1サイクルで完了し、それ以外のFPNewを使う算術演算命令はより長いレイテンシで完了できるようにする。

always_comb begin
  o_ex3_mv_phy_wr.valid   = r_ex3_wr_valid & (r_ex3_pipe_ctrl.pipe == PIPE_FAST);
  o_ex3_mv_phy_wr.rd_rnid = r_ex3_issue.wr_reg.rnid;
  o_ex3_mv_phy_wr.rd_type = r_ex3_issue.wr_reg.typ;
  o_ex3_mv_phy_wr.rd_data = r_ex3_res_data;

  ex3_mv_done_if.done                = r_ex3_issue.valid & (r_ex3_pipe_ctrl.pipe == PIPE_FAST);
  ex3_mv_done_if.index_oh            = r_ex3_index;
  ex3_mv_done_if.payload.except_valid        = 1'b0;
  ex3_mv_done_if.payload.except_type         = msrh_pkg::except_t'('h0);
  ex3_mv_done_if.payload.fflags_update_valid = 1'b0;
  ex3_mv_done_if.payload.fflags              = 'h0;

  o_fpnew_phy_wr.valid   = w_fpnew_result_valid;
  o_fpnew_phy_wr.rd_rnid = w_fpnew_rnid;
  o_fpnew_phy_wr.rd_type = w_fpnew_reg_type;
  o_fpnew_phy_wr.rd_data = w_fpnew_result_data;

  fpnew_done_if.done                = w_fpnew_result_valid;
  fpnew_done_if.index_oh            = w_fpnew_sched_index;
  fpnew_done_if.payload.except_valid        = 1'b0;
  fpnew_done_if.payload.except_type         = msrh_pkg::except_t'('h0);
  fpnew_done_if.payload.fflags_update_valid = w_fpnew_result_valid;
  fpnew_done_if.payload.fflags              = w_fpnew_result_fflags;

end // always_comb

fpnew_wrapperのパイプライン側も変更して、サイクル数を伸ばしていく。さらにtagポートを使用して、書き込み時に必要な情報を一緒にパイプラインに流していく。

以下の実装のTagTypeの部分と、NumPipeRegsの部分を変更した。

  fpnew_fma
    #(
      .FpFormat   (fpnew_pkg::FP64),
      .NumPipeRegs(msrh_conf_pkg::FPNEW_LATENCY),
      .PipeConfig (fpnew_pkg::BEFORE),
      .TagType    (aux_fpnew_t),
      .AuxType    (logic)
      )
  fpnew_64
  (
   .clk_i  (i_clk    ),
   .rst_ni (i_reset_n),
   // Input signals
   .operands_i      (w_fma64_rs       ),  // input logic [2:0][WIDTH-1:0]      // 3 operands
   .is_boxed_i      (w_fma64_boxed    ),  // input logic [2:0]                 // 3 operands
   .rnd_mode_i      (i_rnd_mode       ),  // input fpnew_pkg::roundmode_e
   .op_i            (w_fpnew_op       ),  // input fpnew_pkg::operation_e
   .op_mod_i        (w_fpnew_op_mod   ),  // input logic
   .tag_i           (w_aux_fpnew_in    ),  // input TagType
   .aux_i           (w_aux_fpnew_in   ),  // input AuxType
   // Input Handshake
   .in_valid_i      (w_fma64_in_valid ),  // input  logic
   .in_ready_o      (o_ready          ),  // output logic
   .flush_i         (1'b0             ),  // input  logic
   // Output signals
   .result_o        (w_fma64_result   ),  // output logic [WIDTH-1:0]
   .status_o        (w_fma64_fflags   ),  // output fpnew_pkg::status_t
   .extension_bit_o (                 ),  // output logic
   .tag_o           (w_fma64_aux      ),  // output TagType
   .aux_o           (                 ),  // output AuxType
   // Output handshake
   .out_valid_o     (w_fma64_out_valid),  // output logic
   .out_ready_i     (1'b1             ),  // input  logic
   // Indication of valid data in flight
   .busy_o          (                 )   // output logic
   );

また、それぞれのコンフィグレーションでFPUパイプラインの長さを変えて、それぞれのパイプライン長で検証できるようにした。

ag FPNEW_LATENCY ../src/*_conf_pkg.sv
../src/msrh_big_conf_pkg.sv
39:  localparam FPNEW_LATENCY = 6;

../src/msrh_giant_conf_pkg.sv
39:  localparam FPNEW_LATENCY = 6;

../src/msrh_small_conf_pkg.sv
39:  localparam FPNEW_LATENCY = 2;

../src/msrh_standard_conf_pkg.sv
39:  localparam FPNEW_LATENCY = 4;

../src/msrh_tiny_conf_pkg.sv
39:  localparam FPNEW_LATENCY = 1;