mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Initial implementation of SVNAPOT and SVPBMT does not break regression
This commit is contained in:
parent
9f44241d0f
commit
c07ad03f9d
@ -85,6 +85,7 @@ module ifu import cvw::*; #(parameter cvw_t P) (
|
|||||||
input logic STATUS_SUM, // Status CSR: Supervisor access to user memory
|
input logic STATUS_SUM, // Status CSR: Supervisor access to user memory
|
||||||
input logic STATUS_MPRV, // Status CSR: modify machine privilege
|
input logic STATUS_MPRV, // Status CSR: modify machine privilege
|
||||||
input logic [1:0] STATUS_MPP, // Status CSR: previous machine privilege level
|
input logic [1:0] STATUS_MPP, // Status CSR: previous machine privilege level
|
||||||
|
input logic ENVCFG_PBMTE, // Page-based memory types enabled
|
||||||
input logic sfencevmaM, // Virtual memory address fence, invalidate TLB entries
|
input logic sfencevmaM, // Virtual memory address fence, invalidate TLB entries
|
||||||
output logic ITLBMissF, // ITLB miss causes HPTW (hardware pagetable walker) walk
|
output logic ITLBMissF, // ITLB miss causes HPTW (hardware pagetable walker) walk
|
||||||
output logic InstrUpdateDAF, // ITLB hit needs to update dirty or access bits
|
output logic InstrUpdateDAF, // ITLB hit needs to update dirty or access bits
|
||||||
@ -170,7 +171,7 @@ module ifu import cvw::*; #(parameter cvw_t P) (
|
|||||||
assign TLBFlush = sfencevmaM & ~StallMQ;
|
assign TLBFlush = sfencevmaM & ~StallMQ;
|
||||||
|
|
||||||
mmu #(.P(P), .TLB_ENTRIES(P.ITLB_ENTRIES), .IMMU(1))
|
mmu #(.P(P), .TLB_ENTRIES(P.ITLB_ENTRIES), .IMMU(1))
|
||||||
immu(.clk, .reset, .SATP_REGW, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP,
|
immu(.clk, .reset, .SATP_REGW, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .ENVCFG_PBMTE,
|
||||||
.PrivilegeModeW, .DisableTranslation(1'b0),
|
.PrivilegeModeW, .DisableTranslation(1'b0),
|
||||||
.VAdr(PCFExt),
|
.VAdr(PCFExt),
|
||||||
.Size(2'b10),
|
.Size(2'b10),
|
||||||
|
@ -80,6 +80,7 @@ module lsu import cvw::*; #(parameter cvw_t P) (
|
|||||||
input logic [P.XLEN-1:0] SATP_REGW, // SATP (supervisor address translation and protection) CSR
|
input logic [P.XLEN-1:0] SATP_REGW, // SATP (supervisor address translation and protection) CSR
|
||||||
input logic STATUS_MXR, STATUS_SUM, STATUS_MPRV, // STATUS CSR bits: make executable readable, supervisor user memory, machine privilege
|
input logic STATUS_MXR, STATUS_SUM, STATUS_MPRV, // STATUS CSR bits: make executable readable, supervisor user memory, machine privilege
|
||||||
input logic [1:0] STATUS_MPP, // Machine previous privilege mode
|
input logic [1:0] STATUS_MPP, // Machine previous privilege mode
|
||||||
|
input logic ENVCFG_PBMTE, // Page-based memory types enabled
|
||||||
input logic [P.XLEN-1:0] PCSpillF, // Fetch PC
|
input logic [P.XLEN-1:0] PCSpillF, // Fetch PC
|
||||||
input logic ITLBMissF, // ITLB miss causes HPTW (hardware pagetable walker) walk
|
input logic ITLBMissF, // ITLB miss causes HPTW (hardware pagetable walker) walk
|
||||||
input logic InstrUpdateDAF, // ITLB hit needs to update dirty or access bits
|
input logic InstrUpdateDAF, // ITLB hit needs to update dirty or access bits
|
||||||
@ -189,7 +190,7 @@ module lsu import cvw::*; #(parameter cvw_t P) (
|
|||||||
assign DisableTranslation = SelHPTW | FlushDCacheM;
|
assign DisableTranslation = SelHPTW | FlushDCacheM;
|
||||||
assign WriteAccessM = PreLSURWM[0] | (|CMOpM);
|
assign WriteAccessM = PreLSURWM[0] | (|CMOpM);
|
||||||
mmu #(.P(P), .TLB_ENTRIES(P.DTLB_ENTRIES), .IMMU(0))
|
mmu #(.P(P), .TLB_ENTRIES(P.DTLB_ENTRIES), .IMMU(0))
|
||||||
dmmu(.clk, .reset, .SATP_REGW, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP,
|
dmmu(.clk, .reset, .SATP_REGW, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .ENVCFG_PBMTE,
|
||||||
.PrivilegeModeW, .DisableTranslation, .VAdr(IHAdrM), .Size(LSUFunct3M[1:0]),
|
.PrivilegeModeW, .DisableTranslation, .VAdr(IHAdrM), .Size(LSUFunct3M[1:0]),
|
||||||
.PTE, .PageTypeWriteVal(PageType), .TLBWrite(DTLBWriteM), .TLBFlush(sfencevmaM),
|
.PTE, .PageTypeWriteVal(PageType), .TLBWrite(DTLBWriteM), .TLBFlush(sfencevmaM),
|
||||||
.PhysicalAddress(PAdrM), .TLBMiss(DTLBMissM), .Cacheable(CacheableM), .Idempotent(), .SelTIM(SelDTIM),
|
.PhysicalAddress(PAdrM), .TLBMiss(DTLBMissM), .Cacheable(CacheableM), .Idempotent(), .SelTIM(SelDTIM),
|
||||||
|
@ -34,6 +34,7 @@ module mmu import cvw::*; #(parameter cvw_t P,
|
|||||||
input logic STATUS_SUM, // Status CSR: Supervisor access to user memory
|
input logic STATUS_SUM, // Status CSR: Supervisor access to user memory
|
||||||
input logic STATUS_MPRV, // Status CSR: modify machine privilege
|
input logic STATUS_MPRV, // Status CSR: modify machine privilege
|
||||||
input logic [1:0] STATUS_MPP, // Status CSR: previous machine privilege level
|
input logic [1:0] STATUS_MPP, // Status CSR: previous machine privilege level
|
||||||
|
input logic ENVCFG_PBMTE, // Page-based memory types enabled
|
||||||
input logic [1:0] PrivilegeModeW, // Current privilege level of the processeor
|
input logic [1:0] PrivilegeModeW, // Current privilege level of the processeor
|
||||||
input logic DisableTranslation, // virtual address translation disabled during D$ flush and HPTW walk that use physical addresses
|
input logic DisableTranslation, // virtual address translation disabled during D$ flush and HPTW walk that use physical addresses
|
||||||
input logic [P.XLEN+1:0] VAdr, // virtual/physical address from IEU or physical address from HPTW
|
input logic [P.XLEN+1:0] VAdr, // virtual/physical address from IEU or physical address from HPTW
|
||||||
@ -70,6 +71,7 @@ module mmu import cvw::*; #(parameter cvw_t P,
|
|||||||
logic TLBHit; // Hit in TLB
|
logic TLBHit; // Hit in TLB
|
||||||
logic TLBPageFault; // Page fault from TLB
|
logic TLBPageFault; // Page fault from TLB
|
||||||
logic ReadNoAmoAccessM; // Read that is not part of atomic operation causes Load faults. Otherwise StoreAmo faults
|
logic ReadNoAmoAccessM; // Read that is not part of atomic operation causes Load faults. Otherwise StoreAmo faults
|
||||||
|
logic [1:0] PBMemoryType; // PBMT field of PTE during TLB hit, or 00 otherwise
|
||||||
|
|
||||||
// only instantiate TLB if Virtual Memory is supported
|
// only instantiate TLB if Virtual Memory is supported
|
||||||
if (P.VIRTMEM_SUPPORTED) begin:tlb
|
if (P.VIRTMEM_SUPPORTED) begin:tlb
|
||||||
@ -80,16 +82,17 @@ module mmu import cvw::*; #(parameter cvw_t P,
|
|||||||
.clk, .reset,
|
.clk, .reset,
|
||||||
.SATP_MODE(SATP_REGW[P.XLEN-1:P.XLEN-P.SVMODE_BITS]),
|
.SATP_MODE(SATP_REGW[P.XLEN-1:P.XLEN-P.SVMODE_BITS]),
|
||||||
.SATP_ASID(SATP_REGW[P.ASID_BASE+P.ASID_BITS-1:P.ASID_BASE]),
|
.SATP_ASID(SATP_REGW[P.ASID_BASE+P.ASID_BITS-1:P.ASID_BASE]),
|
||||||
.VAdr(VAdr[P.XLEN-1:0]), .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP,
|
.VAdr(VAdr[P.XLEN-1:0]), .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .ENVCFG_PBMTE,
|
||||||
.PrivilegeModeW, .ReadAccess, .WriteAccess,
|
.PrivilegeModeW, .ReadAccess, .WriteAccess,
|
||||||
.DisableTranslation, .PTE, .PageTypeWriteVal,
|
.DisableTranslation, .PTE, .PageTypeWriteVal,
|
||||||
.TLBWrite, .TLBFlush, .TLBPAdr, .TLBMiss, .TLBHit,
|
.TLBWrite, .TLBFlush, .TLBPAdr, .TLBMiss, .TLBHit,
|
||||||
.Translate, .TLBPageFault, .UpdateDA);
|
.Translate, .TLBPageFault, .UpdateDA, .PBMemoryType);
|
||||||
end else begin:tlb // just pass address through as physical
|
end else begin:tlb // just pass address through as physical
|
||||||
assign Translate = 0;
|
assign Translate = 0;
|
||||||
assign TLBMiss = 0;
|
assign TLBMiss = 0;
|
||||||
assign TLBHit = 1; // *** is this necessary
|
assign TLBHit = 1; // *** is this necessary
|
||||||
assign TLBPageFault = 0;
|
assign TLBPageFault = 0;
|
||||||
|
assign PBMemoryType = 2'b00;
|
||||||
end
|
end
|
||||||
|
|
||||||
// If translation is occuring, select translated physical address from TLB
|
// If translation is occuring, select translated physical address from TLB
|
||||||
@ -103,7 +106,7 @@ module mmu import cvw::*; #(parameter cvw_t P,
|
|||||||
///////////////////////////////////////////
|
///////////////////////////////////////////
|
||||||
|
|
||||||
pmachecker #(P) pmachecker(.PhysicalAddress, .Size,
|
pmachecker #(P) pmachecker(.PhysicalAddress, .Size,
|
||||||
.AtomicAccessM, .ExecuteAccessF, .WriteAccessM, .ReadAccessM,
|
.AtomicAccessM, .ExecuteAccessF, .WriteAccessM, .ReadAccessM, .PBMemoryType,
|
||||||
.Cacheable, .Idempotent, .SelTIM,
|
.Cacheable, .Idempotent, .SelTIM,
|
||||||
.PMAInstrAccessFaultF, .PMALoadAccessFaultM, .PMAStoreAmoAccessFaultM);
|
.PMAInstrAccessFaultF, .PMALoadAccessFaultM, .PMAStoreAmoAccessFaultM);
|
||||||
|
|
||||||
|
@ -35,6 +35,7 @@ module pmachecker import cvw::*; #(parameter cvw_t P) (
|
|||||||
input logic ExecuteAccessF, // Execute access
|
input logic ExecuteAccessF, // Execute access
|
||||||
input logic WriteAccessM, // Write access
|
input logic WriteAccessM, // Write access
|
||||||
input logic ReadAccessM, // Read access
|
input logic ReadAccessM, // Read access
|
||||||
|
input logic [1:0] PBMemoryType, // PBMT field of PTE during TLB hit, or 00 otherwise
|
||||||
output logic Cacheable, Idempotent, SelTIM,
|
output logic Cacheable, Idempotent, SelTIM,
|
||||||
output logic PMAInstrAccessFaultF,
|
output logic PMAInstrAccessFaultF,
|
||||||
output logic PMALoadAccessFaultM,
|
output logic PMALoadAccessFaultM,
|
||||||
@ -45,6 +46,7 @@ module pmachecker import cvw::*; #(parameter cvw_t P) (
|
|||||||
logic AccessRW, AccessRWX, AccessRX;
|
logic AccessRW, AccessRWX, AccessRX;
|
||||||
logic [10:0] SelRegions;
|
logic [10:0] SelRegions;
|
||||||
logic AtomicAllowed;
|
logic AtomicAllowed;
|
||||||
|
logic CacheableRegion, IdempotentRegion;
|
||||||
|
|
||||||
// Determine what type of access is being made
|
// Determine what type of access is being made
|
||||||
assign AccessRW = ReadAccessM | WriteAccessM;
|
assign AccessRW = ReadAccessM | WriteAccessM;
|
||||||
@ -54,11 +56,15 @@ module pmachecker import cvw::*; #(parameter cvw_t P) (
|
|||||||
// Determine which region of physical memory (if any) is being accessed
|
// Determine which region of physical memory (if any) is being accessed
|
||||||
adrdecs #(P) adrdecs(PhysicalAddress, AccessRW, AccessRX, AccessRWX, Size, SelRegions);
|
adrdecs #(P) adrdecs(PhysicalAddress, AccessRW, AccessRX, AccessRWX, Size, SelRegions);
|
||||||
|
|
||||||
// Only non-core RAM/ROM memory regions are cacheable
|
// Only non-core RAM/ROM memory regions are cacheable. PBMT can override cachable; NC and IO are uncachable
|
||||||
assign Cacheable = SelRegions[8] | SelRegions[7] | SelRegions[6]; // exclusion-tag: unused-cachable
|
assign CacheableRegion = SelRegions[8] | SelRegions[7] | SelRegions[6];
|
||||||
|
assign Cacheable = (PBMemoryType == 2'b00) ? CacheableRegion : 0; // exclusion-tag: unused-cachable
|
||||||
|
|
||||||
// Nonidemdempotent means access could have side effect and must not be done speculatively or redundantly
|
// Nonidemdempotent means access could have side effect and must not be done speculatively or redundantly
|
||||||
// I/O is nonidempotent.
|
// I/O is nonidempotent. PBMT can override PMA; NC is idempotent and IO is non-idempotent
|
||||||
assign Idempotent = SelRegions[10] | SelRegions[9] | SelRegions[8] | SelRegions[7] | SelRegions[6]; // exclusion-tag: unused-idempotent
|
assign IdempotentRegion = SelRegions[10] | SelRegions[9] | SelRegions[8] | SelRegions[7] | SelRegions[6];
|
||||||
|
assign Idempotent = (PBMemoryType == 2'b00) ? IdempotentRegion : (PBMemoryType == 2'b01); // exclusion-tag: unused-idempotent
|
||||||
|
|
||||||
// Atomic operations are only allowed on RAM
|
// Atomic operations are only allowed on RAM
|
||||||
assign AtomicAllowed = SelRegions[10] | SelRegions[8] | SelRegions[6]; // exclusion-tag: unused-atomic
|
assign AtomicAllowed = SelRegions[10] | SelRegions[8] | SelRegions[6]; // exclusion-tag: unused-atomic
|
||||||
// Check if tightly integrated memories are selected
|
// Check if tightly integrated memories are selected
|
||||||
|
@ -57,12 +57,13 @@ module tlb import cvw::*; #(parameter cvw_t P,
|
|||||||
input logic [P.ASID_BITS-1:0] SATP_ASID,
|
input logic [P.ASID_BITS-1:0] SATP_ASID,
|
||||||
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 ENVCFG_PBMTE, // Page-based memory types enabled
|
||||||
input logic [1:0] PrivilegeModeW, // Current privilege level of the processeor
|
input logic [1:0] PrivilegeModeW, // Current privilege level of the processeor
|
||||||
input logic ReadAccess,
|
input logic ReadAccess,
|
||||||
input logic WriteAccess,
|
input logic WriteAccess,
|
||||||
input logic DisableTranslation,
|
input logic DisableTranslation,
|
||||||
input logic [P.XLEN-1:0] VAdr, // address input before translation (could be physical or virtual)
|
input logic [P.XLEN-1:0] VAdr, // address input before translation (could be physical or virtual)
|
||||||
input logic [P.XLEN-1:0] PTE,
|
input logic [P.XLEN-1:0] PTE, // page table entry to write
|
||||||
input logic [1:0] PageTypeWriteVal,
|
input logic [1:0] PageTypeWriteVal,
|
||||||
input logic TLBWrite,
|
input logic TLBWrite,
|
||||||
input logic TLBFlush,
|
input logic TLBFlush,
|
||||||
@ -71,10 +72,11 @@ module tlb import cvw::*; #(parameter cvw_t P,
|
|||||||
output logic TLBHit,
|
output logic TLBHit,
|
||||||
output logic Translate,
|
output logic Translate,
|
||||||
output logic TLBPageFault,
|
output logic TLBPageFault,
|
||||||
output logic UpdateDA
|
output logic UpdateDA,
|
||||||
|
output logic [1:0] PBMemoryType // PBMT field of PTE during TLB hit, or 00 otherwise
|
||||||
);
|
);
|
||||||
|
|
||||||
logic [TLB_ENTRIES-1:0] Matches, WriteEnables, PTE_Gs; // used as the one-hot encoding of WriteIndex
|
logic [TLB_ENTRIES-1:0] Matches, WriteEnables, PTE_Gs, PTE_NAPOTs; // used as the one-hot encoding of WriteIndex
|
||||||
// Sections of the virtual and physical addresses
|
// Sections of the virtual and physical addresses
|
||||||
logic [P.VPN_BITS-1:0] VPN;
|
logic [P.VPN_BITS-1:0] VPN;
|
||||||
logic [P.PPN_BITS-1:0] PPN;
|
logic [P.PPN_BITS-1:0] PPN;
|
||||||
@ -84,7 +86,9 @@ module tlb import cvw::*; #(parameter cvw_t P,
|
|||||||
logic CAMHit;
|
logic CAMHit;
|
||||||
logic SV39Mode;
|
logic SV39Mode;
|
||||||
logic Misaligned;
|
logic Misaligned;
|
||||||
|
logic BadPTEWrite; // trying to write malformed PTE
|
||||||
logic MegapageMisaligned;
|
logic MegapageMisaligned;
|
||||||
|
logic PTE_N; // NAPOT page table entry
|
||||||
|
|
||||||
if(P.XLEN == 32) begin
|
if(P.XLEN == 32) begin
|
||||||
assign MegapageMisaligned = |(PPN[9:0]); // must have zero PPN0
|
assign MegapageMisaligned = |(PPN[9:0]); // must have zero PPN0
|
||||||
@ -101,20 +105,28 @@ module tlb import cvw::*; #(parameter cvw_t P,
|
|||||||
|
|
||||||
assign VPN = VAdr[P.VPN_BITS+11:12];
|
assign VPN = VAdr[P.VPN_BITS+11:12];
|
||||||
|
|
||||||
tlbcontrol #(P, ITLB) tlbcontrol(.SATP_MODE, .VAdr, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP,
|
// check if reserved, N, or PBMT bits are malformed when PTE is written in RV64
|
||||||
|
assign BadPTEWrite = (P.XLEN == 64) & TLBWrite & (
|
||||||
|
PTE[P.XLEN-1] & ~P.SVNAPOT_SUPPORTED | // N must be 0 if SVNAPOT is not supported
|
||||||
|
PTE[P.XLEN-2:P.XLEN-3] != 0 & ~P.SVPBMT_SUPPORTED | // PBMT must be 0 if SVBPMT is not supported
|
||||||
|
PTE[P.XLEN-2:P.XLEN-3] == 3 | // PBMT of 3 is reserved and never legal
|
||||||
|
PTE[P.XLEN-4:P.XLEN-10] != 0 ); // Reserved bits must be 0
|
||||||
|
|
||||||
|
tlbcontrol #(P, ITLB) tlbcontrol(.SATP_MODE, .VAdr, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .ENVCFG_PBMTE,
|
||||||
.PrivilegeModeW, .ReadAccess, .WriteAccess, .DisableTranslation, .TLBFlush,
|
.PrivilegeModeW, .ReadAccess, .WriteAccess, .DisableTranslation, .TLBFlush,
|
||||||
.PTEAccessBits, .CAMHit, .Misaligned, .TLBMiss, .TLBHit, .TLBPageFault,
|
.PTEAccessBits, .CAMHit, .Misaligned, .BadPTEWrite,
|
||||||
.UpdateDA, .SV39Mode, .Translate);
|
.TLBMiss, .TLBHit, .TLBPageFault,
|
||||||
|
.UpdateDA, .SV39Mode, .Translate, .PTE_N, .PBMemoryType);
|
||||||
|
|
||||||
tlblru #(TLB_ENTRIES) lru(.clk, .reset, .TLBWrite, .TLBFlush, .Matches, .CAMHit, .WriteEnables);
|
tlblru #(TLB_ENTRIES) lru(.clk, .reset, .TLBWrite, .TLBFlush, .Matches, .CAMHit, .WriteEnables);
|
||||||
tlbcam #(P, TLB_ENTRIES, P.VPN_BITS + P.ASID_BITS, P.VPN_SEGMENT_BITS)
|
tlbcam #(P, TLB_ENTRIES, P.VPN_BITS + P.ASID_BITS, P.VPN_SEGMENT_BITS)
|
||||||
tlbcam(.clk, .reset, .VPN, .PageTypeWriteVal, .SV39Mode, .TLBFlush, .WriteEnables, .PTE_Gs,
|
tlbcam(.clk, .reset, .VPN, .PageTypeWriteVal, .SV39Mode, .TLBFlush, .WriteEnables, .PTE_Gs, .PTE_NAPOTs,
|
||||||
.SATP_ASID, .Matches, .HitPageType, .CAMHit);
|
.SATP_ASID, .Matches, .HitPageType, .CAMHit);
|
||||||
tlbram #(P, TLB_ENTRIES) tlbram(.clk, .reset, .PTE, .Matches, .WriteEnables, .PPN, .PTEAccessBits, .PTE_Gs);
|
tlbram #(P, TLB_ENTRIES) tlbram(.clk, .reset, .PTE, .Matches, .WriteEnables, .PPN, .PTEAccessBits, .PTE_Gs, .PTE_NAPOTs);
|
||||||
|
|
||||||
// Replace segments of the virtual page number with segments of the physical
|
// Replace segments of the virtual page number with segments of the physical
|
||||||
// page number. For 4 KB pages, the entire virtual page number is replaced.
|
// page number. For 4 KB pages, the entire virtual page number is replaced.
|
||||||
// For superpages, some segments are considered offsets into a larger page.
|
// For superpages, some segments are considered offsets into a larger page.
|
||||||
tlbmixer #(P) Mixer(.VPN, .PPN, .HitPageType, .Offset(VAdr[11:0]), .TLBHit, .TLBPAdr);
|
tlbmixer #(P) Mixer(.VPN, .PPN, .HitPageType, .Offset(VAdr[11:0]), .TLBHit, .PTE_N, .TLBPAdr);
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
@ -38,6 +38,7 @@ module tlbcam import cvw::*; #(parameter cvw_t P,
|
|||||||
input logic TLBFlush,
|
input logic TLBFlush,
|
||||||
input logic [TLB_ENTRIES-1:0] WriteEnables,
|
input logic [TLB_ENTRIES-1:0] WriteEnables,
|
||||||
input logic [TLB_ENTRIES-1:0] PTE_Gs,
|
input logic [TLB_ENTRIES-1:0] PTE_Gs,
|
||||||
|
input logic [TLB_ENTRIES-1:0] PTE_NAPOTs, // entry is in NAPOT mode (N bit set and PPN[3:0] = 1000)
|
||||||
input logic [P.ASID_BITS-1:0] SATP_ASID,
|
input logic [P.ASID_BITS-1:0] SATP_ASID,
|
||||||
output logic [TLB_ENTRIES-1:0] Matches,
|
output logic [TLB_ENTRIES-1:0] Matches,
|
||||||
output logic [1:0] HitPageType,
|
output logic [1:0] HitPageType,
|
||||||
@ -53,7 +54,7 @@ module tlbcam import cvw::*; #(parameter cvw_t P,
|
|||||||
// page number segments.
|
// page number segments.
|
||||||
|
|
||||||
tlbcamline #(P, KEY_BITS, SEGMENT_BITS) camlines[TLB_ENTRIES-1:0](
|
tlbcamline #(P, KEY_BITS, SEGMENT_BITS) camlines[TLB_ENTRIES-1:0](
|
||||||
.clk, .reset, .VPN, .SATP_ASID, .SV39Mode, .PTE_G(PTE_Gs), .PageTypeWriteVal, .TLBFlush,
|
.clk, .reset, .VPN, .SATP_ASID, .SV39Mode, .PTE_G(PTE_Gs), .PTE_NAPOT(PTE_NAPOTs), .PageTypeWriteVal, .TLBFlush,
|
||||||
.WriteEnable(WriteEnables), .PageTypeRead, .Match(Matches));
|
.WriteEnable(WriteEnables), .PageTypeRead, .Match(Matches));
|
||||||
assign CAMHit = |Matches & ~TLBFlush;
|
assign CAMHit = |Matches & ~TLBFlush;
|
||||||
or_rows #(TLB_ENTRIES,2) PageTypeOr(PageTypeRead, HitPageType);
|
or_rows #(TLB_ENTRIES,2) PageTypeOr(PageTypeRead, HitPageType);
|
||||||
|
@ -37,6 +37,7 @@ module tlbcamline import cvw::*; #(parameter cvw_t P,
|
|||||||
input logic SV39Mode,
|
input logic SV39Mode,
|
||||||
input logic WriteEnable, // Write a new entry to this line
|
input logic WriteEnable, // Write a new entry to this line
|
||||||
input logic PTE_G,
|
input logic PTE_G,
|
||||||
|
input logic PTE_NAPOT, // entry is in NAPOT mode (N bit set and PPN[3:0] = 1000)
|
||||||
input logic [1:0] PageTypeWriteVal,
|
input logic [1:0] PageTypeWriteVal,
|
||||||
input logic TLBFlush, // Flush this line (set valid to 0)
|
input logic TLBFlush, // Flush this line (set valid to 0)
|
||||||
output logic [1:0] PageTypeRead, // *** should this be the stored version or the always updated one?
|
output logic [1:0] PageTypeRead, // *** should this be the stored version or the always updated one?
|
||||||
@ -76,7 +77,7 @@ module tlbcamline import cvw::*; #(parameter cvw_t P,
|
|||||||
end else begin: match
|
end else begin: match
|
||||||
|
|
||||||
logic [SEGMENT_BITS-1:0] Key2, Key3, Query2, Query3;
|
logic [SEGMENT_BITS-1:0] Key2, Key3, Query2, Query3;
|
||||||
logic Match2, Match3;
|
logic Match2, Match3, MatchNAPOT;
|
||||||
|
|
||||||
assign {Query3, Query2, Query1, Query0} = VPN;
|
assign {Query3, Query2, Query1, Query0} = VPN;
|
||||||
assign {Key_ASID, Key3, Key2, Key1, Key0} = Key;
|
assign {Key_ASID, Key3, Key2, Key1, Key0} = Key;
|
||||||
@ -84,7 +85,9 @@ module tlbcamline import cvw::*; #(parameter cvw_t P,
|
|||||||
// Calculate the actual match value based on the input vpn and the page type.
|
// Calculate the actual match value based on the input vpn and the page type.
|
||||||
// For example, a gigapage in SV39 only cares about VPN[2], so VPN[0] and VPN[1]
|
// For example, a gigapage in SV39 only cares about VPN[2], so VPN[0] and VPN[1]
|
||||||
// should automatically match.
|
// should automatically match.
|
||||||
assign Match0 = (Query0 == Key0) | (PageType > 2'd0); // least signifcant section
|
// In Svnapot, if N bit is set and bottom 4 bits of PPN = 1000, then these bits don't need to match
|
||||||
|
assign MatchNAPOT = P.SVNAPOT_SUPPORTED & PTE_NAPOT & (Query0[SEGMENT_BITS-1:4] == Key0[SEGMENT_BITS-1:4]);
|
||||||
|
assign Match0 = (Query0 == Key0) | (PageType > 2'd0) | MatchNAPOT; // least significant section
|
||||||
assign Match1 = (Query1 == Key1) | (PageType > 2'd1);
|
assign Match1 = (Query1 == Key1) | (PageType > 2'd1);
|
||||||
assign Match2 = (Query2 == Key2) | (PageType > 2'd2);
|
assign Match2 = (Query2 == Key2) | (PageType > 2'd2);
|
||||||
assign Match3 = (Query3 == Key3) | SV39Mode; // this should always match in sv39 because they aren't used
|
assign Match3 = (Query3 == Key3) | SV39Mode; // this should always match in sv39 because they aren't used
|
||||||
|
@ -31,6 +31,7 @@ module tlbcontrol import cvw::*; #(parameter cvw_t P, ITLB = 0) (
|
|||||||
input logic [P.XLEN-1:0] VAdr,
|
input logic [P.XLEN-1:0] VAdr,
|
||||||
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 ENVCFG_PBMTE, // Page-based memory types enabled
|
||||||
input logic [1:0] PrivilegeModeW, // Current privilege level of the processeor
|
input logic [1:0] PrivilegeModeW, // Current privilege level of the processeor
|
||||||
input logic ReadAccess, WriteAccess,
|
input logic ReadAccess, WriteAccess,
|
||||||
input logic DisableTranslation,
|
input logic DisableTranslation,
|
||||||
@ -38,22 +39,27 @@ module tlbcontrol import cvw::*; #(parameter cvw_t P, ITLB = 0) (
|
|||||||
input logic [10:0] PTEAccessBits,
|
input logic [10:0] PTEAccessBits,
|
||||||
input logic CAMHit,
|
input logic CAMHit,
|
||||||
input logic Misaligned,
|
input logic Misaligned,
|
||||||
|
input logic BadPTEWrite, // trying to write malformed PTE
|
||||||
output logic TLBMiss,
|
output logic TLBMiss,
|
||||||
output logic TLBHit,
|
output logic TLBHit,
|
||||||
output logic TLBPageFault,
|
output logic TLBPageFault,
|
||||||
output logic UpdateDA,
|
output logic UpdateDA,
|
||||||
output logic SV39Mode,
|
output logic SV39Mode,
|
||||||
output logic Translate
|
output logic Translate,
|
||||||
|
output logic PTE_N, // NAPOT page table entry
|
||||||
|
output logic [1:0] PBMemoryType // PBMT field of PTE during TLB hit, or 00 otherwise
|
||||||
);
|
);
|
||||||
|
|
||||||
// Sections of the page table entry
|
// Sections of the page table entry
|
||||||
logic [1:0] EffectivePrivilegeMode;
|
logic [1:0] EffectivePrivilegeMode;
|
||||||
|
|
||||||
logic PTE_N, PTE_D, PTE_A, PTE_U, PTE_X, PTE_W, PTE_R, PTE_V; // Useful PTE Control Bits
|
logic PTE_D, PTE_A, PTE_U, PTE_X, PTE_W, PTE_R, PTE_V; // Useful PTE Control Bits
|
||||||
logic [1:0] PTE_PBMT;
|
logic [1:0] PTE_PBMT;
|
||||||
logic UpperBitsUnequal;
|
logic UpperBitsUnequal;
|
||||||
logic TLBAccess;
|
logic TLBAccess;
|
||||||
logic ImproperPrivilege;
|
logic ImproperPrivilege;
|
||||||
|
logic BadPBMT;
|
||||||
|
logic CausePageFault;
|
||||||
|
|
||||||
// Grab the sv mode from SATP and determine whether translation should occur
|
// Grab the sv mode from SATP and determine whether translation should occur
|
||||||
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
|
||||||
@ -66,25 +72,28 @@ module tlbcontrol import cvw::*; #(parameter cvw_t P, ITLB = 0) (
|
|||||||
vm64check #(P) vm64check(.SATP_MODE, .VAdr, .SV39Mode, .UpperBitsUnequal);
|
vm64check #(P) vm64check(.SATP_MODE, .VAdr, .SV39Mode, .UpperBitsUnequal);
|
||||||
|
|
||||||
// unswizzle useful PTE bits
|
// unswizzle useful PTE bits
|
||||||
assign PTE_N = PTEAccessBits[10] & P.SVNAPOT_SUPPORTED;
|
assign PTE_N = PTEAccessBits[10];
|
||||||
assign PTE_PBMT = PTEAccessBits[9:8] & {2{P.SVPBMT_SUPPORTED}};
|
assign PTE_PBMT = PTEAccessBits[9:8];
|
||||||
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, PTE_V} = PTEAccessBits[4:0];
|
assign {PTE_U, PTE_X, PTE_W, PTE_R, PTE_V} = PTEAccessBits[4:0];
|
||||||
|
|
||||||
|
// Page fault if PBMT is nonzero when SVPBMT is not supported and enabled
|
||||||
|
assign BadPBMT = PTE_PBMT != 0 & ~(P.SVPBMT_SUPPORTED & ENVCFG_PBMTE);
|
||||||
|
|
||||||
|
// Send PMA a 2-bit MemoryType that is PBMT during leaf page table accesses and 0 otherwise
|
||||||
|
assign PBMemoryType = PTE_PBMT & {2{Translate & TLBHit & P.SVPBMT_SUPPORTED}};
|
||||||
|
|
||||||
// Check whether the access is allowed, page faulting if not.
|
// Check whether the access is allowed, page faulting if not.
|
||||||
if (ITLB == 1) begin:itlb // Instruction TLB fault checking
|
if (ITLB == 1) begin:itlb // Instruction TLB fault checking
|
||||||
// User mode may only execute user mode pages, and supervisor mode may
|
// User mode may only execute user mode pages, and supervisor mode may
|
||||||
// only execute non-user mode pages.
|
// only execute non-user mode pages.
|
||||||
assign ImproperPrivilege = ((EffectivePrivilegeMode == P.U_MODE) & ~PTE_U) |
|
assign ImproperPrivilege = ((EffectivePrivilegeMode == P.U_MODE) & ~PTE_U) |
|
||||||
((EffectivePrivilegeMode == P.S_MODE) & PTE_U);
|
((EffectivePrivilegeMode == P.S_MODE) & PTE_U);
|
||||||
if(P.SVADU_SUPPORTED) begin : hptwwrites
|
assign CausePageFault = ImproperPrivilege | ~PTE_X | UpperBitsUnequal | BadPTEWrite | BadPBMT | Misaligned | ~PTE_V | (~PTE_A & P.SVADU_SUPPORTED);
|
||||||
assign UpdateDA = Translate & TLBHit & ~PTE_A & ~TLBPageFault;
|
assign TLBPageFault = Translate & TLBHit & CausePageFault;
|
||||||
assign TLBPageFault = Translate & TLBHit & (ImproperPrivilege | ~PTE_X | UpperBitsUnequal | Misaligned | ~PTE_V);
|
// Determine wheter to update DA bits
|
||||||
end else begin
|
if(P.SVADU_SUPPORTED) assign UpdateDA = Translate & TLBHit & ~PTE_A & ~TLBPageFault;
|
||||||
// fault for software handling if access bit is off
|
else assign UpdateDA = ~PTE_A;
|
||||||
assign UpdateDA = ~PTE_A;
|
|
||||||
assign TLBPageFault = Translate & TLBHit & (ImproperPrivilege | ~PTE_X | UpdateDA | UpperBitsUnequal | Misaligned | ~PTE_V);
|
|
||||||
end
|
|
||||||
end else begin:dtlb // Data TLB fault checking
|
end else begin:dtlb // Data TLB fault checking
|
||||||
logic InvalidRead, InvalidWrite;
|
logic InvalidRead, InvalidWrite;
|
||||||
|
|
||||||
|
@ -35,13 +35,14 @@ module tlbmixer import cvw::*; #(parameter cvw_t P) (
|
|||||||
input logic [1:0] HitPageType,
|
input logic [1:0] HitPageType,
|
||||||
input logic [11:0] Offset,
|
input logic [11:0] Offset,
|
||||||
input logic TLBHit,
|
input logic TLBHit,
|
||||||
|
input logic PTE_N, // NAPOT page table entry
|
||||||
output logic [P.PA_BITS-1:0] TLBPAdr
|
output logic [P.PA_BITS-1:0] TLBPAdr
|
||||||
);
|
);
|
||||||
|
|
||||||
localparam EXTRA_BITS = P.PPN_BITS - P.VPN_BITS;
|
localparam EXTRA_BITS = P.PPN_BITS - P.VPN_BITS;
|
||||||
logic [P.PPN_BITS-1:0] ZeroExtendedVPN;
|
logic [P.PPN_BITS-1:0] ZeroExtendedVPN;
|
||||||
logic [P.PPN_BITS-1:0] PageNumberMask;
|
logic [P.PPN_BITS-1:0] PageNumberMask;
|
||||||
logic [P.PPN_BITS-1:0] PPNMixed;
|
logic [P.PPN_BITS-1:0] PPNMixed, PPNMixed2;
|
||||||
|
|
||||||
// produce PageNumberMask with 1s where virtual page number bits should be untranslaetd for superpages
|
// produce PageNumberMask with 1s where virtual page number bits should be untranslaetd for superpages
|
||||||
if (P.XLEN == 32)
|
if (P.XLEN == 32)
|
||||||
@ -57,11 +58,45 @@ module tlbmixer import cvw::*; #(parameter cvw_t P) (
|
|||||||
|
|
||||||
// merge low segments of VPN with high segments of PPN decided by the pagetype.
|
// merge low segments of VPN with high segments of PPN decided by the pagetype.
|
||||||
assign ZeroExtendedVPN = {{EXTRA_BITS{1'b0}}, VPN}; // forces the VPN to be the same width as PPN.
|
assign ZeroExtendedVPN = {{EXTRA_BITS{1'b0}}, VPN}; // forces the VPN to be the same width as PPN.
|
||||||
assign PPNMixed = PPN | ZeroExtendedVPN & PageNumberMask; //
|
assign PPNMixed = PPN | ZeroExtendedVPN & PageNumberMask; // low bits of PPN are already zero
|
||||||
//mux2 #(1) mixmux[P.PPN_BITS-1:0](ZeroExtendedVPN, PPN, PageNumberMask, PPNMixed);
|
|
||||||
//assign PPNMixed = (ZeroExtendedVPN & ~PageNumberMask) | (PPN & PageNumberMask);
|
// In Svnapot, when N=1, use bottom bits of VPN for contiugous translations
|
||||||
|
if (P.SVNAPOT_SUPPORTED) begin
|
||||||
|
// 64 KiB contiguous NAPOT translations suported
|
||||||
|
logic [3:0] PPNMixedBot;
|
||||||
|
mux2 #(4) napotmux(PPNMixed[3:0], VPN, PTE_N, PPNMixedBot);
|
||||||
|
assign PPNMixed2 = {PPNMixed[P.PPN_BITS-1:4], PPNMixedBot};
|
||||||
|
|
||||||
|
/* // Generalized NAPOT implementation supporting various sized contiguous regions
|
||||||
|
// This would also require a priority encoder in the tlbcam
|
||||||
|
// Not yet tested
|
||||||
|
logic [8:0] NAPOTMask, NAPOTPN, PPNMixedBot;
|
||||||
|
always_comb begin
|
||||||
|
casez(PPN[8:0])
|
||||||
|
9'b100000000: NAPOTMask = 9'b111111111;
|
||||||
|
9'b?10000000: NAPOTMask = 9'b011111111;
|
||||||
|
9'b??1000000: NAPOTMask = 9'b001111111;
|
||||||
|
9'b???100000: NAPOTMask = 9'b000111111;
|
||||||
|
9'b????10000: NAPOTMask = 9'b000011111;
|
||||||
|
9'b?????1000: NAPOTMask = 9'b000001111;
|
||||||
|
9'b??????100: NAPOTMask = 9'b000000111;
|
||||||
|
9'b???????10: NAPOTMask = 9'b000000011;
|
||||||
|
9'b????????1: NAPOTMask = 9'b000000001;
|
||||||
|
default: NAPOTMask = 9'b000000000;
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
// check malformed NAPOT PPN, which should cause page fault
|
||||||
|
// Replace PPN with VPN in lower bits of page number based on mask
|
||||||
|
assign NAPOTPN = VPN & NAPOTMask | PPN & ~NAPOTMask;
|
||||||
|
mux2 #(9) napotmux(PPNMixed[8:0], NAPOTPN, PTE_N, PPNMixedBot);
|
||||||
|
assign PPNMixed2 = {PPNMixed[PPN_BITS-1:9], PPNMixedBot}; */
|
||||||
|
|
||||||
|
end else begin // no Svnapot
|
||||||
|
assign PPNMixed2 = PPNMixed;
|
||||||
|
end
|
||||||
|
|
||||||
// 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
|
||||||
mux2 #(P.PA_BITS) hitmux('0, {PPNMixed, Offset}, TLBHit, TLBPAdr); // set PA to 0 if TLB misses, to cause segementation error if this miss somehow passes through system
|
mux2 #(P.PA_BITS) hitmux('0, {PPNMixed2, Offset}, TLBHit, TLBPAdr); // set PA to 0 if TLB misses, to cause segementation error if this miss somehow passes through system
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
@ -36,19 +36,20 @@ module tlbram import cvw::*; #(parameter cvw_t P,
|
|||||||
input logic [TLB_ENTRIES-1:0] Matches, WriteEnables,
|
input logic [TLB_ENTRIES-1:0] Matches, WriteEnables,
|
||||||
output logic [P.PPN_BITS-1:0] PPN,
|
output logic [P.PPN_BITS-1:0] PPN,
|
||||||
output logic [10:0] PTEAccessBits,
|
output logic [10:0] PTEAccessBits,
|
||||||
output logic [TLB_ENTRIES-1:0] PTE_Gs
|
output logic [TLB_ENTRIES-1:0] PTE_Gs,
|
||||||
|
output logic [TLB_ENTRIES-1:0] PTE_NAPOTs // entry is in NAPOT mode (N bit set and PPN[3:0] = 1000)
|
||||||
);
|
);
|
||||||
|
|
||||||
logic [P.XLEN-1:0] RamRead[TLB_ENTRIES-1:0]; // stores the page table entries
|
logic [P.XLEN-1:0] RamRead[TLB_ENTRIES-1:0]; // stores the page table entries
|
||||||
logic [P.XLEN-1:0] PageTableEntry;
|
logic [P.XLEN-1:0] PageTableEntry;
|
||||||
|
|
||||||
// RAM implemented with array of flops and AND/OR read logic
|
// RAM implemented with array of flops and AND/OR read logic
|
||||||
tlbramline #(P.XLEN) tlbramline[TLB_ENTRIES-1:0]
|
tlbramline #(P) tlbramline[TLB_ENTRIES-1:0]
|
||||||
(.clk, .reset, .re(Matches), .we(WriteEnables),
|
(.clk, .reset, .re(Matches), .we(WriteEnables),
|
||||||
.d(PTE), .q(RamRead), .PTE_G(PTE_Gs));
|
.d(PTE), .q(RamRead), .PTE_G(PTE_Gs), .PTE_NAPOT(PTE_NAPOTs));
|
||||||
or_rows #(TLB_ENTRIES, P.XLEN) PTEOr(RamRead, PageTableEntry);
|
or_rows #(TLB_ENTRIES, P.XLEN) PTEOr(RamRead, PageTableEntry);
|
||||||
|
|
||||||
// Rename the bits read from the TLB RAM
|
// Rename the bits read from the TLB RAM
|
||||||
assign PTEAccessBits = {PageTableEntry[P.XLEN-1:P.XLEN-3], PageTableEntry[7:0]}; // include N and PBMT bits
|
assign PTEAccessBits = {PageTableEntry[P.XLEN-1:P.XLEN-3] & {3{P.XLEN == 64}}, PageTableEntry[7:0]}; // include N and PBMT bits
|
||||||
assign PPN = PageTableEntry[P.PPN_BITS+9:10];
|
assign PPN = PageTableEntry[P.PPN_BITS+9:10];
|
||||||
endmodule
|
endmodule
|
||||||
|
@ -26,16 +26,26 @@
|
|||||||
// and limitations under the License.
|
// and limitations under the License.
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
module tlbramline #(parameter WIDTH = 22)
|
module tlbramline import cvw::*; #(parameter cvw_t P)
|
||||||
(input logic clk, reset,
|
(input logic clk, reset,
|
||||||
input logic re, we,
|
input logic re, we,
|
||||||
input logic [WIDTH-1:0] d,
|
input logic [P.XLEN-1:0] d,
|
||||||
output logic [WIDTH-1:0] q,
|
output logic [P.XLEN-1:0] q,
|
||||||
output logic PTE_G);
|
output logic PTE_G,
|
||||||
|
output logic PTE_NAPOT // entry is in NAPOT mode (N bit set and PPN[3:0] = 1000)
|
||||||
|
);
|
||||||
|
|
||||||
logic [WIDTH-1:0] line;
|
logic [P.XLEN-1:0] line;
|
||||||
|
|
||||||
|
if (P.XLEN == 64) begin // save 7 reserved bits
|
||||||
|
// could optimize out N and PBMT from d[63:61] if they aren't supported
|
||||||
|
logic [56:0] ptereg;
|
||||||
|
flopenr #(57) pteflop(clk, reset, we, {d[63:61], d[53:0]}, ptereg);
|
||||||
|
assign line = {ptereg[56:54], 7'b0, ptereg[53:0]};
|
||||||
|
end else // rv32
|
||||||
|
flopenr #(P.XLEN) pteflop(clk, reset, we, d, line);
|
||||||
|
|
||||||
flopenr #(WIDTH) pteflop(clk, reset, we, d, line);
|
|
||||||
assign q = re ? line : 0;
|
assign q = re ? line : 0;
|
||||||
assign PTE_G = line[5]; // send global bit to CAM as part of ASID matching
|
assign PTE_G = line[5]; // send global bit to CAM as part of ASID matching
|
||||||
|
assign PTE_NAPOT = P.SVNAPOT_SUPPORTED & line[P.XLEN-1] & (line[13:10] == 4'b1000); // send NAPOT bit to CAM as part of matching lsbs of VPN
|
||||||
endmodule
|
endmodule
|
||||||
|
@ -85,6 +85,7 @@ module csr import cvw::*; #(parameter cvw_t P) (
|
|||||||
output var logic [P.PA_BITS-3:0] PMPADDR_ARRAY_REGW[P.PMP_ENTRIES-1:0],
|
output var logic [P.PA_BITS-3:0] PMPADDR_ARRAY_REGW[P.PMP_ENTRIES-1:0],
|
||||||
output logic [2:0] FRM_REGW,
|
output logic [2:0] FRM_REGW,
|
||||||
output logic [3:0] ENVCFG_CBE,
|
output logic [3:0] ENVCFG_CBE,
|
||||||
|
output logic ENVCFG_PBMTE, // Page-based memory type enable
|
||||||
//
|
//
|
||||||
output logic [P.XLEN-1:0] CSRReadValW, // value read from CSR
|
output logic [P.XLEN-1:0] CSRReadValW, // value read from CSR
|
||||||
output logic [P.XLEN-1:0] UnalignedPCNextF, // Next PC, accounting for traps and returns
|
output logic [P.XLEN-1:0] UnalignedPCNextF, // Next PC, accounting for traps and returns
|
||||||
@ -127,7 +128,6 @@ module csr import cvw::*; #(parameter cvw_t P) (
|
|||||||
logic [63:0] MENVCFG_REGW;
|
logic [63:0] MENVCFG_REGW;
|
||||||
logic [P.XLEN-1:0] SENVCFG_REGW;
|
logic [P.XLEN-1:0] SENVCFG_REGW;
|
||||||
logic ENVCFG_STCE; // supervisor timer counter enable
|
logic ENVCFG_STCE; // supervisor timer counter enable
|
||||||
logic ENVCFG_PBMTE; // page-based memory types enable
|
|
||||||
logic ENVCFG_FIOM; // fence implies io (presently not used)
|
logic ENVCFG_FIOM; // fence implies io (presently not used)
|
||||||
|
|
||||||
// only valid unflushed instructions can access CSRs
|
// only valid unflushed instructions can access CSRs
|
||||||
|
@ -83,6 +83,7 @@ module privileged import cvw::*; #(parameter cvw_t P) (
|
|||||||
output var logic [P.PA_BITS-3:0] PMPADDR_ARRAY_REGW [P.PMP_ENTRIES-1:0], // PMP address entries to MMU
|
output var logic [P.PA_BITS-3:0] PMPADDR_ARRAY_REGW [P.PMP_ENTRIES-1:0], // PMP address entries to MMU
|
||||||
output logic [2:0] FRM_REGW, // FPU rounding mode
|
output logic [2:0] FRM_REGW, // FPU rounding mode
|
||||||
output logic [3:0] ENVCFG_CBE, // Cache block operation enables
|
output logic [3:0] ENVCFG_CBE, // Cache block operation enables
|
||||||
|
output logic ENVCFG_PBMTE, // Page-based memory type enable
|
||||||
// PC logic output in privileged unit
|
// PC logic output in privileged unit
|
||||||
output logic [P.XLEN-1:0] UnalignedPCNextF, // Next PC from trap/return PC logic
|
output logic [P.XLEN-1:0] UnalignedPCNextF, // Next PC from trap/return PC logic
|
||||||
// control outputs
|
// control outputs
|
||||||
@ -137,7 +138,7 @@ module privileged import cvw::*; #(parameter cvw_t P) (
|
|||||||
.STATUS_MIE, .STATUS_SIE, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_TW, .STATUS_FS,
|
.STATUS_MIE, .STATUS_SIE, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_TW, .STATUS_FS,
|
||||||
.MEDELEG_REGW, .MIP_REGW, .MIE_REGW, .MIDELEG_REGW,
|
.MEDELEG_REGW, .MIP_REGW, .MIE_REGW, .MIDELEG_REGW,
|
||||||
.SATP_REGW, .PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW,
|
.SATP_REGW, .PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW,
|
||||||
.SetFflagsM, .FRM_REGW, .ENVCFG_CBE,
|
.SetFflagsM, .FRM_REGW, .ENVCFG_CBE, .ENVCFG_PBMTE,
|
||||||
.CSRReadValW,.UnalignedPCNextF, .IllegalCSRAccessM, .BigEndianM);
|
.CSRReadValW,.UnalignedPCNextF, .IllegalCSRAccessM, .BigEndianM);
|
||||||
|
|
||||||
// pipeline early-arriving trap sources
|
// pipeline early-arriving trap sources
|
||||||
|
@ -78,6 +78,7 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
|
|||||||
logic LoadStallD, StoreStallD, MDUStallD, CSRRdStallD;
|
logic LoadStallD, StoreStallD, MDUStallD, CSRRdStallD;
|
||||||
logic SquashSCW;
|
logic SquashSCW;
|
||||||
logic MDUActiveE; // Mul/Div instruction being executed
|
logic MDUActiveE; // Mul/Div instruction being executed
|
||||||
|
logic ENVCFG_PBMTE; // Page-based memory type enable
|
||||||
logic [3:0] ENVCFG_CBE; // Cache Block operation enables
|
logic [3:0] ENVCFG_CBE; // Cache Block operation enables
|
||||||
logic [3:0] CMOpM; // 1: cbo.inval; 2: cbo.flush; 4: cbo.clean; 8: cbo.zero
|
logic [3:0] CMOpM; // 1: cbo.inval; 2: cbo.flush; 4: cbo.clean; 8: cbo.zero
|
||||||
logic IFUPrefetchE, LSUPrefetchM; // instruction / data prefetch hints
|
logic IFUPrefetchE, LSUPrefetchM; // instruction / data prefetch hints
|
||||||
@ -184,7 +185,7 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
|
|||||||
.IllegalBaseInstrD, .IllegalFPUInstrD, .InstrPageFaultF, .IllegalIEUFPUInstrD, .InstrMisalignedFaultM,
|
.IllegalBaseInstrD, .IllegalFPUInstrD, .InstrPageFaultF, .IllegalIEUFPUInstrD, .InstrMisalignedFaultM,
|
||||||
// mmu management
|
// mmu management
|
||||||
.PrivilegeModeW, .PTE, .PageType, .SATP_REGW, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV,
|
.PrivilegeModeW, .PTE, .PageType, .SATP_REGW, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV,
|
||||||
.STATUS_MPP, .ITLBWriteF, .sfencevmaM, .ITLBMissF,
|
.STATUS_MPP, .ENVCFG_PBMTE, .ITLBWriteF, .sfencevmaM, .ITLBMissF,
|
||||||
// pmp/pma (inside mmu) signals.
|
// pmp/pma (inside mmu) signals.
|
||||||
.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW, .InstrAccessFaultF, .InstrUpdateDAF);
|
.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW, .InstrAccessFaultF, .InstrUpdateDAF);
|
||||||
|
|
||||||
@ -232,6 +233,7 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
|
|||||||
.STATUS_SUM, // from csr
|
.STATUS_SUM, // from csr
|
||||||
.STATUS_MPRV, // from csr
|
.STATUS_MPRV, // from csr
|
||||||
.STATUS_MPP, // from csr
|
.STATUS_MPP, // from csr
|
||||||
|
.ENVCFG_PBMTE, // from csr
|
||||||
.sfencevmaM, // connects to privilege
|
.sfencevmaM, // connects to privilege
|
||||||
.DCacheStallM, // connects to privilege
|
.DCacheStallM, // connects to privilege
|
||||||
.LoadPageFaultM, // connects to privilege
|
.LoadPageFaultM, // connects to privilege
|
||||||
@ -294,7 +296,7 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
|
|||||||
.PrivilegeModeW, .SATP_REGW,
|
.PrivilegeModeW, .SATP_REGW,
|
||||||
.STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .STATUS_FS,
|
.STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .STATUS_FS,
|
||||||
.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW,
|
.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW,
|
||||||
.FRM_REGW, .ENVCFG_CBE, .BreakpointFaultM, .EcallFaultM, .wfiM, .IntPendingM, .BigEndianM);
|
.FRM_REGW, .ENVCFG_CBE, .ENVCFG_PBMTE, .BreakpointFaultM, .EcallFaultM, .wfiM, .IntPendingM, .BigEndianM);
|
||||||
end else begin
|
end else begin
|
||||||
assign CSRReadValW = 0;
|
assign CSRReadValW = 0;
|
||||||
assign UnalignedPCNextF = PC2NextF;
|
assign UnalignedPCNextF = PC2NextF;
|
||||||
|
Loading…
Reference in New Issue
Block a user