[smc/hw] Halt prefetcher on page boundary

-Also allow non-dPTW memory stalls to prevent iPTWs

Fix: 296616288
Change-Id: I5395c52aa09da78bb1a74d9bd3fdb0ff85f24651
diff --git a/hw/top_matcha/ip/smc/rtl/smc_core.sv b/hw/top_matcha/ip/smc/rtl/smc_core.sv
index 5559088..e65e55e 100644
--- a/hw/top_matcha/ip/smc/rtl/smc_core.sv
+++ b/hw/top_matcha/ip/smc/rtl/smc_core.sv
@@ -557,7 +557,8 @@
     .ptw_instr_walk_i     (mmu_ptw_instr_walk),
     .ptw_spec_iwalk_i     (mmu_ptw_spec_iwalk),
     .ptw_if_flush_i       (mmu_ptw_if_flush),
-    .ptw_pc_change_instr_i(ptw_pc_change_instr)
+    .ptw_pc_change_instr_i(ptw_pc_change_instr),
+    .legal_page_boundary_i(mmu_legal_boundary)
   );
 
   // Core is waiting for the ISide when ID/EX stage is ready for a new instruction but none are
diff --git a/hw/top_matcha/ip/smc/rtl/smc_if_stage.sv b/hw/top_matcha/ip/smc/rtl/smc_if_stage.sv
index 4a09596..24f1efa 100644
--- a/hw/top_matcha/ip/smc/rtl/smc_if_stage.sv
+++ b/hw/top_matcha/ip/smc/rtl/smc_if_stage.sv
@@ -121,7 +121,8 @@
   input logic                         ptw_instr_walk_i,
   input logic                         ptw_spec_iwalk_i,
   input logic                         ptw_if_flush_i,
-  input logic                         ptw_pc_change_instr_i
+  input logic                         ptw_pc_change_instr_i,
+  input logic                         legal_page_boundary_i
 );
 
   logic              instr_valid_id_d, instr_valid_id_q;
@@ -337,33 +338,34 @@
     smc_prefetch_buffer #(
       .ResetAll        (ResetAll)
     ) prefetch_buffer_i (
-        .clk_i               ( clk_i                      ),
-        .rst_ni              ( rst_ni                     ),
+        .clk_i                ( clk_i                      ),
+        .rst_ni               ( rst_ni                     ),
 
-        .req_i               ( req_i                      ),
+        .req_i                ( req_i                      ),
 
-        .branch_i            ( prefetch_branch            ),
-        .addr_i              ( prefetch_addr              ),
+        .branch_i             ( prefetch_branch            ),
+        .addr_i               ( prefetch_addr              ),
 
-        .ready_i             ( fetch_ready                ),
-        .valid_o             ( fetch_valid_raw            ),
-        .rdata_o             ( fetch_rdata                ),
-        .addr_o              ( fetch_addr                 ),
-        .err_o               ( fetch_err                  ),
-        .err_plus2_o         ( fetch_err_plus2            ),
+        .ready_i              ( fetch_ready                ),
+        .valid_o              ( fetch_valid_raw            ),
+        .rdata_o              ( fetch_rdata                ),
+        .addr_o               ( fetch_addr                 ),
+        .err_o                ( fetch_err                  ),
+        .err_plus2_o          ( fetch_err_plus2            ),
 
-        .instr_req_o         ( instr_req_o                ),
-        .instr_addr_o        ( instr_addr_o               ),
-        .instr_gnt_i         ( instr_gnt_i                ),
-        .instr_rvalid_i      ( instr_rvalid_i             ),
-        .instr_rdata_i       ( instr_rdata_i[31:0]        ),
-        .instr_err_i         ( instr_err                  ),
+        .instr_req_o          ( instr_req_o                ),
+        .instr_addr_o         ( instr_addr_o               ),
+        .instr_gnt_i          ( instr_gnt_i                ),
+        .instr_rvalid_i       ( instr_rvalid_i             ),
+        .instr_rdata_i        ( instr_rdata_i[31:0]        ),
+        .instr_err_i          ( instr_err                  ),
 
-        .busy_o              ( prefetch_busy              ),
+        .busy_o               ( prefetch_busy              ),
 
-        .ptw_instr_walk_i    ( ptw_instr_walk_i           ),
-        .ptw_spec_iwalk_i    ( ptw_spec_iwalk_i           ),
-        .ptw_if_flush_i      ( ptw_if_flush_i             )
+        .ptw_instr_walk_i     ( ptw_instr_walk_i           ),
+        .ptw_spec_iwalk_i     ( ptw_spec_iwalk_i           ),
+        .ptw_if_flush_i       ( ptw_if_flush_i             ),
+        .legal_page_boundary_i( legal_page_boundary_i      )
     );
     // ICache tieoffs
     logic                   unused_icen, unused_icinv, unused_scr_key_valid;
diff --git a/hw/top_matcha/ip/smc/rtl/smc_mmu.sv b/hw/top_matcha/ip/smc/rtl/smc_mmu.sv
index f02890c..30fc471 100644
--- a/hw/top_matcha/ip/smc/rtl/smc_mmu.sv
+++ b/hw/top_matcha/ip/smc/rtl/smc_mmu.sv
@@ -266,7 +266,7 @@
   always_comb begin
     legal_boundary_d = 1'b0;
     if (paging_en) begin
-      if ((~itlb_hit & lsu_outstanding_req & dtlb_ptw_active) | instr_ptw) begin
+      if ((~itlb_hit & lsu_outstanding_req) | instr_ptw) begin
         legal_boundary_d = cross_page_boundary & ~pc_mod_instr_i;
       end
     end
@@ -317,7 +317,7 @@
       instr_page_fault_o  = imem_access_error;
 
     // ITLB miss
-    end else if (paging_en && ptw_active_o) begin
+    end else if (paging_en && (ptw_active_o | ~itlb_hit)) begin
 
       // Stall IF while PTW occurs through DMEM. Allow fetches that cross
       // page boundaries to complete.
diff --git a/hw/top_matcha/ip/smc/rtl/smc_prefetch_buffer.sv b/hw/top_matcha/ip/smc/rtl/smc_prefetch_buffer.sv
index d3f80f0..0c2a69d 100644
--- a/hw/top_matcha/ip/smc/rtl/smc_prefetch_buffer.sv
+++ b/hw/top_matcha/ip/smc/rtl/smc_prefetch_buffer.sv
@@ -41,7 +41,8 @@
   // MMU
   input logic         ptw_instr_walk_i,
   input logic         ptw_spec_iwalk_i,
-  input logic         ptw_if_flush_i
+  input logic         ptw_if_flush_i,
+  input logic         legal_page_boundary_i
 );
 
   localparam int unsigned NUM_REQS  = 2;
@@ -89,7 +90,8 @@
   // The fifo is ready to accept a new request if it is not full - including space reserved for
   // requests already outstanding.
   // Overlay the fifo fill state with the outstanding requests to see if there is space.
-  assign fifo_ready = ~&(fifo_busy | rdata_outstanding_rev) & ~ptw_spec_iwalk_i & ~ptw_instr_walk_i;
+  assign fifo_ready = ~&(fifo_busy | rdata_outstanding_rev) & ~ptw_spec_iwalk_i &
+                         ~ptw_instr_walk_i & ~legal_page_boundary_i;
 
   smc_fetch_fifo #(
     .NUM_REQS (NUM_REQS),