-
Notifications
You must be signed in to change notification settings - Fork 2
/
forward.v
118 lines (93 loc) · 3.5 KB
/
forward.v
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
`timescale 1ns / 1ps
// forwarding unit, in stage EX
module forward(
input [31:0] ex_instru, // ID/EX.instru
input [31:0] ex_mem_instru, // EX/MEM.WriteReg
input [31:0] mem_wb_instru, // MEM/WB.WriteReg
input c_ex_mem_RegWrite, // EX/MEM.RegWrite
input c_mem_wb_RegWrite, // MEM/WB.RegWrite
output reg [1:0] c_data1_src, // ALU.data1.src (A)
output reg [1:0] c_data2_src // ALU.data2.src (B)
);
// Note: ex_instru[25:21] == ID/EX.Rs
// ex_instru[20:16] == ID/EX.Rt
reg [4:0] ex_mem_wReg,mem_wb_wReg; // exactly Rd
// if I-type, use Rt; if R-type, use Rd
always @(*) begin
if(ex_mem_instru[31:26] == 0) begin
ex_mem_wReg = ex_mem_instru[15:11];
end else begin
ex_mem_wReg = ex_mem_instru[20:16]; // I
end
if(mem_wb_instru[31:26] == 0) begin
mem_wb_wReg = mem_wb_instru[15:11];
end else begin
mem_wb_wReg = mem_wb_instru[20:16]; // I
end
end
always @(*) begin
// $display("ex_mem: 0x%H | mem_wb: 0x%H ",ex_mem_instru,mem_wb_instru);
if(c_ex_mem_RegWrite==1 & (ex_mem_wReg != 0) & (ex_mem_wReg == ex_instru[25:21])) begin
c_data1_src = 2'b10; // from EX/MEM
end else if (c_mem_wb_RegWrite==1 & (mem_wb_wReg != 0) & (mem_wb_wReg == ex_instru[25:21]) &
!(c_ex_mem_RegWrite==1 & (ex_mem_wReg != 0) & (ex_mem_wReg == ex_instru[25:21]))) begin
c_data1_src = 2'b01; // from from MEM/WB
end else begin
c_data1_src = 2'b00; // from current stage
end
// $display ("DATA1_FWD:: 0x%H | 0x%H | 0x%H",c_mem_wb_RegWrite,mem_wb_wReg,ex_instru);
end
always @(*) begin
if(c_ex_mem_RegWrite==1 & (ex_mem_wReg != 0) & (ex_mem_wReg == ex_instru[20:16])) begin
c_data2_src = 2'b10; // from EX/MEM
end else if (c_mem_wb_RegWrite==1 & (mem_wb_wReg != 0) & (mem_wb_wReg == ex_instru[20:16]) &
!(c_ex_mem_RegWrite==1 & (ex_mem_wReg != 0) & (ex_mem_wReg == ex_instru[20:16]))) begin
c_data2_src = 2'b01; // from from MEM/WB
end else begin
c_data2_src = 2'b00; // from current stage
end
end
endmodule
// TODO: [bonus] merge from LYR: beq hazard (forwarding)
module Forwarding_bonus( // created by lyr
input [4:0] IF_ID_Rs,IF_ID_Rt,ID_EX_Rs,ID_EX_Rt,EX_MEM_Rd,MEM_WB_Rd,
// note: MEM_WB_Rd is destination of MEM/WB register, for lw & addi: rt, add: rd
input EX_MEM_RegWrite,MEM_WB_RegWrite,ID_beq,ID_bne,
output reg [1:0] FullFwdA,FullFwdB,
output reg BranFwdA,BranFwdB
);
initial begin
FullFwdA=2'b00;
FullFwdB=2'b00;
BranFwdA=1'b0;
BranFwdB=1'b0;
end
always @(*) begin // FullFwdA
if ((ID_EX_Rs == EX_MEM_Rd) && EX_MEM_RegWrite && (EX_MEM_Rd!=5'b0)) // R-format
FullFwdA=2'b10;
else if ((ID_EX_Rs == MEM_WB_Rd) && MEM_WB_RegWrite && (MEM_WB_Rd!=5'b0)) // lw & R-format
FullFwdA=2'b01;
else
FullFwdA=2'b00;
end
always @(*) begin // FullFwdB
if ((ID_EX_Rt == EX_MEM_Rd) && EX_MEM_RegWrite && (EX_MEM_Rd!=5'b0))
FullFwdB=2'b10;
else if ((ID_EX_Rt == MEM_WB_Rd) && MEM_WB_RegWrite && (MEM_WB_Rd!=5'b0))
FullFwdB=2'b01;
else
FullFwdB=2'b00;
end
always @(*) begin //BranFwdA
if((ID_beq || ID_bne) && (IF_ID_Rs == EX_MEM_Rd) && (EX_MEM_Rd!=5'b0) && EX_MEM_RegWrite)
BranFwdA=1'b1;
else
BranFwdA=1'b0;
end
always @(*) begin //BranFwdB
if((ID_beq || ID_bne) && (IF_ID_Rt == EX_MEM_Rd) && (EX_MEM_Rd!=5'b0) && EX_MEM_RegWrite)
BranFwdB=1'b1;
else
BranFwdB=1'b0;
end
endmodule