diff --git a/rtl/serv_decode.v b/rtl/serv_decode.v index 1dbfdef..7457b97 100644 --- a/rtl/serv_decode.v +++ b/rtl/serv_decode.v @@ -6,9 +6,9 @@ module serv_decode input wire i_cnt_en, input wire [31:2] i_wb_rdt, input wire i_wb_en, - input wire i_alu_cmp, //To state - output wire o_take_branch, + output wire o_bne_or_bge, + output wire o_cond_branch, output wire o_e_op, output wire o_ebreak, output wire o_branch_op, @@ -33,7 +33,7 @@ module serv_decode output wire o_alu_cmp_uns, output wire o_alu_sh_signed, output wire o_alu_sh_right, - output wire [3:0] o_alu_rd_sel, + output wire [3:0] o_alu_rd_sel, //To RF output reg [4:0] o_rf_rd_addr, output reg [4:0] o_rf_rs1_addr, @@ -97,13 +97,8 @@ module serv_decode //False for JALR/LOAD/STORE/OP/OPIMM? assign o_bufreg_clr_lsb = opcode[4] & ((opcode[1:0] == 2'b00) | (opcode[1:0] == 2'b11)); - //Take branch for jump or branch instructions (opcode == 1x0xx) if - //a) It's an unconditional branch (opcode[0] == 1) - //b) It's a conditional branch (opcode[0] == 0) of type beq,blt,bltu (funct3[0] == 0) and ALU compare is true - //c) It's a conditional branch (opcode[0] == 0) of type bne,bge,bgeu (funct3[0] == 1) and ALU compare is false - //Only valid during the last cycle of INIT, when the branch condition has - //been calculated. - assign o_take_branch = opcode[4] & !opcode[2] & (opcode[0] | (i_alu_cmp^funct3[0])); + assign o_bne_or_bge = funct3[0]; + assign o_cond_branch = !opcode[0]; assign o_ctrl_utype = !opcode[4] & opcode[2] & opcode[0]; assign o_ctrl_jal_or_jalr = opcode[4] & opcode[0]; diff --git a/rtl/serv_state.v b/rtl/serv_state.v index b919264..ba80f7c 100644 --- a/rtl/serv_state.v +++ b/rtl/serv_state.v @@ -11,7 +11,9 @@ module serv_state output wire o_rf_wreq, input wire i_rf_ready, output wire o_rf_rd_en, - input wire i_take_branch, + input wire i_cond_branch, + input wire i_bne_or_bge, + input wire i_alu_cmp, input wire i_branch_op, input wire i_mem_op, input wire i_shift_op, @@ -65,6 +67,13 @@ module serv_state assign o_alu_shamt_en = (o_cnt0to3 | cnt4) & o_init; + //Take branch for jump or branch instructions (opcode == 1x0xx) if + //a) It's an unconditional branch (opcode[0] == 1) + //b) It's a conditional branch (opcode[0] == 0) of type beq,blt,bltu (funct3[0] == 0) and ALU compare is true + //c) It's a conditional branch (opcode[0] == 0) of type bne,bge,bgeu (funct3[0] == 1) and ALU compare is false + //Only valid during the last cycle of INIT, when the branch condition has + //been calculated. + wire take_branch = i_branch_op & (!i_cond_branch | (i_alu_cmp^i_bne_or_bge)); //slt*, branch/jump, shift, load/store wire two_stage_op = i_slt_op | i_mem_op | i_branch_op | i_shift_op; @@ -89,7 +98,7 @@ module serv_state always @(posedge i_clk) begin if (o_cnt_done) - o_ctrl_jump <= o_init & i_take_branch; + o_ctrl_jump <= o_init & take_branch; if (o_cnt_en) stage_two_pending <= o_init; diff --git a/rtl/serv_top.v b/rtl/serv_top.v index 2e1a988..501c0b9 100644 --- a/rtl/serv_top.v +++ b/rtl/serv_top.v @@ -63,7 +63,8 @@ module serv_top wire [3:0] immdec_ctrl; - wire take_branch; + wire bne_or_bge; + wire cond_branch; wire e_op; wire ebreak; wire branch_op; @@ -165,7 +166,9 @@ module serv_top .o_rf_wreq (o_rf_wreq), .i_rf_ready (i_rf_ready), .o_rf_rd_en (rd_en), - .i_take_branch (take_branch), + .i_bne_or_bge (bne_or_bge), + .i_cond_branch (cond_branch), + .i_alu_cmp (alu_cmp), .i_branch_op (branch_op), .i_mem_op (mem_op), .i_shift_op (shift_op), @@ -202,9 +205,9 @@ module serv_top .i_cnt_en (cnt_en), .i_wb_rdt (i_ibus_rdt[31:2]), .i_wb_en (o_ibus_cyc & i_ibus_ack), - .i_alu_cmp (alu_cmp), //To state - .o_take_branch (take_branch), + .o_bne_or_bge (bne_or_bge), + .o_cond_branch (cond_branch), .o_e_op (e_op), .o_ebreak (ebreak), .o_branch_op (branch_op),