From fa19a111c6fc5a9ec2ac8137275d6d47c18e704a Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Thu, 15 Dec 2022 10:05:17 -0600 Subject: [PATCH] Hazard cleanup. --- pipelined/src/hazard/hazard.sv | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/pipelined/src/hazard/hazard.sv b/pipelined/src/hazard/hazard.sv index b05a27952..50c077f60 100644 --- a/pipelined/src/hazard/hazard.sv +++ b/pipelined/src/hazard/hazard.sv @@ -46,6 +46,8 @@ module hazard( logic StallFCause, StallDCause, StallECause, StallMCause, StallWCause; logic FirstUnstalledD, FirstUnstalledE, FirstUnstalledM, FirstUnstalledW; + logic FlushDCause, FlushECause, FlushMCause, FlushWCause; + // stalls and flushes // loads: stall for one cycle if the subsequent instruction depends on the load @@ -59,25 +61,21 @@ module hazard( // A stage must stall if the next stage is stalled // If any stages are stalled, the first stage that isn't stalled must flush. - // *** can stalls be pushed into earlier stages (e.g. no stall after Decode?) + assign FlushDCause = TrapM | RetM | BPPredWrongE | CSRWriteFenceM; + assign FlushECause = TrapM | RetM | BPPredWrongE | CSRWriteFenceM; + assign FlushMCause = TrapM | RetM | CSRWriteFenceM; + // 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 FlushWCause = TrapM & ~(BreakpointFaultM | EcallFaultM); - // *** consider replacing CSRWriteFencePendingDEM with a flush rather than a stall. - //assign StallFCause = CSRWriteFencePendingDEM & ~(TrapM | RetM | BPPredWrongE); assign StallFCause = '0; // stall in decode if instruction is a load/mul/csr dependent on previous - assign StallDCause = (LoadStallD | StoreStallD | MDUStallD | CSRRdStallD | FCvtIntStallD | FStallD) & ~(TrapM | RetM | BPPredWrongE | CSRWriteFenceM); + assign StallDCause = (LoadStallD | StoreStallD | MDUStallD | CSRRdStallD | FCvtIntStallD | FStallD) & ~(FlushDCause); assign StallECause = (DivBusyE | FDivBusyE) & ~(TrapM | CSRWriteFenceM); // *** can we move to decode stage (KP?) // WFI terminates if any enabled interrupt is pending, even if global interrupts are disabled. It could also terminate with TW trap assign StallMCause = ((wfiM) & (~TrapM & ~IntPendingM)); assign StallWCause = ((IFUStallF | LSUStallM) & ~TrapM); // | (FDivBusyE & ~TrapM & ~IntPendingM); - // head version - // assign StallWCause = LSUStallM | IFUStallF | (FDivBusyE & ~TrapM & ~IntPendingM); // *** FDivBusyE should look like DivBusyE -// assign StallMCause = (wfiM & (~TrapM & ~IntPendingM)); // | FDivBusyE; -// assign StallECause = (DivBusyE | FDivBusyE) & ~(TrapM); // *** can we move to decode stage (KP?) - // *** ross: my changes to cache and lsu need to disable ifu/lsu stalls on a Trap. - - assign #1 StallF = StallFCause | StallD; assign #1 StallD = StallDCause | StallE; assign #1 StallE = StallECause | StallM; @@ -90,10 +88,8 @@ 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 #1 FlushD = FirstUnstalledD | TrapM | RetM | BPPredWrongE | CSRWriteFenceM; - assign #1 FlushE = FirstUnstalledE | TrapM | RetM | BPPredWrongE | CSRWriteFenceM ; // *** why is BPPredWrongE here, but not needed in simple processor - assign #1 FlushM = FirstUnstalledM | TrapM | RetM | CSRWriteFenceM; - // 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 #1 FlushW = FirstUnstalledW | (TrapM & ~(BreakpointFaultM | EcallFaultM)); + assign #1 FlushD = FirstUnstalledD | FlushDCause; + assign #1 FlushE = FirstUnstalledE | FlushECause ; // *** why is BPPredWrongE here, but not needed in simple processor + assign #1 FlushM = FirstUnstalledM | FlushMCause; + assign #1 FlushW = FirstUnstalledW | FlushWCause; endmodule