From 24916d42e2fa76c728b33160b7228f68adbf22a5 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Wed, 19 Jun 2024 11:40:02 -0700 Subject: [PATCH] Refactored TLBMiss and TLBMissOrUpdateA(D) to simplify spill, ifu, lsu, and hptw. --- src/ifu/ifu.sv | 17 ++++++++++------- src/ifu/spill.sv | 5 ++--- src/lsu/lsu.sv | 11 +++++++---- src/mmu/hptw.sv | 24 +++++++++--------------- src/wally/wallypipelinedcore.sv | 10 ++++------ 5 files changed, 32 insertions(+), 35 deletions(-) diff --git a/src/ifu/ifu.sv b/src/ifu/ifu.sv index aba53e198..ed2830868 100644 --- a/src/ifu/ifu.sv +++ b/src/ifu/ifu.sv @@ -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 //////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/ifu/spill.sv b/src/ifu/spill.sv index 5b82aac76..b2ee6e9e2 100644 --- a/src/ifu/spill.sv +++ b/src/ifu/spill.sv @@ -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; diff --git a/src/lsu/lsu.sv b/src/lsu/lsu.sv index 9fed86cc0..7aba958e6 100644 --- a/src/lsu/lsu.sv +++ b/src/lsu/lsu.sv @@ -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]; diff --git a/src/mmu/hptw.sv b/src/mmu/hptw.sv index 5e6b99e4d..e66ae88fa 100644 --- a/src/mmu/hptw.sv +++ b/src/mmu/hptw.sv @@ -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. diff --git a/src/wally/wallypipelinedcore.sv b/src/wally/wallypipelinedcore.sv index a8d30919c..d3589a93a 100644 --- a/src/wally/wallypipelinedcore.sv +++ b/src/wally/wallypipelinedcore.sv @@ -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