[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),