浮動小数点命令とレジスタをサポートするために、リネームと物理レジスタの実装を変更する。
物理レジスタについては、x0(=ft0)レジスタに書き込みができるように変更する。また、リネームにおいてはx0(=ft0)もリネームを実行する。
汎用レジスタに対する特殊な条件を挿入する必要がある。
// When instruction commit normally, return old RNID // even thouhg instruction is dead, newly allocated RNID should be return assign w_push_freelist = r_commit_rnid_update_dly.commit & r_commit_rnid_update_dly.rnid_valid[d_idx] & (r_commit_rnid_update_dly.rd_typ[d_idx] == REG_TYPE) & ((REG_TYPE == GPR) ? (r_commit_rnid_update_dly.rd_regidx[d_idx] != 'h0) : 1'b1);
こちらも同様。汎用レジスタに対してのみ特殊な条件を挿入する。
generate for (genvar r_idx = 0; r_idx < msrh_pkg::RNID_SIZE; r_idx++) begin : reg_loop if ((REG_TYPE == GPR) & (r_idx == 0)) begin assign r_phy_regs[r_idx] = {riscv_pkg::XLEN_W{1'b0}}; end else begin logic w_wr_valid; logic [riscv_pkg::XLEN_W-1:0] w_wr_data; select_oh #( .SEL_WIDTH (msrh_pkg::TGT_BUS_SIZE), .KEY_WIDTH (msrh_pkg::RNID_W), .DATA_WIDTH(riscv_pkg::XLEN_W) ) wr_data_select ( .i_cmp_key(r_idx[msrh_pkg::RNID_W-1:0]), .i_valid(wr_valid), .i_keys(wr_rnid), .i_data(wr_data), .o_valid(w_wr_valid), .o_data(w_wr_data) ); always_ff @(posedge i_clk, negedge i_reset_n) begin if (!i_reset_n) begin r_phy_regs[r_idx] <= {riscv_pkg::XLEN_W{1'b0}}; end else begin if (w_wr_valid) begin r_phy_regs[r_idx] <= w_wr_data; end end end end // else: !if((REG_TYPE == GPR) & (r_idx == 0)) end endgenerate
これに基づいて、いよいよ少しずつFPUのパイプラインを実装して行く。
logic [ 63: 0] w_ex2_rs1_canonical; logic [ 63: 0] w_ex2_rs2_canonical; assign w_ex2_rs1_canonical = !(&w_ex2_rs1_selected_data[63:32]) ? 64'hffffffff_7fc00000 : w_ex2_rs1_selected_data; assign w_ex2_rs2_canonical = !(&w_ex2_rs2_selected_data[63:32]) ? 64'hffffffff_7fc00000 : w_ex2_rs2_selected_data; always_comb begin case (r_ex2_pipe_ctrl.op) OP_FMV_X_W : w_ex2_res_data = {{32{w_ex2_rs1_selected_data[31]}}, w_ex2_rs1_selected_data[31: 0]}; OP_FMV_W_X : w_ex2_res_data = w_ex2_rs1_selected_data; OP_FMV_X_D : w_ex2_res_data = w_ex2_rs1_selected_data; OP_FMV_D_X : w_ex2_res_data = w_ex2_rs1_selected_data; OP_FSGNJ_D : w_ex2_res_data = { w_ex2_rs2_selected_data[63], w_ex2_rs1_selected_data[62:0]}; OP_FSGNJN_D : w_ex2_res_data = {~w_ex2_rs2_selected_data[63], w_ex2_rs1_selected_data[62:0]}; OP_FSGNJX_D : w_ex2_res_data = { w_ex2_rs1_selected_data[63] ^ w_ex2_rs2_selected_data[63], w_ex2_rs1_selected_data[62:0]}; OP_FSGNJ_S : w_ex2_res_data = {w_ex2_rs1_canonical[63:32], w_ex2_rs2_canonical[31], w_ex2_rs1_canonical[30:0]}; OP_FSGNJN_S : w_ex2_res_data = {w_ex2_rs1_canonical[63:32], ~w_ex2_rs2_canonical[31], w_ex2_rs1_canonical[30:0]}; OP_FSGNJX_S : w_ex2_res_data = {w_ex2_rs1_canonical[63:32], w_ex2_rs1_canonical[31] ^ w_ex2_rs2_canonical[31], w_ex2_rs1_canonical[30: 0]}; default : w_ex2_res_data = 'h0; endcase // case (r_ex3_pipe_ctrl.op) end // always_comb
とりあえずは符号変換命令までは実装できた。しかしテストベンチではfeq
が実行されているようだ。ここでコケる―。
4730 : 707 : PC=[0000000080000b74] (U,15,02) f20580d3 fmv.d.x ft1, a1 FPR[01](94) <= ffffffff11111111 4731 : 708 : PC=[0000000080000b78] (U,00,01) f2060153 fmv.d.x ft2, a2 FPR[02](42) <= ffffffff11111111 4732 : 709 : PC=[0000000080000b7c] (U,01,01) 22208053 fsgnj.d ft0, ft1, ft2 FPR[00](68) <= ffffffff11111111 4745 : 710 : PC=[0000000080000b80] (U,02,01) a0002553 feq.s a0, ft0, ft0 ========================================== Wrong GPR[10](10): RTL = 0000000000000000, ISS = 0000000000000001 ========================================== =============================== SIMULATION FINISH : FAIL (CODE=100) ===============================