diff --git a/src/ariane.sv b/src/ariane.sv index 94d2b6bc1..2ae720df3 100644 --- a/src/ariane.sv +++ b/src/ariane.sv @@ -303,7 +303,7 @@ module ariane .NR_WB_PORTS ( NR_WB_PORTS ) ) issue_stage_i ( - .flush_unissued_instr_i ( flush_unissued_instr_i ), + .flush_unissued_instr_i ( flush_unissued_instr_ctrl_id ), .flush_i ( flush_ctrl_id ), .decoded_instr_i ( issue_entry_id_issue ), diff --git a/src/branch_unit.sv b/src/branch_unit.sv index 2f0aa9642..28648f233 100644 --- a/src/branch_unit.sv +++ b/src/branch_unit.sv @@ -131,17 +131,18 @@ module branch_unit ( end end end - // to resolve the branch in ID -> only do this if this was indeed a branch (hence vald_i is asserted) + // to resolve the branch in ID resolve_branch_o = 1'b1; // the other case would be that this instruction was no branch but branch prediction thought that it was one // this is essentially also a mis-predict - end else if (fu_valid_i && branch_predict_i.valid) begin + end else if (fu_valid_i && branch_predict_i.valid && branch_predict_i.predict_taken) begin // re-set the branch to the next PC resolved_branch_o.is_mispredict = 1'b1; resolved_branch_o.target_address = next_pc; // clear this entry so that we are not constantly mis-predicting resolved_branch_o.clear = 1'b1; resolved_branch_o.valid = 1'b1; + resolve_branch_o = 1'b1; end end // use ALU exception signal for storing instruction fetch exceptions if diff --git a/src/controller.sv b/src/controller.sv index cdcbd6599..a3f1e856d 100644 --- a/src/controller.sv +++ b/src/controller.sv @@ -68,6 +68,7 @@ module controller ( if (sfence_vma_i) begin flush_pcgen_o = 1'b1; flush_if_o = 1'b1; + flush_unissued_instr_o = 1'b1; flush_id_o = 1'b1; flush_ex_o = 1'b1; flush_tlb_o = 1'b1; @@ -79,6 +80,7 @@ module controller ( if (flush_csr_i) begin flush_pcgen_o = 1'b1; flush_if_o = 1'b1; + flush_unissued_instr_o = 1'b1; flush_id_o = 1'b1; flush_ex_o = 1'b1; end @@ -91,6 +93,7 @@ module controller ( // for the PC GEN stage but instead tells it to take the PC we gave it flush_pcgen_o = 1'b0; flush_if_o = 1'b1; + flush_unissued_instr_o = 1'b1; flush_id_o = 1'b1; flush_ex_o = 1'b1; end @@ -102,6 +105,7 @@ module controller ( // don't flush pcgen as we want to take the exception flush_pcgen_o = 1'b0; flush_if_o = 1'b1; + flush_unissued_instr_o = 1'b1; flush_id_o = 1'b1; flush_ex_o = 1'b1; end diff --git a/src/issue_stage.sv b/src/issue_stage.sv index 342a15182..7c2e5c0af 100755 --- a/src/issue_stage.sv +++ b/src/issue_stage.sv @@ -107,8 +107,14 @@ module issue_stage #( if (resolve_branch_i) begin unresolved_branch_n = 1'b0; end - // if the instruction is valid and it is a control flow instruction - if (decoded_instr_valid_i && is_ctrl_flow_i) begin + // if the instruction is valid, it is a control flow instruction and the issue stage acknowledged its dispatch + // set the unresolved branch flag + if (issue_ack_iro_sb && decoded_instr_valid_i && is_ctrl_flow_i) begin + unresolved_branch_n = 1'b1; + end + // if we predicted a taken branch this means that we need to stall issue for one cycle to resolve the + // branch, otherwise we might issue a wrong instruction + if (issue_ack_iro_sb && decoded_instr_i.bp.valid && decoded_instr_i.bp.predict_taken) begin unresolved_branch_n = 1'b1; end // if we are requested to flush also flush the unresolved branch flag because either the flush diff --git a/src/scoreboard.sv b/src/scoreboard.sv index 2b57cdb94..d02f6173a 100644 --- a/src/scoreboard.sv +++ b/src/scoreboard.sv @@ -88,8 +88,8 @@ module scoreboard #( issue_instr_o.trans_id = issue_pointer_q; // we are ready if we are not full and don't have any unresolved branches, but it can be // the case that we have an unresolved branch which is cleared in that cycle (resolved_branch_i == 1) - issue_instr_valid_o = decoded_instr_valid_i && !unresolved_branch_i && !issue_full; - decoded_instr_ack_o = issue_ack_i; + issue_instr_valid_o = decoded_instr_valid_i && !unresolved_branch_i; + decoded_instr_ack_o = issue_ack_i && !issue_full; end // maintain a FIFO with issued instructions @@ -102,7 +102,7 @@ module scoreboard #( issue_pointer_n = issue_pointer_q; // if we got a acknowledge from the issue stage, put this scoreboard entry in the queue - if (issue_instr_valid_o) begin + if (decoded_instr_valid_i && decoded_instr_ack_o) begin // the decoded instruction we put in there is valid (1st bit) // increase the issue counter issue_cnt++;