-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathforward.sv
More file actions
260 lines (210 loc) · 16.9 KB
/
forward.sv
File metadata and controls
260 lines (210 loc) · 16.9 KB
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
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
// Forwarding unit for handling data hazards
module forward
#(
parameter BITS = 32,
parameter REG_ADDR_BITS = 5
)
(
// Stage 2 source register addresses (for three-stage hazards)
input logic [REG_ADDR_BITS-1:0] r1_addr,
input logic [REG_ADDR_BITS-1:0] r2_addr,
// Stage 3 source register addresses (for one/two-stage hazards)
input logic [REG_ADDR_BITS-1:0] r1_addr_s3,
input logic [REG_ADDR_BITS-1:0] r2_addr_s3,
// Stage 3 control signals (for stall detection)
input logic sel_mem_s3,
input logic [REG_ADDR_BITS-1:0] waddr_s3,
input logic rw_s3,
// Stage 4 writeback info
input logic rw_s4,
input logic [REG_ADDR_BITS-1:0] waddr_s4,
input logic sel_mem_s4,
// Stage 5 writeback info
input logic rw_s5,
input logic [REG_ADDR_BITS-1:0] waddr_s5,
// Control hazard signals (for jump register and branches)
input logic jreg, // JR instruction signal
input logic breq, // BEQ instruction signal
input logic brne, // BNE instruction signal
// Forwarding control outputs
output logic r1_fwd_s4, // Forward from Stage 4 to r1 (Stage 3)
output logic r2_fwd_s4, // Forward from Stage 4 to r2 (Stage 3)
output logic r1_fwd_s5, // Forward from Stage 5 to r1 (Stage 3)
output logic r2_fwd_s5, // Forward from Stage 5 to r2 (Stage 3)
output logic r1_fwd_s6, // Forward from Stage 5 to r1 (Stage 2)
output logic r2_fwd_s6, // Forward from Stage 5 to r2 (Stage 2)
// Jump register forwarding outputs
output logic j_fwd_s4, // Forward from Stage 4 to PC for JR
output logic j_fwd_s5, // Forward from Stage 5 to PC for JR
// Branch forwarding outputs
output logic b_r1_fwd_s4, // Forward from Stage 4 to r1 for branches
output logic b_r2_fwd_s4, // Forward from Stage 4 to r2 for branches
output logic b_r1_fwd_s5, // Forward from Stage 5 to r1 for branches
output logic b_r2_fwd_s5, // Forward from Stage 5 to r2 for branches
// Stall control output
output logic stall_pipe // Stall pipeline for load-use hazard
);
// ═══════════════════════════════════════════════════════════════
// STEP 1: One-Stage Hazard Detection (EX-to-EX forwarding)
// Forward from Stage 4 (MEM) to Stage 3 (EX)
// Forward alu_out_s4 even for loads (stall should prevent this)
// ═══════════════════════════════════════════════════════════════
// Forward from Stage 4 to r1
assign r1_fwd_s4 = (!rw_s4) && // Stage 4 is doing a write
(waddr_s4 != 5'b0) && // Not writing to $zero
(waddr_s4 == r1_addr_s3); // Addresses match
// Forward from Stage 4 to r2
assign r2_fwd_s4 = (!rw_s4) && // Stage 4 is doing a write
(waddr_s4 != 5'b0) && // Not writing to $zero
(waddr_s4 == r2_addr_s3); // Addresses match
// ═══════════════════════════════════════════════════════════════
// STEP 2: Two-Stage Hazard Detection (MEM-to-EX forwarding)
// Forward from Stage 5 (WB) to Stage 3 (EX)
// Priority: Stage 4 forwarding takes precedence over Stage 5
// ═══════════════════════════════════════════════════════════════
// Forward from Stage 5 to r1 in Stage 3 (only if Stage 4 is not forwarding)
assign r1_fwd_s5 = (!rw_s5) && // Stage 5 is doing a write
(waddr_s5 != 5'b0) && // Not writing to $zero
(waddr_s5 == r1_addr_s3) && // Addresses match
(!r1_fwd_s4); // Stage 4 NOT forwarding (priority)
// Forward from Stage 5 to r2 in Stage 3 (only if Stage 4 is not forwarding)
assign r2_fwd_s5 = (!rw_s5) && // Stage 5 is doing a write
(waddr_s5 != 5'b0) && // Not writing to $zero
(waddr_s5 == r2_addr_s3) && // Addresses match
(!r2_fwd_s4); // Stage 4 NOT forwarding (priority)
// ═══════════════════════════════════════════════════════════════
// STEP 4: Three-Stage Hazard Detection (WB-to-ID forwarding)
// Forward from Stage 5 (WB) to Stage 2 (ID)
// This handles the write-then-read same-cycle case
// ═══════════════════════════════════════════════════════════════
// Forward from Stage 5 to r1 in Stage 2
assign r1_fwd_s6 = (!rw_s5) && // Stage 5 is doing a write
(waddr_s5 != 5'b0) && // Not writing to $zero
(waddr_s5 == r1_addr); // Stage 2 needs it
// Forward from Stage 5 to r2 in Stage 2
assign r2_fwd_s6 = (!rw_s5) && // Stage 5 is doing a write
(waddr_s5 != 5'b0) && // Not writing to $zero
(waddr_s5 == r2_addr); // Stage 2 needs it
// ═══════════════════════════════════════════════════════════════
// STEP 6: Memory Hazard Detection (Load-Use Stalling)
// Detect when a load instruction's result is needed immediately
// Solution: Stall the pipeline for 1 cycle
// ═══════════════════════════════════════════════════════════════
logic load_use_r1; // Load-use hazard on r1
logic load_use_r2; // Load-use hazard on r2
// Detect load-use hazard on r1
assign load_use_r1 = sel_mem_s3 && // Stage 3 is a load (reading memory)
(waddr_s3 != 5'b0) && // Not loading to $zero
(waddr_s3 == r1_addr); // Stage 2 needs this register
// Detect load-use hazard on r2
assign load_use_r2 = sel_mem_s3 && // Stage 3 is a load (reading memory)
(waddr_s3 != 5'b0) && // Not loading to $zero
(waddr_s3 == r2_addr); // Stage 2 needs this register
// ═══════════════════════════════════════════════════════════════
// STEP 8: Jump Register Stall Detection (Stage 3 Hazard)
// Detect when JR needs a register being computed in Stage 3
// Solution: Stall for 1 cycle, then forward from Stage 4
// ═══════════════════════════════════════════════════════════════
logic jr_stall_s3; // JR needs to stall for Stage 3 computation
// Detect JR hazard with Stage 3
assign jr_stall_s3 = jreg && // JR instruction
(!rw_s3) && // Stage 3 is writing
(waddr_s3 != 5'b0) && // Not writing to $zero
(waddr_s3 == r1_addr); // Writing to register JR needs
// ═══════════════════════════════════════════════════════════════
// STEP 9: Jump Register Load-Use Stall (Stage 4 Load Hazard)
// Detect when JR needs a value being loaded from memory in Stage 4
// Solution: Stall for 2 cycles, then forward from Stage 5
// ═══════════════════════════════════════════════════════════════
logic jr_stall_s4; // JR needs to stall for Stage 4 memory load
// Detect JR hazard with Stage 4 load
assign jr_stall_s4 = jreg && // JR instruction
sel_mem_s4 && // Stage 4 is a load (reading memory)
(waddr_s4 != 5'b0) && // Not loading to $zero
(waddr_s4 == r1_addr); // Loading to register JR needs
// ═══════════════════════════════════════════════════════════════
// STEP 7: Jump Register Hazard Detection (Stage 4 Forwarding)
// Forward from Stage 4 (MEM) to PC for JR instruction
// Handles case with 1 NOP between instruction and JR
// Priority: Stage 4 has higher priority than Stage 5
// ═══════════════════════════════════════════════════════════════
// Forward from Stage 4 to PC for JR
assign j_fwd_s4 = jreg && // JR instruction
(!rw_s4) && // Stage 4 is writing
(waddr_s4 != 5'b0) && // Not writing to $zero
(waddr_s4 == r1_addr); // Writing to register JR needs
// ═══════════════════════════════════════════════════════════════
// STEP 6: Jump Register Hazard Detection (Stage 5 Forwarding)
// Forward from Stage 5 (WB) to PC for JR instruction
// Handles case with 2 NOPs between instruction and JR
// Priority: Only forward from Stage 5 if Stage 4 is not forwarding
// ═══════════════════════════════════════════════════════════════
// Forward from Stage 5 to PC for JR (only if Stage 4 not forwarding)
assign j_fwd_s5 = jreg && // JR instruction
(!rw_s5) && // Stage 5 is writing
(waddr_s5 != 5'b0) && // Not writing to $zero
(waddr_s5 == r1_addr) && // Writing to register JR needs
(!j_fwd_s4); // Stage 4 NOT forwarding (priority)
// ═══════════════════════════════════════════════════════════════
// STEP 10: Branch Hazard Detection (Forwarding and Stalling)
// Similar to JR, but check BOTH r1 and r2 sources
// Forward to equality module for branch comparison
// ═══════════════════════════════════════════════════════════════
logic branch_instr; // BEQ or BNE instruction
assign branch_instr = breq || brne;
// ───────────────────────────────────────────────────────────────
// Stage 4 Forwarding for Branches (1 NOP between)
// ───────────────────────────────────────────────────────────────
// Forward from Stage 4 to r1 for branches
assign b_r1_fwd_s4 = branch_instr && // Branch instruction
(!rw_s4) && // Stage 4 is writing
(waddr_s4 != 5'b0) && // Not writing to $zero
(waddr_s4 == r1_addr); // Writing to register branch needs
// Forward from Stage 4 to r2 for branches
assign b_r2_fwd_s4 = branch_instr && // Branch instruction
(!rw_s4) && // Stage 4 is writing
(waddr_s4 != 5'b0) && // Not writing to $zero
(waddr_s4 == r2_addr); // Writing to register branch needs
// ───────────────────────────────────────────────────────────────
// Stage 5 Forwarding for Branches (2 NOPs between)
// ───────────────────────────────────────────────────────────────
// Forward from Stage 5 to r1 for branches (only if Stage 4 not forwarding)
assign b_r1_fwd_s5 = branch_instr && // Branch instruction
(!rw_s5) && // Stage 5 is writing
(waddr_s5 != 5'b0) && // Not writing to $zero
(waddr_s5 == r1_addr) && // Writing to register branch needs
(!b_r1_fwd_s4); // Stage 4 NOT forwarding (priority)
// Forward from Stage 5 to r2 for branches (only if Stage 4 not forwarding)
assign b_r2_fwd_s5 = branch_instr && // Branch instruction
(!rw_s5) && // Stage 5 is writing
(waddr_s5 != 5'b0) && // Not writing to $zero
(waddr_s5 == r2_addr) && // Writing to register branch needs
(!b_r2_fwd_s4); // Stage 4 NOT forwarding (priority)
// ───────────────────────────────────────────────────────────────
// Branch Stall Detection (Stage 3 Hazard - 1-cycle stall)
// ───────────────────────────────────────────────────────────────
logic br_stall_s3; // Branch needs to stall for Stage 3 computation
// Detect branch hazard with Stage 3 (either r1 or r2)
assign br_stall_s3 = branch_instr && // Branch instruction
(!rw_s3) && // Stage 3 is writing
(waddr_s3 != 5'b0) && // Not writing to $zero
((waddr_s3 == r1_addr) || // Writing to r1 OR
(waddr_s3 == r2_addr)); // Writing to r2
// ───────────────────────────────────────────────────────────────
// Branch Load-Use Stall Detection (Stage 4 Load - 2-cycle stall)
// ───────────────────────────────────────────────────────────────
logic br_stall_s4; // Branch needs to stall for Stage 4 memory load
// Detect branch hazard with Stage 4 load (either r1 or r2)
assign br_stall_s4 = branch_instr && // Branch instruction
sel_mem_s4 && // Stage 4 is a load (reading memory)
(waddr_s4 != 5'b0) && // Not loading to $zero
((waddr_s4 == r1_addr) || // Loading to r1 OR
(waddr_s4 == r2_addr)); // Loading to r2
// ───────────────────────────────────────────────────────────────
// Combined Stall Signal
// ───────────────────────────────────────────────────────────────
// Update stall_pipe to include branch stalls
assign stall_pipe = load_use_r1 || load_use_r2 || // Data hazard stalls
jr_stall_s3 || jr_stall_s4 || // JR stalls
br_stall_s3 || br_stall_s4; // Branch stalls
endmodule