From c7ec9282fe255a0bb9e7df7a120720fdfafb2ba5 Mon Sep 17 00:00:00 2001 From: David Harris Date: Thu, 2 Jun 2022 14:18:55 +0000 Subject: [PATCH] Provided sfencevmaM to hazard unit and renamed TLBFlush signals to sfencevma going into LSU/IFU. Preparing for SFENCE.VMA to flush the pipeline, but that is not yet working. --- pipelined/src/hazard/hazard.sv | 14 ++++++++------ pipelined/src/ifu/ifu.sv | 16 ++++++++++++++-- pipelined/src/lsu/lsu.sv | 4 ++-- pipelined/src/privileged/privdec.sv | 8 ++++---- pipelined/src/privileged/privileged.sv | 6 +++--- pipelined/src/wally/wallypipelinedcore.sv | 14 ++++++-------- 6 files changed, 37 insertions(+), 25 deletions(-) diff --git a/pipelined/src/hazard/hazard.sv b/pipelined/src/hazard/hazard.sv index cf4cdaa8..98a7ff28 100644 --- a/pipelined/src/hazard/hazard.sv +++ b/pipelined/src/hazard/hazard.sv @@ -38,7 +38,7 @@ module hazard( (* mark_debug = "true" *) input logic FPUStallD, FStallD, (* mark_debug = "true" *) input logic DivBusyE,FDivBusyE, (* mark_debug = "true" *) input logic EcallFaultM, BreakpointFaultM, -(* mark_debug = "true" *) input logic InvalidateICacheM, wfiM, IntPendingM, +(* mark_debug = "true" *) input logic InvalidateICacheM, sfencevmaM, wfiM, IntPendingM, // Stall & flush outputs (* mark_debug = "true" *) output logic StallF, StallD, StallE, StallM, StallW, (* mark_debug = "true" *) output logic FlushF, FlushD, FlushE, FlushM, FlushW @@ -46,7 +46,7 @@ module hazard( logic StallFCause, StallDCause, StallECause, StallMCause, StallWCause; logic FirstUnstalledD, FirstUnstalledE, FirstUnstalledM, FirstUnstalledW; - + logic Fence, PrivilegedFlush; // stalls and flushes // loads: stall for one cycle if the subsequent instruction depends on the load @@ -82,10 +82,12 @@ module hazard( assign FirstUnstalledW = ~StallW & StallM; // Each stage flushes if the previous stage is the last one stalled (for cause) or the system has reason to flush - assign FlushF = BPPredWrongE | InvalidateICacheM; - assign FlushD = FirstUnstalledD | TrapM | RetM | BPPredWrongE | InvalidateICacheM; // *** does RetM only need to flush if the privilege changes? - assign FlushE = FirstUnstalledE | TrapM | RetM | BPPredWrongE | InvalidateICacheM; // *** why is BPPredWrongE here, but not needed in simple processor - assign FlushM = FirstUnstalledM | TrapM | RetM | InvalidateICacheM; + assign Fence = InvalidateICacheM; // | sfencevmaM; // fences flush Fetch stage ***why + assign PrivilegedFlush = TrapM | RetM | Fence; // privileged stage change and fences flush pipeline + assign FlushF = BPPredWrongE | Fence; + assign FlushD = FirstUnstalledD | PrivilegedFlush | BPPredWrongE; + assign FlushE = FirstUnstalledE | PrivilegedFlush | BPPredWrongE; // *** why is BPPredWrongE here, but not needed in simple processor + assign FlushM = FirstUnstalledM | PrivilegedFlush; // on Trap the memory stage should be flushed going into the W stage, // except if the instruction causing the Trap is an ecall or ebreak. assign FlushW = FirstUnstalledW | (TrapM & ~(BreakpointFaultM | EcallFaultM)); diff --git a/pipelined/src/ifu/ifu.sv b/pipelined/src/ifu/ifu.sv index be340b2e..8fa35102 100644 --- a/pipelined/src/ifu/ifu.sv +++ b/pipelined/src/ifu/ifu.sv @@ -72,7 +72,7 @@ module ifu ( 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 ITLBWriteF, sfencevmaM, output logic ITLBMissF, InstrDAPageFaultF, 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], @@ -137,6 +137,18 @@ module ifu ( //////////////////////////////////////////////////////////////////////////////////////////////// if(`ZICSR_SUPPORTED == 1) begin : immu + /////////////////////////////////////////// + // sfence.vma causes TLB flushes + /////////////////////////////////////////// + // sets ITLBFlush to pulse for one cycle of the sfence.vma instruction + // In this instr we want to flush the tlb and then do a pagetable walk to update the itlb and continue the program. + // But we're still in the stalled sfence instruction, so if itlbflushf == sfencevmaM, tlbflush would never drop and + // the tlbwrite would never take place after the pagetable walk. by adding in ~StallMQ, we are able to drop itlbflush + // after a cycle AND pulse it for another cycle on any further back-to-back sfences. + logic StallMQ, TLBFlush; + flopr #(1) StallMReg(.clk, .reset, .d(StallM), .q(StallMQ)); + assign TLBFlush = sfencevmaM & ~StallMQ; + mmu #(.TLB_ENTRIES(`ITLB_ENTRIES), .IMMU(1)) immu(.clk, .reset, .SATP_REGW, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .PrivilegeModeW, .DisableTranslation(1'b0), @@ -145,7 +157,7 @@ module ifu ( .PTE(PTE), .PageTypeWriteVal(PageType), .TLBWrite(ITLBWriteF), - .TLBFlush(ITLBFlushF), + .TLBFlush, .PhysicalAddress(PCPF), .TLBMiss(ITLBMissF), .Cacheable(CacheableF), .Idempotent(), .AtomicAllowed(), diff --git a/pipelined/src/lsu/lsu.sv b/pipelined/src/lsu/lsu.sv index e6458385..72beea1b 100644 --- a/pipelined/src/lsu/lsu.sv +++ b/pipelined/src/lsu/lsu.sv @@ -55,7 +55,7 @@ module lsu ( // cpu privilege input logic [1:0] PrivilegeModeW, input logic BigEndianM, - input logic DTLBFlushM, + input logic sfencevmaM, // faults output logic LoadPageFaultM, StoreAmoPageFaultM, output logic LoadMisalignedFaultM, LoadAccessFaultM, @@ -157,7 +157,7 @@ module lsu ( .PTE, .PageTypeWriteVal(PageType), .TLBWrite(DTLBWriteM), - .TLBFlush(DTLBFlushM), + .TLBFlush(sfencevmaM), .PhysicalAddress(LSUPAdrM), .TLBMiss(DTLBMissM), .Cacheable(CacheableM), .Idempotent(), .AtomicAllowed(), diff --git a/pipelined/src/privileged/privdec.sv b/pipelined/src/privileged/privdec.sv index 8271f332..367c9e82 100644 --- a/pipelined/src/privileged/privdec.sv +++ b/pipelined/src/privileged/privdec.sv @@ -39,7 +39,7 @@ module privdec ( input logic [1:0] PrivilegeModeW, input logic STATUS_TSR, STATUS_TVM, STATUS_TW, input logic [1:0] STATUS_FS, - output logic IllegalInstrFaultM, ITLBFlushF, DTLBFlushM, + output logic IllegalInstrFaultM, output logic EcallFaultM, BreakpointFaultM, output logic sretM, mretM, wfiM, sfencevmaM); @@ -84,9 +84,9 @@ module privdec ( // But we're still in the stalled sfence instruction, so if itlbflushf == sfencevmaM, tlbflush would never drop and // the tlbwrite would never take place after the pagetable walk. by adding in ~StallMQ, we are able to drop itlbflush // after a cycle AND pulse it for another cycle on any further back-to-back sfences. - flopr #(1) StallMReg(.clk, .reset, .d(StallM), .q(StallMQ)); - assign ITLBFlushF = sfencevmaM & ~StallMQ; - assign DTLBFlushM = sfencevmaM; +// flopr #(1) StallMReg(.clk, .reset, .d(StallM), .q(StallMQ)); +// assign ITLBFlushF = sfencevmaM & ~StallMQ; +// assign DTLBFlushM = sfencevmaM; /////////////////////////////////////////// // Fault on illegal instructions diff --git a/pipelined/src/privileged/privileged.sv b/pipelined/src/privileged/privileged.sv index a65039bf..f9f8a99a 100644 --- a/pipelined/src/privileged/privileged.sv +++ b/pipelined/src/privileged/privileged.sv @@ -38,7 +38,7 @@ module privileged ( output logic [`XLEN-1:0] CSRReadValW, output logic [`XLEN-1:0] PrivilegedNextPCM, output logic RetM, TrapM, - output logic ITLBFlushF, DTLBFlushM, + output logic sfencevmaM, input logic InstrValidM, CommittedM, input logic FRegWriteM, LoadStallD, input logic BPPredDirWrongM, @@ -85,7 +85,7 @@ module privileged ( logic [`XLEN-1:0] MEDELEG_REGW; logic [11:0] MIDELEG_REGW; - logic sretM, mretM, sfencevmaM; + logic sretM, mretM; logic IllegalCSRAccessM; logic IllegalIEUInstrFaultM; logic IllegalFPUInstrM; @@ -115,7 +115,7 @@ module privileged ( privdec pmd(.clk, .reset, .StallM, .InstrM(InstrM[31:20]), .PrivilegedM, .IllegalIEUInstrFaultM, .IllegalCSRAccessM, .IllegalFPUInstrM, .PrivilegeModeW, .STATUS_TSR, .STATUS_TVM, .STATUS_TW, .STATUS_FS, .IllegalInstrFaultM, - .ITLBFlushF, .DTLBFlushM, .EcallFaultM, .BreakpointFaultM, + .EcallFaultM, .BreakpointFaultM, .sretM, .mretM, .wfiM, .sfencevmaM); /////////////////////////////////////////// diff --git a/pipelined/src/wally/wallypipelinedcore.sv b/pipelined/src/wally/wallypipelinedcore.sv index ccbc25df..30f0c43e 100644 --- a/pipelined/src/wally/wallypipelinedcore.sv +++ b/pipelined/src/wally/wallypipelinedcore.sv @@ -101,7 +101,6 @@ module wallypipelinedcore ( // memory management unit signals logic ITLBWriteF; - logic ITLBFlushF, DTLBFlushM; logic ITLBMissF; logic [`XLEN-1:0] SATP_REGW; logic STATUS_MXR, STATUS_SUM, STATUS_MPRV; @@ -109,7 +108,7 @@ module wallypipelinedcore ( logic [1:0] PrivilegeModeW; logic [`XLEN-1:0] PTE; logic [1:0] PageType; - logic wfiM, IntPendingM; + logic sfencevmaM, wfiM, IntPendingM; logic SelHPTW; // PMA checker signals @@ -190,7 +189,7 @@ module wallypipelinedcore ( // mmu management .PrivilegeModeW, .PTE, .PageType, .SATP_REGW, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, - .STATUS_MPP, .ITLBWriteF, .ITLBFlushF, + .STATUS_MPP, .ITLBWriteF, .sfencevmaM, .ITLBMissF, // pmp/pma (inside mmu) signals. *** temporarily from AHB bus but eventually replace with internal versions pre H @@ -262,7 +261,7 @@ module wallypipelinedcore ( .STATUS_MPRV, // from csr .STATUS_MPP, // from csr - .DTLBFlushM, // connects to privilege + .sfencevmaM, // connects to privilege .LoadPageFaultM, // connects to privilege .StoreAmoPageFaultM, // connects to privilege .LoadMisalignedFaultM, // connects to privilege @@ -301,7 +300,7 @@ module wallypipelinedcore ( .FPUStallD, .FStallD, .DivBusyE, .FDivBusyE, .EcallFaultM, .BreakpointFaultM, - .InvalidateICacheM, .wfiM, .IntPendingM, + .InvalidateICacheM, .sfencevmaM, .wfiM, .IntPendingM, // Stall & flush outputs .StallF, .StallD, .StallE, .StallM, .StallW, .FlushF, .FlushD, .FlushE, .FlushM, .FlushW @@ -315,7 +314,7 @@ module wallypipelinedcore ( .CSRReadM, .CSRWriteM, .SrcAM, .PCM, .InstrM, .CSRReadValW, .PrivilegedNextPCM, .RetM, .TrapM, - .ITLBFlushF, .DTLBFlushM, + .sfencevmaM, .InstrValidM, .CommittedM, .FRegWriteM, .LoadStallD, .BPPredDirWrongM, .BTBPredPCWrongM, @@ -344,8 +343,7 @@ module wallypipelinedcore ( assign RetM = 0; assign TrapM = 0; assign wfiM = 0; - assign ITLBFlushF = 0; - assign DTLBFlushM = 0; + assign sfencevmaM = 0; assign BigEndianM = 0; end if (`M_SUPPORTED) begin:mdu