From f373d7bcb69421674735efd8a78220aa4d772cd8 Mon Sep 17 00:00:00 2001 From: Olof Kindgren Date: Tue, 25 Aug 2020 11:55:08 +0200 Subject: [PATCH] Reuse immediate regs for RF addresses --- rtl/serv_decode.v | 6 ++++ rtl/serv_immdec.v | 86 ++++++++++++++++++++++++++++++++--------------- rtl/serv_top.v | 3 ++ 3 files changed, 67 insertions(+), 28 deletions(-) diff --git a/rtl/serv_decode.v b/rtl/serv_decode.v index f5846ee..f735b1a 100644 --- a/rtl/serv_decode.v +++ b/rtl/serv_decode.v @@ -48,6 +48,7 @@ module serv_decode output wire o_csr_imm_en, //To top output wire [3:0] o_immdec_ctrl, + output wire [3:0] o_immdec_en, output wire o_op_b_source, output wire o_rd_csr_en, output wire o_rd_alu_en); @@ -202,6 +203,11 @@ module serv_decode assign o_immdec_ctrl[2] = opcode[4] & !opcode[0]; assign o_immdec_ctrl[3] = opcode[4]; + assign o_immdec_en[3] = opcode[4] | opcode[3] | opcode[2] | !opcode[0]; //B I J S U + assign o_immdec_en[2] = (opcode[4] & opcode[2]) | !opcode[3] | opcode[0]; // I J U + assign o_immdec_en[1] = (opcode[2:1] == 2'b01) | (opcode[2] & opcode[0]) | o_csr_imm_en;// J U + assign o_immdec_en[0] = ~o_rd_op; //B S + assign o_alu_rd_sel[0] = (funct3 == 3'b000); // Add/sub assign o_alu_rd_sel[1] = (funct3[2:1] == 2'b01); //SLT* assign o_alu_rd_sel[2] = funct3[2]; //Bool diff --git a/rtl/serv_immdec.v b/rtl/serv_immdec.v index 0216be7..aa40e7d 100644 --- a/rtl/serv_immdec.v +++ b/rtl/serv_immdec.v @@ -1,11 +1,13 @@ `default_nettype none module serv_immdec + #(parameter SHARED_RFADDR_IMM_REGS = 1) ( input wire i_clk, //State input wire i_cnt_en, input wire i_cnt_done, //Control + input wire [3:0] i_immdec_en, input wire i_csr_imm_en, input wire [3:0] i_ctrl, output wire [4:0] o_rd_addr, @@ -26,37 +28,65 @@ module serv_immdec reg [4:0] imm24_20; reg [4:0] imm11_7; - reg [4:0] rd_addr; - reg [4:0] rs1_addr; - reg [4:0] rs2_addr; - - assign o_rd_addr = rd_addr; - assign o_rs1_addr = rs1_addr; - assign o_rs2_addr = rs2_addr; - assign o_imm = i_cnt_done ? signbit : i_ctrl[0] ? imm11_7[0] : imm24_20[0]; assign o_csr_imm = imm19_12_20[4]; - always @(posedge i_clk) begin - if (i_wb_en) begin - /* CSR immediates are always zero-extended, hence clear the signbit */ - signbit <= i_wb_rdt[31] & !i_csr_imm_en; - imm19_12_20 <= {i_wb_rdt[19:12],i_wb_rdt[20]}; - imm7 <= i_wb_rdt[7]; - imm30_25 <= i_wb_rdt[30:25]; - imm24_20 <= i_wb_rdt[24:20]; - imm11_7 <= i_wb_rdt[11:7]; + generate + if (SHARED_RFADDR_IMM_REGS) begin + assign o_rs1_addr = imm19_12_20[8:4]; + assign o_rs2_addr = imm24_20; + assign o_rd_addr = imm11_7; - rd_addr <= i_wb_rdt[11:7]; - rs1_addr <= i_wb_rdt[19:15]; - rs2_addr <= i_wb_rdt[24:20]; + always @(posedge i_clk) begin + if (i_wb_en) begin + /* CSR immediates are always zero-extended, hence clear the signbit */ + signbit <= i_wb_rdt[31] & !i_csr_imm_en; + end + if (i_wb_en | (i_cnt_en & i_immdec_en[1])) + imm19_12_20 <= i_wb_en ? {i_wb_rdt[19:12],i_wb_rdt[20]} : {i_ctrl[3] ? signbit : imm24_20[0], imm19_12_20[8:1]}; + if (i_wb_en | (i_cnt_en)) + imm7 <= i_wb_en ? i_wb_rdt[7] : signbit; + + if (i_wb_en | (i_cnt_en & i_immdec_en[3])) + imm30_25 <= i_wb_en ? i_wb_rdt[30:25] : {i_ctrl[2] ? imm7 : i_ctrl[1] ? signbit : imm19_12_20[0], imm30_25[5:1]}; + + if (i_wb_en | (i_cnt_en & i_immdec_en[2])) + imm24_20 <= i_wb_en ? i_wb_rdt[24:20] : {imm30_25[0], imm24_20[4:1]}; + + if (i_wb_en | (i_cnt_en & i_immdec_en[0])) + imm11_7 <= i_wb_en ? i_wb_rdt[11:7] : {imm30_25[0], imm11_7[4:1]}; + end + end else begin + reg [4:0] rd_addr; + reg [4:0] rs1_addr; + reg [4:0] rs2_addr; + + assign o_rd_addr = rd_addr; + assign o_rs1_addr = rs1_addr; + assign o_rs2_addr = rs2_addr; + always @(posedge i_clk) begin + if (i_wb_en) begin + /* CSR immediates are always zero-extended, hence clear the signbit */ + signbit <= i_wb_rdt[31] & !i_csr_imm_en; + imm19_12_20 <= {i_wb_rdt[19:12],i_wb_rdt[20]}; + imm7 <= i_wb_rdt[7]; + imm30_25 <= i_wb_rdt[30:25]; + imm24_20 <= i_wb_rdt[24:20]; + imm11_7 <= i_wb_rdt[11:7]; + + rd_addr <= i_wb_rdt[11:7]; + rs1_addr <= i_wb_rdt[19:15]; + rs2_addr <= i_wb_rdt[24:20]; + end + if (i_cnt_en) begin + imm19_12_20 <= {i_ctrl[3] ? signbit : imm24_20[0], imm19_12_20[8:1]}; + imm7 <= signbit; + imm30_25 <= {i_ctrl[2] ? imm7 : i_ctrl[1] ? signbit : imm19_12_20[0], imm30_25[5:1]}; + imm24_20 <= {imm30_25[0], imm24_20[4:1]}; + imm11_7 <= {imm30_25[0], imm11_7[4:1]}; + end + end end - if (i_cnt_en) begin - imm19_12_20 <= {i_ctrl[3] ? signbit : imm24_20[0], imm19_12_20[8:1]}; - imm7 <= signbit; - imm30_25 <= {i_ctrl[2] ? imm7 : i_ctrl[1] ? signbit : imm19_12_20[0], imm30_25[5:1]}; - imm24_20 <= {imm30_25[0], imm24_20[4:1]}; - imm11_7 <= {imm30_25[0], imm11_7[4:1]}; - end - end + endgenerate + endmodule diff --git a/rtl/serv_top.v b/rtl/serv_top.v index e976e81..3f6aac2 100644 --- a/rtl/serv_top.v +++ b/rtl/serv_top.v @@ -63,6 +63,7 @@ module serv_top wire [4:0] rs2_addr; wire [3:0] immdec_ctrl; + wire [3:0] immdec_en; wire sh_right; wire bne_or_bge; @@ -253,6 +254,7 @@ module serv_top .o_csr_imm_en (csr_imm_en), //To top .o_immdec_ctrl (immdec_ctrl), + .o_immdec_en (immdec_en), .o_rd_csr_en (rd_csr_en), .o_rd_alu_en (rd_alu_en)); @@ -263,6 +265,7 @@ module serv_top .i_cnt_en (cnt_en), .i_cnt_done (cnt_done), //Control + .i_immdec_en (immdec_en), .i_csr_imm_en (csr_imm_en), .i_ctrl (immdec_ctrl), .o_rd_addr (rd_addr),