mirror of
https://github.com/lowRISC/ibex.git
synced 2025-04-22 04:47:25 -04:00
[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:
parent
d19189ba43
commit
a5ae9f4995
2 changed files with 27 additions and 13 deletions
|
@ -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 ),
|
||||
|
|
|
@ -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};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue