diff --git a/rtl/ibex_ex_block.sv b/rtl/ibex_ex_block.sv index 58ff6943..feb151fa 100644 --- a/rtl/ibex_ex_block.sv +++ b/rtl/ibex_ex_block.sv @@ -60,7 +60,7 @@ module ibex_ex_block #( logic [33:0] alu_adder_result_ext; logic alu_cmp_result, alu_is_equal_result; logic multdiv_valid; - logic multdiv_en; + logic multdiv_sel; logic [31:0] alu_imd_val_d; logic alu_imd_val_we; logic [33:0] multdiv_imd_val_d; @@ -76,12 +76,12 @@ module ibex_ex_block #( from the multdiv_i module are eliminated */ if (RV32M) begin : gen_multdiv_m - assign multdiv_en = mult_en_i | div_en_i; + assign multdiv_sel = multdiv_sel_i; end else begin : gen_multdiv_no_m - assign multdiv_en = 1'b0; + assign multdiv_sel = 1'b0; end - assign result_ex_o = multdiv_en ? multdiv_result : alu_result; + assign result_ex_o = multdiv_sel ? multdiv_result : alu_result; // branch handling assign branch_decision_o = alu_cmp_result; @@ -204,7 +204,9 @@ module ibex_ex_block #( ); end - // ALU output valid in same cycle, multiplier/divider may require multiple cycles - assign ex_valid_o = multdiv_en ? multdiv_valid : !alu_imd_val_we; + // Multiplier/divider may require multiple cycles. The ALU output is valid in the same cycle + // unless the intermediate result register is being written (which indicates this isn't the + // final cycle of ALU operation). + assign ex_valid_o = multdiv_sel ? multdiv_valid : !alu_imd_val_we; endmodule diff --git a/rtl/ibex_multdiv_fast.sv b/rtl/ibex_multdiv_fast.sv index 79404a30..424c6dae 100644 --- a/rtl/ibex_multdiv_fast.sv +++ b/rtl/ibex_multdiv_fast.sv @@ -226,7 +226,7 @@ module ibex_multdiv_fast #( if (!rst_ni) begin mult_state_q <= MULL; end else begin - if (mult_en_i) begin + if (mult_en_internal) begin mult_state_q <= mult_state_d; end end diff --git a/rtl/ibex_multdiv_slow.sv b/rtl/ibex_multdiv_slow.sv index 5e13f4c0..0c2d3280 100644 --- a/rtl/ibex_multdiv_slow.sv +++ b/rtl/ibex_multdiv_slow.sv @@ -161,7 +161,7 @@ module ibex_multdiv_slow op_numerator_q <= 32'h0; md_state_q <= MD_IDLE; end else begin - if (~multdiv_hold) begin + if ((mult_en_i || div_en_i) && !multdiv_hold) begin multdiv_state_q <= multdiv_state_d; op_b_shift_q <= op_b_shift_d; op_a_shift_q <= op_a_shift_d;