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:
David Harris 2021-07-06 15:29:42 -04:00
parent 412691df2d
commit 032c38b7e7
6 changed files with 45 additions and 31 deletions

View File

@ -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),

View File

@ -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),

View File

@ -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,14 +95,16 @@ 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

View File

@ -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

View File

@ -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

View File

@ -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