Refactored TLBMiss and TLBMissOrUpdateA(D) to simplify spill, ifu, lsu, and hptw.

This commit is contained in:
Ross Thompson 2024-06-19 11:40:02 -07:00
parent 71f267a17a
commit 24916d42e2
5 changed files with 32 additions and 35 deletions

View File

@ -90,8 +90,7 @@ module ifu import cvw::*; #(parameter cvw_t P) (
input logic ENVCFG_PBMTE, // Page-based memory types enabled
input logic ENVCFG_ADUE, // HPTW A/D Update enable
input logic sfencevmaM, // Virtual memory address fence, invalidate TLB entries
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 ITLBMissOrUpdateAF, // ITLB miss causes HPTW (hardware pagetable walker) walk or update access bit
input var logic [7:0] PMPCFG_ARRAY_REGW[P.PMP_ENTRIES-1:0], // PMP configuration from privileged unit
input var logic [P.PA_BITS-3:0] PMPADDR_ARRAY_REGW[P.PMP_ENTRIES-1:0],// PMP address from privileged unit
output logic InstrAccessFaultF, // Instruction access fault
@ -140,7 +139,9 @@ module ifu import cvw::*; #(parameter cvw_t P) (
logic [15:0] InstrRawE, InstrRawM;
logic [LINELEN-1:0] FetchBuffer;
logic [31:0] ShiftUncachedInstr;
logic ITLBMissF;
logic InstrUpdateAF; // ITLB hit needs to update dirty or access bits
assign PCFExt = {2'b00, PCSpillF};
/////////////////////////////////////////////////////////////////////////////////////////////
@ -148,8 +149,8 @@ module ifu import cvw::*; #(parameter cvw_t P) (
/////////////////////////////////////////////////////////////////////////////////////////////
if(P.ZCA_SUPPORTED) begin : Spill
spill #(P) spill(.clk, .reset, .StallF, .FlushD, .PCF, .PCPlus4F, .PCNextF, .InstrRawF, .InstrUpdateDAF, .CacheableF,
.IFUCacheBusStallF, .ITLBMissF, .PCSpillNextF, .PCSpillF, .SelSpillNextF, .PostSpillInstrRawF, .CompressedF);
spill #(P) spill(.clk, .reset, .StallF, .FlushD, .PCF, .PCPlus4F, .PCNextF, .InstrRawF, .CacheableF,
.IFUCacheBusStallF, .ITLBMissOrUpdateAF, .PCSpillNextF, .PCSpillF, .SelSpillNextF, .PostSpillInstrRawF, .CompressedF);
end else begin : NoSpill
assign PCSpillNextF = PCNextF;
assign PCSpillF = PCF;
@ -189,15 +190,17 @@ module ifu import cvw::*; #(parameter cvw_t P) (
.InstrAccessFaultF, .LoadAccessFaultM(), .StoreAmoAccessFaultM(),
.InstrPageFaultF, .LoadPageFaultM(), .StoreAmoPageFaultM(),
.LoadMisalignedFaultM(), .StoreAmoMisalignedFaultM(),
.UpdateDA(InstrUpdateDAF), .CMOpM(4'b0),
.UpdateDA(InstrUpdateAF), .CMOpM(4'b0),
.AtomicAccessM(1'b0),.ExecuteAccessF(1'b1), .WriteAccessM(1'b0), .ReadAccessM(1'b0),
.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW);
assign ITLBMissOrUpdateAF = ITLBMissF | (P.SVADU_SUPPORTED & InstrUpdateAF);
end else begin
assign {ITLBMissF, InstrAccessFaultF, InstrPageFaultF, InstrUpdateDAF} = '0;
assign {ITLBMissF, InstrAccessFaultF, InstrPageFaultF, InstrUpdateAF} = '0;
assign PCPF = PCFExt[P.PA_BITS-1:0];
assign CacheableF = 1'b1;
assign SelIROM = '0;
assign ITLBMissOrUpdateAF = '0;
end
////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -39,8 +39,7 @@ module spill import cvw::*; #(parameter cvw_t P) (
input logic [P.XLEN-1:0] PCNextF, // The next PCF
input logic [31:0] InstrRawF, // Instruction from the IROM, I$, or bus. Used to check if the instruction if compressed
input logic IFUCacheBusStallF, // I$ or bus are stalled. Transition to second fetch of spill after the first is fetched
input logic ITLBMissF, // ITLB miss, ignore memory request
input logic InstrUpdateDAF, // Ignore memory request if the hptw support write and a DA page fault occurs (hptw is still active)
input logic ITLBMissOrUpdateAF, // ITLB miss causes HPTW (hardware pagetable walker) walk or update access bit
input logic CacheableF, // Is the instruction from the cache?
output logic [P.XLEN-1:0] PCSpillNextF, // The next PCF for one of the two memory addresses of the spill
output logic [P.XLEN-1:0] PCSpillF, // PCF for one of the two memory addresses of the spill
@ -86,7 +85,7 @@ module spill import cvw::*; #(parameter cvw_t P) (
end else
assign SpillF = PCF[1];
// Don't take the spill if there is a stall, TLB miss, or hardware update to the D/A bits
assign TakeSpillF = SpillF & ~EarlyCompressedF & ~IFUCacheBusStallF & ~(ITLBMissF | (P.SVADU_SUPPORTED & InstrUpdateDAF));
assign TakeSpillF = SpillF & ~EarlyCompressedF & ~IFUCacheBusStallF & ~ITLBMissOrUpdateAF;
always_ff @(posedge clk)
if (reset | FlushD) CurrState <= STATE_READY;

View File

@ -86,8 +86,7 @@ module lsu import cvw::*; #(parameter cvw_t P) (
input logic ENVCFG_PBMTE, // Page-based memory types enabled
input logic ENVCFG_ADUE, // HPTW A/D Update enable
input logic [P.XLEN-1:0] PCSpillF, // Fetch PC
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 ITLBMissOrUpdateAF, // ITLB miss causes HPTW (hardware pagetable walker) walk or update access bit
output logic [P.XLEN-1:0] PTE, // Page table entry write to ITLB
output logic [1:0] PageType, // Type of page table entry to write to ITLB
output logic ITLBWriteF, // Write PTE to ITLB
@ -153,6 +152,8 @@ module lsu import cvw::*; #(parameter cvw_t P) (
logic SelDTIM; // Select DTIM rather than bus or D$
logic [P.XLEN-1:0] WriteDataZM;
logic LSULoadPageFaultM, LSUStoreAmoPageFaultM;
logic DTLBMissOrUpdateDAM;
/////////////////////////////////////////////////////////////////////////////////////////////
// Pipeline for IEUAdr E to M
@ -192,8 +193,8 @@ module lsu import cvw::*; #(parameter cvw_t P) (
/////////////////////////////////////////////////////////////////////////////////////////////
if(P.VIRTMEM_SUPPORTED) begin : hptw
hptw #(P) hptw(.clk, .reset, .MemRWM, .AtomicM, .ITLBMissF, .ITLBWriteF,
.DTLBMissM, .DTLBWriteM, .InstrUpdateDAF, .DataUpdateDAM,
hptw #(P) hptw(.clk, .reset, .MemRWM, .AtomicM, .ITLBMissOrUpdateAF, .ITLBWriteF,
.DTLBMissOrUpdateDAM, .DTLBWriteM, .DataUpdateDAM,
.FlushW, .DCacheBusStallM, .SATP_REGW, .PCSpillF,
.STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .ENVCFG_ADUE, .PrivilegeModeW,
.ReadDataM(ReadDataM[P.XLEN-1:0]), // ReadDataM is LLEN, but HPTW only needs XLEN
@ -251,7 +252,9 @@ module lsu import cvw::*; #(parameter cvw_t P) (
.WriteAccessM, .ReadAccessM(PreLSURWM[1]),
.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW);
assign DTLBMissOrUpdateDAM = DTLBMissM | (P.SVADU_SUPPORTED & DataUpdateDAM);
end else begin // No MMU, so no PMA/page faults and no address translation
assign DTLBMissOrUpdateDAM = '0;
assign {DTLBMissM, LSULoadAccessFaultM, LSUStoreAmoAccessFaultM, LoadMisalignedFaultM, StoreAmoMisalignedFaultM} = '0;
assign {LSULoadPageFaultM, LSUStoreAmoPageFaultM} = '0;
assign PAdrM = IHAdrM[P.PA_BITS-1:0];

