mmu cleanup

This commit is contained in:
David Harris 2023-01-14 18:14:38 -08:00
parent 7c5548a39c
commit ee1b4fe221
16 changed files with 194 additions and 166 deletions

View File

@ -6,6 +6,8 @@
// //
// Purpose: Address decoder // Purpose: Address decoder
// //
// Documentation: RISC-V System on Chip Design Chapter 8
//
// A component of the CORE-V-WALLY configurable RISC-V project. // A component of the CORE-V-WALLY configurable RISC-V project.
// //
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University // Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University

View File

@ -6,6 +6,8 @@
// //
// Purpose: All the address decoders for peripherals // 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. // A component of the CORE-V-WALLY configurable RISC-V project.
// //
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University // 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 [`PA_BITS-1:0] PhysicalAddress,
input logic AccessRW, AccessRX, AccessRWX, input logic AccessRW, AccessRX, AccessRWX,
input logic [1:0] Size, 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); localparam logic [3:0] SUPPORTED_SIZE = (`LLEN == 32 ? 4'b0111 : 4'b1111);

View File

@ -8,8 +8,9 @@
// adding support for terapage encoding, and for setting the HPTWAdr using the new level, // adding support for terapage encoding, and for setting the HPTWAdr using the new level,
// adding the internal SvMode signal // adding the internal SvMode signal
// //
// Purpose: Page Table Walker // Purpose: Hardware Page Table Walker
// Part of the Memory Management Unit (MMU) //
// Documentation: RISC-V System on Chip Design Chapter 8
// //
// A component of the CORE-V-WALLY configurable RISC-V project. // A component of the CORE-V-WALLY configurable RISC-V project.
// //
@ -31,39 +32,39 @@
`include "wally-config.vh" `include "wally-config.vh"
module hptw ( module hptw (
input logic clk, reset, 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] 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] PCF, // addresses to translate
input logic [`XLEN+1:0] IEUAdrExtM, // addresses to translate input logic [`XLEN+1:0] IEUAdrExtM, // addresses to translate
input logic [1:0] MemRWM, AtomicM, input logic [1:0] MemRWM, AtomicM,
// system status // system status
input logic STATUS_MXR, STATUS_SUM, STATUS_MPRV, input logic STATUS_MXR, STATUS_SUM, STATUS_MPRV,
input logic [1:0] STATUS_MPP, input logic [1:0] STATUS_MPP,
input logic [1:0] PrivilegeModeW, input logic [1:0] PrivilegeModeW,
input logic [`XLEN-1:0] ReadDataM, // page table entry from LSU input logic [`XLEN-1:0] ReadDataM, // page table entry from LSU
input logic [`XLEN-1:0] WriteDataM, input logic [`XLEN-1:0] WriteDataM,
input logic DCacheStallW, // stall from LSU input logic DCacheStallW, // stall from LSU
input logic [2:0] Funct3M, input logic [2:0] Funct3M,
input logic [6:0] Funct7M, input logic [6:0] Funct7M,
input logic ITLBMissF, input logic ITLBMissF,
input logic DTLBMissM, input logic DTLBMissM,
input logic FlushW, input logic FlushW,
input logic InstrDAPageFaultF, input logic InstrDAPageFaultF,
input logic DataDAPageFaultM, input logic DataDAPageFaultM,
output logic [`XLEN-1:0] PTE, // page table entry to TLBs output logic [`XLEN-1:0] PTE, // page table entry to TLBs
output logic [1:0] PageType, // page type to TLBs output logic [1:0] PageType, // page type to TLBs
(* mark_debug = "true" *) output logic ITLBWriteF, DTLBWriteM, // write TLB with new entry (* mark_debug = "true" *) output logic ITLBWriteF, DTLBWriteM, // write TLB with new entry
output logic [1:0] PreLSURWM, output logic [1:0] PreLSURWM,
output logic [`XLEN+1:0] IHAdrM, output logic [`XLEN+1:0] IHAdrM,
output logic [`XLEN-1:0] IHWriteDataM, output logic [`XLEN-1:0] IHWriteDataM,
output logic [1:0] LSUAtomicM, output logic [1:0] LSUAtomicM,
output logic [2:0] LSUFunct3M, output logic [2:0] LSUFunct3M,
output logic [6:0] LSUFunct7M, output logic [6:0] LSUFunct7M,
output logic IgnoreRequestTLB, output logic IgnoreRequestTLB,
output logic SelHPTW, output logic SelHPTW,
output logic HPTWStall, output logic HPTWStall,
input logic LSULoadAccessFaultM, LSUStoreAmoAccessFaultM, input logic LSULoadAccessFaultM, LSUStoreAmoAccessFaultM,
output logic LoadAccessFaultM, StoreAmoAccessFaultM, HPTWInstrAccessFaultM output logic LoadAccessFaultM, StoreAmoAccessFaultM, HPTWInstrAccessFaultM
); );
typedef enum logic [3:0] {L0_ADR, L0_RD, typedef enum logic [3:0] {L0_ADR, L0_RD,
@ -72,37 +73,35 @@ module hptw (
L3_ADR, L3_RD, L3_ADR, L3_RD,
LEAF, IDLE, UPDATE_PTE} statetype; LEAF, IDLE, UPDATE_PTE} statetype;
logic DTLBWalk; // register TLBs translation miss requests logic DTLBWalk; // register TLBs translation miss requests
logic [`PPN_BITS-1:0] BasePageTablePPN; logic [`PPN_BITS-1:0] BasePageTablePPN;
logic [`PPN_BITS-1:0] CurrentPPN; logic [`PPN_BITS-1:0] CurrentPPN;
logic Executable, Writable, Readable, Valid, PTE_U; logic Executable, Writable, Readable, Valid, PTE_U;
logic Misaligned, MegapageMisaligned; logic Misaligned, MegapageMisaligned;
logic ValidPTE, LeafPTE, ValidLeafPTE, ValidNonLeafPTE; logic ValidPTE, LeafPTE, ValidLeafPTE, ValidNonLeafPTE;
logic StartWalk; logic StartWalk;
logic TLBMiss; logic TLBMiss;
logic PRegEn; logic PRegEn;
logic [1:0] NextPageType; logic [1:0] NextPageType;
logic [`SVMODE_BITS-1:0] SvMode; logic [`SVMODE_BITS-1:0] SvMode;
logic [`XLEN-1:0] TranslationVAdr; logic [`XLEN-1:0] TranslationVAdr;
logic [`XLEN-1:0] NextPTE; logic [`XLEN-1:0] NextPTE;
logic UpdatePTE; logic UpdatePTE;
logic DAPageFault; logic DAPageFault;
logic [`PA_BITS-1:0] HPTWReadAdr; logic [`PA_BITS-1:0] HPTWReadAdr;
logic SelHPTWAdr; logic SelHPTWAdr;
logic [`XLEN+1:0] HPTWAdrExt; logic [`XLEN+1:0] HPTWAdrExt;
logic ITLBMissOrDAFaultF; logic ITLBMissOrDAFaultF;
logic DTLBMissOrDAFaultM; logic DTLBMissOrDAFaultM;
logic [`PA_BITS-1:0] HPTWAdr; logic [`PA_BITS-1:0] HPTWAdr;
logic [1:0] HPTWRW; logic [1:0] HPTWRW;
logic [2:0] HPTWSize; // 32 or 64 bit access. logic [2:0] HPTWSize; // 32 or 64 bit access
(* mark_debug = "true" *) statetype WalkerState, NextWalkerState, InitialWalkerState;
(* mark_debug = "true" *) statetype WalkerState, NextWalkerState, InitialWalkerState;
// map hptw access faults onto either the original LSU load/store fault or instruction access fault // 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 LoadAccessFaultM = WalkerState == IDLE ? LSULoadAccessFaultM : (LSULoadAccessFaultM | LSUStoreAmoAccessFaultM) & DTLBWalk & MemRWM[1] & ~MemRWM[0];
assign StoreAmoAccessFaultM = WalkerState == IDLE ? LSUStoreAmoAccessFaultM : (LSULoadAccessFaultM | LSUStoreAmoAccessFaultM) & DTLBWalk & MemRWM[0]; assign StoreAmoAccessFaultM = WalkerState == IDLE ? LSUStoreAmoAccessFaultM : (LSULoadAccessFaultM | LSUStoreAmoAccessFaultM) & DTLBWalk & MemRWM[0];
assign HPTWInstrAccessFaultM = WalkerState == IDLE ? 1'b0: (LSUStoreAmoAccessFaultM | LSULoadAccessFaultM) & ~DTLBWalk; assign HPTWInstrAccessFaultM = WalkerState == IDLE ? 1'b0: (LSUStoreAmoAccessFaultM | LSULoadAccessFaultM) & ~DTLBWalk;
// Extract bits from CSRs and inputs // Extract bits from CSRs and inputs
@ -112,7 +111,6 @@ module hptw (
// Determine which address to translate // Determine which address to translate
mux2 #(`XLEN) vadrmux(PCF, IEUAdrExtM[`XLEN-1:0], DTLBWalk, TranslationVAdr); 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]; assign CurrentPPN = PTE[`PPN_BITS+9:10];
// State flops // State flops
@ -120,7 +118,6 @@ module hptw (
assign PRegEn = HPTWRW[1] & ~DCacheStallW | UpdatePTE; assign PRegEn = HPTWRW[1] & ~DCacheStallW | UpdatePTE;
flopenr #(`XLEN) PTEReg(clk, reset, PRegEn, NextPTE, PTE); // Capture page table entry from data cache flopenr #(`XLEN) PTEReg(clk, reset, PRegEn, NextPTE, PTE); // Capture page table entry from data cache
// Assign PTE descriptors common across all XLEN values // 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 // 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]; assign {PTE_U, Executable, Writable, Readable, Valid} = PTE[4:0];
@ -130,7 +127,6 @@ module hptw (
assign ValidNonLeafPTE = ValidPTE & ~LeafPTE; assign ValidNonLeafPTE = ValidPTE & ~LeafPTE;
if(`HPTW_WRITES_SUPPORTED) begin : hptwwrites if(`HPTW_WRITES_SUPPORTED) begin : hptwwrites
logic ReadAccess, WriteAccess; logic ReadAccess, WriteAccess;
logic InvalidRead, InvalidWrite; logic InvalidRead, InvalidWrite;
logic UpperBitsUnequalPageFault; logic UpperBitsUnequalPageFault;
@ -141,10 +137,10 @@ module hptw (
logic [`PA_BITS-1:0] HPTWWriteAdr; logic [`PA_BITS-1:0] HPTWWriteAdr;
logic SetDirty; logic SetDirty;
logic Dirty, Accessed; 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 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); mux2 #(`XLEN) NextPTEMux(ReadDataM, AccessedPTE, UpdatePTE, NextPTE);
flopenr #(`PA_BITS) HPTWAdrWriteReg(clk, reset, SaveHPTWAdr, HPTWReadAdr, HPTWWriteAdr); flopenr #(`PA_BITS) HPTWAdrWriteReg(clk, reset, SaveHPTWAdr, HPTWReadAdr, HPTWWriteAdr);
assign SaveHPTWAdr = WalkerState == L0_ADR; assign SaveHPTWAdr = WalkerState == L0_ADR;
@ -161,8 +157,8 @@ module hptw (
((EffectivePrivilegeMode == `S_MODE) & PTE_U & (~STATUS_SUM & DTLBWalk)); ((EffectivePrivilegeMode == `S_MODE) & PTE_U & (~STATUS_SUM & DTLBWalk));
// Check for page faults // Check for page faults
vm64check vm64check(.SATP_MODE(SATP_REGW[`XLEN-1:`XLEN-`SVMODE_BITS]), .VAdr(TranslationVAdr), vm64check vm64check(.SATP_MODE(SATP_REGW[`XLEN-1:`XLEN-`SVMODE_BITS]), .VAdr(TranslationVAdr),
.SV39Mode(), .UpperBitsUnequalPageFault); .SV39Mode(), .UpperBitsUnequalPageFault);
assign InvalidRead = ReadAccess & ~Readable & (~STATUS_MXR | ~Executable); assign InvalidRead = ReadAccess & ~Readable & (~STATUS_MXR | ~Executable);
assign InvalidWrite = WriteAccess & ~Writable; assign InvalidWrite = WriteAccess & ~Writable;
assign OtherPageFault = DTLBWalk? ImproperPrivilege | InvalidRead | InvalidWrite | UpperBitsUnequalPageFault | Misaligned | ~Valid : assign OtherPageFault = DTLBWalk? ImproperPrivilege | InvalidRead | InvalidWrite | UpperBitsUnequalPageFault | Misaligned | ~Valid :
@ -190,7 +186,6 @@ module hptw (
assign DTLBWriteM = (WalkerState == LEAF & ~DAPageFault) & DTLBWalk; assign DTLBWriteM = (WalkerState == LEAF & ~DAPageFault) & DTLBWalk;
assign ITLBWriteF = (WalkerState == LEAF & ~DAPageFault) & ~DTLBWalk; assign ITLBWriteF = (WalkerState == LEAF & ~DAPageFault) & ~DTLBWalk;
// FSM to track PageType based on the levels of the page table traversed // FSM to track PageType based on the levels of the page table traversed
flopr #(2) PageTypeReg(clk, reset, NextPageType, PageType); flopr #(2) PageTypeReg(clk, reset, NextPageType, PageType);
always_comb always_comb
@ -251,36 +246,35 @@ module hptw (
flopenl #(.TYPE(statetype)) WalkerStateReg(clk, reset | FlushW, 1'b1, NextWalkerState, IDLE, WalkerState); flopenl #(.TYPE(statetype)) WalkerStateReg(clk, reset | FlushW, 1'b1, NextWalkerState, IDLE, WalkerState);
always_comb always_comb
case (WalkerState) case (WalkerState)
IDLE: if (TLBMiss) NextWalkerState = InitialWalkerState; IDLE: if (TLBMiss) NextWalkerState = InitialWalkerState;
else NextWalkerState = IDLE; else NextWalkerState = IDLE;
L3_ADR: NextWalkerState = L3_RD; // first access in SV48 L3_ADR: NextWalkerState = L3_RD; // first access in SV48
L3_RD: if (DCacheStallW) NextWalkerState = L3_RD; L3_RD: if (DCacheStallW) NextWalkerState = L3_RD;
else NextWalkerState = L2_ADR; else NextWalkerState = L2_ADR;
L2_ADR: if (InitialWalkerState == L2_ADR | ValidNonLeafPTE) NextWalkerState = L2_RD; // first access in SV39 L2_ADR: if (InitialWalkerState == L2_ADR | ValidNonLeafPTE) NextWalkerState = L2_RD; // first access in SV39
else NextWalkerState = LEAF; else NextWalkerState = LEAF;
L2_RD: if (DCacheStallW) NextWalkerState = L2_RD; L2_RD: if (DCacheStallW) NextWalkerState = L2_RD;
else NextWalkerState = L1_ADR; else NextWalkerState = L1_ADR;
L1_ADR: if (InitialWalkerState == L1_ADR | ValidNonLeafPTE) NextWalkerState = L1_RD; // first access in SV32 L1_ADR: if (InitialWalkerState == L1_ADR | ValidNonLeafPTE) NextWalkerState = L1_RD; // first access in SV32
else if (ValidNonLeafPTE) NextWalkerState = L1_RD; else if (ValidNonLeafPTE) NextWalkerState = L1_RD;
else NextWalkerState = LEAF; else NextWalkerState = LEAF;
L1_RD: if (DCacheStallW) NextWalkerState = L1_RD; L1_RD: if (DCacheStallW) NextWalkerState = L1_RD;
else NextWalkerState = L0_ADR; else NextWalkerState = L0_ADR;
L0_ADR: if (ValidNonLeafPTE) NextWalkerState = L0_RD; L0_ADR: if (ValidNonLeafPTE) NextWalkerState = L0_RD;
else NextWalkerState = LEAF; else NextWalkerState = LEAF;
L0_RD: if (DCacheStallW) NextWalkerState = L0_RD; L0_RD: if (DCacheStallW) NextWalkerState = L0_RD;
else NextWalkerState = LEAF; else NextWalkerState = LEAF;
LEAF: if (`HPTW_WRITES_SUPPORTED & DAPageFault) NextWalkerState = UPDATE_PTE; LEAF: if (`HPTW_WRITES_SUPPORTED & DAPageFault) NextWalkerState = UPDATE_PTE;
else NextWalkerState = IDLE; else NextWalkerState = IDLE;
UPDATE_PTE: if(DCacheStallW) NextWalkerState = UPDATE_PTE; UPDATE_PTE: if(DCacheStallW) NextWalkerState = UPDATE_PTE;
else NextWalkerState = LEAF; else NextWalkerState = LEAF;
default: NextWalkerState = IDLE; // should never be reached default: NextWalkerState = IDLE; // should never be reached
endcase // case (WalkerState) endcase // case (WalkerState)
assign IgnoreRequestTLB = WalkerState == IDLE & TLBMiss; assign IgnoreRequestTLB = WalkerState == IDLE & TLBMiss;
assign SelHPTW = WalkerState != IDLE; assign SelHPTW = WalkerState != IDLE;
assign HPTWStall = (WalkerState != IDLE) | (WalkerState == IDLE & TLBMiss); assign HPTWStall = (WalkerState != IDLE) | (WalkerState == IDLE & TLBMiss);
assign ITLBMissOrDAFaultF = ITLBMissF | (`HPTW_WRITES_SUPPORTED & InstrDAPageFaultF); assign ITLBMissOrDAFaultF = ITLBMissF | (`HPTW_WRITES_SUPPORTED & InstrDAPageFaultF);
assign DTLBMissOrDAFaultM = DTLBMissM | (`HPTW_WRITES_SUPPORTED & DataDAPageFaultM); assign DTLBMissOrDAFaultM = DTLBMissM | (`HPTW_WRITES_SUPPORTED & DataDAPageFaultM);

View File

@ -6,6 +6,8 @@
// //
// Purpose: Memory management unit, including TLB, PMA, PMP // 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. // A component of the CORE-V-WALLY configurable RISC-V project.
// //
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University // Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
@ -27,18 +29,20 @@
`include "wally-config.vh" `include "wally-config.vh"
module mmu #(parameter TLB_ENTRIES = 8, IMMU = 0) ( module mmu #(parameter TLB_ENTRIES = 8, IMMU = 0) (
input logic clk, reset, input logic clk, reset,
input logic [`XLEN-1:0] SATP_REGW, // Current value of satp CSR (from privileged unit) 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 STATUS_MXR, // Status CSR: make executable page readable
input logic [1:0] STATUS_MPP, // previous machine privilege level input logic STATUS_SUM, // Status CSR: Supervisor access to user memory
input logic [1:0] PrivilegeModeW, // Current privilege level of the processeor input logic STATUS_MPRV, // Status CSR: modify machine privilege
input logic DisableTranslation, // virtual address translation disabled during D$ flush and HPTW walk that use physical addresses input logic [1:0] STATUS_MPP, // Status CSR: previous machine privilege level
input logic [`XLEN+1:0] VAdr, // virtual/physical address from IEU or physical address from HPTW input logic [1:0] PrivilegeModeW, // Current privilege level of the processeor
input logic [1:0] Size, // access size: 00 = 8 bits, 01 = 16 bits, 10 = 32 bits , 11 = 64 bits input logic DisableTranslation, // virtual address translation disabled during D$ flush and HPTW walk that use physical addresses
input logic [`XLEN-1:0] PTE, // page table entry input logic [`XLEN+1:0] VAdr, // virtual/physical address from IEU or physical address from HPTW
input logic [1:0] PageTypeWriteVal, // page type input logic [1:0] Size, // access size: 00 = 8 bits, 01 = 16 bits, 10 = 32 bits , 11 = 64 bits
input logic TLBWrite, // write TLB entry input logic [`XLEN-1:0] PTE, // page table entry
input logic TLBFlush, // Invalidate all TLB entries 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 [`PA_BITS-1:0] PhysicalAddress, // PAdr when no translation, or translated VAdr (TLBPAdr) when there is translation
output logic TLBMiss, // Miss TLB output logic TLBMiss, // Miss TLB
output logic Cacheable, // PMA indicates memory address is cachable 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 DAPageFault, // page fault due to setting dirty or access bit
output logic LoadMisalignedFaultM, StoreAmoMisalignedFaultM, // misaligned fault sources output logic LoadMisalignedFaultM, StoreAmoMisalignedFaultM, // misaligned fault sources
// PMA checker signals // 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 [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 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, .Cacheable, .Idempotent, .SelTIM,
.PMAInstrAccessFaultF, .PMALoadAccessFaultM, .PMAStoreAmoAccessFaultM); .PMAInstrAccessFaultF, .PMALoadAccessFaultM, .PMAStoreAmoAccessFaultM);
pmpchecker pmpchecker(.PhysicalAddress, .PrivilegeModeW, if (`PMP_ENTRIES > 0) // instantiate PMP
.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW, pmpchecker pmpchecker(.PhysicalAddress, .PrivilegeModeW,
.ExecuteAccessF, .WriteAccessM, .ReadAccessM, .PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW,
.PMPInstrAccessFaultF, .PMPLoadAccessFaultM, .PMPStoreAmoAccessFaultM); .ExecuteAccessF, .WriteAccessM, .ReadAccessM,
.PMPInstrAccessFaultF, .PMPLoadAccessFaultM, .PMPStoreAmoAccessFaultM);
else begin
assign PMPInstrAccessFaultF = 0;
assign PMPLoadAccessFaultM = 0;
assign PMPStoreAmoAccessFaultM = 0;
end
// Access faults // Access faults
// If TLB miss and translating we want to not have faults from the PMA and PMP checkers. // If TLB miss and translating we want to not have faults from the PMA and PMP checkers.

View File

@ -8,6 +8,8 @@
// the memory region accessed. // the memory region accessed.
// Can report illegal accesses to the trap unit and cause a fault. // 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. // A component of the CORE-V-WALLY configurable RISC-V project.
// //
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University // Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
@ -31,17 +33,20 @@
module pmachecker ( module pmachecker (
input logic [`PA_BITS-1:0] PhysicalAddress, input logic [`PA_BITS-1:0] PhysicalAddress,
input logic [1:0] Size, input logic [1:0] Size,
input logic AtomicAccessM, ExecuteAccessF, WriteAccessM, ReadAccessM, // *** atomicaccessM is unused but might want to stay in for future use. input logic AtomicAccessM, // Atomic access
output logic Cacheable, Idempotent, SelTIM, input logic ExecuteAccessF, // Execute access
output logic PMAInstrAccessFaultF, input logic WriteAccessM, // Write access
output logic PMALoadAccessFaultM, input logic ReadAccessM, // Read access
output logic PMAStoreAmoAccessFaultM output logic Cacheable, Idempotent, SelTIM,
output logic PMAInstrAccessFaultF,
output logic PMALoadAccessFaultM,
output logic PMAStoreAmoAccessFaultM
); );
logic PMAAccessFault; logic PMAAccessFault;
logic AccessRW, AccessRWX, AccessRX; logic AccessRW, AccessRWX, AccessRX;
logic [10:0] SelRegions; logic [10:0] SelRegions;
logic AtomicAllowed; logic AtomicAllowed;
// Determine what type of access is being made // Determine what type of access is being made
assign AccessRW = ReadAccessM | WriteAccessM; assign AccessRW = ReadAccessM | WriteAccessM;

View File

@ -10,6 +10,8 @@
// naturally aligned power-of-two region/NAPOT), then selects the // naturally aligned power-of-two region/NAPOT), then selects the
// output based on which mode is input. // 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. // A component of the CORE-V-WALLY configurable RISC-V project.
// //
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University // Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
@ -31,24 +33,24 @@
`include "wally-config.vh" `include "wally-config.vh"
module pmpadrdec ( module pmpadrdec (
input logic [`PA_BITS-1:0] PhysicalAddress, input logic [`PA_BITS-1:0] PhysicalAddress,
input logic [7:0] PMPCfg, input logic [7:0] PMPCfg,
input logic [`XLEN-1:0] PMPAdr, input logic [`XLEN-1:0] PMPAdr,
input logic PAgePMPAdrIn, input logic PAgePMPAdrIn,
output logic PAgePMPAdrOut, output logic PAgePMPAdrOut,
output logic Match, Active, output logic Match, Active,
output logic L, X, W, R output logic L, X, W, R
); );
localparam TOR = 2'b01; // define PMP addressing mode codes
localparam NA4 = 2'b10; localparam TOR = 2'b01;
localparam NAPOT = 2'b11; localparam NA4 = 2'b10;
localparam NAPOT = 2'b11;
logic TORMatch, NAMatch;
logic PAltPMPAdr;
logic [`PA_BITS-1:0] CurrentAdrFull;
logic [1:0] AdrMode;
logic TORMatch, NAMatch;
logic PAltPMPAdr;
logic [`PA_BITS-1:0] CurrentAdrFull;
logic [1:0] AdrMode;
assign AdrMode = PMPCfg[4:3]; assign AdrMode = PMPCfg[4:3];

View File

@ -9,6 +9,8 @@
// Can raise an access fault on illegal reads, writes, and instruction // Can raise an access fault on illegal reads, writes, and instruction
// fetches. // fetches.
// //
// Documentation: RISC-V System on Chip Design Chapter 8
//
// A component of the CORE-V-WALLY configurable RISC-V project. // A component of the CORE-V-WALLY configurable RISC-V project.
// //
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University // Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
@ -32,50 +34,43 @@
module pmpchecker ( module pmpchecker (
input logic [`PA_BITS-1:0] PhysicalAddress, input logic [`PA_BITS-1:0] PhysicalAddress,
input logic [1:0] PrivilegeModeW, 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 // 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 // `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, // 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` // 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, // keyword, the compiler warns us that it's interpreting the signal as a var,
// which we might not intend. // which we might not intend.
input var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0], 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 var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW [`PMP_ENTRIES-1:0],
input logic ExecuteAccessF, WriteAccessM, ReadAccessM, input logic ExecuteAccessF, WriteAccessM, ReadAccessM,
output logic PMPInstrAccessFaultF, output logic PMPInstrAccessFaultF,
output logic PMPLoadAccessFaultM, output logic PMPLoadAccessFaultM,
output logic PMPStoreAmoAccessFaultM output logic PMPStoreAmoAccessFaultM
); );
if (`PMP_ENTRIES > 0) begin: pmpchecker // Bit i is high when the address falls in PMP region i
// Bit i is high when the address falls in PMP region i logic EnforcePMP;
logic EnforcePMP; logic [`PMP_ENTRIES-1:0] Match; // physical address matches one of the pmp ranges
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] 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] 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] L, X, W, R; // PMP matches and has flag set logic [`PMP_ENTRIES-1:0] PAgePMPAdr; // for TOR PMP matching, PhysicalAddress > PMPAdr[i]
logic [`PMP_ENTRIES-1:0] PAgePMPAdr; // for TOR PMP matching, PhysicalAddress > PMPAdr[i]
pmpadrdec pmpadrdecs[`PMP_ENTRIES-1:0]( pmpadrdec pmpadrdecs[`PMP_ENTRIES-1:0](
.PhysicalAddress, .PhysicalAddress,
.PMPCfg(PMPCFG_ARRAY_REGW), .PMPCfg(PMPCFG_ARRAY_REGW),
.PMPAdr(PMPADDR_ARRAY_REGW), .PMPAdr(PMPADDR_ARRAY_REGW),
.PAgePMPAdrIn({PAgePMPAdr[`PMP_ENTRIES-2:0], 1'b1}), .PAgePMPAdrIn({PAgePMPAdr[`PMP_ENTRIES-2:0], 1'b1}),
.PAgePMPAdrOut(PAgePMPAdr), .PAgePMPAdrOut(PAgePMPAdr),
.Match, .Active, .L, .X, .W, .R); .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 // 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 EnforcePMP = (PrivilegeModeW == `M_MODE) ? |(L & FirstMatch) : |Active;
assign PMPInstrAccessFaultF = EnforcePMP & ExecuteAccessF & ~|(X & FirstMatch) ; assign PMPInstrAccessFaultF = EnforcePMP & ExecuteAccessF & ~|(X & FirstMatch) ;
assign PMPStoreAmoAccessFaultM = EnforcePMP & WriteAccessM & ~|(W & FirstMatch) ; assign PMPStoreAmoAccessFaultM = EnforcePMP & WriteAccessM & ~|(W & FirstMatch) ;
assign PMPLoadAccessFaultM = EnforcePMP & ReadAccessM & ~|(R & FirstMatch) ; assign PMPLoadAccessFaultM = EnforcePMP & ReadAccessM & ~|(R & FirstMatch) ;
end else begin: pmpchecker // no checker endmodule
assign PMPInstrAccessFaultF = 0;
assign PMPLoadAccessFaultM = 0;
assign PMPStoreAmoAccessFaultM = 0;
end
endmodule

View File

@ -9,6 +9,8 @@
// Purpose: Translation lookaside buffer // Purpose: Translation lookaside buffer
// Cache of virtural-to-physical address translations // 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. // A component of the CORE-V-WALLY configurable RISC-V project.
// //
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University // Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University

View File

@ -9,6 +9,8 @@
// Purpose: Stores virtual page numbers with cached translations. // Purpose: Stores virtual page numbers with cached translations.
// Determines whether a given virtual page number is in the TLB. // 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. // A component of the CORE-V-WALLY configurable RISC-V project.
// //
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University // Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University

View File

@ -9,6 +9,8 @@
// Purpose: CAM line for the translation lookaside buffer (TLB) // Purpose: CAM line for the translation lookaside buffer (TLB)
// Determines whether a virtual page number matches the stored key. // 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. // A component of the CORE-V-WALLY configurable RISC-V project.
// //
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University // Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University

View File

@ -6,6 +6,8 @@
// //
// Purpose: Control signals for TLB // 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. // A component of the CORE-V-WALLY configurable RISC-V project.
// //
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University // Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University

View File

@ -7,6 +7,8 @@
// Purpose: Implementation of bit pseudo least-recently-used algorithm for // Purpose: Implementation of bit pseudo least-recently-used algorithm for
// cache evictions. Outputs the index of the next entry to be written. // 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. // A component of the CORE-V-WALLY configurable RISC-V project.
// //
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University // Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University

View File

@ -9,6 +9,8 @@
// number with segments from the second, based on the page type. // 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. // 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. // A component of the CORE-V-WALLY configurable RISC-V project.
// //
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University // Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University

View File

@ -8,6 +8,8 @@
// Outputs the physical page number and access bits of the current // Outputs the physical page number and access bits of the current
// virtual address on a TLB hit. // 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. // A component of the CORE-V-WALLY configurable RISC-V project.
// //
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University // Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University

View File

@ -6,6 +6,8 @@
// //
// Purpose: One line of the RAM, with enabled flip-flop and logic for reading into distributed OR // 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. // A component of the CORE-V-WALLY configurable RISC-V project.
// //
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University // Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University

View File

@ -6,6 +6,8 @@
// //
// Purpose: Check for good upper address bits in RV64 mode // 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. // A component of the CORE-V-WALLY configurable RISC-V project.
// //
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University // Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University