forked from Github_Repos/cvw
mmu cleanup
This commit is contained in:
parent
7c5548a39c
commit
ee1b4fe221
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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];
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user