aboutsummaryrefslogtreecommitdiff
path: root/hdl/ex_stage.v
blob: cca87e99c82058c5104b6592e53bb4d307f17e8f (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
module ex_stage(
                input             clk,
                input             rst,

                input             wb_reg_write,
                input             wb_mem_to_reg,
                
                input             mem_read, 
                input             mem_write,
                
                input             ex_imm_command,
                input             ex_alu_src_b,
                input             ex_dst_reg_sel,
                input [1:0]       ex_alu_op,
                
                input [31:0]      A,
                input [31:0]      B,
                input [31:0]      sign_extend_offset,
                input [4:0]       rt, // target register
                input [4:0]       rd, // destination register
                input [5:0]       opcode, 
                input [1:0]       rs_fwd_sel, // forwarding muxes control
                input [1:0]       rt_fwd_sel, // forwarding muxes control
                input [31:0]      mem_fwd_val, // forwarding from EX_MEM
                input [31:0]      wb_fwd_val, // forwarding from WB
                
                // outputs
                output [4:0]      ex_dst_reg,
                output [5:0]      ex_opcode,
                
                output reg [31:0] EX_MEM_alu_result,
                output reg [31:0] EX_MEM_B_value,
                output reg [4:0]  EX_MEM_dst_reg,
                output reg [5:0]  EX_MEM_opcode,                 
                output reg        EX_MEM_mem_read,
                output reg        EX_MEM_mem_write,
                output reg        EX_MEM_wb_reg_write,
                output reg        EX_MEM_wb_mem_to_reg                
);


   wire [5:0]                     func_field;     // func code field in instruction
   wire [5:0]                     func_code;      // func code for ALU control   
   wire [4:0]                     alu_ctl;        // ALU control lines

   reg [31:0]                     alu_a_in;
   wire [31:0]                    alu_b_in;
   reg[31:0]                      b_value;
   
   wire [31:0]                    alu_result;                    
   wire                           zero;


   always @* 
     begin
        case(rs_fwd_sel)
          0: alu_a_in = A;
          1: alu_a_in = mem_fwd_val;
          2: alu_a_in = wb_fwd_val;
        endcase
     end

   always @* 
     begin
        case(rt_fwd_sel)
          0: b_value = B;
          1: b_value = mem_fwd_val;
          2: b_value = wb_fwd_val;
        endcase
     end

   assign alu_b_in   = ex_alu_src_b ? sign_extend_offset : b_value;
   assign func_field = sign_extend_offset [5:0]; // looks wierd, but func code is encoded there
   assign func_code  = ex_imm_command ? {{2'b10},{~opcode[2] & opcode[1] & ~opcode[0]},opcode[2:0]} : func_field;
   assign ex_opcode  = opcode;
   assign ex_dst_reg = ex_dst_reg_sel ? rd : rt;
   
   
   
   alu_ctrl aluctl_inst(
                        .alu_op    (ex_alu_op),
                        .func_code (func_code),
                        .alu_ctl   (alu_ctl)
                       );

   alu alu_inst (
                 .alu_ctl   (alu_ctl), 
                 .a_in      (alu_a_in), 
                 .b_in      (alu_b_in), 
                 .result    (alu_result), 
                 .zero_flag (zero)
                 );

   // EX/MEM Pipeline register
   always @(posedge clk) begin
      if (rst)
        begin
           EX_MEM_alu_result <= 0;
           EX_MEM_B_value <= 0;
           EX_MEM_dst_reg <= 0;
           EX_MEM_mem_read <= 0;
           EX_MEM_mem_write <= 0;
           EX_MEM_wb_reg_write <= 0;
           EX_MEM_wb_mem_to_reg <= 0;
        end
      else
        begin
           EX_MEM_alu_result <= alu_result;
           EX_MEM_B_value <= b_value;
           EX_MEM_dst_reg <= ex_dst_reg;
           EX_MEM_opcode <= opcode;           
           EX_MEM_mem_read <= mem_read;
           EX_MEM_mem_write <= mem_write;
           EX_MEM_wb_reg_write <= wb_reg_write;
           EX_MEM_wb_mem_to_reg <= wb_mem_to_reg;
        end
	end
   

endmodule