forked from Github_Repos/cvw
MMU produces page fault when upper bits aren't equal. Renamed input to MMU to be 'Address' and moved translation mux into MMU out of TLB
This commit is contained in:
parent
412691df2d
commit
032c38b7e7
@ -120,7 +120,7 @@ module ifu (
|
||||
endgenerate
|
||||
|
||||
mmu #(.TLB_ENTRIES(`ITLB_ENTRIES), .IMMU(1))
|
||||
immu(.VirtualAddress(PCF),
|
||||
immu(.Address(PCF),
|
||||
.Size(2'b10),
|
||||
.PTE(PageTableEntryF),
|
||||
.PageTypeWriteVal(PageTypeF),
|
||||
|
@ -115,10 +115,6 @@ module lsu
|
||||
STATE_PTW_DONE} statetype;
|
||||
statetype CurrState, NextState;
|
||||
|
||||
|
||||
logic PMPInstrAccessFaultF, PMAInstrAccessFaultF; // *** these are just so that the mmu has somewhere to put these outputs since they aren't used in dmem
|
||||
// *** if you're allowed to parameterize outputs/ inputs existence, these are an easy delete.
|
||||
|
||||
logic DTLBMissM;
|
||||
logic [`XLEN-1:0] PageTableEntryM;
|
||||
logic [1:0] PageTypeM;
|
||||
@ -216,7 +212,7 @@ module lsu
|
||||
|
||||
|
||||
mmu #(.TLB_ENTRIES(`DTLB_ENTRIES), .IMMU(0))
|
||||
dmmu(.VirtualAddress(MemAdrMtoLSU),
|
||||
dmmu(.Address(MemAdrMtoLSU),
|
||||
.Size(SizeToLSU[1:0]),
|
||||
.PTE(PageTableEntryM),
|
||||
.PageTypeWriteVal(PageTypeM),
|
||||
|
@ -44,8 +44,8 @@ module mmu #(parameter TLB_ENTRIES = 8, // nuber of TLB Entries
|
||||
// 11 - TLB is accessed for both read and write
|
||||
input logic DisableTranslation,
|
||||
|
||||
// Virtual address input
|
||||
input logic [`XLEN-1:0] VirtualAddress,
|
||||
// address input (could be virtual or physical)
|
||||
input logic [`XLEN-1:0] Address,
|
||||
input logic [1:0] Size, // 00 = 8 bits, 01 = 16 bits, 10 = 32 bits , 11 = 64 bits
|
||||
|
||||
// Controls for writing a new entry to the TLB
|
||||
@ -75,6 +75,8 @@ module mmu #(parameter TLB_ENTRIES = 8, // nuber of TLB Entries
|
||||
|
||||
);
|
||||
|
||||
logic [`PA_BITS-1:0] TLBPhysicalAddress;
|
||||
logic [`XLEN+1:0] AddressExt;
|
||||
logic PMPSquashBusAccess, PMASquashBusAccess;
|
||||
logic Cacheable, Idempotent, AtomicAllowed; // *** here so that the pmachecker has somewhere to put these outputs. *** I'm leaving them as outputs to pma checker, but I'm stopping them here.
|
||||
// Translation lookaside buffer
|
||||
@ -82,6 +84,7 @@ module mmu #(parameter TLB_ENTRIES = 8, // nuber of TLB Entries
|
||||
logic PMAInstrAccessFaultF, PMPInstrAccessFaultF;
|
||||
logic PMALoadAccessFaultM, PMPLoadAccessFaultM;
|
||||
logic PMAStoreAccessFaultM, PMPStoreAccessFaultM;
|
||||
logic Translate;
|
||||
|
||||
|
||||
// only instantiate TLB if Virtual Memory is supported
|
||||
@ -92,15 +95,17 @@ module mmu #(parameter TLB_ENTRIES = 8, // nuber of TLB Entries
|
||||
assign WriteAccess = WriteAccessM;
|
||||
tlb #(.TLB_ENTRIES(TLB_ENTRIES), .ITLB(IMMU)) tlb(.*);
|
||||
end else begin // just pass address through as physical
|
||||
logic [`XLEN+1:0] VAExt;
|
||||
assign VAExt = {2'b00, VirtualAddress}; // extend length of virtual address if necessary for RV32
|
||||
assign PhysicalAddress = VAExt[`PA_BITS-1:0];
|
||||
assign Translate = 0;
|
||||
assign TLBMiss = 0;
|
||||
assign TLBHit = 1;
|
||||
assign TLBHit = 1; // *** is this necessary
|
||||
assign TLBPageFault = 0;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// If translation is occuring, select translated physical address from TLB
|
||||
assign AddressExt = {2'b00, Address}; // extend length of virtual address if necessary for RV32
|
||||
mux2 #(`PA_BITS) addressmux(AddressExt[`PA_BITS-1:0], TLBPhysicalAddress, Translate, PhysicalAddress);
|
||||
|
||||
///////////////////////////////////////////
|
||||
// Check physical memory accesses
|
||||
///////////////////////////////////////////
|
||||
|
@ -68,8 +68,8 @@ module tlb #(parameter TLB_ENTRIES = 8,
|
||||
input logic ReadAccess, WriteAccess,
|
||||
input logic DisableTranslation,
|
||||
|
||||
// Virtual address input
|
||||
input logic [`XLEN-1:0] VirtualAddress,
|
||||
// address input before translation (could be physical or virtual)
|
||||
input logic [`XLEN-1:0] Address,
|
||||
|
||||
// Controls for writing a new entry to the TLB
|
||||
input logic [`XLEN-1:0] PTE,
|
||||
@ -80,16 +80,15 @@ module tlb #(parameter TLB_ENTRIES = 8,
|
||||
input logic TLBFlush,
|
||||
|
||||
// Physical address outputs
|
||||
output logic [`PA_BITS-1:0] PhysicalAddress,
|
||||
output logic [`PA_BITS-1:0] TLBPhysicalAddress,
|
||||
output logic TLBMiss,
|
||||
output logic TLBHit,
|
||||
output logic Translate,
|
||||
|
||||
// Faults
|
||||
output logic TLBPageFault
|
||||
);
|
||||
|
||||
logic Translate;
|
||||
|
||||
// Store current virtual memory mode (SV32, SV39, SV48, ect...)
|
||||
//logic [`SVMODE_BITS-1:0] SvMode;
|
||||
logic [1:0] EffectivePrivilegeMode; // privilege mode, possibly modified by MPRV
|
||||
@ -99,8 +98,7 @@ module tlb #(parameter TLB_ENTRIES = 8,
|
||||
// Sections of the virtual and physical addresses
|
||||
logic [`VPN_BITS-1:0] VirtualPageNumber;
|
||||
logic [`PPN_BITS-1:0] PhysicalPageNumber, PhysicalPageNumberMixed;
|
||||
logic [`PA_BITS-1:0] PhysicalAddressFull;
|
||||
logic [`XLEN+1:0] VAExt;
|
||||
logic [`XLEN+1:0] AddressExt;
|
||||
|
||||
// Sections of the page table entry
|
||||
logic [7:0] PTEAccessBits;
|
||||
@ -116,7 +114,7 @@ module tlb #(parameter TLB_ENTRIES = 8,
|
||||
assign ASID = SATP_REGW[`ASID_BASE+`ASID_BITS-1:`ASID_BASE];
|
||||
|
||||
// Determine whether to write TLB
|
||||
assign VirtualPageNumber = VirtualAddress[`VPN_BITS+11:12];
|
||||
assign VirtualPageNumber = Address[`VPN_BITS+11:12];
|
||||
|
||||
tlbcontrol tlbcontrol(.*);
|
||||
|
||||
@ -134,7 +132,5 @@ module tlb #(parameter TLB_ENTRIES = 8,
|
||||
|
||||
// Output the hit physical address if translation is currently on.
|
||||
// Provide physical address of zero if not TLBHits, to cause segmentation error if miss somehow percolated through signal
|
||||
assign VAExt = {2'b00, VirtualAddress}; // extend length of virtual address if necessary for RV32
|
||||
mux2 #(`PA_BITS) hitmux('0, {PhysicalPageNumberMixed, VirtualAddress[11:0]}, TLBHit, PhysicalAddressFull); // set PA to 0 if TLB misses, to cause segementation error if this miss somehow passes through system
|
||||
mux2 #(`PA_BITS) addressmux(VAExt[`PA_BITS-1:0], PhysicalAddressFull, Translate, PhysicalAddress);
|
||||
mux2 #(`PA_BITS) hitmux('0, {PhysicalPageNumberMixed, Address[11:0]}, TLBHit, TLBPhysicalAddress); // set PA to 0 if TLB misses, to cause segementation error if this miss somehow passes through system
|
||||
endmodule
|
||||
|
@ -32,6 +32,7 @@ module tlbcontrol #(parameter TLB_ENTRIES = 8,
|
||||
|
||||
// Current value of satp CSR (from privileged unit)
|
||||
input logic [`XLEN-1:0] SATP_REGW,
|
||||
input logic [`XLEN-1:0] Address,
|
||||
input logic STATUS_MXR, STATUS_SUM, STATUS_MPRV,
|
||||
input logic [1:0] STATUS_MPP,
|
||||
input logic [1:0] PrivilegeModeW, // Current privilege level of the processeor
|
||||
@ -58,7 +59,8 @@ module tlbcontrol #(parameter TLB_ENTRIES = 8,
|
||||
logic [`SVMODE_BITS-1:0] SVMode;
|
||||
|
||||
logic PTE_D, PTE_A, PTE_U, PTE_X, PTE_W, PTE_R; // Useful PTE Control Bits
|
||||
logic DAFault;
|
||||
logic UpperBitsUnequalPageFault;
|
||||
logic DAPageFault;
|
||||
logic TLBAccess;
|
||||
|
||||
// Grab the sv mode from SATP and determine whether translation should occur
|
||||
@ -66,13 +68,27 @@ module tlbcontrol #(parameter TLB_ENTRIES = 8,
|
||||
assign EffectivePrivilegeMode = (ITLB == 1) ? PrivilegeModeW : (STATUS_MPRV ? STATUS_MPP : PrivilegeModeW); // DTLB uses MPP mode when MPRV is 1
|
||||
assign Translate = (SVMode != `NO_TRANSLATE) & (EffectivePrivilegeMode != `M_MODE) & ~ DisableTranslation;
|
||||
generate
|
||||
if (`XLEN==64) assign SV39Mode = (SVMode == `SV39);
|
||||
else assign SV39Mode = 0;
|
||||
if (`XLEN==64) begin
|
||||
assign SV39Mode = (SVMode == `SV39);
|
||||
// generate page fault if upper bits aren't all the same
|
||||
logic UpperOnes39, UpperZeros39, UpperOnes48, UpperZeros48;
|
||||
assign UpperOnes39 = &(Address[63:39]);
|
||||
assign UpperZeros39 = ~|(Address[63:39]);
|
||||
assign UpperOnes48 = &(Address[63:48]);
|
||||
assign UpperZeros48 = ~|(Address[63:48]);
|
||||
assign UpperBitsUnequalPageFault = SV39Mode ? (Address[38] ? UpperOnes39 : UpperZeros39) : (Address[47] ? UpperOnes48 : UpperZeros48);
|
||||
end else begin
|
||||
assign SV39Mode = 0;
|
||||
assign UpperBitsUnequalPageFault = 0;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// Determine whether TLB is being used
|
||||
assign TLBAccess = ReadAccess || WriteAccess;
|
||||
|
||||
// Check whether upper bits of virtual addresss are all equal
|
||||
|
||||
|
||||
// unswizzle useful PTE bits
|
||||
assign {PTE_D, PTE_A} = PTEAccessBits[7:6];
|
||||
assign {PTE_U, PTE_X, PTE_W, PTE_R} = PTEAccessBits[4:1];
|
||||
@ -87,8 +103,8 @@ module tlbcontrol #(parameter TLB_ENTRIES = 8,
|
||||
assign ImproperPrivilege = ((EffectivePrivilegeMode == `U_MODE) && ~PTE_U) ||
|
||||
((EffectivePrivilegeMode == `S_MODE) && PTE_U);
|
||||
// fault for software handling if access bit is off
|
||||
assign DAFault = ~PTE_A;
|
||||
assign TLBPageFault = Translate && TLBHit && (ImproperPrivilege || ~PTE_X || DAFault);
|
||||
assign DAPageFault = ~PTE_A;
|
||||
assign TLBPageFault = Translate && TLBHit && (ImproperPrivilege || ~PTE_X || DAPageFault || UpperBitsUnequalPageFault);
|
||||
end else begin
|
||||
logic ImproperPrivilege, InvalidRead, InvalidWrite;
|
||||
|
||||
@ -104,8 +120,8 @@ module tlbcontrol #(parameter TLB_ENTRIES = 8,
|
||||
// low.
|
||||
assign InvalidWrite = WriteAccess && ~PTE_W;
|
||||
// Fault for software handling if access bit is off or writing a page with dirty bit off
|
||||
assign DAFault = ~PTE_A | WriteAccess & ~PTE_D;
|
||||
assign TLBPageFault = Translate && TLBHit && (ImproperPrivilege || InvalidRead || InvalidWrite || DAFault);
|
||||
assign DAPageFault = ~PTE_A | WriteAccess & ~PTE_D;
|
||||
assign TLBPageFault = Translate && TLBHit && (ImproperPrivilege || InvalidRead || InvalidWrite || DAPageFault || UpperBitsUnequalPageFault);
|
||||
end
|
||||
endgenerate
|
||||
|
||||
|
@ -125,7 +125,8 @@ module csrsr (
|
||||
STATUS_SIE <= #1 0; //`S_SUPPORTED;
|
||||
STATUS_UIE <= #1 0; //`U_SUPPORTED;
|
||||
end else if (~StallW) begin
|
||||
if (FloatRegWriteW) STATUS_FS_INT <= #12'b11; // mark Float State dirty *** this should happen in M stage, be part of if/else
|
||||
if (FloatRegWriteW) STATUS_FS_INT <= #12'b11; // mark Float State dirty *** this should happen in M stage, be part of if/else;
|
||||
// *** also, FS_INT needs to be set when any bits of the fcsr are written
|
||||
if (TrapM) begin
|
||||
// Update interrupt enables per Privileged Spec p. 21
|
||||
// y = PrivilegeModeW
|
||||
|
Loading…
Reference in New Issue
Block a user