From e75f92e4ae9b1a8b4ddede386006fa817a503dee Mon Sep 17 00:00:00 2001 From: Alban Gruin <alban.gruin@irit.fr> Date: Fri, 9 Apr 2021 10:36:17 +0200 Subject: [PATCH] fixup! frontend: disable branch prediction, mkII --- src/frontend/frontend.sv | 45 +++++++++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/src/frontend/frontend.sv b/src/frontend/frontend.sv index 714f4ab3..819a885f 100644 --- a/src/frontend/frontend.sv +++ b/src/frontend/frontend.sv @@ -109,7 +109,9 @@ module frontend import ariane_pkg::*; #( cf_t [ariane_pkg::INSTR_PER_FETCH-1:0] cf_type; logic [ariane_pkg::INSTR_PER_FETCH-1:0] taken_rvi_cf; logic [ariane_pkg::INSTR_PER_FETCH-1:0] taken_rvc_cf; - logic [ariane_pkg::INSTR_PER_FETCH-1:0] should_stall; + + logic stalling_d, stalling_q; + logic previous_is_branch; logic serving_unaligned; // Re-align instructions @@ -169,7 +171,6 @@ module frontend import ariane_pkg::*; #( taken_rvi_cf = '0; taken_rvc_cf = '0; predict_address = '0; - should_stall = '0; for (int i = 0; i < INSTR_PER_FETCH; i++) cf_type[i] = ariane_pkg::NoCF; @@ -178,10 +179,9 @@ module frontend import ariane_pkg::*; #( ras_update = '0; // lower most prediction gets precedence - for (int i = INSTR_PER_FETCH - 1; i >= 0 ; i--) begin + for (int unsigned i = INSTR_PER_FETCH - 1; i >= 0 ; i--) begin // Direct jumps are always predicted correctly since we have their // target address. - should_stall[i] = is_branch[i] | is_return[i] | is_jalr[i]; unique case ({is_branch[i], is_return[i], is_jump[i], is_jalr[i]}) 4'b0000:; // regular instruction e.g.: no branch @@ -246,28 +246,37 @@ module frontend import ariane_pkg::*; #( end end end - end + end // always_comb // or reduce struct always_comb begin bp_valid = 1'b0; instruction_really_valid = '0; + previous_is_branch = 1'b0; + stalling_d = stalling_q; + + if (!stalling_q) begin + // BP cannot be valid if we have a return instruction and the RAS is not giving a valid address + // Check that we encountered a control flow and that for a return the RAS + // contains a valid prediction. + for (int unsigned i = 0; i < INSTR_PER_FETCH; i++) begin + bp_valid |= ((cf_type[i] != NoCF & cf_type[i] != Return) | ((cf_type[i] == Return) & ras_predict.valid)); + + if (enable_bp_i) begin + instruction_really_valid[i] = instruction_valid[i]; + end else begin + instruction_really_valid[i] = instruction_valid[i] && !(previous_is_branch); + end - // BP cannot be valid if we have a return instruction and the RAS is not giving a valid address - // Check that we encountered a control flow and that for a return the RAS - // contains a valid prediction. - for (int unsigned i = 0; i < INSTR_PER_FETCH; i++) begin - bp_valid |= ((cf_type[i] != NoCF & cf_type[i] != Return) | ((cf_type[i] == Return) & ras_predict.valid)); - - if (enable_bp_i) begin - instruction_really_valid[i] = instruction_valid[i]; - end else if (i == 0) begin - instruction_really_valid[i] = instruction_valid[i] && !(should_stall[i]); - end else begin - instruction_really_valid[i] = instruction_valid[i] && instruction_really_valid[i - 1] && !(should_stall[i]); + previous_is_branch |= !(cf_type[i] inside {NoCF, Jump}); end + + stalling_d |= previous_is_branch; + end else if (resolved_branch_i.valid) begin + stalling_d = 1'b0; end end + assign is_mispredict = resolved_branch_i.valid & resolved_branch_i.is_mispredict; // Cache interface @@ -368,6 +377,7 @@ module frontend import ariane_pkg::*; #( icache_ex_valid_q <= ariane_pkg::FE_NONE; btb_q <= '0; bht_q <= '0; + stalling_q <= '0; end else begin npc_rst_load_q <= 1'b0; npc_q <= npc_d; @@ -384,6 +394,7 @@ module frontend import ariane_pkg::*; #( // save the uppermost prediction btb_q <= btb_prediction[INSTR_PER_FETCH-1]; bht_q <= bht_prediction[INSTR_PER_FETCH-1]; + stalling_q <= stalling_d; end end end -- GitLab