mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Refactored TLBMiss and TLBMissOrUpdateA(D) to simplify spill, ifu, lsu, and hptw.
This commit is contained in:
parent
71f267a17a
commit
24916d42e2
@ -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
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -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;
|
||||
|
@ -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];
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user