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
|
`timescale 1ns / 1ps
module forwarding_unit (
input ex_mem_reg_write,
input mem_wb_reg_write,
input [4:0] ex_mem_dst_reg,
input [4:0] mem_wb_dst_reg,
input [4:0] id_ex_rs,
input [4:0] id_ex_rt,
input [4:0] if_id_rs,
input [4:0] if_id_rt,
output [1:0] if_rs_forward_control,
output [1:0] id_rt_forward_control,
output [1:0] ex_rs_forward_control,
output [1:0] ex_rt_forward_control );
//tmp signals
wire [3:0] id_fwd_ctrl, ex_fwd_ctrl;
// encoding for muxes control signals
// general for both forwarding muxes
// 2'b01 - from EX_MEM pipe reg
// 2'b10 - from MEM_WB pipe reg
// 2'b00 - no forwarding
assign if_rs_forward_control = id_fwd_ctrl[0] ? 2'b01 : id_fwd_ctrl[2] ? 2'b10 : 2'b00;
assign id_rt_forward_control = id_fwd_ctrl[1] ? 2'b01 : id_fwd_ctrl[3] ? 2'b10 : 2'b00;
assign ex_rs_forward_control = ex_fwd_ctrl[0] ? 2'b01 : ex_fwd_ctrl[2] ? 2'b10 : 2'b00;
assign ex_rt_forward_control = ex_fwd_ctrl[1] ? 2'b01 : ex_fwd_ctrl[3] ? 2'b10 : 2'b00;
base_forwarding_unit ex_forwarding_inst(
.ex_mem_reg_write(ex_mem_reg_write),
.mem_wb_reg_write(mem_wb_reg_write),
.ex_mem_dst_reg(ex_mem_dst_reg),
.mem_wb_dst_reg(mem_wb_dst_reg),
.rs(id_ex_rs),
.rt(id_ex_rt),
.forward_control(ex_fwd_ctrl));
base_forwarding_unit id_forwarding_inst(
.ex_mem_reg_write(ex_mem_reg_write),
.mem_wb_reg_write(mem_wb_reg_write),
.ex_mem_dst_reg(ex_mem_dst_reg),
.mem_wb_dst_reg(mem_wb_dst_reg),
.rs(if_id_rs),
.rt(if_id_rt),
.forward_control(id_fwd_ctrl));
endmodule
/* Generic base logic module to implement forwarding
*
* Description of forward_control signal:
* 0000 - no forwarding
* 0001 - forwarding value from EX_MEM for replace rs value on destination stage.
* EX_MEM[Value] -> PIPE_STAGE[rs]
* 0010 - forwarding value from EX_MEM for replace rt value on destination stage.
* EX_MEM[Value] -> PIPE_STAGE[rt]
* 0100 - forwarding value from WB for replace rs value on destination stage.
* WB[Value] -> PIPE_STAGE[rs]
* 1000 - forwarding value from WB for replace rt value on destination stage.
* WB[Value] -> PIPE_STAGE[rt]
* 0011 - forwarding value from EX_MEM for replace rs and rt value on destination stage
* EX_MEM[Value] -> PIPE_STAGE[rs]; EX_MEM[Value] -> PIPE_STAGE[rt]
* 1100 - forwarding value from WB for replace Rs and Rt value on destination stage
* WB[Value] -> PIPE_STAGE[rs]; WB[Value] -> PIPE_STAGE[rt]
* 0110 - forwarding value from EX_MEM for replace rt value on destination stage.
* EX_MEM[Value] -> PIPE_STAGE[rt]
* forwarding value from WB for replace rs value on destination stage.
* WB[Value] -> PIPE_STAGE[rs]
* 1001 - forwarding value from EX_MEM for replace rs value on destination stage.
* EX_MEM[Value] -> PIPE_STAGE[rs]
* forwarding value from WB for replace rt value on destination stage.
* WB[Value] -> PIPE_STAGE[rt]
*/
module base_forwarding_unit ( input ex_mem_reg_write,
input mem_wb_reg_write,
input [4:0] ex_mem_dst_reg,
input [4:0] mem_wb_dst_reg,
input [4:0] rs,
input [4:0] rt,
output reg [3:0] forward_control);
//service signals
reg ex_mem_dst_reg_is_not_zero;
reg mem_wb_dst_reg_is_not_zero;
always @* begin
ex_mem_dst_reg_is_not_zero = |ex_mem_dst_reg;
mem_wb_dst_reg_is_not_zero = |mem_wb_dst_reg;
forward_control = 4'h0;
if (ex_mem_reg_write & ex_mem_dst_reg_is_not_zero) begin
if (ex_mem_dst_reg == rs)
forward_control[0] = 1'b1;
else
forward_control[0] = 1'b0;
if (ex_mem_dst_reg == rt)
forward_control[1] = 1'b1;
else
forward_control[1] = 1'b0;
end
else
forward_control[1:0] = 2'b00;
if (mem_wb_reg_write & mem_wb_dst_reg_is_not_zero) begin
if ((mem_wb_dst_reg == rs) & (ex_mem_dst_reg != rs))
forward_control[2] = 1'b1;
else
forward_control[2] = 1'b0;
if ((mem_wb_dst_reg == rt) & (ex_mem_dst_reg != rt))
forward_control[3] = 1'b1;
else
forward_control[3] = 1'b0;
end
else
forward_control[3:2] = 2'b00;
end
endmodule
|