aboutsummaryrefslogtreecommitdiff
path: root/hdl/forwarding_unit.v
blob: ab9821994653531737548832bc2bd01aeca10f9a (plain)
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
`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