forked from Github_Repos/cvw
Implement virtual memory protection
This commit is contained in:
parent
44da1488ff
commit
4bae666fa1
@ -47,6 +47,7 @@ module dmem (
|
||||
output logic SquashSCW,
|
||||
// faults
|
||||
input logic DataAccessFaultM,
|
||||
output logic DTLBLoadPageFaultM, DTLBStorePageFaultM,
|
||||
output logic LoadMisalignedFaultM, LoadAccessFaultM,
|
||||
output logic StoreMisalignedFaultM, StoreAccessFaultM,
|
||||
// TLB management
|
||||
@ -54,22 +55,25 @@ module dmem (
|
||||
input logic [`XLEN-1:0] PageTableEntryM,
|
||||
input logic [1:0] PageTypeM,
|
||||
input logic [`XLEN-1:0] SATP_REGW,
|
||||
input logic STATUS_MXR, STATUS_SUM,
|
||||
input logic DTLBWriteM, DTLBFlushM,
|
||||
output logic DTLBMissM, DTLBHitM
|
||||
);
|
||||
|
||||
logic MemAccessM; // Whether memory needs to be accessed
|
||||
logic SquashSCM;
|
||||
// *** needs to be sent to trap unit
|
||||
logic DTLBPageFaultM;
|
||||
|
||||
tlb #(3) dtlb(.TLBAccess(MemAccessM), .VirtualAddress(MemAdrM),
|
||||
tlb #(.ENTRY_BITS(3), .ITLB(0)) dtlb(.TLBAccessType(MemRWM), .VirtualAddress(MemAdrM),
|
||||
.PageTableEntryWrite(PageTableEntryM), .PageTypeWrite(PageTypeM),
|
||||
.TLBWrite(DTLBWriteM), .TLBFlush(DTLBFlushM),
|
||||
.PhysicalAddress(MemPAdrM), .TLBMiss(DTLBMissM),
|
||||
.TLBHit(DTLBHitM), .TLBPageFault(DTLBPageFaultM),
|
||||
.*);
|
||||
|
||||
// Specify which type of page fault is occurring
|
||||
assign DTLBLoadPageFaultM = DTLBPageFaultM & MemRWM[1];
|
||||
assign DTLBStorePageFaultM = DTLBPageFaultM & MemRWM[0];
|
||||
|
||||
// Determine if an Unaligned access is taking place
|
||||
always_comb
|
||||
case(Funct3M[1:0])
|
||||
@ -83,7 +87,6 @@ module dmem (
|
||||
// *** this is also the place to squash if the cache is hit
|
||||
assign MemReadM = MemRWM[1] & ~DataMisalignedM;
|
||||
assign MemWriteM = MemRWM[0] & ~DataMisalignedM && ~SquashSCM;
|
||||
assign MemAccessM = |MemRWM;
|
||||
|
||||
// Determine if address is valid
|
||||
assign LoadMisalignedFaultM = DataMisalignedM & MemRWM[1];
|
||||
|
@ -85,6 +85,9 @@ module ahblite (
|
||||
logic IReady, DReady;
|
||||
logic CaptureDataM;
|
||||
|
||||
// Describes type of access
|
||||
logic Atomic, Execute, Write, Read;
|
||||
|
||||
assign HCLK = clk;
|
||||
assign HRESETn = ~reset;
|
||||
|
||||
@ -109,15 +112,6 @@ module ahblite (
|
||||
else NextBusState = IDLE;
|
||||
MMUTRANSLATE: if (~HREADY) NextBusState = MMUTRANSLATE;
|
||||
else NextBusState = IDLE;
|
||||
// *** Could the MMUIDLE state just be the normal idle state?
|
||||
// Do we trust MMUTranslate to be high exactly when we need translation?
|
||||
// MMUIDLE: if (MMUTranslate)
|
||||
// NextBusState = MMUTRANSLATE;
|
||||
// else if (AtomicM[1]) NextBusState = ATOMICREAD;
|
||||
// else if (MemReadM) NextBusState = MEMREAD; // Memory has priority over instructions
|
||||
// else if (MemWriteM) NextBusState = MEMWRITE;
|
||||
// else if (InstrReadF) NextBusState = INSTRREAD;
|
||||
// else NextBusState = IDLE;
|
||||
ATOMICREAD: if (~HREADY) NextBusState = ATOMICREAD;
|
||||
else NextBusState = ATOMICWRITE;
|
||||
ATOMICWRITE: if (~HREADY) NextBusState = ATOMICWRITE;
|
||||
@ -148,6 +142,13 @@ module ahblite (
|
||||
assign #1 InstrStall = ((NextBusState == INSTRREAD) || (NextBusState == INSTRREADC) ||
|
||||
(NextBusState == MMUTRANSLATE) || (MMUTranslate && ~MMUTranslationComplete));
|
||||
|
||||
// Determine access type (important for determining whether to fault)
|
||||
assign Atomic = ((NextBusState == ATOMICREAD) || (NextBusState == ATOMICWRITE));
|
||||
assign Execute = ((NextBusState == INSTRREAD) || (NextBusState == INSTRREADC));
|
||||
assign Write = ((NextBusState == MEMWRITE) || (NextBusState == ATOMICWRITE));
|
||||
assign Read = ((NextBusState == MEMREAD) || (NextBusState == ATOMICREAD) ||
|
||||
(NextBusState == MMUTRANSLATE));
|
||||
|
||||
// bus outputs
|
||||
assign #1 GrantData = (NextBusState == MEMREAD) || (NextBusState == MEMWRITE) ||
|
||||
(NextBusState == ATOMICREAD) || (NextBusState == ATOMICWRITE);
|
||||
|
@ -61,7 +61,9 @@ module pagetablewalker (
|
||||
output logic MMUTranslationComplete,
|
||||
|
||||
// Faults
|
||||
output logic InstrPageFaultF, LoadPageFaultM, StorePageFaultM
|
||||
output logic WalkerInstrPageFaultF,
|
||||
output logic WalkerLoadPageFaultM,
|
||||
output logic WalkerStorePageFaultM
|
||||
);
|
||||
|
||||
// Internal signals
|
||||
@ -147,7 +149,6 @@ module pagetablewalker (
|
||||
|
||||
assign SvMode = SATP_REGW[31];
|
||||
|
||||
// *** Do we need a synchronizer here for walker to talk to ahblite?
|
||||
flopenl #(3) mmureg(HCLK, ~HRESETn, 1'b1, NextWalkerState, IDLE, WalkerState);
|
||||
|
||||
// State transition logic
|
||||
@ -193,9 +194,9 @@ module pagetablewalker (
|
||||
MMUTranslationComplete = '0;
|
||||
DTLBWriteM = '0;
|
||||
ITLBWriteF = '0;
|
||||
InstrPageFaultF = '0;
|
||||
LoadPageFaultM = '0;
|
||||
StorePageFaultM = '0;
|
||||
WalkerInstrPageFaultF = '0;
|
||||
WalkerLoadPageFaultM = '0;
|
||||
WalkerStorePageFaultM = '0;
|
||||
|
||||
case (NextWalkerState)
|
||||
LEVEL1: begin
|
||||
@ -216,9 +217,9 @@ module pagetablewalker (
|
||||
FAULT: begin
|
||||
TranslationPAdr = {CurrentPPN, VPN0, 2'b00};
|
||||
MMUTranslationComplete = '1;
|
||||
InstrPageFaultF = ~DTLBMissM;
|
||||
LoadPageFaultM = DTLBMissM && ~MemStore;
|
||||
StorePageFaultM = DTLBMissM && MemStore;
|
||||
WalkerInstrPageFaultF = ~DTLBMissM;
|
||||
WalkerLoadPageFaultM = DTLBMissM && ~MemStore;
|
||||
WalkerStorePageFaultM = DTLBMissM && MemStore;
|
||||
end
|
||||
default: begin
|
||||
// nothing
|
||||
@ -298,9 +299,9 @@ module pagetablewalker (
|
||||
MMUTranslationComplete = '0;
|
||||
DTLBWriteM = '0;
|
||||
ITLBWriteF = '0;
|
||||
InstrPageFaultF = '0;
|
||||
LoadPageFaultM = '0;
|
||||
StorePageFaultM = '0;
|
||||
WalkerInstrPageFaultF = '0;
|
||||
WalkerLoadPageFaultM = '0;
|
||||
WalkerStorePageFaultM = '0;
|
||||
|
||||
case (NextWalkerState)
|
||||
LEVEL2: begin
|
||||
@ -325,9 +326,9 @@ module pagetablewalker (
|
||||
FAULT: begin
|
||||
TranslationPAdr = {CurrentPPN, VPN0, 3'b000};
|
||||
MMUTranslationComplete = '1;
|
||||
InstrPageFaultF = ~DTLBMissM;
|
||||
LoadPageFaultM = DTLBMissM && ~MemStore;
|
||||
StorePageFaultM = DTLBMissM && MemStore;
|
||||
WalkerInstrPageFaultF = ~DTLBMissM;
|
||||
WalkerLoadPageFaultM = DTLBMissM && ~MemStore;
|
||||
WalkerStorePageFaultM = DTLBMissM && MemStore;
|
||||
end
|
||||
default: begin
|
||||
// nothing
|
||||
|
@ -54,6 +54,7 @@ module ifu (
|
||||
// output logic [`XLEN-1:0] PCLinkW,
|
||||
// Faults
|
||||
input logic IllegalBaseInstrFaultD,
|
||||
output logic ITLBInstrPageFaultF,
|
||||
output logic IllegalIEUInstrFaultD,
|
||||
output logic InstrMisalignedFaultM,
|
||||
output logic [`XLEN-1:0] InstrMisalignedAdrM,
|
||||
@ -62,6 +63,7 @@ module ifu (
|
||||
input logic [`XLEN-1:0] PageTableEntryF,
|
||||
input logic [1:0] PageTypeF,
|
||||
input logic [`XLEN-1:0] SATP_REGW,
|
||||
input logic STATUS_MXR, STATUS_SUM,
|
||||
input logic ITLBWriteF, ITLBFlushF,
|
||||
output logic ITLBMissF, ITLBHitF
|
||||
);
|
||||
@ -74,14 +76,12 @@ module ifu (
|
||||
logic CompressedF;
|
||||
logic [31:0] InstrRawD, InstrE, InstrW;
|
||||
logic [31:0] nop = 32'h00000013; // instruction for NOP
|
||||
// *** send this to the trap unit
|
||||
logic ITLBPageFaultF;
|
||||
|
||||
tlb #(3) itlb(.TLBAccess(1'b1), .VirtualAddress(PCF),
|
||||
tlb #(.ENTRY_BITS(3), .ITLB(1)) itlb(.TLBAccessType(2'b10), .VirtualAddress(PCF),
|
||||
.PageTableEntryWrite(PageTableEntryF), .PageTypeWrite(PageTypeF),
|
||||
.TLBWrite(ITLBWriteF), .TLBFlush(ITLBFlushF),
|
||||
.PhysicalAddress(PCPF), .TLBMiss(ITLBMissF),
|
||||
.TLBHit(ITLBHitF), .TLBPageFault(ITLBPageFaultF),
|
||||
.TLBHit(ITLBHitF), .TLBPageFault(ITLBInstrPageFaultF),
|
||||
.*);
|
||||
|
||||
// branch predictor signals
|
||||
|
@ -44,26 +44,26 @@
|
||||
* RSW(2) -- for OS
|
||||
*/
|
||||
|
||||
/* *** TODO:
|
||||
* - add LRU algorithm (select the write index based on which entry was used
|
||||
* least recently)
|
||||
*/
|
||||
|
||||
`include "wally-config.vh"
|
||||
`include "wally-constants.vh"
|
||||
|
||||
// The TLB will have 2**ENTRY_BITS total entries
|
||||
module tlb #(parameter ENTRY_BITS = 3) (
|
||||
module tlb #(parameter ENTRY_BITS = 3,
|
||||
parameter ITLB = 0) (
|
||||
input clk, reset,
|
||||
|
||||
// Current value of satp CSR (from privileged unit)
|
||||
input [`XLEN-1:0] SATP_REGW,
|
||||
input STATUS_MXR, STATUS_SUM,
|
||||
|
||||
// Current privilege level of the processeor
|
||||
input [1:0] PrivilegeModeW,
|
||||
|
||||
// High if the TLB is currently being accessed
|
||||
input TLBAccess,
|
||||
// 00 - TLB is not being accessed
|
||||
// 1x - TLB is accessed for a read (or an instruction)
|
||||
// x1 - TLB is accessed for a write
|
||||
// 11 - TLB is accessed for both read and write
|
||||
input [1:0] TLBAccessType,
|
||||
|
||||
// Virtual address input
|
||||
input [`XLEN-1:0] VirtualAddress,
|
||||
@ -87,17 +87,7 @@ module tlb #(parameter ENTRY_BITS = 3) (
|
||||
|
||||
logic SvMode;
|
||||
logic Translate;
|
||||
|
||||
generate
|
||||
if (`XLEN == 32) begin
|
||||
assign SvMode = SATP_REGW[31]; // *** change to an enum somehow?
|
||||
end else begin
|
||||
assign SvMode = SATP_REGW[63]; // currently just a boolean whether translation enabled
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// Whether translation should occur
|
||||
assign Translate = SvMode & (PrivilegeModeW != `M_MODE);
|
||||
logic TLBAccess, ReadAccess, WriteAccess;
|
||||
|
||||
// *** If we want to support multiple virtual memory modes (ie sv39 AND sv48),
|
||||
// we could have some muxes that control which parameters are current.
|
||||
@ -116,6 +106,9 @@ module tlb #(parameter ENTRY_BITS = 3) (
|
||||
logic [7:0] PTEAccessBits;
|
||||
logic [11:0] PageOffset;
|
||||
|
||||
// Useful PTE Control Bits
|
||||
logic PTE_U, PTE_X, PTE_W, PTE_R;
|
||||
|
||||
// Pattern location in the CAM and type of page hit
|
||||
logic [ENTRY_BITS-1:0] VPNIndex;
|
||||
logic [1:0] HitPageType;
|
||||
@ -123,18 +116,68 @@ module tlb #(parameter ENTRY_BITS = 3) (
|
||||
// Whether the virtual address has a match in the CAM
|
||||
logic CAMHit;
|
||||
|
||||
// Grab the sv bit from SATP
|
||||
generate
|
||||
if (`XLEN == 32) begin
|
||||
assign SvMode = SATP_REGW[31]; // *** change to an enum somehow?
|
||||
end else begin
|
||||
assign SvMode = SATP_REGW[63]; // currently just a boolean whether translation enabled
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// Whether translation should occur
|
||||
assign Translate = SvMode & (PrivilegeModeW != `M_MODE);
|
||||
|
||||
// Determine how the TLB is currently being used
|
||||
assign ReadAccess = TLBAccessType[1];
|
||||
assign WriteAccess = TLBAccessType[0];
|
||||
assign TLBAccess = ReadAccess || WriteAccess;
|
||||
|
||||
assign VirtualPageNumber = VirtualAddress[`VPN_BITS+11:12];
|
||||
assign PageOffset = VirtualAddress[11:0];
|
||||
|
||||
// Currently use random replacement algorithm
|
||||
// tlb_rand rdm(.*);
|
||||
// TLB entries are evicted according to the LRU algorithm
|
||||
tlb_lru lru(.*);
|
||||
|
||||
tlb_ram #(ENTRY_BITS) ram(.*);
|
||||
tlb_cam #(ENTRY_BITS, `VPN_BITS, `VPN_SEGMENT_BITS) cam(.*);
|
||||
tlb_ram #(ENTRY_BITS) tlb_ram(.*);
|
||||
tlb_cam #(ENTRY_BITS, `VPN_BITS, `VPN_SEGMENT_BITS) tlb_cam(.*);
|
||||
|
||||
// *** check whether access is allowed, otherwise fault
|
||||
assign TLBPageFault = 0; // *** temporary
|
||||
// unswizzle useful PTE bits
|
||||
assign PTE_U = PTEAccessBits[4];
|
||||
assign PTE_X = PTEAccessBits[3];
|
||||
assign PTE_W = PTEAccessBits[2];
|
||||
assign PTE_R = PTEAccessBits[1];
|
||||
|
||||
// Check whether the access is allowed, page faulting if not.
|
||||
// *** We might not have S mode.
|
||||
generate
|
||||
if (ITLB == 1) begin
|
||||
logic ImproperPrivilege;
|
||||
|
||||
// User mode may only execute user mode pages, and supervisor mode may
|
||||
// only execute non-user mode pages.
|
||||
assign ImproperPrivilege = ((PrivilegeModeW == `U_MODE) && ~PTE_U) ||
|
||||
((PrivilegeModeW == `S_MODE) && PTE_U);
|
||||
assign TLBPageFault = Translate && TLBHit && (ImproperPrivilege || ~PTE_X);
|
||||
end else begin
|
||||
logic ImproperPrivilege, InvalidRead, InvalidWrite;
|
||||
|
||||
// User mode may only load/store from user mode pages, and supervisor mode
|
||||
// may only access user mode pages when STATUS_SUM is low.
|
||||
assign ImproperPrivilege = ((PrivilegeModeW == `U_MODE) && ~PTE_U) ||
|
||||
((PrivilegeModeW == `S_MODE) && PTE_U && ~STATUS_SUM);
|
||||
// Check for read error. Reads are invalid when the page is not readable
|
||||
// (and executable pages are not readable) or when the page is neither
|
||||
// readable nor executable (and executable pages are readable).
|
||||
assign InvalidRead = ReadAccess &&
|
||||
((~STATUS_MXR && ~PTE_R) || (STATUS_MXR && ~PTE_R && PTE_X));
|
||||
// Check for write error. Writes are invalid when the page's write bit is
|
||||
// low.
|
||||
assign InvalidWrite = WriteAccess && ~PTE_W;
|
||||
assign TLBPageFault = Translate && TLBHit &&
|
||||
(ImproperPrivilege || InvalidRead || InvalidWrite);
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// *** Not the cleanest solution.
|
||||
// The highest segment of the physical page number has some extra bits
|
||||
@ -158,6 +201,8 @@ module tlb #(parameter ENTRY_BITS = 3) (
|
||||
// Output the hit physical address if translation is currently on.
|
||||
generate
|
||||
if (`XLEN == 32) begin
|
||||
// *** If we want rv32 to use the full 34 bit physical address space, this
|
||||
// must be changed
|
||||
mux2 #(`XLEN) addressmux(VirtualAddress, PhysicalAddressFull[31:0], Translate, PhysicalAddress);
|
||||
end else begin
|
||||
mux2 #(`XLEN) addressmux(VirtualAddress, {8'b0, PhysicalAddressFull}, Translate, PhysicalAddress);
|
||||
|
@ -49,6 +49,7 @@ module csr #(parameter
|
||||
output logic [`XLEN-1:0] SATP_REGW,
|
||||
output logic [11:0] MIP_REGW, MIE_REGW,
|
||||
output logic STATUS_MIE, STATUS_SIE,
|
||||
output logic STATUS_MXR, STATUS_SUM,
|
||||
input logic [4:0] SetFflagsM,
|
||||
output logic [2:0] FRM_REGW,
|
||||
// output logic [11:0] MIP_REGW, SIP_REGW, UIP_REGW, MIE_REGW, SIE_REGW, UIE_REGW,
|
||||
|
@ -36,10 +36,11 @@ module csrsr (
|
||||
output logic [`XLEN-1:0] MSTATUS_REGW, SSTATUS_REGW, USTATUS_REGW,
|
||||
output logic [1:0] STATUS_MPP,
|
||||
output logic STATUS_SPP, STATUS_TSR,
|
||||
output logic STATUS_MIE, STATUS_SIE
|
||||
output logic STATUS_MIE, STATUS_SIE,
|
||||
output logic STATUS_MXR, STATUS_SUM
|
||||
);
|
||||
|
||||
logic STATUS_SD, STATUS_TW, STATUS_TVM, STATUS_MXR, STATUS_SUM, STATUS_SUM_INT, STATUS_MPRV, STATUS_MPRV_INT;
|
||||
logic STATUS_SD, STATUS_TW, STATUS_TVM, STATUS_SUM_INT, STATUS_MPRV, STATUS_MPRV_INT;
|
||||
logic [1:0] STATUS_SXL, STATUS_UXL, STATUS_XS, STATUS_FS, STATUS_FS_INT, STATUS_MPP_NEXT;
|
||||
logic STATUS_MPIE, STATUS_SPIE, STATUS_UPIE, STATUS_UIE;
|
||||
|
||||
|
@ -40,7 +40,8 @@ module privileged (
|
||||
input logic InstrValidW, FloatRegWriteW, LoadStallD, BPPredWrongM,
|
||||
input logic [3:0] InstrClassM,
|
||||
input logic PrivilegedM,
|
||||
input logic InstrPageFaultF, LoadPageFaultM, StorePageFaultM,
|
||||
input logic ITLBInstrPageFaultF, DTLBLoadPageFaultM, DTLBStorePageFaultM,
|
||||
input logic WalkerInstrPageFaultF, WalkerLoadPageFaultM, WalkerStorePageFaultM,
|
||||
input logic InstrMisalignedFaultM, InstrAccessFaultF, IllegalIEUInstrFaultD,
|
||||
input logic LoadMisalignedFaultM, LoadAccessFaultM,
|
||||
input logic StoreMisalignedFaultM, StoreAccessFaultM,
|
||||
@ -49,6 +50,7 @@ module privileged (
|
||||
input logic [4:0] SetFflagsM,
|
||||
output logic [1:0] PrivilegeModeW,
|
||||
output logic [`XLEN-1:0] SATP_REGW,
|
||||
output logic STATUS_MXR, STATUS_SUM,
|
||||
output logic [2:0] FRM_REGW,
|
||||
input logic FlushD, FlushE, FlushM, StallD, StallW, StallE, StallM
|
||||
);
|
||||
@ -63,7 +65,8 @@ module privileged (
|
||||
logic uretM, sretM, mretM, ecallM, ebreakM, wfiM, sfencevmaM;
|
||||
logic IllegalCSRAccessM;
|
||||
logic IllegalIEUInstrFaultE, IllegalIEUInstrFaultM;
|
||||
logic InstrPageFaultD, InstrPageFaultE, InstrPageFaultM;
|
||||
logic LoadPageFaultM, StorePageFaultM;
|
||||
logic InstrPageFaultF, InstrPageFaultD, InstrPageFaultE, InstrPageFaultM;
|
||||
logic InstrAccessFaultD, InstrAccessFaultE, InstrAccessFaultM;
|
||||
logic IllegalInstrFaultM;
|
||||
|
||||
@ -123,11 +126,12 @@ module privileged (
|
||||
assign EcallFaultM = ecallM;
|
||||
assign ITLBFlushF = sfencevmaM;
|
||||
assign DTLBFlushM = sfencevmaM;
|
||||
// *** Page faults now driven by page table walker. Might need to make the
|
||||
// below signals ORs of a walker fault and a tlb fault if both of those come in
|
||||
// assign InstrPageFaultM = 0;
|
||||
// assign LoadPageFaultM = 0;
|
||||
// assign StorePageFaultM = 0;
|
||||
|
||||
// A page fault might occur because of insufficient privilege during a TLB
|
||||
// lookup or a improperly formatted page table during walking
|
||||
assign InstrPageFaultF = ITLBInstrPageFaultF || WalkerInstrPageFaultF;
|
||||
assign LoadPageFaultM = DTLBLoadPageFaultM || WalkerLoadPageFaultM;
|
||||
assign StorePageFaultM = DTLBStorePageFaultM || WalkerStorePageFaultM;
|
||||
|
||||
// pipeline fault signals
|
||||
flopenrc #(2) faultregD(clk, reset, FlushD, ~StallD,
|
||||
|
@ -77,7 +77,8 @@ module wallypipelinedhart (
|
||||
logic InstrMisalignedFaultM;
|
||||
logic DataMisalignedM;
|
||||
logic IllegalBaseInstrFaultD, IllegalIEUInstrFaultD;
|
||||
logic InstrPageFaultF, LoadPageFaultM, StorePageFaultM;
|
||||
logic ITLBInstrPageFaultF, DTLBLoadPageFaultM, DTLBStorePageFaultM;
|
||||
logic WalkerInstrPageFaultF, WalkerLoadPageFaultM, WalkerStorePageFaultM;
|
||||
logic LoadMisalignedFaultM, LoadAccessFaultM;
|
||||
logic StoreMisalignedFaultM, StoreAccessFaultM;
|
||||
logic [`XLEN-1:0] InstrMisalignedAdrM;
|
||||
@ -103,6 +104,7 @@ module wallypipelinedhart (
|
||||
logic ITLBMissF, ITLBHitF;
|
||||
logic DTLBMissM, DTLBHitM;
|
||||
logic [`XLEN-1:0] SATP_REGW;
|
||||
logic STATUS_MXR, STATUS_SUM;
|
||||
logic [1:0] PrivilegeModeW;
|
||||
|
||||
logic [`XLEN-1:0] PageTableEntryF, PageTableEntryM;
|
||||
|
Loading…
Reference in New Issue
Block a user