[rtl] Add data-independent timing to multdiv_fast

- No early return on divide by zero

Signed-off-by: Tom Roberts <tomroberts@lowrisc.org>
This commit is contained in:
Tom Roberts 2020-04-03 16:04:53 +01:00 committed by Tom Roberts
parent d19189ba43
commit a5ae9f4995
2 changed files with 27 additions and 13 deletions

View file

@ -177,7 +177,8 @@ module ibex_ex_block #(
.alu_operand_b_o ( multdiv_alu_operand_b ),
.alu_adder_ext_i ( alu_adder_result_ext ),
.alu_adder_i ( alu_adder_result_ex_o ),
.equal_to_zero ( alu_is_equal_result ),
.equal_to_zero_i ( alu_is_equal_result ),
.data_ind_timing_i ( data_ind_timing_i ),
.imd_val_q_i ( imd_val_q_i ),
.imd_val_d_o ( multdiv_imd_val_d ),
.imd_val_we_o ( multdiv_imd_val_we ),
@ -203,7 +204,8 @@ module ibex_ex_block #(
.alu_operand_b_o ( multdiv_alu_operand_b ),
.alu_adder_ext_i ( alu_adder_result_ext ),
.alu_adder_i ( alu_adder_result_ex_o ),
.equal_to_zero ( alu_is_equal_result ),
.equal_to_zero_i ( alu_is_equal_result ),
.data_ind_timing_i ( data_ind_timing_i ),
.imd_val_q_i ( imd_val_q_i ),
.imd_val_d_o ( multdiv_imd_val_d ),
.imd_val_we_o ( multdiv_imd_val_we ),

View file

@ -29,7 +29,8 @@ module ibex_multdiv_fast #(
input logic [31:0] op_b_i,
input logic [33:0] alu_adder_ext_i,
input logic [31:0] alu_adder_i,
input logic equal_to_zero,
input logic equal_to_zero_i,
input logic data_ind_timing_i,
output logic [32:0] alu_operand_a_o,
output logic [32:0] alu_operand_b_o,
@ -78,6 +79,7 @@ module ibex_multdiv_fast #(
logic multdiv_en;
logic mult_hold;
logic div_hold;
logic div_by_zero_d, div_by_zero_q;
logic mult_en_internal;
logic div_en_internal;
@ -95,17 +97,19 @@ module ibex_multdiv_fast #(
always_ff @(posedge clk_i or negedge rst_ni) begin
if (!rst_ni) begin
div_counter_q <= '0;
md_state_q <= MD_IDLE;
op_denominator_q <= '0;
op_numerator_q <= '0;
op_quotient_q <= '0;
div_counter_q <= '0;
md_state_q <= MD_IDLE;
op_denominator_q <= '0;
op_numerator_q <= '0;
op_quotient_q <= '0;
div_by_zero_q <= '0;
end else if (div_en_internal) begin
div_counter_q <= div_counter_d;
op_denominator_q <= op_denominator_d;
op_numerator_q <= op_numerator_d;
op_quotient_q <= op_quotient_d;
md_state_q <= md_state_d;
div_by_zero_q <= div_by_zero_d;
end
end
@ -381,7 +385,7 @@ module ibex_multdiv_fast #(
assign div_sign_a = op_a_i[31] & signed_mode_i[0];
assign div_sign_b = op_b_i[31] & signed_mode_i[1];
assign div_change_sign = div_sign_a ^ div_sign_b;
assign div_change_sign = (div_sign_a ^ div_sign_b) & ~div_by_zero_q;
assign rem_change_sign = div_sign_a;
@ -396,19 +400,27 @@ module ibex_multdiv_fast #(
alu_operand_b_o = {~op_b_i, 1'b1};
div_valid = 1'b0;
div_hold = 1'b0;
div_by_zero_d = div_by_zero_q;
unique case(md_state_q)
MD_IDLE: begin
if (operator_i == MD_OP_DIV) begin
// Check if the Denominator is 0
// quotient for division by 0
// quotient for division by 0 is specified to be -1
// Note with data-independent time option, the full divide operation will proceed as
// normal and will naturally return -1
op_remainder_d = '1;
md_state_d = equal_to_zero ? MD_FINISH : MD_ABS_A;
md_state_d = (!data_ind_timing_i && equal_to_zero_i) ? MD_FINISH : MD_ABS_A;
// Record that this is a div by zero to stop the sign change at the end of the
// division (in data_ind_timing mode).
div_by_zero_d = equal_to_zero_i;
end else begin
// Check if the Denominator is 0
// remainder for division by 0
// remainder for division by 0 is specified to be the numerator (operand a)
// Note with data-independent time option, the full divide operation will proceed as
// normal and will naturally return operand a
op_remainder_d = {2'b0, op_a_i};
md_state_d = equal_to_zero ? MD_FINISH : MD_ABS_A;
md_state_d = (!data_ind_timing_i && equal_to_zero_i) ? MD_FINISH : MD_ABS_A;
end
// 0 - B = 0 iff B == 0
alu_operand_a_o = {32'h0 , 1'b1};