Fix IF stalls preventing deassertion of regfile write enable (#222)

* ID stage: make single-cycle instr clear `instr_multicycle_done_q`

Previously, this signal was only cleared when starting the next
multi-cycle instruction.

* ID stage: only eval `instr_multicycle_done_q` for multi-cycle instr

This signal should only be evaluated if the ID/EX stage currently
executes a multi-cycle instruction. Without this commit, the signal
is also evaluated for single-cycle instructions and can for example
cause the register file write enable to not be de-asserted in case of
stalls in the IF stage.

This bug was repored by @udinator. This resolves lowrisc/ibex#216.
This commit is contained in:
Pirmin Vogel 2019-08-06 17:04:57 +01:00 committed by udinator
parent e5bdf1ea9f
commit ea0296d74a

View file

@ -163,6 +163,7 @@ module ibex_id_stage #(
logic jump_set;
logic instr_executing;
logic instr_multicycle;
logic instr_multicycle_done_n, instr_multicycle_done_q;
logic stall_lsu;
logic stall_multdiv;
@ -477,11 +478,14 @@ module ibex_id_stage #(
// ID-EX/WB //
//////////////
assign multdiv_en_dec = mult_en_dec | div_en_dec;
assign instr_multicycle = data_req_dec | multdiv_en_dec | branch_in_dec | jump_in_dec;
// Forward decoder output to EX, WB and controller only if current instr is still
// being executed. This is the case if the current instr is either:
// - a new instr (not yet done)
// - a multicycle instr that is not yet done
assign instr_executing = (instr_new_i | ~instr_multicycle_done_q);
assign instr_executing = instr_new_i | (instr_multicycle & ~instr_multicycle_done_q);
assign data_req_id = instr_executing ? data_req_dec : 1'b0;
assign mult_en_id = instr_executing ? mult_en_dec : 1'b0;
assign div_en_id = instr_executing ? div_en_dec : 1'b0;
@ -489,6 +493,7 @@ module ibex_id_stage #(
///////////
// ID-EX //
///////////
assign data_req_ex_o = data_req_id;
assign data_we_ex_o = data_we_id;
assign data_type_ex_o = data_type_id;
@ -531,8 +536,6 @@ module ibex_id_stage #(
// ID-EX/WB FSM //
//////////////////
assign multdiv_en_dec = mult_en_dec | div_en_dec;
always_comb begin : id_wb_fsm
id_wb_fsm_ns = id_wb_fsm_cs;
instr_multicycle_done_n = instr_multicycle_done_q;
@ -580,6 +583,7 @@ module ibex_id_stage #(
instr_multicycle_done_n = 1'b0;
end
default: begin
instr_multicycle_done_n = 1'b0;
instr_ret_o = 1'b1;
end
endcase