mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
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
|
endgenerate
|
||||||
|
|
||||||
mmu #(.TLB_ENTRIES(`ITLB_ENTRIES), .IMMU(1))
|
mmu #(.TLB_ENTRIES(`ITLB_ENTRIES), .IMMU(1))
|
||||||
immu(.VirtualAddress(PCF),
|
immu(.Address(PCF),
|
||||||
.Size(2'b10),
|
.Size(2'b10),
|
||||||
.PTE(PageTableEntryF),
|
.PTE(PageTableEntryF),
|
||||||
.PageTypeWriteVal(PageTypeF),
|
.PageTypeWriteVal(PageTypeF),
|
||||||
|
@ -115,10 +115,6 @@ module lsu
|
|||||||
STATE_PTW_DONE} statetype;
|
STATE_PTW_DONE} statetype;
|
||||||
statetype CurrState, NextState;
|
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 DTLBMissM;
|
||||||
logic [`XLEN-1:0] PageTableEntryM;
|
logic [`XLEN-1:0] PageTableEntryM;
|
||||||
logic [1:0] PageTypeM;
|
logic [1:0] PageTypeM;
|
||||||
@ -216,7 +212,7 @@ module lsu
|
|||||||
|
|
||||||
|
|
||||||
mmu #(.TLB_ENTRIES(`DTLB_ENTRIES), .IMMU(0))
|
mmu #(.TLB_ENTRIES(`DTLB_ENTRIES), .IMMU(0))
|
||||||
dmmu(.VirtualAddress(MemAdrMtoLSU),
|
dmmu(.Address(MemAdrMtoLSU),
|
||||||
.Size(SizeToLSU[1:0]),
|
.Size(SizeToLSU[1:0]),
|
||||||
.PTE(PageTableEntryM),
|
.PTE(PageTableEntryM),
|
||||||
.PageTypeWriteVal(PageTypeM),
|
.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
|
// 11 - TLB is accessed for both read and write
|
||||||
input logic DisableTranslation,
|
input logic DisableTranslation,
|
||||||
|
|
||||||
// Virtual address input
|
// address input (could be virtual or physical)
|
||||||
input logic [`XLEN-1:0] VirtualAddress,
|
input logic [`XLEN-1:0] Address,
|
||||||
input logic [1:0] Size, // 00 = 8 bits, 01 = 16 bits, 10 = 32 bits , 11 = 64 bits
|
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
|
// 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 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.
|
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
|
// Translation lookaside buffer
|
||||||
@ -82,6 +84,7 @@ module mmu #(parameter TLB_ENTRIES = 8, // nuber of TLB Entries
|
|||||||
logic PMAInstrAccessFaultF, PMPInstrAccessFaultF;
|
logic PMAInstrAccessFaultF, PMPInstrAccessFaultF;
|
||||||
logic PMALoadAccessFaultM, PMPLoadAccessFaultM;
|
logic PMALoadAccessFaultM, PMPLoadAccessFaultM;
|
||||||
logic PMAStoreAccessFaultM, PMPStoreAccessFaultM;
|
logic PMAStoreAccessFaultM, PMPStoreAccessFaultM;
|
||||||
|
logic Translate;
|
||||||
|
|
||||||
|
|
||||||
// only instantiate TLB if Virtual Memory is supported
|
// 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;
|
assign WriteAccess = WriteAccessM;
|
||||||
tlb #(.TLB_ENTRIES(TLB_ENTRIES), .ITLB(IMMU)) tlb(.*);
|
tlb #(.TLB_ENTRIES(TLB_ENTRIES), .ITLB(IMMU)) tlb(.*);
|
||||||
end else begin // just pass address through as physical
|
end else begin // just pass address through as physical
|
||||||
logic [`XLEN+1:0] VAExt;
|
assign Translate = 0;
|
||||||
assign VAExt = {2'b00, VirtualAddress}; // extend length of virtual address if necessary for RV32
|
|
||||||
assign PhysicalAddress = VAExt[`PA_BITS-1:0];
|
|
||||||
assign TLBMiss = 0;
|
assign TLBMiss = 0;
|
||||||
assign TLBHit = 1;
|
assign TLBHit = 1; // *** is this necessary
|
||||||
assign TLBPageFault = 0;
|
assign TLBPageFault = 0;
|
||||||
end
|
end
|
||||||
endgenerate
|
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
|
// Check physical memory accesses
|
||||||
///////////////////////////////////////////
|
///////////////////////////////////////////
|
||||||
|
@ -68,8 +68,8 @@ module tlb #(parameter TLB_ENTRIES = 8,
|
|||||||
input logic ReadAccess, WriteAccess,
|
input logic ReadAccess, WriteAccess,
|
||||||
input logic DisableTranslation,
|
input logic DisableTranslation,
|
||||||
|
|
||||||
// Virtual address input
|
// address input before translation (could be physical or virtual)
|
||||||
input logic [`XLEN-1:0] VirtualAddress,
|
input logic [`XLEN-1:0] Address,
|
||||||
|
|
||||||
// Controls for writing a new entry to the TLB
|
// Controls for writing a new entry to the TLB
|
||||||
input logic [`XLEN-1:0] PTE,
|
input logic [`XLEN-1:0] PTE,
|
||||||
@ -80,16 +80,15 @@ module tlb #(parameter TLB_ENTRIES = 8,
|
|||||||
input logic TLBFlush,
|
input logic TLBFlush,
|
||||||
|
|
||||||
// Physical address outputs
|
// Physical address outputs
|
||||||
output logic [`PA_BITS-1:0] PhysicalAddress,
|
output logic [`PA_BITS-1:0] TLBPhysicalAddress,
|
||||||
output logic TLBMiss,
|
output logic TLBMiss,
|
||||||
output logic TLBHit,
|
output logic TLBHit,
|
||||||
|
output logic Translate,
|
||||||
|
|
||||||
// Faults
|
// Faults
|
||||||
output logic TLBPageFault
|
output logic TLBPageFault
|
||||||
);
|
);
|
||||||
|
|
||||||
logic Translate;
|
|
||||||
|
|
||||||
// Store current virtual memory mode (SV32, SV39, SV48, ect...)
|
// Store current virtual memory mode (SV32, SV39, SV48, ect...)
|
||||||
//logic [`SVMODE_BITS-1:0] SvMode;
|
//logic [`SVMODE_BITS-1:0] SvMode;
|
||||||
logic [1:0] EffectivePrivilegeMode; // privilege mode, possibly modified by MPRV
|
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
|
// Sections of the virtual and physical addresses
|
||||||
logic [`VPN_BITS-1:0] VirtualPageNumber;
|
logic [`VPN_BITS-1:0] VirtualPageNumber;
|
||||||
logic [`PPN_BITS-1:0] PhysicalPageNumber, PhysicalPageNumberMixed;
|
logic [`PPN_BITS-1:0] PhysicalPageNumber, PhysicalPageNumberMixed;
|
||||||
logic [`PA_BITS-1:0] PhysicalAddressFull;
|
logic [`XLEN+1:0] AddressExt;
|
||||||
logic [`XLEN+1:0] VAExt;
|
|
||||||
|
|
||||||
// Sections of the page table entry
|
// Sections of the page table entry
|
||||||
logic [7:0] PTEAccessBits;
|
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];
|
assign ASID = SATP_REGW[`ASID_BASE+`ASID_BITS-1:`ASID_BASE];
|
||||||
|
|
||||||
// Determine whether to write TLB
|
// Determine whether to write TLB
|
||||||
assign VirtualPageNumber = VirtualAddress[`VPN_BITS+11:12];
|
assign VirtualPageNumber = Address[`VPN_BITS+11:12];
|
||||||
|
|
||||||
tlbcontrol tlbcontrol(.*);
|
tlbcontrol tlbcontrol(.*);
|
||||||
|
|
||||||
@ -134,7 +132,5 @@ module tlb #(parameter TLB_ENTRIES = 8,
|
|||||||
|
|
||||||
// Output the hit physical address if translation is currently on.
|
// 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
|
// 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, Address[11:0]}, TLBHit, TLBPhysicalAddress); // set PA to 0 if TLB misses, to cause segementation error if this miss somehow passes through system
|
||||||
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);
|
|
||||||
endmodule
|
endmodule
|
||||||
|
@ -32,6 +32,7 @@ module tlbcontrol #(parameter TLB_ENTRIES = 8,
|
|||||||
|
|
||||||
// Current value of satp CSR (from privileged unit)
|
// Current value of satp CSR (from privileged unit)
|
||||||
input logic [`XLEN-1:0] SATP_REGW,
|
input logic [`XLEN-1:0] SATP_REGW,
|
||||||
|
input logic [`XLEN-1:0] Address,
|
||||||
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, // Current privilege level of the processeor
|
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 [`SVMODE_BITS-1:0] SVMode;
|
||||||
|
|
||||||
logic PTE_D, PTE_A, PTE_U, PTE_X, PTE_W, PTE_R; // Useful PTE Control Bits
|
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;
|
logic TLBAccess;
|
||||||
|
|
||||||
// Grab the sv mode from SATP and determine whether translation should occur
|
// 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 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;
|
assign Translate = (SVMode != `NO_TRANSLATE) & (EffectivePrivilegeMode != `M_MODE) & ~ DisableTranslation;
|
||||||
generate
|
generate
|
||||||
if (`XLEN==64) assign SV39Mode = (SVMode == `SV39);
|
if (`XLEN==64) begin
|
||||||
else assign SV39Mode = 0;
|
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
|
endgenerate
|
||||||
|
|
||||||
// Determine whether TLB is being used
|
// Determine whether TLB is being used
|
||||||
assign TLBAccess = ReadAccess || WriteAccess;
|
assign TLBAccess = ReadAccess || WriteAccess;
|
||||||
|
|
||||||
|
// Check whether upper bits of virtual addresss are all equal
|
||||||
|
|
||||||
|
|
||||||
// unswizzle useful PTE bits
|
// unswizzle useful PTE bits
|
||||||
assign {PTE_D, PTE_A} = PTEAccessBits[7:6];
|
assign {PTE_D, PTE_A} = PTEAccessBits[7:6];
|
||||||
assign {PTE_U, PTE_X, PTE_W, PTE_R} = PTEAccessBits[4:1];
|
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) ||
|
assign ImproperPrivilege = ((EffectivePrivilegeMode == `U_MODE) && ~PTE_U) ||
|
||||||
((EffectivePrivilegeMode == `S_MODE) && PTE_U);
|
((EffectivePrivilegeMode == `S_MODE) && PTE_U);
|
||||||
// fault for software handling if access bit is off
|
// fault for software handling if access bit is off
|
||||||
assign DAFault = ~PTE_A;
|
assign DAPageFault = ~PTE_A;
|
||||||
assign TLBPageFault = Translate && TLBHit && (ImproperPrivilege || ~PTE_X || DAFault);
|
assign TLBPageFault = Translate && TLBHit && (ImproperPrivilege || ~PTE_X || DAPageFault || UpperBitsUnequalPageFault);
|
||||||
end else begin
|
end else begin
|
||||||
logic ImproperPrivilege, InvalidRead, InvalidWrite;
|
logic ImproperPrivilege, InvalidRead, InvalidWrite;
|
||||||
|
|
||||||
@ -104,8 +120,8 @@ module tlbcontrol #(parameter TLB_ENTRIES = 8,
|
|||||||
// low.
|
// low.
|
||||||
assign InvalidWrite = WriteAccess && ~PTE_W;
|
assign InvalidWrite = WriteAccess && ~PTE_W;
|
||||||
// Fault for software handling if access bit is off or writing a page with dirty bit off
|
// 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 DAPageFault = ~PTE_A | WriteAccess & ~PTE_D;
|
||||||
assign TLBPageFault = Translate && TLBHit && (ImproperPrivilege || InvalidRead || InvalidWrite || DAFault);
|
assign TLBPageFault = Translate && TLBHit && (ImproperPrivilege || InvalidRead || InvalidWrite || DAPageFault || UpperBitsUnequalPageFault);
|
||||||
end
|
end
|
||||||
endgenerate
|
endgenerate
|
||||||
|
|
||||||
|
@ -125,7 +125,8 @@ module csrsr (
|
|||||||
STATUS_SIE <= #1 0; //`S_SUPPORTED;
|
STATUS_SIE <= #1 0; //`S_SUPPORTED;
|
||||||
STATUS_UIE <= #1 0; //`U_SUPPORTED;
|
STATUS_UIE <= #1 0; //`U_SUPPORTED;
|
||||||
end else if (~StallW) begin
|
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
|
if (TrapM) begin
|
||||||
// Update interrupt enables per Privileged Spec p. 21
|
// Update interrupt enables per Privileged Spec p. 21
|
||||||
// y = PrivilegeModeW
|
// y = PrivilegeModeW
|
||||||
|
Loading…
Reference in New Issue
Block a user