cvw/wally-pipelined/src/hazard/hazard.sv

88 lines
4.6 KiB
Systemverilog
Raw Normal View History

2021-01-15 04:37:51 +00:00
///////////////////////////////////////////
// hazard.sv
//
// Written: David_Harris@hmc.edu 9 January 2021
// Modified:
//
// Purpose: Determine forwarding, stalls and flushes
//
// A component of the Wally configurable RISC-V project.
//
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software
// is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
///////////////////////////////////////////
`include "wally-config.vh"
2021-01-15 04:37:51 +00:00
module hazard(
2021-02-02 18:53:13 +00:00
// Detect hazards
// input logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E, RdE, RdM, RdW,
// input logic MemReadE,
// input logic RegWriteM, RegWriteW,
input logic PCSrcE, CSRWritePendingDEM, RetM, TrapM,
2021-02-16 03:27:35 +00:00
input logic LoadStallD, MulDivStallD,
2021-01-30 06:43:49 +00:00
input logic InstrStall, DataStall,
// Stall outputs
2021-02-08 04:21:55 +00:00
output logic StallF, StallD, StallE, StallM, StallW,
output logic FlushD, FlushE, FlushM, FlushW
2021-02-02 18:42:23 +00:00
);
logic BranchFlushDE;
2021-02-08 04:21:55 +00:00
logic StallFCause, StallDCause, StallECause, StallMCause, StallWCause;
logic FirstUnstalledD, FirstUnstalledE, FirstUnstalledM, FirstUnstalledW;
2021-01-15 04:37:51 +00:00
// stalls and flushes
// loads: stall for one cycle if the subsequent instruction depends on the load
// branches and jumps: flush the next two instructions if the branch is taken in EXE
// CSR Writes: stall all instructions after the CSR until it completes, except that PC must change when branch is resolved
// this also applies to other privileged instructions such as M/S/URET, ECALL/EBREAK
// Exceptions: flush entire pipeline
// Ret instructions: occur in M stage. Might be possible to move earlier, but be careful about hazards
2021-01-30 06:43:49 +00:00
// General stall and flush rules:
// A stage must stall if the next stage is stalled
// If any stages are stalled, the first stage that isn't stalled must flush.
2021-02-02 18:42:23 +00:00
assign BranchFlushDE = PCSrcE | RetM | TrapM;
// changed 2/22/21 harris to turn off stallF when RetM or TrapM
// changed 2/23/21 harris to BranchFlushDEM to solve bug in ECALL about JAL being ignored
// assign StallFCause = /*InstrStall | */ CSRWritePendingDEM; // stall at fetch if unable to get the instruction,
// assign StallFCause = /*InstrStall | */ CSRWritePendingDEM & ~(RetM | TrapM); // stall at fetch if unable to get the instruction,
assign StallFCause = /*InstrStall | */ CSRWritePendingDEM & ~(BranchFlushDE); // stall at fetch if unable to get the instruction,
2021-02-08 04:21:55 +00:00
// or if a CSR will be written and may change system behavior
2021-02-25 05:28:41 +00:00
assign StallDCause = LoadStallD | MulDivStallD; // stall in decode if instruction is a load dependent on previous
2021-02-08 04:21:55 +00:00
assign StallECause = 0;
assign StallMCause = 0; // sDataStall; // not yet used***
2021-02-15 15:10:50 +00:00
assign StallWCause = DataStall | InstrStall;
2021-01-30 06:43:49 +00:00
2021-02-08 04:21:55 +00:00
// Each stage stalls if the next stage is stalled or there is a cause to stall this stage.
2021-02-02 18:42:23 +00:00
assign StallF = StallD | StallFCause;
2021-02-08 04:21:55 +00:00
assign StallD = StallE | StallDCause;
assign StallE = StallM | StallECause;
assign StallM = StallW | StallMCause;
assign StallW = StallWCause;
assign FirstUnstalledD = (~StallD & StallF);
assign FirstUnstalledE = (~StallE & StallD);
assign FirstUnstalledM = (~StallM & StallE);
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 FlushD = FirstUnstalledD || BranchFlushDE; // PCSrcE |InstrStall | CSRWritePendingDEM | RetM | TrapM;
assign FlushE = FirstUnstalledE || BranchFlushDE; //LoadStallD | PCSrcE | RetM | TrapM;
assign FlushM = FirstUnstalledM || RetM || TrapM;
assign FlushW = FirstUnstalledW | TrapM;
2021-01-15 04:37:51 +00:00
endmodule