From 484754dc3d1fb4d1b878e7d73319b56f69dc3aaa Mon Sep 17 00:00:00 2001
From: Alban Gruin <alban.gruin@irit.fr>
Date: Tue, 8 Feb 2022 14:04:19 +0100
Subject: [PATCH] cva6: don't backup on direct jumps

Signed-off-by: Alban Gruin <alban.gruin@irit.fr>
---
 src/ariane.sv            |  2 +-
 src/frontend/frontend.sv |  8 ++++++--
 src/frontend/sras.sv     | 32 ++++++++++++++++++++------------
 3 files changed, 27 insertions(+), 15 deletions(-)

diff --git a/src/ariane.sv b/src/ariane.sv
index e437e155..e6fe962d 100644
--- a/src/ariane.sv
+++ b/src/ariane.sv
@@ -688,7 +688,7 @@ module ariane import ariane_pkg::*; #(
 `ifdef WT_DCACHE
   logic icache_valid_spec, icache_bad_spec;
 
-  assign icache_valid_spec = resolved_branch.valid && !(resolved_branch.is_mispredict);
+  assign icache_valid_spec = resolved_branch.valid && !(resolved_branch.is_mispredict) && (resolved_branch.cf_type != Jump);
   assign icache_bad_spec = resolved_branch.valid && resolved_branch.is_mispredict;
 
   // this is a cache subsystem that is compatible with OpenPiton
diff --git a/src/frontend/frontend.sv b/src/frontend/frontend.sv
index d161af18..d0f7b5ca 100644
--- a/src/frontend/frontend.sv
+++ b/src/frontend/frontend.sv
@@ -165,7 +165,7 @@ module frontend import ariane_pkg::*; #(
       assign is_cf[i] = instruction_valid[i] & (rvi_branch[i] | rvc_branch[i] | rvi_jalr[i] | rvc_jalr[i] | rvc_jr[i]);
     end
 
-    assign begin_spec_o = ((|is_branch) | (|is_call) | (|is_return) | (|is_jump) | (|is_jalr)) & (~replay);
+    assign begin_spec_o = (|is_cf) & (~replay);
 
     // taken/not taken
     always_comb begin
@@ -253,7 +253,8 @@ module frontend import ariane_pkg::*; #(
       // contains a valid prediction.
       for (int i = 0; i < INSTR_PER_FETCH; i++) bp_valid |= ((cf_type[i] != NoCF & cf_type[i] != Return) | ((cf_type[i] == Return) & ras_predict.valid));
     end
-    assign is_correct_predict = resolved_branch_i.valid & !(resolved_branch_i.is_mispredict);
+
+    assign is_correct_predict = resolved_branch_i.valid & !(resolved_branch_i.is_mispredict) & (resolved_branch_i.cf_type != Jump);
     assign is_mispredict = resolved_branch_i.valid & resolved_branch_i.is_mispredict;
 
     // Cache interface
@@ -471,6 +472,9 @@ module frontend import ariane_pkg::*; #(
         @(posedge clk_i) disable iff (!rst_ni) replay |-> ~instr_queue_ready)
           else $warning(1, "[frontend] replay & instr_queue_ready...");
 
+      assert property (
+        @(posedge clk_i) disable iff (!rst_ni) resolved_branch_i.cf_type == Jump |-> !resolved_branch_i.is_mispredict)
+        else $warning(1, "[frontend] mispredicted jump");
     `endif
     // pragma translate_on
 endmodule
diff --git a/src/frontend/sras.sv b/src/frontend/sras.sv
index 4f1aea3a..b1b6b62f 100644
--- a/src/frontend/sras.sv
+++ b/src/frontend/sras.sv
@@ -67,10 +67,14 @@ module sras #(
                 end else begin
                     if (prev_plus_one == '0 || pp_plus_one == '0) begin
                         ovf_counter_d[ptr_spec_d] = ovf_counter_q[ptr_spec_q] + 1'b1;
-                        ovf_counter_d[ptr_spec_q] = ovf_counter_q[ptr_spec_q] + 1'b1;
+                        if (begin_spec_i) begin
+                            ovf_counter_d[ptr_spec_q] = ovf_counter_q[ptr_spec_q] + 1'b1;
+                        end
                     end else begin
                         tos_d[ptr_spec_d] = prev_plus_one;
-                        tos_d[ptr_spec_q] = pp_plus_one;
+                        if (begin_spec_i) begin
+                            tos_d[ptr_spec_q] = pp_plus_one;
+                        end
                     end
                 end
             end else if (!push_i && pop_i) begin
@@ -117,7 +121,7 @@ module sras #(
     always_comb begin
         prev_stack = stack_q[ptr_spec_q];
 
-        if (can_push) begin
+        if (can_push && begin_spec_i) begin
             prev_stack[pp_plus_one] = to_push;
         end
     end
@@ -153,17 +157,21 @@ module sras #(
          assert (2 ** $clog2(DEPTH) == DEPTH) else $fatal(1,"[sras] DEPTH is not a power of 2");
       end
 
-      assert property (
-        @(posedge clk_i) disable iff (!rst_ni) push_i |-> begin_spec_i)
-          else $warning (1,"[sras] push_i & ~begin_spec_i");
+      // assert property (
+      //   @(posedge clk_i) disable iff (!rst_ni) push_i |-> begin_spec_i)
+      //     else $warning (1,"[sras] push_i & ~begin_spec_i");
+
+      // assert property (
+      //   @(posedge clk_i) disable iff (!rst_ni) (begin_spec_i & !(bad_spec_i)) |-> (ptr_spec_d != ptr_backup_d))
+      //     else $warning (1,"[sras] speculation overflow");
 
-      assert property (
-        @(posedge clk_i) disable iff (!rst_ni) (begin_spec_i & !(bad_spec_i)) |-> (ptr_spec_d != ptr_backup_d))
-          else $fatal (1,"[sras] speculation overflow");
+      // assert property (
+      //   @(posedge clk_i) disable iff (!rst_ni) (begin_spec_i & (!bad_spec_i) & (ptr_spec_d == ptr_backup_d)) |-> (~push_i))
+      //     else $warning (1,"[sras] backup overwrite");
 
-      assert property (
-        @(posedge clk_i) disable iff (!rst_ni) valid_spec_i |-> ((ptr_backup_q == ptr_spec_q) |-> (ptr_backup_d == ptr_spec_d)))
-          else $fatal (1,"[sras] backup overtake");
+      // assert property (
+      //   @(posedge clk_i) disable iff (!rst_ni) valid_spec_i |-> ((ptr_backup_q == ptr_spec_q) |-> (ptr_backup_d == ptr_spec_d)))
+      //     else $fatal (1,"[sras] backup overtake");
     `endif
     // pragma translate_on
 endmodule
-- 
GitLab