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 2

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
        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
    input  ID_Link,
34
        input  EX_Link,
35
        input  EX_RegWrite,
36
        input  MEM_RegWrite,
37
        input  WB_RegWrite,
38
        input  MEM_MemRead,
39
    input  MEM_MemWrite,        // Needed for Store Conditional which writes to a register
40
    input  InstMem_Read,
41
        input  InstMem_Ready,
42
        input  Mfc0,                            // Using fwd mux; not part of haz/fwd.
43
    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
        output IF_Stall,
48
        output ID_Stall,
49
        output EX_Stall,
50
    output M_Stall,
51
    output WB_Stall,
52
        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
     * 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
         */
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
 
109
        // 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
 
133
 
134
        // 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
 
158
 
159
        // Stalls and Control Flow Final Assignments    
160
    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
        // 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
    assign EX_RsFwdSel = (EX_Fwd_1) ? 2'b01 : ((EX_Fwd_3) ? 2'b10 : 2'b00);
170
        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
endmodule

powered by: WebSVN 2.1.0

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