diff --git a/wally-pipelined/src/cache/dcache_ptw_interaction_README.txt b/wally-pipelined/src/cache/dcache_ptw_interaction_README.txt index 59d768fce..cc7a96cc1 100644 --- a/wally-pipelined/src/cache/dcache_ptw_interaction_README.txt +++ b/wally-pipelined/src/cache/dcache_ptw_interaction_README.txt @@ -24,7 +24,7 @@ in the memory stage. This is the core reason for the complexity. The above table classifies the operations into 8 categories. 2 of the 8 are not possible because a DTLB miss implies a memory operation. Each (I/D)TLB miss results in either a write to the corresponding TLB or a TLB fault. -To complicate things it is possilbe to have current ITLB and DTLB misses, which +To complicate things it is possilbe to have concurrent ITLB and DTLB misses, which both can result in either a write or a fault. The table belows shows the possible scenarios and the sequence of operations. @@ -72,3 +72,19 @@ to normal mode. Type 5a is a Type 4a with a current memory operation. The Dcache first switches to walker mode +Other traps. +A new problem has emerged. What happens when an interrupt occurs during a page table walk? +The dcache has an output called CommittedM which tells the CPU if the memory operation is +committed into the memory system. It would be wrong to pin the interrupt to a memory operation +when it is already or partially committed to the memory system. Instead the next instruction +has to be pinned to the interrupt. The complexity occurs with the ITLB miss; types 4, 5 and 7. + +Type 4: The ITLB misses and starts using the dcache to fetch the page table. There is no memory +operation. Depending on where in the walk the operations could be aborted. If the tlb is not yet +updated then the walk could be aborted. However if the TLB is updated then the interrupt must be +delayed until the next instruction. + +What is the meaning of CommittedM? +This signal informs the CPU if a memory operation is not started or if it is between started +and done. Once a memory op is started it should not be interrupted. This is used to prevent the +CPU from generating an interrupt after the operation is partially or completely done. diff --git a/wally-pipelined/src/cache/dcachefsm.sv b/wally-pipelined/src/cache/dcachefsm.sv index 59f90462f..7137fea05 100644 --- a/wally-pipelined/src/cache/dcachefsm.sv +++ b/wally-pipelined/src/cache/dcachefsm.sv @@ -192,16 +192,9 @@ module dcachefsm LRUWriteEn = 1'b0; CommittedM = 1'b0; - if(FlushDCacheM) begin - NextState = STATE_FLUSH; - DCacheStall = 1'b1; - SelAdrM = 2'b11; - FlushAdrCntRst = 1'b1; - FlushWayCntRst = 1'b1; - end // TLB Miss - else if((AnyCPUReqM & DTLBMissM) | ITLBMissF) begin + if(((AnyCPUReqM & DTLBMissM) | ITLBMissF) & ~(ExceptionM | PendingInterruptM)) begin // the LSU arbiter has not yet selected the PTW. // The CPU needs to be stalled until that happens. // If we set DCacheStall for 1 cycle before going to @@ -212,6 +205,16 @@ module dcachefsm DCacheStall = 1'b1; NextState = STATE_PTW_READY; end + + // Flush dcache to next level of memory + else if(FlushDCacheM & ~(ExceptionM | PendingInterruptM)) begin + NextState = STATE_FLUSH; + DCacheStall = 1'b1; + SelAdrM = 2'b11; + FlushAdrCntRst = 1'b1; + FlushWayCntRst = 1'b1; + end + // amo hit else if(AtomicM[1] & (&MemRWM) & CacheableM & ~(ExceptionM | PendingInterruptM) & CacheHit & ~DTLBMissM) begin SelAdrM = 2'b10; @@ -623,7 +626,7 @@ module dcachefsm CntReset = 1'b0; AHBWrite = 1'b0; AHBRead = 1'b0; - CommittedM = 1'b0; + CommittedM = 1'b1; NextState = STATE_READY; diff --git a/wally-pipelined/src/cache/icache.sv b/wally-pipelined/src/cache/icache.sv index d433f6ed3..7df4c4b84 100644 --- a/wally-pipelined/src/cache/icache.sv +++ b/wally-pipelined/src/cache/icache.sv @@ -31,7 +31,10 @@ module icache input logic clk, reset, input logic StallF, input logic [`PA_BITS-1:0] PCNextF, - input logic [`PA_BITS-1:0] PCPF, + input logic [`PA_BITS-1:0] PCPF, + + input logic ExceptionM, PendingInterruptM, + // Data read in from the ebu unit input logic [`XLEN-1:0] InstrInF, input logic InstrAckF, @@ -286,6 +289,8 @@ module icache .ITLBMissF, .ITLBWriteF, .WalkerInstrPageFaultF, + .ExceptionM, + .PendingInterruptM, .InstrAckF, .InstrReadF, .hit, diff --git a/wally-pipelined/src/cache/icachefsm.sv b/wally-pipelined/src/cache/icachefsm.sv index 2461e0dd4..fa0268bb8 100644 --- a/wally-pipelined/src/cache/icachefsm.sv +++ b/wally-pipelined/src/cache/icachefsm.sv @@ -36,6 +36,8 @@ module icachefsm input logic ITLBWriteF, input logic WalkerInstrPageFaultF, + input logic ExceptionM, PendingInterruptM, + // BUS interface input logic InstrAckF, @@ -135,7 +137,7 @@ module icachefsm STATE_READY: begin SelAdr = 2'b00; ICacheReadEn = 1'b1; - if (ITLBMissF) begin + if (ITLBMissF & ~(ExceptionM | PendingInterruptM)) begin NextState = STATE_TLB_MISS; end else if (hit & ~spill) begin ICacheStallF = 1'b0; diff --git a/wally-pipelined/src/ifu/ifu.sv b/wally-pipelined/src/ifu/ifu.sv index 9ddb39019..b18d8bc3c 100644 --- a/wally-pipelined/src/ifu/ifu.sv +++ b/wally-pipelined/src/ifu/ifu.sv @@ -27,60 +27,62 @@ `include "wally-config.vh" module ifu ( - input logic clk, reset, - input logic StallF, StallD, StallE, StallM, StallW, - input logic FlushF, FlushD, FlushE, FlushM, FlushW, + input logic clk, reset, + input logic StallF, StallD, StallE, StallM, StallW, + input logic FlushF, FlushD, FlushE, FlushM, FlushW, // Fetch - input logic [`XLEN-1:0] InstrInF, - input logic InstrAckF, - output logic [`XLEN-1:0] PCF, - output logic [`PA_BITS-1:0] InstrPAdrF, - output logic InstrReadF, - output logic ICacheStallF, + input logic [`XLEN-1:0] InstrInF, + input logic InstrAckF, + output logic [`XLEN-1:0] PCF, + output logic [`PA_BITS-1:0] InstrPAdrF, + output logic InstrReadF, + output logic ICacheStallF, // Execute - output logic [`XLEN-1:0] PCLinkE, - input logic PCSrcE, - input logic [`XLEN-1:0] PCTargetE, - output logic [`XLEN-1:0] PCE, - output logic BPPredWrongE, + output logic [`XLEN-1:0] PCLinkE, + input logic PCSrcE, + input logic [`XLEN-1:0] PCTargetE, + output logic [`XLEN-1:0] PCE, + output logic BPPredWrongE, // Mem - input logic RetM, TrapM, - input logic [`XLEN-1:0] PrivilegedNextPCM, - input logic InvalidateICacheM, - output logic [31:0] InstrD, InstrM, - output logic [`XLEN-1:0] PCM, - output logic [4:0] InstrClassM, - output logic BPPredDirWrongM, - output logic BTBPredPCWrongM, - output logic RASPredPCWrongM, - output logic BPPredClassNonCFIWrongM, + input logic RetM, TrapM, + input logic [`XLEN-1:0] PrivilegedNextPCM, + input logic InvalidateICacheM, + output logic [31:0] InstrD, InstrM, + output logic [`XLEN-1:0] PCM, + output logic [4:0] InstrClassM, + output logic BPPredDirWrongM, + output logic BTBPredPCWrongM, + output logic RASPredPCWrongM, + output logic BPPredClassNonCFIWrongM, // Writeback // output logic [`XLEN-1:0] PCLinkW, // Faults - input logic IllegalBaseInstrFaultD, - output logic ITLBInstrPageFaultF, - output logic IllegalIEUInstrFaultD, - output logic InstrMisalignedFaultM, - output logic [`XLEN-1:0] InstrMisalignedAdrM, + input logic IllegalBaseInstrFaultD, + output logic ITLBInstrPageFaultF, + output logic IllegalIEUInstrFaultD, + output logic InstrMisalignedFaultM, + output logic [`XLEN-1:0] InstrMisalignedAdrM, + input logic ExceptionM, PendingInterruptM, + // mmu management - input logic [1:0] PrivilegeModeW, - input logic [`XLEN-1:0] PTE, - input logic [1:0] PageType, - input logic [`XLEN-1:0] SATP_REGW, - input logic STATUS_MXR, STATUS_SUM, STATUS_MPRV, - input logic [1:0] STATUS_MPP, - input logic ITLBWriteF, ITLBFlushF, - input logic WalkerInstrPageFaultF, + input logic [1:0] PrivilegeModeW, + input logic [`XLEN-1:0] PTE, + input logic [1:0] PageType, + input logic [`XLEN-1:0] SATP_REGW, + input logic STATUS_MXR, STATUS_SUM, STATUS_MPRV, + input logic [1:0] STATUS_MPP, + input logic ITLBWriteF, ITLBFlushF, + input logic WalkerInstrPageFaultF, - output logic ITLBMissF, + output logic ITLBMissF, // pmp/pma (inside mmu) signals. *** temporarily from AHB bus but eventually replace with internal versions pre H - input var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0], - input var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW[`PMP_ENTRIES-1:0], + input var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0], + input var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW[`PMP_ENTRIES-1:0], - output logic InstrAccessFaultF + output logic InstrAccessFaultF ); logic [`XLEN-1:0] PCCorrectE, UnalignedPCNextF, PCNextF; diff --git a/wally-pipelined/src/lsu/lsu.sv b/wally-pipelined/src/lsu/lsu.sv index 1a97d6b33..a62502033 100644 --- a/wally-pipelined/src/lsu/lsu.sv +++ b/wally-pipelined/src/lsu/lsu.sv @@ -134,8 +134,8 @@ module lsu .SATP_REGW(SATP_REGW), .PCF(PCF), .MemAdrM(MemAdrM), - .ITLBMissF(ITLBMissF), - .DTLBMissM(DTLBMissM), + .ITLBMissF(ITLBMissF & ~PendingInterruptM), + .DTLBMissM(DTLBMissM & ~PendingInterruptM), .MemRWM(MemRWM), .PTE(PTE), .PageType, diff --git a/wally-pipelined/src/wally/wallypipelinedhart.sv b/wally-pipelined/src/wally/wallypipelinedhart.sv index 15cc61ba5..dd167788a 100644 --- a/wally-pipelined/src/wally/wallypipelinedhart.sv +++ b/wally-pipelined/src/wally/wallypipelinedhart.sv @@ -159,6 +159,7 @@ module wallypipelinedhart ( .StallF, .StallD, .StallE, .StallM, .StallW, .FlushF, .FlushD, .FlushE, .FlushM, .FlushW, + .ExceptionM, .PendingInterruptM, // Fetch .InstrInF(InstrRData), .InstrAckF, .PCF, .InstrPAdrF, .InstrReadF, .ICacheStallF,