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

Subversion Repositories mips32r1

[/] [mips32r1/] [trunk/] [Hardware/] [XUPV5-LX110T_SoC/] [MIPS32-Pipelined-Hw/] [src/] [MIPS32/] [Hazard_Detection.v] - Blame information for rev 3

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

powered by: WebSVN 2.1.0

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