OpenCores
URL https://opencores.org/ocsvn/mips32r1/mips32r1/trunk

Subversion Repositories mips32r1

[/] [mips32r1/] [trunk/] [Hardware/] [MIPS32_Standalone/] [Hazard_Detection.v] - Blame information for rev 10

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 ayersg
`timescale 1ns / 1ps
2
/*
3
 * File         : Hazard_Detection.v
4
 * Project      : University of Utah, XUM Project MIPS32 core
5
 * Creator(s)   : Grant Ayers (ayers@cs.utah.edu)
6
 *
7
 * Modification History:
8
 *   Rev   Date         Initials  Description of Change
9
 *   1.0   23-Jul-2011  GEA       Initial design.
10
 *   2.0   26-May-2012  GEA       Release version with CP0.
11 7 ayersg
 *   2.01   1-Nov-2012  GEA       Fixed issue with Jal.
12 2 ayersg
 *
13
 * Standards/Formatting:
14
 *   Verilog 2001, 4 soft tab, wide column.
15
 *
16
 * Description:
17
 *   Hazard Detection and Forward Control. This is the glue that allows a
18
 *   pipelined processor to operate efficiently and correctly in the presence
19
 *   of data, structural, and control hazards. For each pipeline stage, it
20
 *   detects whether that stage requires data that is still in the pipeline,
21
 *   and whether that data may be forwarded or if the pipeline must be stalled.
22
 *
23
 *   This module is heavily commented. Read below for more information.
24
 */
25
module Hazard_Detection(
26 3 ayersg
    input  [7:0] DP_Hazards,
27
    input  [4:0] ID_Rs,
28
    input  [4:0] ID_Rt,
29
    input  [4:0] EX_Rs,
30
    input  [4:0] EX_Rt,
31
    input  [4:0] EX_RtRd,
32
    input  [4:0] MEM_RtRd,
33
    input  [4:0] WB_RtRd,
34
    input  EX_Link,
35
    input  EX_RegWrite,
36
    input  MEM_RegWrite,
37
    input  WB_RegWrite,
38
    input  MEM_MemRead,
39 2 ayersg
    input  MEM_MemWrite,        // Needed for Store Conditional which writes to a register
40
    input  InstMem_Read,
41 3 ayersg
    input  InstMem_Ready,
42
    input  Mfc0,                // Using fwd mux; not part of haz/fwd.
43 2 ayersg
    input  IF_Exception_Stall,
44
    input  ID_Exception_Stall,
45
    input  EX_Exception_Stall,
46 10 ayersg
    input  EX_ALU_Stall,
47 2 ayersg
    input  M_Stall_Controller,  // Determined by data memory controller
48 3 ayersg
    output IF_Stall,
49
    output ID_Stall,
50
    output EX_Stall,
51 2 ayersg
    output M_Stall,
52
    output WB_Stall,
53 3 ayersg
    output [1:0] ID_RsFwdSel,
54
    output [1:0] ID_RtFwdSel,
55
    output [1:0] EX_RsFwdSel,
56
    output [1:0] EX_RtFwdSel,
57
    output M_WriteDataFwdSel
58
    );
59
 
60
    /* Hazard and Forward Detection
61
     *
62
     * Most instructions read from one or more registers. Normally this occurs in
63
     * the ID stage. However, frequently the register file in the ID stage is stale
64
     * when one or more forward stages in the pipeline (EX, MEM, or WB) contains
65
     * an instruction which will eventually update it but has not yet done so.
66
     *
67
     * A hazard condition is created when a forward pipeline stage is set to write
68
     * the same register that a current pipeline stage (e.g. in ID) needs to read.
69
     * The solution is to stall the current stage (and effectively all stages behind
70
     * it) or bypass (forward) the data from forward stages. Fortunately forwarding
71
     * works for most combinations of instructions.
72
     *
73
     * Hazard and Forward conditions are handled based on two simple rules:
74
     * "Wants" and "Needs." If an instruction "wants" data in a certain pipeline
75
     * stage, and that data is available further along in the pipeline, it will
76
     * be forwarded. If it "needs" data and the data is not yet available for forwarding,
77
     * the pipeline stage stalls. If it does not want or need data in a certain
78
     * stage, forwarding is disabled and a stall will not occur. This is important
79
     * for instructions which insert custom data, such as jal or movz.
80
     *
81
     * Currently, "Want" and "Need" conditions are defined for both Rs data and Rt
82
     * data (the two read registers in MIPS), and these conditions exist in the
83
     * ID and EX pipeline stages. This is a total of eight condition bits.
84
     *
85
     * A unique exception exists with Store instructions, which don't need the
86
     * "Rt" data until the MEM stage. Because data doesn't change in WB, and WB
87
     * is the only stage following MEM, forwarding is *always* possible from
88
     * WB to Mem. This unit handles this situation, and a condition bit is not
89
     * needed.
90
     *
91 2 ayersg
     * When data is needed from the MEM stage by a previous stage (ID or EX), the
92
     * decision to forward or stall is based on whether MEM is accessing memory
93
     * (stall) or not (forward). Normally store instructions don't write to registers
94
     * and thus are never needed for a data dependence, so the signal 'MEM_MemRead'
95
     * is sufficient to determine. Because of the Store Conditional instruction,
96
     * however, 'MEM_MemWrite' must also be considered because it writes to a register.
97
     *
98 3 ayersg
     */
99
 
100
    wire WantRsByID, NeedRsByID, WantRtByID, NeedRtByID, WantRsByEX, NeedRsByEX, WantRtByEX, NeedRtByEX;
101
    assign WantRsByID = DP_Hazards[7];
102
    assign NeedRsByID = DP_Hazards[6];
103
    assign WantRtByID = DP_Hazards[5];
104
    assign NeedRtByID = DP_Hazards[4];
105
    assign WantRsByEX = DP_Hazards[3];
106
    assign NeedRsByEX = DP_Hazards[2];
107
    assign WantRtByEX = DP_Hazards[1];
108
    assign NeedRtByEX = DP_Hazards[0];
109 2 ayersg
 
110 3 ayersg
    // Trick allowed by RegDst = 0 which gives Rt. MEM_Rt is only used on
111
    // Data Memory write operations (stores), and RegWrite is always 0 in this case.
112
    wire [4:0] MEM_Rt = MEM_RtRd;
113
 
114
    // Forwarding should not happen when the src/dst register is $zero
115
    wire EX_RtRd_NZ  = (EX_RtRd  != 5'b00000);
116
    wire MEM_RtRd_NZ = (MEM_RtRd != 5'b00000);
117
    wire WB_RtRd_NZ  = (WB_RtRd  != 5'b00000);
118
 
119
    // ID Dependencies
120
    wire Rs_IDEX_Match  = (ID_Rs == EX_RtRd)  & EX_RtRd_NZ  & (WantRsByID | NeedRsByID) & EX_RegWrite;
121
    wire Rt_IDEX_Match  = (ID_Rt == EX_RtRd)  & EX_RtRd_NZ  & (WantRtByID | NeedRtByID) & EX_RegWrite;
122
    wire Rs_IDMEM_Match = (ID_Rs == MEM_RtRd) & MEM_RtRd_NZ & (WantRsByID | NeedRsByID) & MEM_RegWrite;
123
    wire Rt_IDMEM_Match = (ID_Rt == MEM_RtRd) & MEM_RtRd_NZ & (WantRtByID | NeedRtByID) & MEM_RegWrite;
124
    wire Rs_IDWB_Match  = (ID_Rs == WB_RtRd)  & WB_RtRd_NZ  & (WantRsByID | NeedRsByID) & WB_RegWrite;
125
    wire Rt_IDWB_Match  = (ID_Rt == WB_RtRd)  & WB_RtRd_NZ  & (WantRtByID | NeedRtByID) & WB_RegWrite;
126
    // EX Dependencies
127
    wire Rs_EXMEM_Match = (EX_Rs == MEM_RtRd) & MEM_RtRd_NZ & (WantRsByEX | NeedRsByEX) & MEM_RegWrite;
128
    wire Rt_EXMEM_Match = (EX_Rt == MEM_RtRd) & MEM_RtRd_NZ & (WantRtByEX | NeedRtByEX) & MEM_RegWrite;
129
    wire Rs_EXWB_Match  = (EX_Rs == WB_RtRd)  & WB_RtRd_NZ  & (WantRsByEX | NeedRsByEX) & WB_RegWrite;
130
    wire Rt_EXWB_Match  = (EX_Rt == WB_RtRd)  & WB_RtRd_NZ  & (WantRtByEX | NeedRtByEX) & WB_RegWrite;
131
    // MEM Dependencies
132
    wire Rt_MEMWB_Match = (MEM_Rt == WB_RtRd) & WB_RtRd_NZ  & WB_RegWrite;
133 2 ayersg
 
134
 
135 3 ayersg
    // ID needs data from EX  : Stall
136
    wire ID_Stall_1 = (Rs_IDEX_Match  &  NeedRsByID);
137
    wire ID_Stall_2 = (Rt_IDEX_Match  &  NeedRtByID);
138
    // ID needs data from MEM : Stall if mem access
139
    wire ID_Stall_3 = (Rs_IDMEM_Match &  (MEM_MemRead | MEM_MemWrite) & NeedRsByID);
140
    wire ID_Stall_4 = (Rt_IDMEM_Match &  (MEM_MemRead | MEM_MemWrite) & NeedRtByID);
141
    // ID wants data from MEM : Forward if not mem access
142
    wire ID_Fwd_1   = (Rs_IDMEM_Match & ~(MEM_MemRead | MEM_MemWrite));
143
    wire ID_Fwd_2   = (Rt_IDMEM_Match & ~(MEM_MemRead | MEM_MemWrite));
144
    // ID wants/needs data from WB  : Forward
145
    wire ID_Fwd_3   = (Rs_IDWB_Match);
146
    wire ID_Fwd_4   = (Rt_IDWB_Match);
147
    // EX needs data from MEM : Stall if mem access
148
    wire EX_Stall_1 = (Rs_EXMEM_Match &  (MEM_MemRead | MEM_MemWrite) & NeedRsByEX);
149
    wire EX_Stall_2 = (Rt_EXMEM_Match &  (MEM_MemRead | MEM_MemWrite) & NeedRtByEX);
150
    // EX wants data from MEM : Forward if not mem access
151
    wire EX_Fwd_1   = (Rs_EXMEM_Match & ~(MEM_MemRead | MEM_MemWrite));
152
    wire EX_Fwd_2   = (Rt_EXMEM_Match & ~(MEM_MemRead | MEM_MemWrite));
153
    // EX wants/needs data from WB  : Forward
154
    wire EX_Fwd_3   = (Rs_EXWB_Match);
155
    wire EX_Fwd_4   = (Rt_EXWB_Match);
156
    // MEM needs data from WB : Forward
157
    wire MEM_Fwd_1  = (Rt_MEMWB_Match);
158 2 ayersg
 
159
 
160 3 ayersg
    // Stalls and Control Flow Final Assignments    
161 2 ayersg
    assign WB_Stall = M_Stall;
162
    assign  M_Stall = IF_Stall | M_Stall_Controller;
163 10 ayersg
    assign EX_Stall = (EX_Stall_1 | EX_Stall_2 | EX_Exception_Stall) | EX_ALU_Stall | M_Stall;
164 2 ayersg
    assign ID_Stall = (ID_Stall_1 | ID_Stall_2 | ID_Stall_3 | ID_Stall_4 | ID_Exception_Stall) | EX_Stall;
165
    assign IF_Stall = InstMem_Read | InstMem_Ready | IF_Exception_Stall;
166
 
167 3 ayersg
    // Forwarding Control Final Assignments
168 7 ayersg
    assign ID_RsFwdSel = (ID_Fwd_1) ? 2'b01 : ((ID_Fwd_3) ? 2'b10 : 2'b00);
169
    assign ID_RtFwdSel = (Mfc0) ? 2'b11 : ((ID_Fwd_2) ? 2'b01 : ((ID_Fwd_4) ? 2'b10 : 2'b00));
170
    assign EX_RsFwdSel = (EX_Link) ? 2'b11 : ((EX_Fwd_1) ? 2'b01 : ((EX_Fwd_3) ? 2'b10 : 2'b00));
171 3 ayersg
    assign EX_RtFwdSel = (EX_Link)  ? 2'b11 : ((EX_Fwd_2) ? 2'b01 : ((EX_Fwd_4) ? 2'b10 : 2'b00));
172
    assign M_WriteDataFwdSel = MEM_Fwd_1;
173
 
174 2 ayersg
endmodule
175 3 ayersg
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.