Skip to content
Snippets Groups Projects
Commit ad1081d2 authored by Alban Gruin's avatar Alban Gruin
Browse files

frontend: fix branch prediction commit


Signed-off-by: default avatarAlban Gruin <alban.gruin@irit.fr>
parent e22bcdf5
No related branches found
No related tags found
No related merge requests found
...@@ -65,11 +65,11 @@ module branch_unit ( ...@@ -65,11 +65,11 @@ module branch_unit (
resolved_branch_o.target_address = (branch_comp_res_i) ? target_address : next_pc; resolved_branch_o.target_address = (branch_comp_res_i) ? target_address : next_pc;
resolved_branch_o.is_taken = branch_comp_res_i; resolved_branch_o.is_taken = branch_comp_res_i;
// check the outcome of the branch speculation // check the outcome of the branch speculation
if (ariane_pkg::op_is_branch(fu_data_i.operator) && branch_comp_res_i != (branch_predict_i.cf == ariane_pkg::Branch)) begin if (ariane_pkg::op_is_branch(fu_data_i.operator)) begin
resolved_branch_o.cf_type = ariane_pkg::Branch;
// we mis-predicted the outcome // we mis-predicted the outcome
// if the outcome doesn't match we've got a mis-predict // if the outcome doesn't match we've got a mis-predict
resolved_branch_o.is_mispredict = 1'b1; resolved_branch_o.is_mispredict = branch_comp_res_i != (branch_predict_i.cf == ariane_pkg::Branch);
resolved_branch_o.cf_type = ariane_pkg::Branch;
end end
if (fu_data_i.operator == ariane_pkg::JALR if (fu_data_i.operator == ariane_pkg::JALR
// check if the address of the jump register is correct and that we actually predicted // check if the address of the jump register is correct and that we actually predicted
......
...@@ -156,7 +156,7 @@ module frontend import ariane_pkg::*; #( ...@@ -156,7 +156,7 @@ module frontend import ariane_pkg::*; #(
// unconditional jumps with known target -> immediately resolved // unconditional jumps with known target -> immediately resolved
assign is_jump[i] = instruction_valid[i] & (rvi_jump[i] | rvc_jump[i]); assign is_jump[i] = instruction_valid[i] & (rvi_jump[i] | rvc_jump[i]);
// unconditional jumps with unknown target -> BTB // unconditional jumps with unknown target -> BTB
assign is_jalr[i] = instruction_valid[i] & ~is_return[i] & ~is_call[i] & (rvi_jalr[i] | rvc_jalr[i] | rvc_jr[i]); assign is_jalr[i] = instruction_valid[i] & ~is_return[i] & (rvi_jalr[i] | rvc_jalr[i] | rvc_jr[i]);
end end
// taken/not taken // taken/not taken
...@@ -173,12 +173,13 @@ module frontend import ariane_pkg::*; #( ...@@ -173,12 +173,13 @@ module frontend import ariane_pkg::*; #(
// lower most prediction gets precedence // lower most prediction gets precedence
for (int i = INSTR_PER_FETCH - 1; i >= 0 ; i--) begin for (int i = INSTR_PER_FETCH - 1; i >= 0 ; i--) begin
ras_pop = 1'b0;
ras_push = 1'b0;
unique case ({is_branch[i], is_return[i], is_jump[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 4'b0000:; // regular instruction e.g.: no branch
// unconditional jump to register, we need the BTB to resolve this // unconditional jump to register, we need the BTB to resolve this
4'b0001: begin 4'b0001: begin
ras_pop = 1'b0;
ras_push = 1'b0;
if (btb_prediction_shifted[i].valid) begin if (btb_prediction_shifted[i].valid) begin
predict_address = btb_prediction_shifted[i].target_address; predict_address = btb_prediction_shifted[i].target_address;
cf_type[i] = ariane_pkg::JumpR; cf_type[i] = ariane_pkg::JumpR;
...@@ -186,8 +187,6 @@ module frontend import ariane_pkg::*; #( ...@@ -186,8 +187,6 @@ module frontend import ariane_pkg::*; #(
end end
// its an unconditional jump to an immediate // its an unconditional jump to an immediate
4'b0010: begin 4'b0010: begin
ras_pop = 1'b0;
ras_push = 1'b0;
taken_rvi_cf[i] = rvi_jump[i]; taken_rvi_cf[i] = rvi_jump[i];
taken_rvc_cf[i] = rvc_jump[i]; taken_rvc_cf[i] = rvc_jump[i];
cf_type[i] = ariane_pkg::Jump; cf_type[i] = ariane_pkg::Jump;
...@@ -196,14 +195,11 @@ module frontend import ariane_pkg::*; #( ...@@ -196,14 +195,11 @@ module frontend import ariane_pkg::*; #(
4'b0100: begin 4'b0100: begin
// make sure to only alter the RAS if we actually consumed the instruction // make sure to only alter the RAS if we actually consumed the instruction
ras_pop = ras_predict.valid & instr_queue_consumed[i]; ras_pop = ras_predict.valid & instr_queue_consumed[i];
ras_push = 1'b0;
predict_address = ras_predict.ra; predict_address = ras_predict.ra;
cf_type[i] = ariane_pkg::Return; cf_type[i] = ariane_pkg::Return;
end end
// branch prediction // branch prediction
4'b1000: begin 4'b1000: begin
ras_pop = 1'b0;
ras_push = 1'b0;
// if we have a valid dynamic prediction use it // if we have a valid dynamic prediction use it
if (bht_prediction_shifted[i].valid) begin if (bht_prediction_shifted[i].valid) begin
taken_rvi_cf[i] = rvi_branch[i] & bht_prediction_shifted[i].taken; taken_rvi_cf[i] = rvi_branch[i] & bht_prediction_shifted[i].taken;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment