FPGA開発日記

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

自作RISC-Vアウトオブオーダコアの実装 (FPNewと算術演算以外の命令サポート)

自作RISC-Vアウトオブオーダコアの実装、FPUを実装している。FPUの基本的な算術演算はFPNewにより動作するようになったが、算術演算以外の命令はまだサポートしていない。調査してみよう。

FPNewはいくつかのサブモジュールから構成されているが、基本的な演算をサポートしているのがfpnew_fmaというモジュールだ。これにより加減算・乗算を実行する。

  fpnew_fma
    #(
      .FpFormat   (fpnew_pkg::FP64),
      .NumPipeRegs(1),
      .PipeConfig (fpnew_pkg::BEFORE),
      .TagType    (logic),
      .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      (fpnew_pkg::RNE   ),  // 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           (1'b0             ),  // input TagType
   .aux_i           (1'b0             ),  // 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           (                 ),  // 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
   );

一方でそれ以外のFCLASS命令や比較命令はfpnew_noncompというモジュールを使って実行するようだ。

  fpnew_noncomp #(
      .FpFormat   (fpnew_pkg::FP64),
      .NumPipeRegs(1),
      .PipeConfig (fpnew_pkg::BEFORE),
      .TagType    (logic),
      .AuxType    (logic)
  ) fpnew_noncomp64 (
    .clk_i  (i_clk    ),
    .rst_ni (i_reset_n),
    .operands_i      ( w_noncomp64_rs         ),
    .is_boxed_i      ( w_noncomp64_boxed      ),
    .rnd_mode_i      ( i_pipe_ctrl.op == OP_FEQ ? fpnew_pkg::RDN :
                       i_pipe_ctrl.op == OP_FLT ? fpnew_pkg::RTZ :
                       i_pipe_ctrl.op == OP_FLE ? fpnew_pkg::RNE :
    .op_i            ( w_fpnew_op         ),
    .op_mod_i        ( w_fpnew_op_mod                            ),
    .tag_i           ( 1'b0                   ),
    .aux_i           (                        ), // Remember whether operation was vectorial
    .in_valid_i      ( w_noncomp64_in_valid   ),
    .in_ready_o      (                        ),
    .flush_i         ( 1'b0                   ),
    .result_o        ( w_noncomp64_result     ),
    .status_o        ( w_noncomp64_status     ),
    .extension_bit_o (                        ),
    .class_mask_o    ( w_noncomp64_class_mask ),
    .is_class_o      (                        ),
    .tag_o           (                        ),
    .aux_o           (                        ),
    .out_valid_o     ( w_noncomp64_out_valid  ),
    .out_ready_i     ( 1'b1                   ),
    .busy_o          (                        )
  );

まずはfclassのテストを実行してみると、正しく結果を取得できた。ちなみにFCLASSの値はFPNewは以下のenumでサポートされており、そのまま整数に変換するだけで汎用レジスタに格納することができる。

  // Classification mask
  typedef enum logic [9:0] {
    NEGINF     = 10'b00_0000_0001,
    NEGNORM    = 10'b00_0000_0010,
    NEGSUBNORM = 10'b00_0000_0100,
    NEGZERO    = 10'b00_0000_1000,
    POSZERO    = 10'b00_0001_0000,
    POSSUBNORM = 10'b00_0010_0000,
    POSNORM    = 10'b00_0100_0000,
    POSINF     = 10'b00_1000_0000,
    SNAN       = 10'b01_0000_0000,
    QNAN       = 10'b10_0000_0000
  } classmask_e;

さらに少し注意して、比較演算のときは比較の種類によって少しフラグを少し使い分ける必要がある。

f:id:msyksphinz:20220401001101p:plain
https://github.com/pulp-platform/fpnew/blob/develop/docs/README.md

これにより、FCLASS命令と比較命令が動作するようになった。