mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
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(
|
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));
|
||||||
|
@ -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
|
||||||
|
@ -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,
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user