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