2021-06-04 15:59:14 +00:00
///////////////////////////////////////////
// mmu.sv
//
// Written: david_harris@hmc.edu and kmacsaigoren@hmc.edu 4 June 2021
// Modified:
//
// Purpose: Memory management unit, including TLB, PMA, PMP
//
2023-01-15 02:14:38 +00:00
// Documentation: RISC-V System on Chip Design Chapter 8
//
2023-01-11 23:15:08 +00:00
// A component of the CORE-V-WALLY configurable RISC-V project.
2021-06-04 15:59:14 +00:00
//
2023-01-10 19:35:20 +00:00
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
2021-06-04 15:59:14 +00:00
//
2023-01-10 19:35:20 +00:00
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
2021-06-04 15:59:14 +00:00
//
2023-01-10 19:35:20 +00:00
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
// may obtain a copy of the License at
2021-06-04 15:59:14 +00:00
//
2023-01-10 19:35:20 +00:00
// https://solderpad.org/licenses/SHL-2.1/
//
// Unless required by applicable law or agreed to in writing, any work distributed under the
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions
// and limitations under the License.
2022-01-07 12:58:40 +00:00
////////////////////////////////////////////////////////////////////////////////////////////////
2021-06-04 15:59:14 +00:00
2023-05-24 21:12:41 +00:00
module mmu import cvw : : * ; # ( parameter cvw_t P ,
parameter TLB_ENTRIES = 8 , IMMU = 0 ) (
2023-01-15 02:14:38 +00:00
input logic clk , reset ,
2023-05-24 21:12:41 +00:00
input logic [ P . XLEN - 1 : 0 ] SATP_REGW , // Current value of satp CSR (from privileged unit)
2023-01-15 02:14:38 +00:00
input logic STATUS_MXR , // Status CSR: make executable page readable
input logic STATUS_SUM , // Status CSR: Supervisor access to user memory
input logic STATUS_MPRV , // Status CSR: modify machine privilege
input logic [ 1 : 0 ] STATUS_MPP , // Status CSR: previous machine privilege level
input logic [ 1 : 0 ] PrivilegeModeW , // Current privilege level of the processeor
input logic DisableTranslation , // virtual address translation disabled during D$ flush and HPTW walk that use physical addresses
2023-05-24 21:12:41 +00:00
input logic [ P . XLEN + 1 : 0 ] VAdr , // virtual/physical address from IEU or physical address from HPTW
2023-01-15 02:14:38 +00:00
input logic [ 1 : 0 ] Size , // access size: 00 = 8 bits, 01 = 16 bits, 10 = 32 bits , 11 = 64 bits
2023-05-24 21:12:41 +00:00
input logic [ P . XLEN - 1 : 0 ] PTE , // page table entry
2023-01-15 02:14:38 +00:00
input logic [ 1 : 0 ] PageTypeWriteVal , // page type
input logic TLBWrite , // write TLB entry
input logic TLBFlush , // Invalidate all TLB entries
2023-05-24 21:12:41 +00:00
output logic [ P . PA_BITS - 1 : 0 ] PhysicalAddress , // PAdr when no translation, or translated VAdr (TLBPAdr) when there is translation
2023-01-15 01:35:21 +00:00
output logic TLBMiss , // Miss TLB
output logic Cacheable , // PMA indicates memory address is cachable
output logic Idempotent , // PMA indicates memory address is idempotent
output logic SelTIM , // Select a tightly integrated memory
2021-06-04 15:59:14 +00:00
// Faults
2023-04-13 23:54:15 +00:00
output logic InstrAccessFaultF , LoadAccessFaultM , StoreAmoAccessFaultM , // access fault sources
output logic InstrPageFaultF , LoadPageFaultM , StoreAmoPageFaultM , // page fault sources
output logic UpdateDA , // page fault due to setting dirty or access bit
output logic LoadMisalignedFaultM , StoreAmoMisalignedFaultM , // misaligned fault sources
2021-06-04 21:05:07 +00:00
// PMA checker signals
2023-04-13 23:54:15 +00:00
input logic AtomicAccessM , ExecuteAccessF , WriteAccessM , ReadAccessM , // access type
2023-05-24 21:12:41 +00:00
input var logic [ 7 : 0 ] PMPCFG_ARRAY_REGW [ P . PMP_ENTRIES - 1 : 0 ] , // PMP configuration
input var logic [ P . PA_BITS - 3 : 0 ] PMPADDR_ARRAY_REGW [ P . PMP_ENTRIES - 1 : 0 ] // PMP addresses
2021-06-04 15:59:14 +00:00
) ;
2023-05-24 21:12:41 +00:00
logic [ P . PA_BITS - 1 : 0 ] TLBPAdr ; // physical address for TLB
2023-01-15 01:35:21 +00:00
logic PMAInstrAccessFaultF ; // Instruction access fault from PMA
logic PMPInstrAccessFaultF ; // Instruction access fault from PMP
logic PMALoadAccessFaultM ; // Load access fault from PMA
logic PMPLoadAccessFaultM ; // Load access fault from PMP
logic PMAStoreAmoAccessFaultM ; // Store or AMO access fault from PMA
logic PMPStoreAmoAccessFaultM ; // Store or AMO access fault from PMP
logic DataMisalignedM ; // load or store misaligned
logic Translate ; // Translation occurs when virtual memory is active and DisableTranslation is off
logic TLBHit ; // Hit in TLB
logic TLBPageFault ; // Page fault from TLB
2023-02-27 02:35:10 +00:00
logic ReadNoAmoAccessM ; // Read that is not part of atomic operation causes Load faults. Otherwise StoreAmo faults
2022-01-27 23:11:27 +00:00
2021-07-06 00:35:31 +00:00
// only instantiate TLB if Virtual Memory is supported
2023-05-24 21:12:41 +00:00
if ( P . VIRTMEM_SUPPORTED ) begin : tlb
2022-01-05 14:35:25 +00:00
logic ReadAccess , WriteAccess ;
assign ReadAccess = ExecuteAccessF | ReadAccessM ; // execute also acts as a TLB read. Execute and Read are never active for the same MMU, so safe to mix pipestages
assign WriteAccess = WriteAccessM ;
2023-01-15 01:35:21 +00:00
tlb # ( . TLB_ENTRIES ( TLB_ENTRIES ) , . ITLB ( IMMU ) ) tlb (
. clk , . reset ,
2023-05-24 21:12:41 +00:00
. SATP_MODE ( SATP_REGW [ P . XLEN - 1 : P . XLEN - P . SVMODE_BITS ] ) ,
. SATP_ASID ( SATP_REGW [ P . ASID_BASE + P . ASID_BITS - 1 : P . ASID_BASE ] ) ,
. VAdr ( VAdr [ P . XLEN - 1 : 0 ] ) , . STATUS_MXR , . STATUS_SUM , . STATUS_MPRV , . STATUS_MPP ,
2022-01-05 14:35:25 +00:00
. PrivilegeModeW , . ReadAccess , . WriteAccess ,
. DisableTranslation , . PTE , . PageTypeWriteVal ,
. TLBWrite , . TLBFlush , . TLBPAdr , . TLBMiss , . TLBHit ,
2023-02-27 01:51:45 +00:00
. Translate , . TLBPageFault , . UpdateDA ) ;
2023-04-13 23:54:15 +00:00
end else begin : tlb // just pass address through as physical
2022-01-05 14:35:25 +00:00
assign Translate = 0 ;
assign TLBMiss = 0 ;
assign TLBHit = 1 ; // *** is this necessary
assign TLBPageFault = 0 ;
end
2021-07-06 19:29:42 +00:00
// If translation is occuring, select translated physical address from TLB
2022-01-07 05:19:09 +00:00
// the lower 12 bits are the page offset. These are never changed from the orginal
// non translated address.
2023-05-24 21:12:41 +00:00
mux2 # ( P . PA_BITS - 12 ) addressmux ( VAdr [ P . PA_BITS - 1 : 12 ] , TLBPAdr [ P . PA_BITS - 1 : 12 ] , Translate , PhysicalAddress [ P . PA_BITS - 1 : 12 ] ) ;
2022-03-25 04:47:28 +00:00
assign PhysicalAddress [ 11 : 0 ] = VAdr [ 11 : 0 ] ;
2022-01-07 05:19:09 +00:00
2021-06-04 15:59:14 +00:00
///////////////////////////////////////////
// Check physical memory accesses
///////////////////////////////////////////
2023-05-24 22:20:55 +00:00
pmachecker # ( P . PA_BITS ) pmachecker ( . PhysicalAddress , . Size ,
2023-01-15 01:35:21 +00:00
. AtomicAccessM , . ExecuteAccessF , . WriteAccessM , . ReadAccessM ,
. Cacheable , . Idempotent , . SelTIM ,
. PMAInstrAccessFaultF , . PMALoadAccessFaultM , . PMAStoreAmoAccessFaultM ) ;
2022-08-27 04:05:20 +00:00
2023-05-24 21:12:41 +00:00
if ( P . PMP_ENTRIES > 0 ) begin : pmp
2023-05-24 22:20:55 +00:00
pmpchecker # ( P ) pmpchecker ( . PhysicalAddress , . PrivilegeModeW ,
2023-02-19 23:31:00 +00:00
. PMPCFG_ARRAY_REGW , . PMPADDR_ARRAY_REGW ,
. ExecuteAccessF , . WriteAccessM , . ReadAccessM ,
. PMPInstrAccessFaultF , . PMPLoadAccessFaultM , . PMPStoreAmoAccessFaultM ) ;
2023-03-28 15:35:23 +00:00
end else begin
2023-02-19 23:31:00 +00:00
assign PMPInstrAccessFaultF = 0 ;
assign PMPStoreAmoAccessFaultM = 0 ;
assign PMPLoadAccessFaultM = 0 ;
end
2021-06-04 21:05:07 +00:00
2023-02-27 02:35:10 +00:00
assign ReadNoAmoAccessM = ReadAccessM & ~ WriteAccessM ; // AMO causes StoreAmo rather than Load fault
2023-01-07 12:49:25 +00:00
// Access faults
2021-07-16 17:22:13 +00:00
// If TLB miss and translating we want to not have faults from the PMA and PMP checkers.
2023-02-26 17:58:34 +00:00
assign InstrAccessFaultF = ( PMAInstrAccessFaultF | PMPInstrAccessFaultF ) & ~ TLBMiss ;
assign LoadAccessFaultM = ( PMALoadAccessFaultM | PMPLoadAccessFaultM ) & ~ TLBMiss ;
assign StoreAmoAccessFaultM = ( PMAStoreAmoAccessFaultM | PMPStoreAmoAccessFaultM ) & ~ TLBMiss ;
2022-01-27 23:11:27 +00:00
2023-01-07 12:49:25 +00:00
// Misaligned faults
2023-05-01 15:14:19 +00:00
always_comb // exclusion-tag: immu-wordaccess
2022-01-27 23:11:27 +00:00
case ( Size [ 1 : 0 ] )
2 'b00 : DataMisalignedM = 0 ; // lb, sb, lbu
2 'b01 : DataMisalignedM = VAdr [ 0 ] ; // lh, sh, lhu
2 'b10 : DataMisalignedM = VAdr [ 1 ] | VAdr [ 0 ] ; // lw, sw, flw, fsw, lwu
2 'b11 : DataMisalignedM = | VAdr [ 2 : 0 ] ; // ld, sd, fld, fsd
endcase
2023-02-27 02:35:10 +00:00
assign LoadMisalignedFaultM = DataMisalignedM & ReadNoAmoAccessM ;
assign StoreAmoMisalignedFaultM = DataMisalignedM & WriteAccessM ;
2023-01-07 12:49:25 +00:00
2022-01-27 23:11:27 +00:00
// Specify which type of page fault is occurring
2023-01-15 01:35:21 +00:00
assign InstrPageFaultF = TLBPageFault & ExecuteAccessF ;
2023-02-27 02:35:10 +00:00
assign LoadPageFaultM = TLBPageFault & ReadNoAmoAccessM ;
assign StoreAmoPageFaultM = TLBPageFault & WriteAccessM ;
2021-06-23 21:43:22 +00:00
endmodule