View File

@ -46,10 +46,9 @@ module hptw import cvw::*; #(parameter cvw_t P) (
input logic DCacheBusStallM, // stall from LSU
input logic [2:0] Funct3M,
input logic [6:0] Funct7M,
input logic ITLBMissF,
input logic DTLBMissM,
input logic ITLBMissOrUpdateAF,
input logic DTLBMissOrUpdateDAM,
input logic FlushW,
input logic InstrUpdateDAF,
input logic DataUpdateDAM,
output logic [P.XLEN-1:0] PTE, // page table entry to TLBs
output logic [1:0] PageType, // page type to TLBs
@ -83,7 +82,7 @@ module hptw import cvw::*; #(parameter cvw_t P) (
logic Misaligned, MegapageMisaligned;
logic ValidPTE, LeafPTE, ValidLeafPTE, ValidNonLeafPTE;
logic StartWalk;
logic TLBMiss;
logic TLBMissOrUpdateDA;
logic PRegEn;
logic [1:0] NextPageType;
logic [P.SVMODE_BITS-1:0] SvMode;
@ -94,8 +93,6 @@ module hptw import cvw::*; #(parameter cvw_t P) (
logic [P.PA_BITS-1:0] HPTWReadAdr;
logic SelHPTWAdr;
logic [P.XLEN+1:0] HPTWAdrExt;
logic DTLBMissOrUpdateDAM;
logic ITLBMissOrUpdateDAF;
logic LSUAccessFaultM;
logic [P.PA_BITS-1:0] HPTWAdr;
logic [1:0] HPTWRW;
@ -139,7 +136,7 @@ module hptw import cvw::*; #(parameter cvw_t P) (
// Extract bits from CSRs and inputs
assign SvMode = SATP_REGW[P.XLEN-1:P.XLEN-P.SVMODE_BITS];
assign BasePageTablePPN = SATP_REGW[P.PPN_BITS-1:0];
assign TLBMiss = DTLBMissOrUpdateDAM | ITLBMissOrUpdateDAF;
assign TLBMissOrUpdateDA = DTLBMissOrUpdateDAM | ITLBMissOrUpdateAF;
// Determine which address to translate
mux2 #(P.XLEN) vadrmux(PCSpillF, IEUAdrExtM[P.XLEN-1:0], DTLBWalk, TranslationVAdr);
@ -220,7 +217,7 @@ module hptw import cvw::*; #(parameter cvw_t P) (
end
// Enable and select signals based on states
assign StartWalk = (WalkerState == IDLE) & TLBMiss;
assign StartWalk = (WalkerState == IDLE) & TLBMissOrUpdateDA;
assign HPTWRW[1] = (WalkerState == L3_RD) | (WalkerState == L2_RD) | (WalkerState == L1_RD) | (WalkerState == L0_RD);
assign DTLBWriteM = (WalkerState == LEAF & ~HPTWUpdateDA) & DTLBWalk;
assign ITLBWriteF = (WalkerState == LEAF & ~HPTWUpdateDA) & ~DTLBWalk;
@ -285,7 +282,7 @@ module hptw import cvw::*; #(parameter cvw_t P) (
flopenl #(.TYPE(statetype)) WalkerStateReg(clk, reset | FlushW, 1'b1, NextWalkerState, IDLE, WalkerState);
always_comb
case (WalkerState)
IDLE: if (TLBMiss) NextWalkerState = InitialWalkerState;
IDLE: if (TLBMissOrUpdateDA) NextWalkerState = InitialWalkerState;
else NextWalkerState = IDLE;
L3_ADR: NextWalkerState = L3_RD; // first access in SV48
L3_RD: if (DCacheBusStallM) NextWalkerState = L3_RD;
@ -314,7 +311,7 @@ module hptw import cvw::*; #(parameter cvw_t P) (
default: NextWalkerState = IDLE; // should never be reached
endcase // case (WalkerState)
assign IgnoreRequestTLB = (WalkerState == IDLE & TLBMiss) | (HPTWFaultM); // RT : 05 April 2023 if hptw request has pmp/a fault suppress bus access.
assign IgnoreRequestTLB = (WalkerState == IDLE & TLBMissOrUpdateDA) | (HPTWFaultM); // RT : 05 April 2023 if hptw request has pmp/a fault suppress bus access.
assign SelHPTW = WalkerState != IDLE;
// RT 30 May 2023: When there is an access fault caused by the hptw itself, the fsm jumps to FAULT, removes
@ -322,10 +319,7 @@ module hptw import cvw::*; #(parameter cvw_t P) (
// The FSM directly transistions to IDLE to ready for the next operation when the delayed version will not be high.
assign HPTWAccessFaultDelay = HPTWLoadAccessFaultDelay | HPTWStoreAmoAccessFaultDelay | HPTWInstrAccessFaultDelay; // *** unused - RT, can we delete?
assign HPTWStall = (WalkerState != IDLE & WalkerState != FAULT) | (WalkerState == IDLE & TLBMiss);
assign DTLBMissOrUpdateDAM = DTLBMissM | (P.SVADU_SUPPORTED & DataUpdateDAM);
assign ITLBMissOrUpdateDAF = ITLBMissF | (P.SVADU_SUPPORTED & InstrUpdateDAF);
assign HPTWStall = (WalkerState != IDLE & WalkerState != FAULT) | (WalkerState == IDLE & TLBMissOrUpdateDA);
// HTPW address/data/control muxing
@ -349,5 +343,5 @@ module hptw import cvw::*; #(parameter cvw_t P) (
endmodule
// another idea. We keep gating the control by ~FlushW, but this adds considerable length to the critical path.
// should we do this differently? For example TLBMiss is gated by ~FlushW and then drives HPTWStall, which drives LSUStallM, which drives
// should we do this differently? For example TLBMissOrUpdateDA is gated by ~FlushW and then drives HPTWStall, which drives LSUStallM, which drives
// the hazard unit to issue stall and flush controlls. ~FlushW already suppresses these in the hazard unit.

