自作RISC-Vアウトオブオーダコアの実装、FPUを実装している。FPNewのデータ変換命令は、また別のユニットが担当するらしい。
fpnew_opgroup_multifmt_slice
というモジュールを使う。
基本的な動かし方は一緒なのだが、データの変換元と変換先の指定にop_mod_i
, src_fmt_i
, dst_fmt_i
, int_fmt_i
というのを使用している。
fpnew_opgroup_multifmt_slice /* #( .OpGroup ( OpGroup ), .Width ( Width ), .FpFmtConfig ( FpFmtMask ), .IntFmtConfig ( IntFmtMask ), .EnableVectors ( EnableVectors ), .NumPipeRegs ( REG ), .PipeConfig ( PipeConfig ), .TagType ( TagType ) ) */ #( .NumPipeRegs(1), .PipeConfig (fpnew_pkg::BEFORE), .TagType (logic) ) fpnew_cvt ( .clk_i ( i_clk ), .rst_ni ( i_reset_n ), .operands_i ( w_multifmt_rs ), .is_boxed_i ( w_multifmt_boxed ), .rnd_mode_i ( fpnew_pkg::RNE ), .op_i ( w_fpnew_op ), .op_mod_i ( w_fpnew_op_mod ), .src_fmt_i ( w_src_fp_fmt ), .dst_fmt_i ( w_dst_fp_fmt ), .int_fmt_i ( w_int_fmt ), .vectorial_op_i ( ), .tag_i ( ), .in_valid_i ( w_cvt_in_valid ), .in_ready_o ( ), .flush_i ( 1'b0 ), .result_o ( w_cast_result ), .status_o ( w_cast_status ), .extension_bit_o ( ), .tag_o ( ), .out_valid_o ( w_cast_out_valid ), .out_ready_i ( 1'b1 ), .busy_o ( ) );
各命令に応じて入出力フォーマットを指定する。
とりあえず命令に応じてFPNew向けに入力信号を制御するデコーダを作った。
case (i_pipe_ctrl.op) OP_FCVT_S_D : {w_cvt_valid, w_int_fmt, w_dst_fp_fmt, w_src_fp_fmt} = {1'b1, fpnew_pkg::INT64, fpnew_pkg::FP32, fpnew_pkg::FP64}; OP_FCVT_D_S : {w_cvt_valid, w_int_fmt, w_dst_fp_fmt, w_src_fp_fmt} = {1'b1, fpnew_pkg::INT64, fpnew_pkg::FP64, fpnew_pkg::FP32}; OP_FCVT_W_D : {w_cvt_valid, w_int_fmt, w_dst_fp_fmt, w_src_fp_fmt} = {1'b1, fpnew_pkg::INT32, fpnew_pkg::FP32, fpnew_pkg::FP64}; OP_FCVT_WU_D : {w_cvt_valid, w_int_fmt, w_dst_fp_fmt, w_src_fp_fmt} = {1'b1, fpnew_pkg::INT32, fpnew_pkg::FP32, fpnew_pkg::FP64}; OP_FCVT_D_W : {w_cvt_valid, w_int_fmt, w_dst_fp_fmt, w_src_fp_fmt} = {1'b1, fpnew_pkg::INT64, fpnew_pkg::FP64, fpnew_pkg::FP32}; OP_FCVT_D_WU : {w_cvt_valid, w_int_fmt, w_dst_fp_fmt, w_src_fp_fmt} = {1'b1, fpnew_pkg::INT32, fpnew_pkg::FP64, fpnew_pkg::FP32}; `ifdef RV64 OP_FCVT_L_D : {w_cvt_valid, w_int_fmt, w_dst_fp_fmt, w_src_fp_fmt} = {1'b1, fpnew_pkg::INT64, fpnew_pkg::FP32, fpnew_pkg::FP64}; OP_FCVT_LU_D : {w_cvt_valid, w_int_fmt, w_dst_fp_fmt, w_src_fp_fmt} = {1'b1, fpnew_pkg::INT64, fpnew_pkg::FP32, fpnew_pkg::FP64}; OP_FMV_X_D : {w_cvt_valid, w_int_fmt, w_dst_fp_fmt, w_src_fp_fmt} = {1'b1, fpnew_pkg::INT32, fpnew_pkg::FP32, fpnew_pkg::FP64}; OP_FCVT_D_L : {w_cvt_valid, w_int_fmt, w_dst_fp_fmt, w_src_fp_fmt} = {1'b1, fpnew_pkg::INT64, fpnew_pkg::FP64, fpnew_pkg::FP64}; OP_FCVT_D_LU : {w_cvt_valid, w_int_fmt, w_dst_fp_fmt, w_src_fp_fmt} = {1'b1, fpnew_pkg::INT64, fpnew_pkg::FP64, fpnew_pkg::FP64}; OP_FMV_D_X : {w_cvt_valid, w_int_fmt, w_dst_fp_fmt, w_src_fp_fmt} = {1'b1, fpnew_pkg::INT32, fpnew_pkg::FP64, fpnew_pkg::FP64}; `endif // RV64 default : {w_cvt_valid, w_int_fmt, w_dst_fp_fmt, w_src_fp_fmt} = {1'b0, fpnew_pkg::INT64, fpnew_pkg::FP32, fpnew_pkg::FP64}; endcase // case (i_pipe_ctrl.op)
何となく動くようになったが、まだテストが落ちる。もう少し解析していこう。