Added stalls for pending SFENCE.VMA and FENCE.I in hazard unit

This commit is contained in:
David Harris 2022-06-02 09:37:59 -07:00
parent 154410a37f
commit 1d8bc2dc1b
4 changed files with 25 additions and 24 deletions

View File

@ -32,13 +32,13 @@
module hazard( module hazard(
// Detect hazards // Detect hazards
(* mark_debug = "true" *) input logic BPPredWrongE, CSRWritePendingDEM, RetM, TrapM, (* mark_debug = "true" *) input logic BPPredWrongE, CSRWriteFencePendingDEM, RetM, TrapM,
(* mark_debug = "true" *) input logic LoadStallD, StoreStallD, MDUStallD, CSRRdStallD, (* mark_debug = "true" *) input logic LoadStallD, StoreStallD, MDUStallD, CSRRdStallD,
(* mark_debug = "true" *) input logic LSUStallM, IFUStallF, (* mark_debug = "true" *) input logic LSUStallM, IFUStallF,
(* mark_debug = "true" *) input logic FPUStallD, FStallD, (* mark_debug = "true" *) input logic FPUStallD, FStallD,
(* mark_debug = "true" *) input logic DivBusyE,FDivBusyE, (* mark_debug = "true" *) input logic DivBusyE,FDivBusyE,
(* mark_debug = "true" *) input logic EcallFaultM, BreakpointFaultM, (* mark_debug = "true" *) input logic EcallFaultM, BreakpointFaultM,
(* mark_debug = "true" *) input logic InvalidateICacheM, sfencevmaM, wfiM, IntPendingM, (* mark_debug = "true" *) input logic wfiM, IntPendingM,
// Stall & flush outputs // Stall & flush outputs
(* mark_debug = "true" *) output logic StallF, StallD, StallE, StallM, StallW, (* mark_debug = "true" *) output logic StallF, StallD, StallE, StallM, StallW,
(* mark_debug = "true" *) output logic FlushF, FlushD, FlushE, FlushM, FlushW (* mark_debug = "true" *) output logic FlushF, FlushD, FlushE, FlushM, FlushW
@ -46,7 +46,6 @@ module hazard(
logic StallFCause, StallDCause, StallECause, StallMCause, StallWCause; logic StallFCause, StallDCause, StallECause, StallMCause, StallWCause;
logic FirstUnstalledD, FirstUnstalledE, FirstUnstalledM, FirstUnstalledW; logic FirstUnstalledD, FirstUnstalledE, FirstUnstalledM, FirstUnstalledW;
logic Fence, PrivilegedFlush;
// stalls and flushes // stalls and flushes
// loads: stall for one cycle if the subsequent instruction depends on the load // loads: stall for one cycle if the subsequent instruction depends on the load
@ -62,7 +61,7 @@ module hazard(
// *** can stalls be pushed into earlier stages (e.g. no stall after Decode?) // *** can stalls be pushed into earlier stages (e.g. no stall after Decode?)
assign StallFCause = CSRWritePendingDEM & ~(TrapM | RetM | BPPredWrongE); assign StallFCause = CSRWriteFencePendingDEM & ~(TrapM | RetM | BPPredWrongE);
// stall in decode if instruction is a load/mul/csr dependent on previous // stall in decode if instruction is a load/mul/csr dependent on previous
assign StallDCause = (LoadStallD | StoreStallD | MDUStallD | CSRRdStallD | FPUStallD | FStallD) & ~(TrapM | RetM | BPPredWrongE); assign StallDCause = (LoadStallD | StoreStallD | MDUStallD | CSRRdStallD | FPUStallD | FStallD) & ~(TrapM | RetM | BPPredWrongE);
assign StallECause = (DivBusyE | FDivBusyE) & ~(TrapM); // *** can we move to decode stage (KP?) assign StallECause = (DivBusyE | FDivBusyE) & ~(TrapM); // *** can we move to decode stage (KP?)
@ -82,12 +81,10 @@ module hazard(
assign FirstUnstalledW = ~StallW & StallM; 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 // Each stage flushes if the previous stage is the last one stalled (for cause) or the system has reason to flush
assign Fence = InvalidateICacheM; // | sfencevmaM; // Fences should flush the pipeline and restart *** sfence not working assign FlushF = BPPredWrongE;
assign PrivilegedFlush = TrapM | RetM | Fence; // privileged stage change and fences flush pipeline assign FlushD = FirstUnstalledD | TrapM | RetM | BPPredWrongE;
assign FlushF = BPPredWrongE | Fence; assign FlushE = FirstUnstalledE | TrapM | RetM | BPPredWrongE; // *** why is BPPredWrongE here, but not needed in simple processor
assign FlushD = FirstUnstalledD | PrivilegedFlush | BPPredWrongE; assign FlushM = FirstUnstalledM | TrapM | RetM;
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, // 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. // except if the instruction causing the Trap is an ecall or ebreak.
assign FlushW = FirstUnstalledW | (TrapM & ~(BreakpointFaultM | EcallFaultM)); assign FlushW = FirstUnstalledW | (TrapM & ~(BreakpointFaultM | EcallFaultM));

View File

@ -67,7 +67,7 @@ module controller(
output logic RegWriteW, // for datapath and Hazard Unit output logic RegWriteW, // for datapath and Hazard Unit
output logic [2:0] ResultSrcW, output logic [2:0] ResultSrcW,
// Stall during CSRs // Stall during CSRs
output logic CSRWritePendingDEM, output logic CSRWriteFencePendingDEM,
output logic StoreStallD output logic StoreStallD
); );
@ -107,6 +107,8 @@ module controller(
logic IEURegWriteE; logic IEURegWriteE;
logic IllegalERegAdrD; logic IllegalERegAdrD;
logic [1:0] AtomicE; logic [1:0] AtomicE;
logic FencePendingD, FencePendingE, FencePendingM;
// Extract fields // Extract fields
assign OpD = InstrD[6:0]; assign OpD = InstrD[6:0];
@ -177,6 +179,7 @@ module controller(
assign CSRZeroSrcD = InstrD[14] ? (InstrD[19:15] == 0) : (Rs1D == 0); // Is a CSR instruction using zero as the source? assign CSRZeroSrcD = InstrD[14] ? (InstrD[19:15] == 0) : (Rs1D == 0); // Is a CSR instruction using zero as the source?
assign CSRWriteD = CSRReadD & !(CSRZeroSrcD & InstrD[13]); // Don't write if setting or clearing zeros assign CSRWriteD = CSRReadD & !(CSRZeroSrcD & InstrD[13]); // Don't write if setting or clearing zeros
assign FencePendingD = PrivilegedD & (InstrD[31:25] == 7'b0001001) | FenceD; // possible sfence.vma or fence.i
// ALU Decoding is lazy, only using func7[5] to distinguish add/sub and srl/sra // ALU Decoding is lazy, only using func7[5] to distinguish add/sub and srl/sra
assign sltD = (Funct3D == 3'b010); assign sltD = (Funct3D == 3'b010);
@ -203,9 +206,9 @@ module controller(
flopenrc #(1) controlregD(clk, reset, FlushD, ~StallD, 1'b1, InstrValidD); flopenrc #(1) controlregD(clk, reset, FlushD, ~StallD, 1'b1, InstrValidD);
// Execute stage pipeline control register and logic // Execute stage pipeline control register and logic
flopenrc #(27) controlregE(clk, reset, FlushE, ~StallE, flopenrc #(28) controlregE(clk, reset, FlushE, ~StallE,
{RegWriteD, ResultSrcD, MemRWD, JumpD, BranchD, ALUControlD, ALUSrcAD, ALUSrcBD, ALUResultSrcD, CSRReadD, CSRWriteD, PrivilegedD, Funct3D, W64D, MDUD, AtomicD, InvalidateICacheD, FlushDCacheD, InstrValidD}, {RegWriteD, ResultSrcD, MemRWD, JumpD, BranchD, ALUControlD, ALUSrcAD, ALUSrcBD, ALUResultSrcD, CSRReadD, CSRWriteD, PrivilegedD, Funct3D, W64D, MDUD, AtomicD, InvalidateICacheD, FlushDCacheD, FencePendingD, InstrValidD},
{IEURegWriteE, ResultSrcE, MemRWE, JumpE, BranchE, ALUControlE, ALUSrcAE, ALUSrcBE, ALUResultSrcE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, W64E, MDUE, AtomicE, InvalidateICacheE, FlushDCacheE, InstrValidE}); {IEURegWriteE, ResultSrcE, MemRWE, JumpE, BranchE, ALUControlE, ALUSrcAE, ALUSrcBE, ALUResultSrcE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, W64E, MDUE, AtomicE, InvalidateICacheE, FlushDCacheE, FencePendingE, InstrValidE});
// Branch Logic // Branch Logic
assign {eqE, ltE, ltuE} = FlagsE; assign {eqE, ltE, ltuE} = FlagsE;
@ -219,16 +222,17 @@ module controller(
assign RegWriteE = IEURegWriteE | FWriteIntE; // IRF register writes could come from IEU or FPU controllers assign RegWriteE = IEURegWriteE | FWriteIntE; // IRF register writes could come from IEU or FPU controllers
// Memory stage pipeline control register // Memory stage pipeline control register
flopenrc #(18) controlregM(clk, reset, FlushM, ~StallM, flopenrc #(19) controlregM(clk, reset, FlushM, ~StallM,
{RegWriteE, ResultSrcE, MemRWE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, FWriteIntE, AtomicE, InvalidateICacheE, FlushDCacheE, InstrValidE}, {RegWriteE, ResultSrcE, MemRWE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, FWriteIntE, AtomicE, InvalidateICacheE, FlushDCacheE, FencePendingE, InstrValidE},
{RegWriteM, ResultSrcM, MemRWM, CSRReadM, CSRWriteM, PrivilegedM, Funct3M, FWriteIntM, AtomicM, InvalidateICacheM, FlushDCacheM, InstrValidM}); {RegWriteM, ResultSrcM, MemRWM, CSRReadM, CSRWriteM, PrivilegedM, Funct3M, FWriteIntM, AtomicM, InvalidateICacheM, FlushDCacheM, FencePendingM, InstrValidM});
// Writeback stage pipeline control register // Writeback stage pipeline control register
flopenrc #(4) controlregW(clk, reset, FlushW, ~StallW, flopenrc #(4) controlregW(clk, reset, FlushW, ~StallW,
{RegWriteM, ResultSrcM}, {RegWriteM, ResultSrcM},
{RegWriteW, ResultSrcW}); {RegWriteW, ResultSrcW});
assign CSRWritePendingDEM = CSRWriteD | CSRWriteE | CSRWriteM; // Stall pipeline at Fetch if a CSR Write or Fence is pending in the subsequent stages
assign CSRWriteFencePendingDEM = CSRWriteD | CSRWriteE | CSRWriteM | FencePendingD | FencePendingE | FencePendingM;
assign StoreStallD = MemRWE[0] & ((|MemRWD) | (|AtomicD)); assign StoreStallD = MemRWE[0] & ((|MemRWD) | (|AtomicD));
endmodule endmodule

View File

@ -71,7 +71,7 @@ module ieu (
output logic FPUStallD, LoadStallD, MDUStallD, CSRRdStallD, output logic FPUStallD, LoadStallD, MDUStallD, CSRRdStallD,
output logic PCSrcE, output logic PCSrcE,
output logic CSRReadM, CSRWriteM, PrivilegedM, output logic CSRReadM, CSRWriteM, PrivilegedM,
output logic CSRWritePendingDEM, output logic CSRWriteFencePendingDEM,
output logic StoreStallD output logic StoreStallD
); );
@ -99,7 +99,7 @@ module ieu (
.Funct3E, .MDUE, .W64E, .JumpE, .StallM, .FlushM, .MemRWM, .Funct3E, .MDUE, .W64E, .JumpE, .StallM, .FlushM, .MemRWM,
.CSRReadM, .CSRWriteM, .PrivilegedM, .SCE, .AtomicM, .Funct3M, .CSRReadM, .CSRWriteM, .PrivilegedM, .SCE, .AtomicM, .Funct3M,
.RegWriteM, .InvalidateICacheM, .FlushDCacheM, .InstrValidM, .FWriteIntM, .RegWriteM, .InvalidateICacheM, .FlushDCacheM, .InstrValidM, .FWriteIntM,
.StallW, .FlushW, .RegWriteW, .ResultSrcW, .CSRWritePendingDEM, .StoreStallD); .StallW, .FlushW, .RegWriteW, .ResultSrcW, .CSRWriteFencePendingDEM, .StoreStallD);
datapath dp( datapath dp(
.clk, .reset, .ImmSrcD, .InstrD, .StallE, .FlushE, .ForwardAE, .ForwardBE, .clk, .reset, .ImmSrcD, .InstrD, .StallE, .FlushE, .ForwardAE, .ForwardBE,

View File

@ -82,7 +82,7 @@ module wallypipelinedcore (
logic StoreAmoMisalignedFaultM, StoreAmoAccessFaultM; logic StoreAmoMisalignedFaultM, StoreAmoAccessFaultM;
logic InvalidateICacheM, FlushDCacheM; logic InvalidateICacheM, FlushDCacheM;
logic PCSrcE; logic PCSrcE;
logic CSRWritePendingDEM; logic CSRWriteFencePendingDEM;
logic DivBusyE; logic DivBusyE;
logic LoadStallD, StoreStallD, MDUStallD, CSRRdStallD; logic LoadStallD, StoreStallD, MDUStallD, CSRRdStallD;
logic SquashSCW; logic SquashSCW;
@ -231,7 +231,7 @@ module wallypipelinedcore (
.FPUStallD, .LoadStallD, .MDUStallD, .CSRRdStallD, .FPUStallD, .LoadStallD, .MDUStallD, .CSRRdStallD,
.PCSrcE, .PCSrcE,
.CSRReadM, .CSRWriteM, .PrivilegedM, .CSRReadM, .CSRWriteM, .PrivilegedM,
.CSRWritePendingDEM, .StoreStallD .CSRWriteFencePendingDEM, .StoreStallD
); // integer execution unit: integer register file, datapath and controller ); // integer execution unit: integer register file, datapath and controller
@ -294,13 +294,13 @@ module wallypipelinedcore (
hazard hzu( hazard hzu(
.BPPredWrongE, .CSRWritePendingDEM, .RetM, .TrapM, .BPPredWrongE, .CSRWriteFencePendingDEM, .RetM, .TrapM,
.LoadStallD, .StoreStallD, .MDUStallD, .CSRRdStallD, .LoadStallD, .StoreStallD, .MDUStallD, .CSRRdStallD,
.LSUStallM, .IFUStallF, .LSUStallM, .IFUStallF,
.FPUStallD, .FStallD, .FPUStallD, .FStallD,
.DivBusyE, .FDivBusyE, .DivBusyE, .FDivBusyE,
.EcallFaultM, .BreakpointFaultM, .EcallFaultM, .BreakpointFaultM,
.InvalidateICacheM, .sfencevmaM, .wfiM, .IntPendingM, .wfiM, .IntPendingM,
// Stall & flush outputs // Stall & flush outputs
.StallF, .StallD, .StallE, .StallM, .StallW, .StallF, .StallD, .StallE, .StallM, .StallW,
.FlushF, .FlushD, .FlushE, .FlushM, .FlushW .FlushF, .FlushD, .FlushE, .FlushM, .FlushW