aboutsummaryrefslogtreecommitdiff
path: root/rv64cpu/rtl/core/mmu/mmu_top.sv
diff options
context:
space:
mode:
Diffstat (limited to 'rv64cpu/rtl/core/mmu/mmu_top.sv')
-rw-r--r--rv64cpu/rtl/core/mmu/mmu_top.sv359
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