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