forked from Github_Repos/cvw
Added stalls for pending SFENCE.VMA and FENCE.I in hazard unit
This commit is contained in:
parent
154410a37f
commit
1d8bc2dc1b
@ -32,13 +32,13 @@
|
||||
|
||||
module hazard(
|
||||
// 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 LSUStallM, IFUStallF,
|
||||
(* 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, sfencevmaM, wfiM, IntPendingM,
|
||||
(* mark_debug = "true" *) input logic 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,6 @@ 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
|
||||
@ -62,7 +61,7 @@ module hazard(
|
||||
|
||||
// *** 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
|
||||
assign StallDCause = (LoadStallD | StoreStallD | MDUStallD | CSRRdStallD | FPUStallD | FStallD) & ~(TrapM | RetM | BPPredWrongE);
|
||||
assign StallECause = (DivBusyE | FDivBusyE) & ~(TrapM); // *** can we move to decode stage (KP?)
|
||||
@ -82,12 +81,10 @@ 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 Fence = InvalidateICacheM; // | sfencevmaM; // Fences should flush the pipeline and restart *** sfence not working
|
||||
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;
|
||||
assign FlushF = BPPredWrongE;
|
||||
assign FlushD = FirstUnstalledD | TrapM | RetM | BPPredWrongE;
|
||||
assign FlushE = FirstUnstalledE | TrapM | RetM | BPPredWrongE; // *** why is BPPredWrongE here, but not needed in simple processor
|
||||
assign FlushM = FirstUnstalledM | TrapM | RetM;
|
||||
// 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));
|
||||
|
@ -67,7 +67,7 @@ module controller(
|
||||
output logic RegWriteW, // for datapath and Hazard Unit
|
||||
output logic [2:0] ResultSrcW,
|
||||
// Stall during CSRs
|
||||
output logic CSRWritePendingDEM,
|
||||
output logic CSRWriteFencePendingDEM,
|
||||
output logic StoreStallD
|
||||
);
|
||||
|
||||
@ -107,6 +107,8 @@ module controller(
|
||||
logic IEURegWriteE;
|
||||
logic IllegalERegAdrD;
|
||||
logic [1:0] AtomicE;
|
||||
logic FencePendingD, FencePendingE, FencePendingM;
|
||||
|
||||
|
||||
// Extract fields
|
||||
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 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
|
||||
assign sltD = (Funct3D == 3'b010);
|
||||
@ -203,9 +206,9 @@ module controller(
|
||||
flopenrc #(1) controlregD(clk, reset, FlushD, ~StallD, 1'b1, InstrValidD);
|
||||
|
||||
// Execute stage pipeline control register and logic
|
||||
flopenrc #(27) controlregE(clk, reset, FlushE, ~StallE,
|
||||
{RegWriteD, ResultSrcD, MemRWD, JumpD, BranchD, ALUControlD, ALUSrcAD, ALUSrcBD, ALUResultSrcD, CSRReadD, CSRWriteD, PrivilegedD, Funct3D, W64D, MDUD, AtomicD, InvalidateICacheD, FlushDCacheD, InstrValidD},
|
||||
{IEURegWriteE, ResultSrcE, MemRWE, JumpE, BranchE, ALUControlE, ALUSrcAE, ALUSrcBE, ALUResultSrcE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, W64E, MDUE, AtomicE, InvalidateICacheE, FlushDCacheE, InstrValidE});
|
||||
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, FencePendingD, InstrValidD},
|
||||
{IEURegWriteE, ResultSrcE, MemRWE, JumpE, BranchE, ALUControlE, ALUSrcAE, ALUSrcBE, ALUResultSrcE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, W64E, MDUE, AtomicE, InvalidateICacheE, FlushDCacheE, FencePendingE, InstrValidE});
|
||||
|
||||
// Branch Logic
|
||||
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
|
||||
|
||||
// Memory stage pipeline control register
|
||||
flopenrc #(18) controlregM(clk, reset, FlushM, ~StallM,
|
||||
{RegWriteE, ResultSrcE, MemRWE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, FWriteIntE, AtomicE, InvalidateICacheE, FlushDCacheE, InstrValidE},
|
||||
{RegWriteM, ResultSrcM, MemRWM, CSRReadM, CSRWriteM, PrivilegedM, Funct3M, FWriteIntM, AtomicM, InvalidateICacheM, FlushDCacheM, InstrValidM});
|
||||
flopenrc #(19) controlregM(clk, reset, FlushM, ~StallM,
|
||||
{RegWriteE, ResultSrcE, MemRWE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, FWriteIntE, AtomicE, InvalidateICacheE, FlushDCacheE, FencePendingE, InstrValidE},
|
||||
{RegWriteM, ResultSrcM, MemRWM, CSRReadM, CSRWriteM, PrivilegedM, Funct3M, FWriteIntM, AtomicM, InvalidateICacheM, FlushDCacheM, FencePendingM, InstrValidM});
|
||||
|
||||
// Writeback stage pipeline control register
|
||||
flopenrc #(4) controlregW(clk, reset, FlushW, ~StallW,
|
||||
{RegWriteM, ResultSrcM},
|
||||
{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));
|
||||
endmodule
|
||||
|
@ -71,7 +71,7 @@ module ieu (
|
||||
output logic FPUStallD, LoadStallD, MDUStallD, CSRRdStallD,
|
||||
output logic PCSrcE,
|
||||
output logic CSRReadM, CSRWriteM, PrivilegedM,
|
||||
output logic CSRWritePendingDEM,
|
||||
output logic CSRWriteFencePendingDEM,
|
||||
output logic StoreStallD
|
||||
);
|
||||
|
||||
@ -99,7 +99,7 @@ module ieu (
|
||||
.Funct3E, .MDUE, .W64E, .JumpE, .StallM, .FlushM, .MemRWM,
|
||||
.CSRReadM, .CSRWriteM, .PrivilegedM, .SCE, .AtomicM, .Funct3M,
|
||||
.RegWriteM, .InvalidateICacheM, .FlushDCacheM, .InstrValidM, .FWriteIntM,
|
||||
.StallW, .FlushW, .RegWriteW, .ResultSrcW, .CSRWritePendingDEM, .StoreStallD);
|
||||
.StallW, .FlushW, .RegWriteW, .ResultSrcW, .CSRWriteFencePendingDEM, .StoreStallD);
|
||||
|
||||
datapath dp(
|
||||
.clk, .reset, .ImmSrcD, .InstrD, .StallE, .FlushE, .ForwardAE, .ForwardBE,
|
||||
|
@ -82,7 +82,7 @@ module wallypipelinedcore (
|
||||
logic StoreAmoMisalignedFaultM, StoreAmoAccessFaultM;
|
||||
logic InvalidateICacheM, FlushDCacheM;
|
||||
logic PCSrcE;
|
||||
logic CSRWritePendingDEM;
|
||||
logic CSRWriteFencePendingDEM;
|
||||
logic DivBusyE;
|
||||
logic LoadStallD, StoreStallD, MDUStallD, CSRRdStallD;
|
||||
logic SquashSCW;
|
||||
@ -231,7 +231,7 @@ module wallypipelinedcore (
|
||||
.FPUStallD, .LoadStallD, .MDUStallD, .CSRRdStallD,
|
||||
.PCSrcE,
|
||||
.CSRReadM, .CSRWriteM, .PrivilegedM,
|
||||
.CSRWritePendingDEM, .StoreStallD
|
||||
.CSRWriteFencePendingDEM, .StoreStallD
|
||||
|
||||
); // integer execution unit: integer register file, datapath and controller
|
||||
|
||||
@ -294,13 +294,13 @@ module wallypipelinedcore (
|
||||
|
||||
|
||||
hazard hzu(
|
||||
.BPPredWrongE, .CSRWritePendingDEM, .RetM, .TrapM,
|
||||
.BPPredWrongE, .CSRWriteFencePendingDEM, .RetM, .TrapM,
|
||||
.LoadStallD, .StoreStallD, .MDUStallD, .CSRRdStallD,
|
||||
.LSUStallM, .IFUStallF,
|
||||
.FPUStallD, .FStallD,
|
||||
.DivBusyE, .FDivBusyE,
|
||||
.EcallFaultM, .BreakpointFaultM,
|
||||
.InvalidateICacheM, .sfencevmaM, .wfiM, .IntPendingM,
|
||||
.wfiM, .IntPendingM,
|
||||
// Stall & flush outputs
|
||||
.StallF, .StallD, .StallE, .StallM, .StallW,
|
||||
.FlushF, .FlushD, .FlushE, .FlushM, .FlushW
|
||||
|
Loading…
Reference in New Issue
Block a user