From a59bf2fbede4994c9b93fe6698ef590b15a48689 Mon Sep 17 00:00:00 2001 From: Alban Gruin <alban.gruin@irit.fr> Date: Mon, 13 Dec 2021 15:32:37 +0100 Subject: [PATCH] Revert "frontend: remove the RAS" This reverts commit 04a4e12b90ada078a9e97cf9856a6a5f7e0b0109. --- src/frontend/frontend.sv | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/src/frontend/frontend.sv b/src/frontend/frontend.sv index e14fe45a..7300c59a 100644 --- a/src/frontend/frontend.sv +++ b/src/frontend/frontend.sv @@ -159,7 +159,7 @@ module frontend import ariane_pkg::*; #( // unconditional jumps with known target -> immediately resolved assign is_jump[i] = instruction_valid[i] & (rvi_jump[i] | rvc_jump[i]); // unconditional jumps with unknown target -> BTB - assign is_jalr[i] = instruction_valid[i] & (rvi_jalr[i] | rvc_jalr[i] | rvc_jr[i]); + assign is_jalr[i] = instruction_valid[i] & ~is_return[i] & ~is_call[i] & (rvi_jalr[i] | rvc_jalr[i] | rvc_jr[i]); // cf that needs a prediction assign is_cf[i] = instruction_valid[i] & (rvi_branch[i] | rvc_branch[i] | rvi_jalr[i] | rvc_jalr[i] | rvc_jr[i]); @@ -181,10 +181,10 @@ module frontend import ariane_pkg::*; #( // lower most prediction gets precedence for (int i = INSTR_PER_FETCH - 1; i >= 0 ; i--) begin - unique case ({is_branch[i], is_jump[i], is_jalr[i]}) - 3'b000:; // regular instruction e.g.: no branch + unique case ({is_branch[i], is_return[i], is_jump[i], is_jalr[i]}) + 4'b0000:; // regular instruction e.g.: no branch // unconditional jump to register, we need the BTB to resolve this - 3'b001: begin + 4'b0001: begin ras_pop = 1'b0; ras_push = 1'b0; if (btb_prediction_shifted[i].valid) begin @@ -193,15 +193,23 @@ module frontend import ariane_pkg::*; #( end end // its an unconditional jump to an immediate - 3'b010: begin + 4'b0010: begin ras_pop = 1'b0; ras_push = 1'b0; taken_rvi_cf[i] = rvi_jump[i]; taken_rvc_cf[i] = rvc_jump[i]; cf_type[i] = ariane_pkg::Jump; end + // return + 4'b0100: begin + // make sure to only alter the RAS if we actually consumed the instruction + ras_pop = ras_predict.valid & instr_queue_consumed[i]; + ras_push = 1'b0; + predict_address = ras_predict.ra; + cf_type[i] = ariane_pkg::Return; + end // branch prediction - 3'b100: begin + 4'b1000: begin ras_pop = 1'b0; ras_push = 1'b0; // if we have a valid dynamic prediction use it @@ -219,6 +227,12 @@ module frontend import ariane_pkg::*; #( default:; // default: $error("Decoded more than one control flow"); endcase + // if this instruction, in addition, is a call, save the resulting address + // but only if we actually consumed the address + if (is_call[i]) begin + ras_push = instr_queue_consumed[i]; + ras_update = addr[i] + (rvc_call[i] ? 2 : 4); + end // calculate the jump target address if (taken_rvc_cf[i] || taken_rvi_cf[i]) begin predict_address = addr[i] + (taken_rvc_cf[i] ? rvc_imm[i] : rvi_imm[i]); -- GitLab