View File

@ -104,7 +104,7 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
// memory management unit signals
logic ITLBWriteF;
logic ITLBMissF;
logic ITLBMissOrUpdateAF;
logic [P.XLEN-1:0] SATP_REGW;
logic STATUS_MXR, STATUS_SUM, STATUS_MPRV;
logic [1:0] STATUS_MPP, STATUS_FS;
@ -162,7 +162,6 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
logic DCacheAccess;
logic ICacheMiss;
logic ICacheAccess;
logic InstrUpdateDAF;
logic BigEndianM;
logic FCvtIntE;
logic CommittedF;
@ -189,9 +188,9 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
.IllegalBaseInstrD, .IllegalFPUInstrD, .InstrPageFaultF, .IllegalIEUFPUInstrD, .InstrMisalignedFaultM,
// mmu management
.PrivilegeModeW, .PTE, .PageType, .SATP_REGW, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV,
.STATUS_MPP, .ENVCFG_PBMTE, .ENVCFG_ADUE, .ITLBWriteF, .sfencevmaM, .ITLBMissF,
.STATUS_MPP, .ENVCFG_PBMTE, .ENVCFG_ADUE, .ITLBWriteF, .sfencevmaM, .ITLBMissOrUpdateAF,
// pmp/pma (inside mmu) signals.
.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW, .InstrAccessFaultF, .InstrUpdateDAF);
.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW, .InstrAccessFaultF);
// integer execution unit: integer register file, datapath and controller
ieu #(P) ieu(.clk, .reset,
@ -250,8 +249,7 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
.HPTWInstrPageFaultF, // connects to privilege
.StoreAmoMisalignedFaultM, // connects to privilege
.StoreAmoAccessFaultM, // connects to privilege
.InstrUpdateDAF,
.PCSpillF, .ITLBMissF, .PTE, .PageType, .ITLBWriteF, .SelHPTW,
.PCSpillF, .ITLBMissOrUpdateAF, .PTE, .PageType, .ITLBWriteF, .SelHPTW,
.LSUStallM);
if(P.BUS_SUPPORTED) begin : ebu