From ee1b4fe221b0f9bad2d2e5bc56256fa065ea5a7f Mon Sep 17 00:00:00 2001 From: David Harris Date: Sat, 14 Jan 2023 18:14:38 -0800 Subject: [PATCH] mmu cleanup --- pipelined/src/mmu/adrdec.sv | 2 + pipelined/src/mmu/adrdecs.sv | 4 +- pipelined/src/mmu/hptw.sv | 170 +++++++++++++++----------------- pipelined/src/mmu/mmu.sv | 44 +++++---- pipelined/src/mmu/pmachecker.sv | 23 +++-- pipelined/src/mmu/pmpadrdec.sv | 34 ++++--- pipelined/src/mmu/pmpchecker.sv | 65 ++++++------ pipelined/src/mmu/tlb.sv | 2 + pipelined/src/mmu/tlbcam.sv | 2 + pipelined/src/mmu/tlbcamline.sv | 2 + pipelined/src/mmu/tlbcontrol.sv | 2 + pipelined/src/mmu/tlblru.sv | 2 + pipelined/src/mmu/tlbmixer.sv | 2 + pipelined/src/mmu/tlbram.sv | 2 + pipelined/src/mmu/tlbramline.sv | 2 + pipelined/src/mmu/vm64check.sv | 2 + 16 files changed, 194 insertions(+), 166 deletions(-) diff --git a/pipelined/src/mmu/adrdec.sv b/pipelined/src/mmu/adrdec.sv index 7f8ed324..ddb8423b 100644 --- a/pipelined/src/mmu/adrdec.sv +++ b/pipelined/src/mmu/adrdec.sv @@ -6,6 +6,8 @@ // // Purpose: Address decoder // +// Documentation: RISC-V System on Chip Design Chapter 8 +// // A component of the CORE-V-WALLY configurable RISC-V project. // // Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University diff --git a/pipelined/src/mmu/adrdecs.sv b/pipelined/src/mmu/adrdecs.sv index 4df5187d..679bd185 100644 --- a/pipelined/src/mmu/adrdecs.sv +++ b/pipelined/src/mmu/adrdecs.sv @@ -6,6 +6,8 @@ // // Purpose: All the address decoders for peripherals // +// Documentation: RISC-V System on Chip Design Chapter 8 +// // A component of the CORE-V-WALLY configurable RISC-V project. // // Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University @@ -31,7 +33,7 @@ module adrdecs ( input logic [`PA_BITS-1:0] PhysicalAddress, input logic AccessRW, AccessRX, AccessRWX, input logic [1:0] Size, - output logic [10:0] SelRegions + output logic [10:0] SelRegions ); localparam logic [3:0] SUPPORTED_SIZE = (`LLEN == 32 ? 4'b0111 : 4'b1111); diff --git a/pipelined/src/mmu/hptw.sv b/pipelined/src/mmu/hptw.sv index d155e6c7..92b60d18 100644 --- a/pipelined/src/mmu/hptw.sv +++ b/pipelined/src/mmu/hptw.sv @@ -8,8 +8,9 @@ // adding support for terapage encoding, and for setting the HPTWAdr using the new level, // adding the internal SvMode signal // -// Purpose: Page Table Walker -// Part of the Memory Management Unit (MMU) +// Purpose: Hardware Page Table Walker +// +// Documentation: RISC-V System on Chip Design Chapter 8 // // A component of the CORE-V-WALLY configurable RISC-V project. // @@ -31,39 +32,39 @@ `include "wally-config.vh" module hptw ( - input logic clk, reset, - input logic [`XLEN-1:0] SATP_REGW, // includes SATP.MODE to determine number of levels in page table - input logic [`XLEN-1:0] PCF, // addresses to translate - input logic [`XLEN+1:0] IEUAdrExtM, // addresses to translate - input logic [1:0] MemRWM, AtomicM, - // system status - input logic STATUS_MXR, STATUS_SUM, STATUS_MPRV, - input logic [1:0] STATUS_MPP, - input logic [1:0] PrivilegeModeW, - input logic [`XLEN-1:0] ReadDataM, // page table entry from LSU - input logic [`XLEN-1:0] WriteDataM, - input logic DCacheStallW, // stall from LSU - input logic [2:0] Funct3M, - input logic [6:0] Funct7M, - input logic ITLBMissF, - input logic DTLBMissM, - input logic FlushW, - input logic InstrDAPageFaultF, - input logic DataDAPageFaultM, - output logic [`XLEN-1:0] PTE, // page table entry to TLBs - output logic [1:0] PageType, // page type to TLBs - (* mark_debug = "true" *) output logic ITLBWriteF, DTLBWriteM, // write TLB with new entry - output logic [1:0] PreLSURWM, - output logic [`XLEN+1:0] IHAdrM, - output logic [`XLEN-1:0] IHWriteDataM, - output logic [1:0] LSUAtomicM, - output logic [2:0] LSUFunct3M, - output logic [6:0] LSUFunct7M, - output logic IgnoreRequestTLB, - output logic SelHPTW, - output logic HPTWStall, - input logic LSULoadAccessFaultM, LSUStoreAmoAccessFaultM, - output logic LoadAccessFaultM, StoreAmoAccessFaultM, HPTWInstrAccessFaultM + input logic clk, reset, + input logic [`XLEN-1:0] SATP_REGW, // includes SATP.MODE to determine number of levels in page table + input logic [`XLEN-1:0] PCF, // addresses to translate + input logic [`XLEN+1:0] IEUAdrExtM, // addresses to translate + input logic [1:0] MemRWM, AtomicM, + // system status + input logic STATUS_MXR, STATUS_SUM, STATUS_MPRV, + input logic [1:0] STATUS_MPP, + input logic [1:0] PrivilegeModeW, + input logic [`XLEN-1:0] ReadDataM, // page table entry from LSU + input logic [`XLEN-1:0] WriteDataM, + input logic DCacheStallW, // stall from LSU + input logic [2:0] Funct3M, + input logic [6:0] Funct7M, + input logic ITLBMissF, + input logic DTLBMissM, + input logic FlushW, + input logic InstrDAPageFaultF, + input logic DataDAPageFaultM, + output logic [`XLEN-1:0] PTE, // page table entry to TLBs + output logic [1:0] PageType, // page type to TLBs + (* mark_debug = "true" *) output logic ITLBWriteF, DTLBWriteM, // write TLB with new entry + output logic [1:0] PreLSURWM, + output logic [`XLEN+1:0] IHAdrM, + output logic [`XLEN-1:0] IHWriteDataM, + output logic [1:0] LSUAtomicM, + output logic [2:0] LSUFunct3M, + output logic [6:0] LSUFunct7M, + output logic IgnoreRequestTLB, + output logic SelHPTW, + output logic HPTWStall, + input logic LSULoadAccessFaultM, LSUStoreAmoAccessFaultM, + output logic LoadAccessFaultM, StoreAmoAccessFaultM, HPTWInstrAccessFaultM ); typedef enum logic [3:0] {L0_ADR, L0_RD, @@ -72,37 +73,35 @@ module hptw ( L3_ADR, L3_RD, LEAF, IDLE, UPDATE_PTE} statetype; - logic DTLBWalk; // register TLBs translation miss requests - logic [`PPN_BITS-1:0] BasePageTablePPN; - logic [`PPN_BITS-1:0] CurrentPPN; - logic Executable, Writable, Readable, Valid, PTE_U; - logic Misaligned, MegapageMisaligned; - logic ValidPTE, LeafPTE, ValidLeafPTE, ValidNonLeafPTE; - logic StartWalk; - logic TLBMiss; - logic PRegEn; - logic [1:0] NextPageType; - logic [`SVMODE_BITS-1:0] SvMode; - logic [`XLEN-1:0] TranslationVAdr; - logic [`XLEN-1:0] NextPTE; - logic UpdatePTE; - logic DAPageFault; - logic [`PA_BITS-1:0] HPTWReadAdr; - logic SelHPTWAdr; + logic DTLBWalk; // register TLBs translation miss requests + logic [`PPN_BITS-1:0] BasePageTablePPN; + logic [`PPN_BITS-1:0] CurrentPPN; + logic Executable, Writable, Readable, Valid, PTE_U; + logic Misaligned, MegapageMisaligned; + logic ValidPTE, LeafPTE, ValidLeafPTE, ValidNonLeafPTE; + logic StartWalk; + logic TLBMiss; + logic PRegEn; + logic [1:0] NextPageType; + logic [`SVMODE_BITS-1:0] SvMode; + logic [`XLEN-1:0] TranslationVAdr; + logic [`XLEN-1:0] NextPTE; + logic UpdatePTE; + logic DAPageFault; + logic [`PA_BITS-1:0] HPTWReadAdr; + logic SelHPTWAdr; logic [`XLEN+1:0] HPTWAdrExt; logic ITLBMissOrDAFaultF; logic DTLBMissOrDAFaultM; logic [`PA_BITS-1:0] HPTWAdr; logic [1:0] HPTWRW; - logic [2:0] HPTWSize; // 32 or 64 bit access. - - - (* mark_debug = "true" *) statetype WalkerState, NextWalkerState, InitialWalkerState; + logic [2:0] HPTWSize; // 32 or 64 bit access + (* mark_debug = "true" *) statetype WalkerState, NextWalkerState, InitialWalkerState; // map hptw access faults onto either the original LSU load/store fault or instruction access fault - assign LoadAccessFaultM = WalkerState == IDLE ? LSULoadAccessFaultM : (LSULoadAccessFaultM | LSUStoreAmoAccessFaultM) & DTLBWalk & MemRWM[1] & ~MemRWM[0]; - assign StoreAmoAccessFaultM = WalkerState == IDLE ? LSUStoreAmoAccessFaultM : (LSULoadAccessFaultM | LSUStoreAmoAccessFaultM) & DTLBWalk & MemRWM[0]; + assign LoadAccessFaultM = WalkerState == IDLE ? LSULoadAccessFaultM : (LSULoadAccessFaultM | LSUStoreAmoAccessFaultM) & DTLBWalk & MemRWM[1] & ~MemRWM[0]; + assign StoreAmoAccessFaultM = WalkerState == IDLE ? LSUStoreAmoAccessFaultM : (LSULoadAccessFaultM | LSUStoreAmoAccessFaultM) & DTLBWalk & MemRWM[0]; assign HPTWInstrAccessFaultM = WalkerState == IDLE ? 1'b0: (LSUStoreAmoAccessFaultM | LSULoadAccessFaultM) & ~DTLBWalk; // Extract bits from CSRs and inputs @@ -112,7 +111,6 @@ module hptw ( // Determine which address to translate mux2 #(`XLEN) vadrmux(PCF, IEUAdrExtM[`XLEN-1:0], DTLBWalk, TranslationVAdr); - //assign TranslationVAdr = DTLBWalk ? IEUAdrExtM[`XLEN-1:0] : PCF; assign CurrentPPN = PTE[`PPN_BITS+9:10]; // State flops @@ -120,7 +118,6 @@ module hptw ( assign PRegEn = HPTWRW[1] & ~DCacheStallW | UpdatePTE; flopenr #(`XLEN) PTEReg(clk, reset, PRegEn, NextPTE, PTE); // Capture page table entry from data cache - // Assign PTE descriptors common across all XLEN values // For non-leaf PTEs, D, A, U bits are reserved and ignored. They do not cause faults while walking the page table assign {PTE_U, Executable, Writable, Readable, Valid} = PTE[4:0]; @@ -130,7 +127,6 @@ module hptw ( assign ValidNonLeafPTE = ValidPTE & ~LeafPTE; if(`HPTW_WRITES_SUPPORTED) begin : hptwwrites - logic ReadAccess, WriteAccess; logic InvalidRead, InvalidWrite; logic UpperBitsUnequalPageFault; @@ -141,10 +137,10 @@ module hptw ( logic [`PA_BITS-1:0] HPTWWriteAdr; logic SetDirty; logic Dirty, Accessed; - logic [`XLEN-1:0] AccessedPTE; + logic [`XLEN-1:0] AccessedPTE; - assign AccessedPTE = {PTE[`XLEN-1:8], (SetDirty | PTE[7]), 1'b1, PTE[5:0]}; // set accessed bit, conditionally set dirty bit - mux2 #(`XLEN) NextPTEMux(ReadDataM, AccessedPTE, UpdatePTE, NextPTE); + assign AccessedPTE = {PTE[`XLEN-1:8], (SetDirty | PTE[7]), 1'b1, PTE[5:0]}; // set accessed bit, conditionally set dirty bit + mux2 #(`XLEN) NextPTEMux(ReadDataM, AccessedPTE, UpdatePTE, NextPTE); flopenr #(`PA_BITS) HPTWAdrWriteReg(clk, reset, SaveHPTWAdr, HPTWReadAdr, HPTWWriteAdr); assign SaveHPTWAdr = WalkerState == L0_ADR; @@ -161,8 +157,8 @@ module hptw ( ((EffectivePrivilegeMode == `S_MODE) & PTE_U & (~STATUS_SUM & DTLBWalk)); // Check for page faults - vm64check vm64check(.SATP_MODE(SATP_REGW[`XLEN-1:`XLEN-`SVMODE_BITS]), .VAdr(TranslationVAdr), - .SV39Mode(), .UpperBitsUnequalPageFault); + vm64check vm64check(.SATP_MODE(SATP_REGW[`XLEN-1:`XLEN-`SVMODE_BITS]), .VAdr(TranslationVAdr), + .SV39Mode(), .UpperBitsUnequalPageFault); assign InvalidRead = ReadAccess & ~Readable & (~STATUS_MXR | ~Executable); assign InvalidWrite = WriteAccess & ~Writable; assign OtherPageFault = DTLBWalk? ImproperPrivilege | InvalidRead | InvalidWrite | UpperBitsUnequalPageFault | Misaligned | ~Valid : @@ -190,7 +186,6 @@ module hptw ( assign DTLBWriteM = (WalkerState == LEAF & ~DAPageFault) & DTLBWalk; assign ITLBWriteF = (WalkerState == LEAF & ~DAPageFault) & ~DTLBWalk; - // FSM to track PageType based on the levels of the page table traversed flopr #(2) PageTypeReg(clk, reset, NextPageType, PageType); always_comb @@ -251,36 +246,35 @@ module hptw ( flopenl #(.TYPE(statetype)) WalkerStateReg(clk, reset | FlushW, 1'b1, NextWalkerState, IDLE, WalkerState); always_comb case (WalkerState) - IDLE: if (TLBMiss) NextWalkerState = InitialWalkerState; - else NextWalkerState = IDLE; - L3_ADR: NextWalkerState = L3_RD; // first access in SV48 - L3_RD: if (DCacheStallW) NextWalkerState = L3_RD; - else NextWalkerState = L2_ADR; + IDLE: if (TLBMiss) NextWalkerState = InitialWalkerState; + else NextWalkerState = IDLE; + L3_ADR: NextWalkerState = L3_RD; // first access in SV48 + L3_RD: if (DCacheStallW) NextWalkerState = L3_RD; + else NextWalkerState = L2_ADR; L2_ADR: if (InitialWalkerState == L2_ADR | ValidNonLeafPTE) NextWalkerState = L2_RD; // first access in SV39 - else NextWalkerState = LEAF; - L2_RD: if (DCacheStallW) NextWalkerState = L2_RD; - else NextWalkerState = L1_ADR; + else NextWalkerState = LEAF; + L2_RD: if (DCacheStallW) NextWalkerState = L2_RD; + else NextWalkerState = L1_ADR; L1_ADR: if (InitialWalkerState == L1_ADR | ValidNonLeafPTE) NextWalkerState = L1_RD; // first access in SV32 - else if (ValidNonLeafPTE) NextWalkerState = L1_RD; - else NextWalkerState = LEAF; - L1_RD: if (DCacheStallW) NextWalkerState = L1_RD; - else NextWalkerState = L0_ADR; - L0_ADR: if (ValidNonLeafPTE) NextWalkerState = L0_RD; - else NextWalkerState = LEAF; - L0_RD: if (DCacheStallW) NextWalkerState = L0_RD; - else NextWalkerState = LEAF; + else if (ValidNonLeafPTE) NextWalkerState = L1_RD; + else NextWalkerState = LEAF; + L1_RD: if (DCacheStallW) NextWalkerState = L1_RD; + else NextWalkerState = L0_ADR; + L0_ADR: if (ValidNonLeafPTE) NextWalkerState = L0_RD; + else NextWalkerState = LEAF; + L0_RD: if (DCacheStallW) NextWalkerState = L0_RD; + else NextWalkerState = LEAF; LEAF: if (`HPTW_WRITES_SUPPORTED & DAPageFault) NextWalkerState = UPDATE_PTE; - else NextWalkerState = IDLE; - UPDATE_PTE: if(DCacheStallW) NextWalkerState = UPDATE_PTE; - else NextWalkerState = LEAF; - default: NextWalkerState = IDLE; // should never be reached + else NextWalkerState = IDLE; + UPDATE_PTE: if(DCacheStallW) NextWalkerState = UPDATE_PTE; + else NextWalkerState = LEAF; + default: NextWalkerState = IDLE; // should never be reached endcase // case (WalkerState) assign IgnoreRequestTLB = WalkerState == IDLE & TLBMiss; assign SelHPTW = WalkerState != IDLE; assign HPTWStall = (WalkerState != IDLE) | (WalkerState == IDLE & TLBMiss); - assign ITLBMissOrDAFaultF = ITLBMissF | (`HPTW_WRITES_SUPPORTED & InstrDAPageFaultF); assign DTLBMissOrDAFaultM = DTLBMissM | (`HPTW_WRITES_SUPPORTED & DataDAPageFaultM); diff --git a/pipelined/src/mmu/mmu.sv b/pipelined/src/mmu/mmu.sv index b8069c21..4a89b439 100644 --- a/pipelined/src/mmu/mmu.sv +++ b/pipelined/src/mmu/mmu.sv @@ -6,6 +6,8 @@ // // Purpose: Memory management unit, including TLB, PMA, PMP // +// Documentation: RISC-V System on Chip Design Chapter 8 +// // A component of the CORE-V-WALLY configurable RISC-V project. // // Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University @@ -27,18 +29,20 @@ `include "wally-config.vh" module mmu #(parameter TLB_ENTRIES = 8, IMMU = 0) ( - input logic clk, reset, - input logic [`XLEN-1:0] SATP_REGW, // Current value of satp CSR (from privileged unit) - input logic STATUS_MXR, STATUS_SUM, STATUS_MPRV, // Status bits affecting translation - input logic [1:0] STATUS_MPP, // 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 - input logic [`XLEN+1:0] VAdr, // virtual/physical address from IEU or physical address from HPTW - input logic [1:0] Size, // access size: 00 = 8 bits, 01 = 16 bits, 10 = 32 bits , 11 = 64 bits - input logic [`XLEN-1:0] PTE, // page table entry - input logic [1:0] PageTypeWriteVal, // page type - input logic TLBWrite, // write TLB entry - input logic TLBFlush, // Invalidate all TLB entries + input logic clk, reset, + input logic [`XLEN-1:0] SATP_REGW, // Current value of satp CSR (from privileged unit) + 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 + input logic [`XLEN+1:0] VAdr, // virtual/physical address from IEU or physical address from HPTW + input logic [1:0] Size, // access size: 00 = 8 bits, 01 = 16 bits, 10 = 32 bits , 11 = 64 bits + input logic [`XLEN-1:0] PTE, // page table entry + input logic [1:0] PageTypeWriteVal, // page type + input logic TLBWrite, // write TLB entry + input logic TLBFlush, // Invalidate all TLB entries output logic [`PA_BITS-1:0] PhysicalAddress, // PAdr when no translation, or translated VAdr (TLBPAdr) when there is translation output logic TLBMiss, // Miss TLB output logic Cacheable, // PMA indicates memory address is cachable @@ -50,7 +54,7 @@ module mmu #(parameter TLB_ENTRIES = 8, IMMU = 0) ( output logic DAPageFault, // page fault due to setting dirty or access bit output logic LoadMisalignedFaultM, StoreAmoMisalignedFaultM, // misaligned fault sources // PMA checker signals - input logic AtomicAccessM, ExecuteAccessF, WriteAccessM, ReadAccessM, // access type + input logic AtomicAccessM, ExecuteAccessF, WriteAccessM, ReadAccessM, // access type input var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0], // PMP configuration input var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW[`PMP_ENTRIES-1:0] // PMP addresses ); @@ -103,10 +107,16 @@ module mmu #(parameter TLB_ENTRIES = 8, IMMU = 0) ( .Cacheable, .Idempotent, .SelTIM, .PMAInstrAccessFaultF, .PMALoadAccessFaultM, .PMAStoreAmoAccessFaultM); - pmpchecker pmpchecker(.PhysicalAddress, .PrivilegeModeW, - .PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW, - .ExecuteAccessF, .WriteAccessM, .ReadAccessM, - .PMPInstrAccessFaultF, .PMPLoadAccessFaultM, .PMPStoreAmoAccessFaultM); + if (`PMP_ENTRIES > 0) // instantiate PMP + pmpchecker pmpchecker(.PhysicalAddress, .PrivilegeModeW, + .PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW, + .ExecuteAccessF, .WriteAccessM, .ReadAccessM, + .PMPInstrAccessFaultF, .PMPLoadAccessFaultM, .PMPStoreAmoAccessFaultM); + else begin + assign PMPInstrAccessFaultF = 0; + assign PMPLoadAccessFaultM = 0; + assign PMPStoreAmoAccessFaultM = 0; + end // Access faults // If TLB miss and translating we want to not have faults from the PMA and PMP checkers. diff --git a/pipelined/src/mmu/pmachecker.sv b/pipelined/src/mmu/pmachecker.sv index 367fef39..e46cfe8b 100644 --- a/pipelined/src/mmu/pmachecker.sv +++ b/pipelined/src/mmu/pmachecker.sv @@ -8,6 +8,8 @@ // the memory region accessed. // Can report illegal accesses to the trap unit and cause a fault. // +// Documentation: RISC-V System on Chip Design Chapter 8 +// // A component of the CORE-V-WALLY configurable RISC-V project. // // Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University @@ -31,17 +33,20 @@ module pmachecker ( input logic [`PA_BITS-1:0] PhysicalAddress, input logic [1:0] Size, - input logic AtomicAccessM, ExecuteAccessF, WriteAccessM, ReadAccessM, // *** atomicaccessM is unused but might want to stay in for future use. - output logic Cacheable, Idempotent, SelTIM, - output logic PMAInstrAccessFaultF, - output logic PMALoadAccessFaultM, - output logic PMAStoreAmoAccessFaultM + input logic AtomicAccessM, // Atomic access + input logic ExecuteAccessF, // Execute access + input logic WriteAccessM, // Write access + input logic ReadAccessM, // Read access + output logic Cacheable, Idempotent, SelTIM, + output logic PMAInstrAccessFaultF, + output logic PMALoadAccessFaultM, + output logic PMAStoreAmoAccessFaultM ); - logic PMAAccessFault; - logic AccessRW, AccessRWX, AccessRX; - logic [10:0] SelRegions; - logic AtomicAllowed; + logic PMAAccessFault; + logic AccessRW, AccessRWX, AccessRX; + logic [10:0] SelRegions; + logic AtomicAllowed; // Determine what type of access is being made assign AccessRW = ReadAccessM | WriteAccessM; diff --git a/pipelined/src/mmu/pmpadrdec.sv b/pipelined/src/mmu/pmpadrdec.sv index 0eaf623d..4aeea116 100644 --- a/pipelined/src/mmu/pmpadrdec.sv +++ b/pipelined/src/mmu/pmpadrdec.sv @@ -10,6 +10,8 @@ // naturally aligned power-of-two region/NAPOT), then selects the // output based on which mode is input. // +// Documentation: RISC-V System on Chip Design Chapter 8 +// // A component of the CORE-V-WALLY configurable RISC-V project. // // Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University @@ -31,24 +33,24 @@ `include "wally-config.vh" module pmpadrdec ( - input logic [`PA_BITS-1:0] PhysicalAddress, - input logic [7:0] PMPCfg, - input logic [`XLEN-1:0] PMPAdr, - input logic PAgePMPAdrIn, - output logic PAgePMPAdrOut, - output logic Match, Active, - output logic L, X, W, R + input logic [`PA_BITS-1:0] PhysicalAddress, + input logic [7:0] PMPCfg, + input logic [`XLEN-1:0] PMPAdr, + input logic PAgePMPAdrIn, + output logic PAgePMPAdrOut, + output logic Match, Active, + output logic L, X, W, R ); - - localparam TOR = 2'b01; - localparam NA4 = 2'b10; - localparam NAPOT = 2'b11; - - logic TORMatch, NAMatch; - logic PAltPMPAdr; - logic [`PA_BITS-1:0] CurrentAdrFull; - logic [1:0] AdrMode; + + // define PMP addressing mode codes + localparam TOR = 2'b01; + localparam NA4 = 2'b10; + localparam NAPOT = 2'b11; + logic TORMatch, NAMatch; + logic PAltPMPAdr; + logic [`PA_BITS-1:0] CurrentAdrFull; + logic [1:0] AdrMode; assign AdrMode = PMPCfg[4:3]; diff --git a/pipelined/src/mmu/pmpchecker.sv b/pipelined/src/mmu/pmpchecker.sv index ae3f03e6..de8ce7b3 100644 --- a/pipelined/src/mmu/pmpchecker.sv +++ b/pipelined/src/mmu/pmpchecker.sv @@ -9,6 +9,8 @@ // Can raise an access fault on illegal reads, writes, and instruction // fetches. // +// Documentation: RISC-V System on Chip Design Chapter 8 +// // A component of the CORE-V-WALLY configurable RISC-V project. // // Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University @@ -32,50 +34,43 @@ module pmpchecker ( input logic [`PA_BITS-1:0] PhysicalAddress, input logic [1:0] PrivilegeModeW, - - // *** ModelSim has a switch -svinputport which controls whether input ports + // ModelSim has a switch -svinputport which controls whether input ports // are nets (wires) or vars by default. The default setting of this switch is // `relaxed`, which means that signals are nets if and only if they are // scalars or one-dimensional vectors. Since this is a two-dimensional vector, // this will be understood as a var. However, if we don't supply the `var` // keyword, the compiler warns us that it's interpreting the signal as a var, // which we might not intend. - input var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0], - input var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW [`PMP_ENTRIES-1:0], - input logic ExecuteAccessF, WriteAccessM, ReadAccessM, - output logic PMPInstrAccessFaultF, - output logic PMPLoadAccessFaultM, - output logic PMPStoreAmoAccessFaultM + input var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0], + input var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW [`PMP_ENTRIES-1:0], + input logic ExecuteAccessF, WriteAccessM, ReadAccessM, + output logic PMPInstrAccessFaultF, + output logic PMPLoadAccessFaultM, + output logic PMPStoreAmoAccessFaultM ); - if (`PMP_ENTRIES > 0) begin: pmpchecker - // Bit i is high when the address falls in PMP region i - logic EnforcePMP; - logic [`PMP_ENTRIES-1:0] Match; // physical address matches one of the pmp ranges - logic [`PMP_ENTRIES-1:0] FirstMatch; // onehot encoding for the first pmpaddr to match the current address. - logic [`PMP_ENTRIES-1:0] Active; // PMP register i is non-null - logic [`PMP_ENTRIES-1:0] L, X, W, R; // PMP matches and has flag set - logic [`PMP_ENTRIES-1:0] PAgePMPAdr; // for TOR PMP matching, PhysicalAddress > PMPAdr[i] + // Bit i is high when the address falls in PMP region i + logic EnforcePMP; + logic [`PMP_ENTRIES-1:0] Match; // physical address matches one of the pmp ranges + logic [`PMP_ENTRIES-1:0] FirstMatch; // onehot encoding for the first pmpaddr to match the current address. + logic [`PMP_ENTRIES-1:0] Active; // PMP register i is non-null + logic [`PMP_ENTRIES-1:0] L, X, W, R; // PMP matches and has flag set + logic [`PMP_ENTRIES-1:0] PAgePMPAdr; // for TOR PMP matching, PhysicalAddress > PMPAdr[i] - pmpadrdec pmpadrdecs[`PMP_ENTRIES-1:0]( - .PhysicalAddress, - .PMPCfg(PMPCFG_ARRAY_REGW), - .PMPAdr(PMPADDR_ARRAY_REGW), - .PAgePMPAdrIn({PAgePMPAdr[`PMP_ENTRIES-2:0], 1'b1}), - .PAgePMPAdrOut(PAgePMPAdr), - .Match, .Active, .L, .X, .W, .R); + pmpadrdec pmpadrdecs[`PMP_ENTRIES-1:0]( + .PhysicalAddress, + .PMPCfg(PMPCFG_ARRAY_REGW), + .PMPAdr(PMPADDR_ARRAY_REGW), + .PAgePMPAdrIn({PAgePMPAdr[`PMP_ENTRIES-2:0], 1'b1}), + .PAgePMPAdrOut(PAgePMPAdr), + .Match, .Active, .L, .X, .W, .R); - priorityonehot #(`PMP_ENTRIES) pmppriority(.a(Match), .y(FirstMatch)); // combine the match signal from all the adress decoders to find the first one that matches. + priorityonehot #(`PMP_ENTRIES) pmppriority(.a(Match), .y(FirstMatch)); // combine the match signal from all the adress decoders to find the first one that matches. - // Only enforce PMP checking for S and U modes when at least one PMP is active or in Machine mode when L bit is set in selected region - assign EnforcePMP = (PrivilegeModeW == `M_MODE) ? |(L & FirstMatch) : |Active; + // Only enforce PMP checking for S and U modes when at least one PMP is active or in Machine mode when L bit is set in selected region + assign EnforcePMP = (PrivilegeModeW == `M_MODE) ? |(L & FirstMatch) : |Active; - assign PMPInstrAccessFaultF = EnforcePMP & ExecuteAccessF & ~|(X & FirstMatch) ; - assign PMPStoreAmoAccessFaultM = EnforcePMP & WriteAccessM & ~|(W & FirstMatch) ; - assign PMPLoadAccessFaultM = EnforcePMP & ReadAccessM & ~|(R & FirstMatch) ; - end else begin: pmpchecker // no checker - assign PMPInstrAccessFaultF = 0; - assign PMPLoadAccessFaultM = 0; - assign PMPStoreAmoAccessFaultM = 0; - end -endmodule + assign PMPInstrAccessFaultF = EnforcePMP & ExecuteAccessF & ~|(X & FirstMatch) ; + assign PMPStoreAmoAccessFaultM = EnforcePMP & WriteAccessM & ~|(W & FirstMatch) ; + assign PMPLoadAccessFaultM = EnforcePMP & ReadAccessM & ~|(R & FirstMatch) ; + endmodule diff --git a/pipelined/src/mmu/tlb.sv b/pipelined/src/mmu/tlb.sv index d80fe2bb..9bbefedf 100644 --- a/pipelined/src/mmu/tlb.sv +++ b/pipelined/src/mmu/tlb.sv @@ -9,6 +9,8 @@ // Purpose: Translation lookaside buffer // Cache of virtural-to-physical address translations // +// Documentation: RISC-V System on Chip Design Chapter 8 +// // A component of the CORE-V-WALLY configurable RISC-V project. // // Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University diff --git a/pipelined/src/mmu/tlbcam.sv b/pipelined/src/mmu/tlbcam.sv index 8f21e13a..796c0de1 100644 --- a/pipelined/src/mmu/tlbcam.sv +++ b/pipelined/src/mmu/tlbcam.sv @@ -9,6 +9,8 @@ // Purpose: Stores virtual page numbers with cached translations. // Determines whether a given virtual page number is in the TLB. // +// Documentation: RISC-V System on Chip Design Chapter 8 +// // A component of the CORE-V-WALLY configurable RISC-V project. // // Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University diff --git a/pipelined/src/mmu/tlbcamline.sv b/pipelined/src/mmu/tlbcamline.sv index 44db71fa..6a0a322a 100644 --- a/pipelined/src/mmu/tlbcamline.sv +++ b/pipelined/src/mmu/tlbcamline.sv @@ -9,6 +9,8 @@ // Purpose: CAM line for the translation lookaside buffer (TLB) // Determines whether a virtual page number matches the stored key. // +// Documentation: RISC-V System on Chip Design Chapter 8 +// // A component of the CORE-V-WALLY configurable RISC-V project. // // Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University diff --git a/pipelined/src/mmu/tlbcontrol.sv b/pipelined/src/mmu/tlbcontrol.sv index 8821ccf2..7c4b50aa 100644 --- a/pipelined/src/mmu/tlbcontrol.sv +++ b/pipelined/src/mmu/tlbcontrol.sv @@ -6,6 +6,8 @@ // // Purpose: Control signals for TLB // +// Documentation: RISC-V System on Chip Design Chapter 8 +// // A component of the CORE-V-WALLY configurable RISC-V project. // // Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University diff --git a/pipelined/src/mmu/tlblru.sv b/pipelined/src/mmu/tlblru.sv index 92c4a97b..9d4449f2 100644 --- a/pipelined/src/mmu/tlblru.sv +++ b/pipelined/src/mmu/tlblru.sv @@ -7,6 +7,8 @@ // Purpose: Implementation of bit pseudo least-recently-used algorithm for // cache evictions. Outputs the index of the next entry to be written. // +// Documentation: RISC-V System on Chip Design Chapter 8 +// // A component of the CORE-V-WALLY configurable RISC-V project. // // Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University diff --git a/pipelined/src/mmu/tlbmixer.sv b/pipelined/src/mmu/tlbmixer.sv index 2e6f5860..f5555c2a 100644 --- a/pipelined/src/mmu/tlbmixer.sv +++ b/pipelined/src/mmu/tlbmixer.sv @@ -9,6 +9,8 @@ // number with segments from the second, based on the page type. // NOTE: this DOES NOT include the 12 bit offset, which is the same no matter the translation mode or page type. // +// Documentation: RISC-V System on Chip Design Chapter 8 +// // A component of the CORE-V-WALLY configurable RISC-V project. // // Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University diff --git a/pipelined/src/mmu/tlbram.sv b/pipelined/src/mmu/tlbram.sv index fd891940..febb8b6f 100644 --- a/pipelined/src/mmu/tlbram.sv +++ b/pipelined/src/mmu/tlbram.sv @@ -8,6 +8,8 @@ // Outputs the physical page number and access bits of the current // virtual address on a TLB hit. // +// Documentation: RISC-V System on Chip Design Chapter 8 +// // A component of the CORE-V-WALLY configurable RISC-V project. // // Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University diff --git a/pipelined/src/mmu/tlbramline.sv b/pipelined/src/mmu/tlbramline.sv index bfad0d7b..035c58d5 100644 --- a/pipelined/src/mmu/tlbramline.sv +++ b/pipelined/src/mmu/tlbramline.sv @@ -6,6 +6,8 @@ // // Purpose: One line of the RAM, with enabled flip-flop and logic for reading into distributed OR // +// Documentation: RISC-V System on Chip Design Chapter 8 +// // A component of the CORE-V-WALLY configurable RISC-V project. // // Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University diff --git a/pipelined/src/mmu/vm64check.sv b/pipelined/src/mmu/vm64check.sv index 39ff328e..549ab83c 100644 --- a/pipelined/src/mmu/vm64check.sv +++ b/pipelined/src/mmu/vm64check.sv @@ -6,6 +6,8 @@ // // Purpose: Check for good upper address bits in RV64 mode // +// Documentation: RISC-V System on Chip Design Chapter 8 +// // A component of the CORE-V-WALLY configurable RISC-V project. // // Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University