mirror of
https://github.com/openhwgroup/cva6.git
synced 2025-04-22 21:27:10 -04:00
🐛 Fixes in branch logic
This commit is contained in:
parent
34519aa8d0
commit
0d2851770b
5 changed files with 19 additions and 8 deletions
|
@ -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 ),
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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++;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue