mirror of
				https://github.com/openhwgroup/cvw
				synced 2025-02-11 06:05:49 +00:00 
			
		
		
		
	Reworked the hazards to eliminate StallFCause. Flush and CSRWrites now flush F,D,E stages and set the correct PCNextF in the M stage.
This commit is contained in:
		
							parent
							
								
									b02550b05c
								
							
						
					
					
						commit
						e774dd2db9
					
				@ -32,7 +32,7 @@
 | 
			
		||||
 | 
			
		||||
module hazard(
 | 
			
		||||
  // Detect hazards
 | 
			
		||||
(* mark_debug = "true" *)	      input logic  BPPredWrongE, CSRWriteFencePendingDEM, RetM, TrapM,
 | 
			
		||||
(* mark_debug = "true" *)	      input logic  BPPredWrongE, CSRWriteFenceM, RetM, TrapM,
 | 
			
		||||
(* mark_debug = "true" *)	      input logic  LoadStallD, StoreStallD, MDUStallD, CSRRdStallD,
 | 
			
		||||
(* mark_debug = "true" *)	      input logic  LSUStallM, IFUStallF,
 | 
			
		||||
(* mark_debug = "true" *)         input logic  FCvtIntStallD, FStallD,
 | 
			
		||||
@ -46,7 +46,6 @@ 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
 | 
			
		||||
@ -60,22 +59,24 @@ 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.
 | 
			
		||||
 | 
			
		||||
  assign FlushDCause = TrapM | RetM | BPPredWrongE;
 | 
			
		||||
  assign FlushECause = TrapM | RetM | BPPredWrongE;
 | 
			
		||||
  assign FlushMCause = 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 FlushWCause = TrapM & ~(BreakpointFaultM | EcallFaultM);
 | 
			
		||||
  // *** can stalls be pushed into earlier stages (e.g. no stall after Decode?)
 | 
			
		||||
 | 
			
		||||
  // *** consider replacing CSRWriteFencePendingDEM with a flush rather than a stall.  
 | 
			
		||||
  assign StallFCause = CSRWriteFencePendingDEM & ~FlushDCause;
 | 
			
		||||
  //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) & ~FlushECause;
 | 
			
		||||
  assign StallECause = (DivBusyE | FDivBusyE) & ~FlushMCause;
 | 
			
		||||
  assign StallDCause = (LoadStallD | StoreStallD | MDUStallD | CSRRdStallD | FCvtIntStallD | FStallD) & ~(TrapM | RetM | BPPredWrongE | CSRWriteFenceM);    
 | 
			
		||||
  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 & ~FlushWCause & ~IntPendingM; 
 | 
			
		||||
    assign StallWCause = ((IFUStallF | LSUStallM) & ~TrapM);
 | 
			
		||||
  //assign StallWCause = (IFUStallF | LSUStallM) & ~FlushWCause;  // if the fpga fails this is likely why.
 | 
			
		||||
  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;
 | 
			
		||||
@ -89,8 +90,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 #1 FlushD = FirstUnstalledD | FlushDCause; 
 | 
			
		||||
  assign #1 FlushE = FirstUnstalledE | FlushECause;
 | 
			
		||||
  assign #1 FlushM = FirstUnstalledM | FlushMCause;
 | 
			
		||||
  assign #1 FlushW = FirstUnstalledW | FlushWCause;
 | 
			
		||||
  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));
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
@ -68,7 +68,8 @@ module controller(
 | 
			
		||||
  output logic 	     RegWriteW, DivW,    // for datapath and Hazard Unit
 | 
			
		||||
  output logic [2:0] ResultSrcW,
 | 
			
		||||
  // Stall during CSRs
 | 
			
		||||
  output logic       CSRWriteFencePendingDEM,
 | 
			
		||||
  //output logic       CSRWriteFencePendingDEM,
 | 
			
		||||
  output logic       CSRWriteFenceM,
 | 
			
		||||
  output logic       StoreStallD
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
@ -92,7 +93,7 @@ module controller(
 | 
			
		||||
  logic       CSRZeroSrcD;
 | 
			
		||||
  logic       CSRReadD;
 | 
			
		||||
  logic [1:0] AtomicD;
 | 
			
		||||
  logic       FenceD;
 | 
			
		||||
  logic       FenceXD;
 | 
			
		||||
  logic       InvalidateICacheD, FlushDCacheD;
 | 
			
		||||
  logic       CSRWriteD, CSRWriteE;
 | 
			
		||||
  logic       InstrValidD, InstrValidE;
 | 
			
		||||
@ -108,7 +109,8 @@ module controller(
 | 
			
		||||
  logic        IEURegWriteE;
 | 
			
		||||
  logic        IllegalERegAdrD;
 | 
			
		||||
  logic [1:0]  AtomicE;
 | 
			
		||||
   logic       FencePendingD, FencePendingE, FencePendingM;
 | 
			
		||||
   logic       FenceD, FenceE, FenceM;
 | 
			
		||||
  logic        SFenceVmaD;
 | 
			
		||||
   logic       DivE, DivM;
 | 
			
		||||
   
 | 
			
		||||
 | 
			
		||||
@ -177,11 +179,12 @@ module controller(
 | 
			
		||||
  assign IllegalBaseInstrFaultD = ControlsD[0] | IllegalERegAdrD;
 | 
			
		||||
  assign {RegWriteD, ImmSrcD, ALUSrcAD, ALUSrcBD, MemRWD,
 | 
			
		||||
          ResultSrcD, BranchD, ALUOpD, JumpD, ALUResultSrcD, W64D, CSRReadD, 
 | 
			
		||||
          PrivilegedD, FenceD, MDUD, AtomicD, unused} = IllegalIEUInstrFaultD ? `CTRLW'b0 : ControlsD;
 | 
			
		||||
          PrivilegedD, FenceXD, MDUD, AtomicD, unused} = IllegalIEUInstrFaultD ? `CTRLW'b0 : ControlsD;
 | 
			
		||||
 | 
			
		||||
  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
 | 
			
		||||
  assign SFenceVmaD = PrivilegedD & (InstrD[31:25] ==  7'b0001001);
 | 
			
		||||
  assign FenceD = SFenceVmaD | FenceXD; // 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);
 | 
			
		||||
@ -196,7 +199,7 @@ module controller(
 | 
			
		||||
  // FENCE.I flushes the D$ and invalidates the I$ if Zifencei is supported and I$ is implemented
 | 
			
		||||
  if (`ZIFENCEI_SUPPORTED & `ICACHE) begin:fencei
 | 
			
		||||
    logic FenceID;
 | 
			
		||||
    assign FenceID = FenceD & (Funct3D == 3'b001); // is it a FENCE.I instruction?
 | 
			
		||||
    assign FenceID = FenceXD & (Funct3D == 3'b001); // is it a FENCE.I instruction?
 | 
			
		||||
    assign InvalidateICacheD = FenceID;
 | 
			
		||||
    assign FlushDCacheD = FenceID;
 | 
			
		||||
  end else begin:fencei
 | 
			
		||||
@ -209,8 +212,8 @@ module controller(
 | 
			
		||||
 | 
			
		||||
  // Execute stage pipeline control register and logic
 | 
			
		||||
  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});
 | 
			
		||||
                           {RegWriteD, ResultSrcD, MemRWD, JumpD, BranchD, ALUControlD, ALUSrcAD, ALUSrcBD, ALUResultSrcD, CSRReadD, CSRWriteD, PrivilegedD, Funct3D, W64D, MDUD, AtomicD, InvalidateICacheD, FlushDCacheD, FenceD, InstrValidD},
 | 
			
		||||
                           {IEURegWriteE, ResultSrcE, MemRWE, JumpE, BranchE, ALUControlE, ALUSrcAE, ALUSrcBE, ALUResultSrcE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, W64E, MDUE, AtomicE, InvalidateICacheE, FlushDCacheE, FenceE, InstrValidE});
 | 
			
		||||
 | 
			
		||||
  // Branch Logic
 | 
			
		||||
  assign BranchSignedE = ~(Funct3E[2:1] == 2'b11);
 | 
			
		||||
@ -227,16 +230,17 @@ module controller(
 | 
			
		||||
  
 | 
			
		||||
  // Memory stage pipeline control register
 | 
			
		||||
  flopenrc #(20) controlregM(clk, reset, FlushM, ~StallM,
 | 
			
		||||
                         {RegWriteE, ResultSrcE, MemRWE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, FWriteIntE, AtomicE, InvalidateICacheE, FlushDCacheE, FencePendingE, InstrValidE, DivE},
 | 
			
		||||
                         {RegWriteM, ResultSrcM, MemRWM, CSRReadM, CSRWriteM, PrivilegedM, Funct3M, FWriteIntM, AtomicM, InvalidateICacheM, FlushDCacheM, FencePendingM, InstrValidM, DivM});
 | 
			
		||||
                         {RegWriteE, ResultSrcE, MemRWE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, FWriteIntE, AtomicE, InvalidateICacheE, FlushDCacheE, FenceE, InstrValidE, DivE},
 | 
			
		||||
                         {RegWriteM, ResultSrcM, MemRWM, CSRReadM, CSRWriteM, PrivilegedM, Funct3M, FWriteIntM, AtomicM, InvalidateICacheM, FlushDCacheM, FenceM, InstrValidM, DivM});
 | 
			
		||||
  
 | 
			
		||||
  // Writeback stage pipeline control register
 | 
			
		||||
  flopenrc #(5) controlregW(clk, reset, FlushW, ~StallW,
 | 
			
		||||
                         {RegWriteM, ResultSrcM, DivM},
 | 
			
		||||
                         {RegWriteW, ResultSrcW, DivW});  
 | 
			
		||||
 | 
			
		||||
  // Stall pipeline at Fetch if a CSR Write or Fence is pending in the subsequent stages
 | 
			
		||||
  assign CSRWriteFencePendingDEM = CSRWriteD | CSRWriteE | CSRWriteM | FencePendingD | FencePendingE | FencePendingM;
 | 
			
		||||
  // Flush F, D, and E stages on a CSR write or Fence.I or SFence.VMA
 | 
			
		||||
  assign CSRWriteFenceM = CSRWriteM | FenceM;
 | 
			
		||||
//  assign CSRWriteFencePendingDEM = CSRWriteD | CSRWriteE | CSRWriteM | FenceD | FenceE | FenceM;
 | 
			
		||||
 | 
			
		||||
  // the synchronous DTIM cannot read immediately after write
 | 
			
		||||
  // a cache cannot read or write immediately after a write
 | 
			
		||||
 | 
			
		||||
@ -71,7 +71,7 @@ module ieu (
 | 
			
		||||
  output logic 		   FCvtIntStallD, LoadStallD, MDUStallD, CSRRdStallD,
 | 
			
		||||
  output logic 		   PCSrcE,
 | 
			
		||||
  output logic 		   CSRReadM, CSRWriteM, PrivilegedM,
 | 
			
		||||
  output logic 		   CSRWriteFencePendingDEM,
 | 
			
		||||
  output logic 		   CSRWriteFenceM,
 | 
			
		||||
  output logic             StoreStallD
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
@ -101,7 +101,7 @@ module ieu (
 | 
			
		||||
    .Funct3E, .MDUE, .W64E, .JumpE, .SCE, .BranchSignedE, .StallM, .FlushM, .MemRWM,
 | 
			
		||||
    .CSRReadM, .CSRWriteM, .PrivilegedM, .AtomicM, .Funct3M,
 | 
			
		||||
    .RegWriteM, .InvalidateICacheM, .FlushDCacheM, .InstrValidM, .FWriteIntM,
 | 
			
		||||
    .StallW, .FlushW, .RegWriteW, .DivW, .ResultSrcW, .CSRWriteFencePendingDEM, .StoreStallD);
 | 
			
		||||
    .StallW, .FlushW, .RegWriteW, .DivW, .ResultSrcW, .CSRWriteFenceM, .StoreStallD);
 | 
			
		||||
 | 
			
		||||
  datapath   dp(
 | 
			
		||||
    .clk, .reset, .ImmSrcD, .InstrD, .StallE, .FlushE, .ForwardAE, .ForwardBE,
 | 
			
		||||
 | 
			
		||||
@ -55,6 +55,7 @@ module ifu (
 | 
			
		||||
	input logic 				RetM, TrapM, 
 | 
			
		||||
    output logic                CommittedF, 
 | 
			
		||||
	input logic [`XLEN-1:0] 	PrivilegedNextPCM, 
 | 
			
		||||
	input logic         	    CSRWriteFenceM,
 | 
			
		||||
    input logic                 InvalidateICacheM,
 | 
			
		||||
	output logic [31:0] 		InstrD, InstrM, 
 | 
			
		||||
	output logic [`XLEN-1:0] 	PCM, 
 | 
			
		||||
@ -288,10 +289,10 @@ module ifu (
 | 
			
		||||
  assign PrivilegedChangePCM = RetM | TrapM;
 | 
			
		||||
 | 
			
		||||
  mux2 #(`XLEN) pcmux1(.d0(PCNext0F), .d1(PCCorrectE), .s(BPPredWrongE), .y(PCNext1F));
 | 
			
		||||
  if(`ICACHE)
 | 
			
		||||
    mux2 #(`XLEN) pcmux2(.d0(PCNext1F), .d1(PCBPWrongInvalidate), .s(InvalidateICacheM), 
 | 
			
		||||
//  if(`ICACHE | `ZICSR_SUPPORTED)
 | 
			
		||||
    mux2 #(`XLEN) pcmux2(.d0(PCNext1F), .d1(PCBPWrongInvalidate), .s(CSRWriteFenceM), 
 | 
			
		||||
      .y(PCNext2F));
 | 
			
		||||
  else assign PCNext2F = PCNext1F;
 | 
			
		||||
//  else assign PCNext2F = PCNext1F;
 | 
			
		||||
  if(`ZICSR_SUPPORTED)
 | 
			
		||||
    mux2 #(`XLEN) pcmux3(.d0(PCNext2F), .d1(PrivilegedNextPCM), .s(PrivilegedChangePCM), 
 | 
			
		||||
      .y(UnalignedPCNextF));
 | 
			
		||||
 | 
			
		||||
@ -79,7 +79,7 @@ module wallypipelinedcore (
 | 
			
		||||
  logic             StoreAmoMisalignedFaultM, StoreAmoAccessFaultM;
 | 
			
		||||
  logic       InvalidateICacheM, FlushDCacheM;
 | 
			
		||||
  logic             PCSrcE;
 | 
			
		||||
  logic             CSRWriteFencePendingDEM;
 | 
			
		||||
  logic             CSRWriteFenceM;
 | 
			
		||||
  logic             DivBusyE;
 | 
			
		||||
  logic             LoadStallD, StoreStallD, MDUStallD, CSRRdStallD;
 | 
			
		||||
  logic             SquashSCW;
 | 
			
		||||
@ -183,7 +183,7 @@ module wallypipelinedcore (
 | 
			
		||||
    .BPPredWrongE, 
 | 
			
		||||
  
 | 
			
		||||
    // Mem
 | 
			
		||||
    .RetM, .TrapM, .CommittedF, .PrivilegedNextPCM, .InvalidateICacheM,
 | 
			
		||||
    .RetM, .TrapM, .CommittedF, .PrivilegedNextPCM, .InvalidateICacheM, .CSRWriteFenceM,
 | 
			
		||||
    .InstrD, .InstrM, .PCM, .InstrClassM, .BPPredDirWrongM,
 | 
			
		||||
    .BTBPredPCWrongM, .RASPredPCWrongM, .BPPredClassNonCFIWrongM,
 | 
			
		||||
  
 | 
			
		||||
@ -241,7 +241,7 @@ module wallypipelinedcore (
 | 
			
		||||
     .FCvtIntStallD, .LoadStallD, .MDUStallD, .CSRRdStallD,
 | 
			
		||||
     .PCSrcE,
 | 
			
		||||
     .CSRReadM, .CSRWriteM, .PrivilegedM,
 | 
			
		||||
     .CSRWriteFencePendingDEM, .StoreStallD
 | 
			
		||||
     .CSRWriteFenceM, .StoreStallD
 | 
			
		||||
 | 
			
		||||
  ); // integer execution unit: integer register file, datapath and controller
 | 
			
		||||
 | 
			
		||||
@ -317,7 +317,7 @@ module wallypipelinedcore (
 | 
			
		||||
 | 
			
		||||
  
 | 
			
		||||
   hazard     hzu(
 | 
			
		||||
     .BPPredWrongE, .CSRWriteFencePendingDEM, .RetM, .TrapM,
 | 
			
		||||
     .BPPredWrongE, .CSRWriteFenceM, .RetM, .TrapM,
 | 
			
		||||
     .LoadStallD, .StoreStallD, .MDUStallD, .CSRRdStallD,
 | 
			
		||||
     .LSUStallM, .IFUStallF,
 | 
			
		||||
     .FCvtIntStallD, .FStallD,
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user