diff --git a/rtl/serv_csr.v b/rtl/serv_csr.v index 1bd69b4..40423e1 100644 --- a/rtl/serv_csr.v +++ b/rtl/serv_csr.v @@ -2,7 +2,7 @@ module serv_csr ( input wire i_clk, - input wire i_run, + input wire i_en, input wire [4:2] i_cnt, input wire [3:2] i_cnt_r, input wire i_e_op, @@ -48,9 +48,9 @@ module serv_csr (i_csr_source == CSR_SOURCE_CSR) ? csr_out : 1'bx; - assign csr_out = (i_mstatus_en & i_run & mstatus) | + assign csr_out = (i_mstatus_en & i_en & mstatus) | i_rf_csr_out | - (i_mcause_en & i_run & mcause); + (i_mcause_en & i_en & mcause); assign o_q = csr_out; @@ -94,7 +94,7 @@ module serv_csr 4'd0; end - if (i_mcause_en & i_run) begin + if (i_mcause_en & i_en) begin if (i_cnt[4:2] == 3'd0) mcause3_0 <= {csr_in, mcause3_0[3:1]}; if ((i_cnt[4:2] == 3'd7) & i_cnt_r[3]) diff --git a/rtl/serv_decode.v b/rtl/serv_decode.v index 801040b..617b9a6 100644 --- a/rtl/serv_decode.v +++ b/rtl/serv_decode.v @@ -16,6 +16,7 @@ module serv_decode output wire o_mem_op, output wire o_shift_op, output wire o_slt_op, + output wire o_rd_op, //To bufreg output wire o_bufreg_loop, output wire o_bufreg_rs1_en, @@ -35,7 +36,6 @@ module serv_decode output wire o_alu_sh_right, output wire [3:0] o_alu_rd_sel, //To RF - output wire o_rf_rd_en, output reg [4:0] o_rf_rd_addr, output reg [4:0] o_rf_rs1_addr, output reg [4:0] o_rf_rs2_addr, @@ -116,9 +116,12 @@ module serv_decode assign o_ctrl_mret = (opcode[4] & opcode[2] & op21 & !(|funct3)); - assign o_rf_rd_en = (opcode[2] | - (!opcode[2] & opcode[4] & opcode[0]) | - (!opcode[2] & !opcode[3] & !opcode[0])); + //Write to RD + //True for OP-IMM, AUIPC, OP, LUI, SYSTEM, JALR, JAL, LOAD + //False for STORE, BRANCH, MISC-MEM + assign o_rd_op = (opcode[2] | + (!opcode[2] & opcode[4] & opcode[0]) | + (!opcode[2] & !opcode[3] & !opcode[0])) & (|o_rf_rd_addr); assign o_alu_sub = opcode[3] & imm30/*alu_sub_r*/; diff --git a/rtl/serv_rf_if.v b/rtl/serv_rf_if.v index f8cf70e..23d3775 100644 --- a/rtl/serv_rf_if.v +++ b/rtl/serv_rf_if.v @@ -16,7 +16,6 @@ module serv_rf_if input wire i_rdata0, input wire i_rdata1, - input wire i_run, //Trap interface input wire i_trap, input wire i_mret, @@ -72,7 +71,7 @@ module serv_rf_if assign o_wreg0 = i_trap ? {4'b1000,CSR_MTVAL} : {1'b0,i_rd_waddr}; assign o_wreg1 = i_trap ? {4'b1000,CSR_MEPC} : {4'b1000,i_csr_addr}; - assign o_wen0 = i_trap | (i_rd_wen & i_run); + assign o_wen0 = i_trap | i_rd_wen; assign o_wen1 = i_trap | i_csr_en; /* diff --git a/rtl/serv_state.v b/rtl/serv_state.v index 61e5078..87fbb42 100644 --- a/rtl/serv_state.v +++ b/rtl/serv_state.v @@ -10,15 +10,16 @@ module serv_state output wire o_rf_rreq, output wire o_rf_wreq, input wire i_rf_ready, + output wire o_rf_rd_en, input wire i_take_branch, input wire i_branch_op, input wire i_mem_op, input wire i_shift_op, input wire i_slt_op, input wire i_e_op, + input wire i_rd_op, input wire [4:0] i_rs1_addr, output wire o_init, - output wire o_run, output wire o_cnt_en, output reg [4:0] o_cnt, output reg [3:0] o_cnt_r, @@ -46,12 +47,11 @@ module serv_state reg cnt_done; reg stage_two_req; wire cnt_en; - wire running; assign o_cnt_done = cnt_done; //Update PC in RUN or TRAP states - assign o_ctrl_pc_en = running | (state == TRAP); + assign o_ctrl_pc_en = cnt_en & !o_init; assign o_csr_imm = (o_cnt < 5) ? i_rs1_addr[o_cnt[2:0]] : 1'b0; assign o_alu_shamt_en = (o_cnt < 5) & (state == INIT); @@ -63,9 +63,6 @@ module serv_state assign o_init = (state == INIT); - assign running = (state == RUN); - assign o_run = running; - //slt*, branch/jump, shift, load/store wire two_stage_op = i_slt_op | i_mem_op | i_branch_op | i_shift_op; @@ -85,6 +82,8 @@ module serv_state //Prepare RF for writes when everything is ready to enter stage two assign o_rf_wreq = ((i_shift_op & i_alu_sh_done & stage_two_pending) | (i_mem_op & i_dbus_ack) | (stage_two_req & (i_slt_op | i_branch_op))) & !trap_pending; + assign o_rf_rd_en = i_rd_op & cnt_en & !o_init; + //Shift operations require bufreg to hold for one cycle between INIT and RUN before shifting assign o_bufreg_hold = !cnt_en & (stage_two_req | ~i_shift_op); diff --git a/rtl/serv_top.v b/rtl/serv_top.v index d8df4cf..0560a8b 100644 --- a/rtl/serv_top.v +++ b/rtl/serv_top.v @@ -66,6 +66,7 @@ module serv_top wire mem_op; wire shift_op; wire slt_op; + wire rd_op; wire rd_alu_en; wire rd_csr_en; @@ -84,7 +85,6 @@ module serv_top wire pc_rel; wire init; - wire run; wire cnt_en; wire [4:0] cnt; wire [3:0] cnt_r; @@ -155,15 +155,16 @@ module serv_top .o_rf_rreq (o_rf_rreq), .o_rf_wreq (o_rf_wreq), .i_rf_ready (i_rf_ready), + .o_rf_rd_en (rd_en), .i_take_branch (take_branch), .i_branch_op (branch_op), .i_mem_op (mem_op), .i_shift_op (shift_op), .i_slt_op (slt_op), .i_e_op (e_op), + .i_rd_op (rd_op), .i_rs1_addr (rs1_addr), .o_init (init), - .o_run (run), .o_cnt_en (cnt_en), .o_cnt (cnt), .o_cnt_r (cnt_r), @@ -199,6 +200,7 @@ module serv_top .o_mem_op (mem_op), .o_shift_op (shift_op), .o_slt_op (slt_op), + .o_rd_op (rd_op), //To bufreg .o_bufreg_loop (bufreg_loop), .o_bufreg_rs1_en (bufreg_rs1_en), @@ -219,7 +221,6 @@ module serv_top .o_alu_sh_right (alu_sh_right), .o_alu_rd_sel (alu_rd_sel), //To RF - .o_rf_rd_en (rd_en), .o_rf_rd_addr (rd_addr), .o_rf_rs1_addr (rs1_addr), .o_rf_rs2_addr (rs2_addr), @@ -333,7 +334,6 @@ module serv_top .i_rdata0 (i_rdata0), .i_rdata1 (i_rdata1), - .i_run (run), //Trap interface .i_trap (trap), .i_mret (mret), @@ -347,7 +347,7 @@ module serv_top .i_csr_addr (csr_addr), .i_csr (csr_in), //RD write port - .i_rd_wen (rd_en & (|rd_addr)), + .i_rd_wen (rd_en), .i_rd_waddr (rd_addr), .i_ctrl_rd (ctrl_rd), .i_alu_rd (alu_rd), @@ -390,7 +390,7 @@ module serv_top serv_csr csr ( .i_clk (clk), - .i_run (run), + .i_en (cnt_en), .i_cnt (cnt[4:2]), .i_cnt_r (cnt_r[3:2]), .i_e_op (e_op),