-
Notifications
You must be signed in to change notification settings - Fork 0
/
hazard_detection.vhd
158 lines (129 loc) · 6.56 KB
/
hazard_detection.vhd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
Library IEEE;
USE IEEE.std_logic_1164.all;
entity Hazard_Detection_Unit_Entity is
port(
--inputs
IF_ID_OPCODE,
ID_EX_OPCODE,
EX_MEM_OPCODE : in std_logic_vector(4 downto 0);
IF_ID_Rsrc1,
IF_ID_Rsrc2,
IF_ID_Rdst : in std_logic_vector(2 downto 0);
ID_EX_Rsrc1,
ID_EX_Rsrc2,
ID_EX_Rdst : in std_logic_vector(2 downto 0);
EX_MEM_Rsrc1,
EX_MEM_Rsrc2,
EX_MEM_Rdst : in std_logic_vector(2 downto 0);
clk : in std_logic;
--outputs
Stall:out std_logic :='0';
IF_ID_Write_Enable :out std_logic :='1'
);
end entity;
architecture Hazard_Detection_Unit_Arch of Hazard_Detection_Unit_Entity is
Signal IF_ID_Read_OP : std_logic;
Signal ID_EX_OP,
EX_MEM_OP : std_logic_vector(1 downto 0);
Signal Stall_First_Case,
Stall_Second_Case,
Stall_Third_Case,
Stall_Fourth_Case,
Stall_Fifth_Case,
Stall_Sixth_Case:std_logic;
begin
--checking write operations in ID_EX
----------------------------------------------------
ID_EX_OP <= "00"
when ID_EX_OPCODE = "00100" OR ID_EX_OPCODE = "00000" OR ID_EX_OPCODE = "10000" OR ID_EX_OPCODE = "10100"
OR ID_EX_OPCODE = "11000" OR ID_EX_OPCODE = "11001" OR ID_EX_OPCODE = "11010"
OR ID_EX_OPCODE = "11011" OR ID_EX_OPCODE = "11100" OR ID_EX_OPCODE = "01000" --not wr or mem operation
else "10" when ID_EX_OPCODE = "10001" OR ID_EX_OPCODE = "10011" OR ID_EX_OPCODE = "10011" --mem op
else "01"; --wr op
----------------------------------------------------
--checking write operations in EX_MEM
----------------------------------------------------
EX_MEM_OP <= "00"
when EX_MEM_OPCODE = "00100" OR EX_MEM_OPCODE = "00000" OR EX_MEM_OPCODE = "10000" OR EX_MEM_OPCODE = "10100"
OR EX_MEM_OPCODE = "11000" OR EX_MEM_OPCODE = "11001" OR EX_MEM_OPCODE = "11010"
OR EX_MEM_OPCODE = "11011" OR EX_MEM_OPCODE = "11100" OR EX_MEM_OPCODE = "01000" --not wr or mem operation
else "10" when EX_MEM_OPCODE = "10001" OR EX_MEM_OPCODE = "10011" OR EX_MEM_OPCODE = "10011" --mem op
else "01"; --wr op
-----------------------------------------------------
--Checking IF_ID FOR READ OPERATIONS
---------------------------------------------------------------------------------------------------------------------
IF_ID_Read_OP <= '0'
when IF_ID_OPCODE = "00101" OR IF_ID_OPCODE = "00000" OR IF_ID_OPCODE = "10001" OR IF_ID_OPCODE = "10010"
OR IF_ID_OPCODE = "10011" OR IF_ID_OPCODE = "11000" OR IF_ID_OPCODE = "11001" OR IF_ID_OPCODE = "01000"
OR IF_ID_OPCODE = "11011" OR IF_ID_OPCODE = "11100" OR IF_ID_OPCODE ="10100" OR IF_ID_OPCODE ="10000"
else '1';
--------------------------------------------------------------------------------------------------------------------
--First case (special case of push and std):
--when IF_ID is push or STD and ID_EX or EX_MEM is write and Rdst = Rsrc we should stall
Stall_First_Case <= '1'
when (IF_ID_OPCODE = "10000" OR IF_ID_OPCODE = "10100")
and ((ID_EX_OP /= "00" and (IF_ID_Rsrc2 = ID_EX_Rdst))
OR (EX_MEM_OP /= "00" and IF_ID_Rsrc2 = EX_MEM_Rdst))
else '0';
--Second case (special case of push and std):
--when IF_ID is push or STD and ID_EX or EX_MEM is SWAP and Rdst(swap) = Rsrc , Rsrc(swap) = Rsrc we should stall
Stall_Second_Case <= '1'
when (IF_ID_OPCODE = "10000" OR IF_ID_OPCODE = "10100")
and ((ID_EX_OPCODE = "01000" and (IF_ID_Rsrc2 = ID_EX_Rdst OR IF_ID_Rsrc2 = ID_EX_Rsrc1))
OR (EX_MEM_OPCODE = "01000" and (IF_ID_Rsrc2 = EX_MEM_Rdst OR IF_ID_Rsrc2 = EX_MEM_Rsrc1)))
else '0';
--Third case (special case of swap):
--when IF_ID is swap and ID_EX or EX_MEM is write , Rsrc2(swap) = Rdst(write) or Rdst(swap) = Rdst(write) we should stall
Stall_Third_Case <= '1'
when IF_ID_OPCODE = "01000"
and ((ID_EX_OP = "01" and (IF_ID_Rsrc1 = ID_EX_Rdst OR IF_ID_Rdst = ID_EX_Rdst))
OR (EX_MEM_OP = "01" and (IF_ID_Rsrc1 = EX_MEM_Rdst OR IF_ID_Rdst = EX_MEM_Rdst)))
else '0';
--Fourth case (special case of swap):
--when IF_ID is read and ID_EX or EX_MEM is swap , Rsrc1(read) = Rdst(swap) or Rsrc2(read) = Rdst(swap)
--or Rsrc1(read) = Rsrc2(swap) or Rsrc2(read) = Rsrc2(swap) we should stall
Stall_Fourth_Case <= '1'
when IF_ID_Read_OP = '1'
and ((ID_EX_OPCODE = "01000" and (IF_ID_Rsrc1 = ID_EX_Rdst OR IF_ID_Rsrc2 = ID_EX_Rdst OR IF_ID_Rsrc1 = ID_EX_Rsrc1 OR IF_ID_Rsrc2 = ID_EX_Rsrc1))
OR (EX_MEM_OPCODE = "01000" and (IF_ID_Rsrc1 = EX_MEM_Rdst OR IF_ID_Rsrc2 = EX_MEM_Rdst OR IF_ID_Rsrc1 = EX_MEM_Rsrc1 OR IF_ID_Rsrc2 = EX_MEM_Rsrc1)))
else '0';
--Fifth case (special case of swap):
--when IF_ID is swap and ID_EX or EX_MEM is swap , Rsrc2(read) = Rdst(swap) or Rdst(read) = Rdst(swap)
--or Rsrc2(read) = Rdst(swap) or Rdst(read) = Rsrc2(swap) we should stall
Stall_Fifth_Case <= '1'
when IF_ID_OPCODE = "01000"
and ((ID_EX_OPCODE = "01000" and (IF_ID_Rsrc1 = ID_EX_Rdst OR IF_ID_Rdst = ID_EX_Rdst OR IF_ID_Rsrc1 = ID_EX_Rsrc1 OR IF_ID_Rdst = ID_EX_Rsrc1))
OR (EX_MEM_OPCODE = "01000" and (IF_ID_Rsrc1 = EX_MEM_Rdst OR IF_ID_Rdst = EX_MEM_Rdst OR IF_ID_Rsrc1 = EX_MEM_Rsrc1 OR IF_ID_Rdst = EX_MEM_Rsrc1)))
else '0';
--Sixth case :
--when IF_ID is read and ID_EX is LOAD and Rsrc1 or Rsrc2 = Rdst we should stall
Stall_Sixth_Case <= '1'
when IF_ID_Read_OP = '1'
and (ID_EX_OP = "10" and (IF_ID_Rsrc1 = ID_EX_Rdst OR IF_ID_Rsrc2 = ID_EX_Rdst))
else '0';
--Stall <= '1'
-- when Stall_First_Case = '1' OR Stall_Second_Case = '1' OR Stall_Third_Case = '1'
-- OR Stall_Fourth_Case = '1' OR Stall_Fifth_Case = '1' OR Stall_Sixth_Case = '1'
--else '0' ;
--
--IF_ID_Write_Enable <= '0'
--when Stall_First_Case = '1' OR Stall_Second_Case = '1' OR Stall_Third_Case = '1'
-- OR Stall_Fourth_Case = '1' OR Stall_Fifth_Case = '1' OR Stall_Sixth_Case = '1'
--
--else '1' ;
process (clk)
begin
if((rising_edge(clk))) then
if( Stall_First_Case = '1' OR Stall_Second_Case = '1' OR Stall_Third_Case = '1'
OR Stall_Fourth_Case = '1' OR Stall_Fifth_Case = '1' OR Stall_Sixth_Case = '1')
then Stall <= '1' ;
else Stall <= '0' ;
end if;
if( Stall_First_Case = '1' OR Stall_Second_Case = '1' OR Stall_Third_Case = '1'
OR Stall_Fourth_Case = '1' OR Stall_Fifth_Case = '1' OR Stall_Sixth_Case = '1')
then IF_ID_Write_Enable <= '0' ;
else IF_ID_Write_Enable <= '1' ;
end if;
end if;
end process;
end architecture;