diff options
Diffstat (limited to 'rv64cpu/rtl/core/mmu/mmu_top.sv')
| -rw-r--r-- | rv64cpu/rtl/core/mmu/mmu_top.sv | 359 |
1 files changed, 0 insertions, 359 deletions
diff --git a/rv64cpu/rtl/core/mmu/mmu_top.sv b/rv64cpu/rtl/core/mmu/mmu_top.sv deleted file mode 100644 index 169bf81..0000000 --- a/rv64cpu/rtl/core/mmu/mmu_top.sv +++ /dev/null @@ -1,359 +0,0 @@ -// Richard CPU -// Copyright (C) 2026 Richard Qin - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. - -// File path: rtl/core/mmu/mmu_top.sv -// Description: MMU top-level integrating iTLB + dTLB + shared PTW - -module mmu_top - import rv64_pkg::*; -#( - parameter int ITLB_ENTRIES = 16, - parameter int DTLB_ENTRIES = 32, - parameter int ASID_WIDTH = 16 -)( - input logic clk, - input logic rst, - - // CSR/context inputs - input logic [XLEN-1:0] satp_value, - input logic [1:0] priv_mode, - input logic sum, - input logic mxr, - - // i-side translation request - input logic i_req_valid, - output logic i_req_ready, - input logic [XLEN-1:0] i_req_vaddr, - output logic i_resp_valid, - output logic i_resp_hit, - output logic i_resp_page_fault, - output logic [XLEN-1:0] i_resp_vaddr, - output logic [XLEN-1:0] i_resp_paddr, - - // d-side translation request - input logic d_req_valid, - output logic d_req_ready, - input logic [XLEN-1:0] d_req_vaddr, - input logic d_req_is_store, - output logic d_resp_valid, - output logic d_resp_hit, - output logic d_resp_page_fault, - output logic [XLEN-1:0] d_resp_paddr, - - // sfence / invalidation - input logic flush_all, - input logic flush_asid_valid, - input logic [ASID_WIDTH-1:0] flush_asid, - input logic flush_vpn_valid, - input logic [44:0] flush_vpn, - - // PTW memory interface - output logic ptw_mem_req_valid, - input logic ptw_mem_req_ready, - output logic [XLEN-1:0] ptw_mem_req_addr, - input logic ptw_mem_resp_valid, - input logic [XLEN-1:0] ptw_mem_resp_data -); - - localparam logic [3:0] SATP_MODE_BARE = 4'd0; - - typedef enum logic [0:0] { - PTW_SRC_I = 1'b0, - PTW_SRC_D = 1'b1 - } ptw_src_t; - - logic [ASID_WIDTH-1:0] req_asid; - logic [3:0] req_mode; - - logic i_tlb_resp_valid; - logic i_tlb_resp_hit; - logic [XLEN-1:0] i_tlb_resp_paddr; - logic i_tlb_resp_page_fault; - logic i_tlb_resp_need_ptw; - - logic d_tlb_resp_valid; - logic d_tlb_resp_hit; - logic [XLEN-1:0] d_tlb_resp_paddr; - logic d_tlb_resp_page_fault; - logic d_tlb_resp_need_ptw; - - logic i_pending_q; - logic d_pending_q; - logic [XLEN-1:0] i_pending_vaddr_q; - logic [XLEN-1:0] d_pending_vaddr_q; - logic [1:0] i_pending_priv_q; - logic [1:0] d_pending_priv_q; - logic i_pending_sum_q; - logic d_pending_sum_q; - logic i_pending_mxr_q; - logic d_pending_mxr_q; - logic [ASID_WIDTH-1:0] i_pending_asid_q; - logic [ASID_WIDTH-1:0] d_pending_asid_q; - logic [3:0] i_pending_mode_q; - logic [3:0] d_pending_mode_q; - logic d_pending_is_store_q; - - logic ptw_req_valid; - logic ptw_req_ready; - logic ptw_resp_valid; - logic ptw_resp_fault; - logic [XLEN-1:0] ptw_resp_paddr; - - logic ptw_refill_valid; - logic [44:0] ptw_refill_vpn; - logic [43:0] ptw_refill_ppn; - logic [2:0] ptw_refill_level; - logic [3:0] ptw_refill_mode; - logic [ASID_WIDTH-1:0] ptw_refill_asid; - logic ptw_refill_g; - logic ptw_refill_u; - logic ptw_refill_r; - logic ptw_refill_w; - logic ptw_refill_x; - logic ptw_refill_a; - logic ptw_refill_d; - - logic ptw_busy_q; - ptw_src_t ptw_owner_q; - ptw_src_t ptw_owner_next; - - logic i_accept; - logic d_accept; - logic i_fast_resp_valid; - logic d_fast_resp_valid; - logic i_ptw_resp_sel; - logic d_ptw_resp_sel; - - logic i_refill_valid; - logic d_refill_valid; - - assign req_mode = satp_value[63:60]; - assign req_asid = satp_value[59 -: ASID_WIDTH]; - - assign i_req_ready = !i_pending_q; - assign d_req_ready = !d_pending_q; - assign i_accept = i_req_valid && i_req_ready; - assign d_accept = d_req_valid && d_req_ready; - - assign i_fast_resp_valid = i_accept && (i_tlb_resp_hit || i_tlb_resp_page_fault); - assign d_fast_resp_valid = d_accept && (d_tlb_resp_hit || d_tlb_resp_page_fault); - - assign i_ptw_resp_sel = ptw_resp_valid && (ptw_owner_q == PTW_SRC_I); - assign d_ptw_resp_sel = ptw_resp_valid && (ptw_owner_q == PTW_SRC_D); - - assign i_resp_valid = i_fast_resp_valid || i_ptw_resp_sel; - assign i_resp_hit = i_fast_resp_valid ? i_tlb_resp_hit : (i_ptw_resp_sel && !ptw_resp_fault); - assign i_resp_page_fault = i_fast_resp_valid ? i_tlb_resp_page_fault : (i_ptw_resp_sel && ptw_resp_fault); - assign i_resp_vaddr = i_fast_resp_valid ? i_req_vaddr : i_pending_vaddr_q; - assign i_resp_paddr = i_fast_resp_valid ? i_tlb_resp_paddr : ptw_resp_paddr; - - assign d_resp_valid = d_fast_resp_valid || d_ptw_resp_sel; - assign d_resp_hit = d_fast_resp_valid ? d_tlb_resp_hit : (d_ptw_resp_sel && !ptw_resp_fault); - assign d_resp_page_fault = d_fast_resp_valid ? d_tlb_resp_page_fault : (d_ptw_resp_sel && ptw_resp_fault); - assign d_resp_paddr = d_fast_resp_valid ? d_tlb_resp_paddr : ptw_resp_paddr; - - always_comb begin - if (d_pending_q) begin - ptw_owner_next = PTW_SRC_D; - end else begin - ptw_owner_next = PTW_SRC_I; - end - end - - assign ptw_req_valid = !ptw_busy_q && (d_pending_q || i_pending_q); - - assign i_refill_valid = ptw_refill_valid && (ptw_owner_q == PTW_SRC_I); - assign d_refill_valid = ptw_refill_valid && (ptw_owner_q == PTW_SRC_D); - - always_ff @(posedge clk) begin - if (rst) begin - i_pending_q <= 1'b0; - d_pending_q <= 1'b0; - ptw_busy_q <= 1'b0; - ptw_owner_q <= PTW_SRC_I; - i_pending_vaddr_q <= '0; - d_pending_vaddr_q <= '0; - i_pending_priv_q <= '0; - d_pending_priv_q <= '0; - i_pending_sum_q <= 1'b0; - d_pending_sum_q <= 1'b0; - i_pending_mxr_q <= 1'b0; - d_pending_mxr_q <= 1'b0; - i_pending_asid_q <= '0; - d_pending_asid_q <= '0; - i_pending_mode_q <= SATP_MODE_BARE; - d_pending_mode_q <= SATP_MODE_BARE; - d_pending_is_store_q <= 1'b0; - end else begin - if (i_accept && i_tlb_resp_need_ptw) begin - i_pending_q <= 1'b1; - i_pending_vaddr_q <= i_req_vaddr; - i_pending_priv_q <= priv_mode; - i_pending_sum_q <= sum; - i_pending_mxr_q <= mxr; - i_pending_asid_q <= req_asid; - i_pending_mode_q <= req_mode; - end - - if (d_accept && d_tlb_resp_need_ptw) begin - d_pending_q <= 1'b1; - d_pending_vaddr_q <= d_req_vaddr; - d_pending_priv_q <= priv_mode; - d_pending_sum_q <= sum; - d_pending_mxr_q <= mxr; - d_pending_asid_q <= req_asid; - d_pending_mode_q <= req_mode; - d_pending_is_store_q <= d_req_is_store; - end - - if (ptw_req_valid && ptw_req_ready) begin - ptw_busy_q <= 1'b1; - ptw_owner_q <= ptw_owner_next; - end - - if (ptw_resp_valid) begin - ptw_busy_q <= 1'b0; - if (ptw_owner_q == PTW_SRC_I) begin - i_pending_q <= 1'b0; - end else begin - d_pending_q <= 1'b0; - end - end - end - end - - tlb #( - .ENTRIES(ITLB_ENTRIES), - .ASID_WIDTH(ASID_WIDTH) - ) u_itlb ( - .clk (clk), - .rst (rst), - .req_valid (i_accept), - .req_vaddr (i_req_vaddr), - .req_asid (req_asid), - .req_mode (req_mode), - .req_priv (priv_mode), - .req_is_fetch (1'b1), - .req_is_store (1'b0), - .req_sum (sum), - .req_mxr (mxr), - .resp_valid (i_tlb_resp_valid), - .resp_hit (i_tlb_resp_hit), - .resp_paddr (i_tlb_resp_paddr), - .resp_page_fault (i_tlb_resp_page_fault), - .resp_need_ptw (i_tlb_resp_need_ptw), - .refill_valid (i_refill_valid), - .refill_vpn (ptw_refill_vpn), - .refill_ppn (ptw_refill_ppn), - .refill_level (ptw_refill_level), - .refill_mode (ptw_refill_mode), - .refill_asid (ptw_refill_asid), - .refill_g (ptw_refill_g), - .refill_u (ptw_refill_u), - .refill_r (ptw_refill_r), - .refill_w (ptw_refill_w), - .refill_x (ptw_refill_x), - .refill_a (ptw_refill_a), - .refill_d (ptw_refill_d), - .flush_all (flush_all), - .flush_asid_valid (flush_asid_valid), - .flush_asid (flush_asid), - .flush_vpn_valid (flush_vpn_valid), - .flush_vpn (flush_vpn), - .flush_mode (req_mode) - ); - - tlb #( - .ENTRIES(DTLB_ENTRIES), - .ASID_WIDTH(ASID_WIDTH) - ) u_dtlb ( - .clk (clk), - .rst (rst), - .req_valid (d_accept), - .req_vaddr (d_req_vaddr), - .req_asid (req_asid), - .req_mode (req_mode), - .req_priv (priv_mode), - .req_is_fetch (1'b0), - .req_is_store (d_req_is_store), - .req_sum (sum), - .req_mxr (mxr), - .resp_valid (d_tlb_resp_valid), - .resp_hit (d_tlb_resp_hit), - .resp_paddr (d_tlb_resp_paddr), - .resp_page_fault (d_tlb_resp_page_fault), - .resp_need_ptw (d_tlb_resp_need_ptw), - .refill_valid (d_refill_valid), - .refill_vpn (ptw_refill_vpn), - .refill_ppn (ptw_refill_ppn), - .refill_level (ptw_refill_level), - .refill_mode (ptw_refill_mode), - .refill_asid (ptw_refill_asid), - .refill_g (ptw_refill_g), - .refill_u (ptw_refill_u), - .refill_r (ptw_refill_r), - .refill_w (ptw_refill_w), - .refill_x (ptw_refill_x), - .refill_a (ptw_refill_a), - .refill_d (ptw_refill_d), - .flush_all (flush_all), - .flush_asid_valid (flush_asid_valid), - .flush_asid (flush_asid), - .flush_vpn_valid (flush_vpn_valid), - .flush_vpn (flush_vpn), - .flush_mode (req_mode) - ); - - ptw #( - .ASID_WIDTH(ASID_WIDTH) - ) u_ptw ( - .clk (clk), - .rst (rst), - .req_valid (ptw_req_valid), - .req_ready (ptw_req_ready), - .req_vaddr ((ptw_owner_next == PTW_SRC_D) ? d_pending_vaddr_q : i_pending_vaddr_q), - .req_asid ((ptw_owner_next == PTW_SRC_D) ? d_pending_asid_q : i_pending_asid_q), - .req_mode ((ptw_owner_next == PTW_SRC_D) ? d_pending_mode_q : i_pending_mode_q), - .req_priv ((ptw_owner_next == PTW_SRC_D) ? d_pending_priv_q : i_pending_priv_q), - .req_is_fetch (ptw_owner_next == PTW_SRC_I), - .req_is_store ((ptw_owner_next == PTW_SRC_D) ? d_pending_is_store_q : 1'b0), - .req_sum ((ptw_owner_next == PTW_SRC_D) ? d_pending_sum_q : i_pending_sum_q), - .req_mxr ((ptw_owner_next == PTW_SRC_D) ? d_pending_mxr_q : i_pending_mxr_q), - .satp_value (satp_value), - .mem_req_valid (ptw_mem_req_valid), - .mem_req_ready (ptw_mem_req_ready), - .mem_req_addr (ptw_mem_req_addr), - .mem_resp_valid(ptw_mem_resp_valid), - .mem_resp_data (ptw_mem_resp_data), - .resp_valid (ptw_resp_valid), - .resp_fault (ptw_resp_fault), - .resp_paddr (ptw_resp_paddr), - .refill_valid (ptw_refill_valid), - .refill_vpn (ptw_refill_vpn), - .refill_ppn (ptw_refill_ppn), - .refill_level (ptw_refill_level), - .refill_mode (ptw_refill_mode), - .refill_asid (ptw_refill_asid), - .refill_g (ptw_refill_g), - .refill_u (ptw_refill_u), - .refill_r (ptw_refill_r), - .refill_w (ptw_refill_w), - .refill_x (ptw_refill_x), - .refill_a (ptw_refill_a), - .refill_d (ptw_refill_d) - ); - -endmodule |
