OpenCores
URL https://opencores.org/ocsvn/aor3000/aor3000/trunk

Subversion Repositories aor3000

[/] [aor3000/] [trunk/] [rtl/] [pipeline/] [pipeline_exe.v] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 alfik
/*
2
 * This file is subject to the terms and conditions of the BSD License. See
3
 * the file "LICENSE" in the main directory of this archive for more details.
4
 *
5
 * Copyright (C) 2014 Aleksander Osman
6
 */
7
 
8
`include "defines.v"
9
 
10
module pipeline_exe(
11
    input               clk,
12
    input               rst_n,
13
 
14
    //
15
    input               config_kernel_mode,
16
 
17
    //
18
    input               exception_start,
19
 
20
    //
21
    input               mem_stall,
22
 
23
    //
24
    input       [6:0]   rf_cmd,
25
    input       [31:0]  rf_instr,
26
    input       [31:0]  rf_pc_plus4,
27
    input       [31:0]  rf_badvpn,
28
    input       [31:0]  rf_a,
29
    input       [31:0]  rf_b,
30
 
31
    //
32
    output reg  [6:0]   exe_cmd,
33
    output reg  [31:0]  exe_instr,
34
    output reg  [31:0]  exe_pc_plus4,
35
    output reg          exe_pc_user_seg,
36
    output reg  [31:0]  exe_badvpn,
37
    output reg  [31:0]  exe_a,
38
    output reg  [31:0]  exe_b,
39
    output reg  [1:0]   exe_branched,
40
    output reg  [31:0]  exe_branch_address,
41
    output reg          exe_cmd_cp0,
42
    output reg          exe_cmd_load,
43
    output reg          exe_cmd_store,
44
 
45
    //
46
    output      [4:0]   exe_result_index,
47
    output reg  [31:0]  exe_result,
48
 
49
    //
50
    output      [31:0]  data_address_next,
51
    output reg  [31:0]  data_address,
52
 
53
    //
54
    output              branch_start,
55
    output      [31:0]  branch_address,
56
 
57
    //
58
    input       [4:0]   write_buffer_counter
59
); /* verilator public_module */
60
 
61
//------------------------------------------------------------------------------
62
 
63
wire exc_int_overflow =
64
    ((rf_cmd == `CMD_3arg_add || rf_cmd == `CMD_addi) && (
65
        (rf_a[31] == 1'b1 && rf_b_imm[31] == 1'b1 && result_sum[31] == 1'b0) ||
66
        (rf_a[31] == 1'b0 && rf_b_imm[31] == 1'b0 && result_sum[31] == 1'b1))) ||
67
    (rf_cmd == `CMD_3arg_sub && (
68
        (rf_a[31] == 1'b1 && rf_b[31] == 1'b0 && result_sub[31] == 1'b0) ||
69
        (rf_a[31] == 1'b0 && rf_b[31] == 1'b1 && result_sub[31] == 1'b1)));
70
 
71
wire [6:0] exe_cmd_next =
72
    (mem_stall || exception_start)? `CMD_null :
73
    (exc_load_address_error)?       `CMD_exc_load_addr_err :
74
    (exc_store_address_error)?      `CMD_exc_store_addr_err :
75
    (exc_int_overflow)?             `CMD_exc_int_overflow :
76
                                    rf_cmd;
77
 
78
wire exe_cmd_cp0_next = ~(mem_stall) && ~(exception_start) && (
79
    rf_cmd == `CMD_mtc0 || rf_cmd == `CMD_cp0_rfe || rf_cmd == `CMD_cp0_tlbr || rf_cmd == `CMD_cp0_tlbp ||
80
    rf_cmd == `CMD_cp0_tlbwi || rf_cmd == `CMD_cp0_tlbwr || rf_cmd == `CMD_mfc0
81
);
82
 
83
wire cmd_load =
84
    rf_cmd == `CMD_lb || rf_cmd == `CMD_lbu || rf_cmd == `CMD_lh  || rf_cmd == `CMD_lhu ||
85
    rf_cmd == `CMD_lw || rf_cmd == `CMD_lwl || rf_cmd == `CMD_lwr;
86
 
87
wire cmd_store =
88
    rf_cmd == `CMD_sb || rf_cmd == `CMD_sh || rf_cmd == `CMD_sw || rf_cmd == `CMD_swl || rf_cmd == `CMD_swr;
89
 
90
wire exe_cmd_load_next = ~(mem_stall) && ~(exception_start) && cmd_load && ~(exc_load_address_error);
91
 
92
wire exe_cmd_store_next = ~(mem_stall) && ~(exception_start) && cmd_store && ~(exc_store_address_error);
93
 
94
always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) exe_cmd         <= `CMD_null; else exe_cmd         <= exe_cmd_next;               end
95
always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) exe_cmd_cp0     <= `FALSE;    else exe_cmd_cp0     <= exe_cmd_cp0_next;           end
96
always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) exe_cmd_load    <= `FALSE;    else exe_cmd_load    <= exe_cmd_load_next;          end
97
always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) exe_cmd_store   <= `FALSE;    else exe_cmd_store   <= exe_cmd_store_next;         end
98
always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) exe_result      <= 32'd0;     else exe_result      <= result;                     end
99
always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) exe_instr       <= 32'd0;     else exe_instr       <= rf_instr;                   end
100
always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) exe_pc_plus4    <= 32'd0;     else exe_pc_plus4    <= rf_pc_plus4;                end
101
always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) exe_pc_user_seg <= `FALSE;    else exe_pc_user_seg <= rf_pc_plus4 > 32'h80000000; end
102
always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) exe_a           <= 32'd0;     else exe_a           <= rf_a;                       end
103
always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) exe_b           <= 32'd0;     else exe_b           <= rf_b;                       end
104
 
105
wire [4:0] rf_instr_rt = rf_instr[20:16];
106
wire [4:0] rf_instr_rd = rf_instr[15:11];
107
 
108
wire exe_cmd_next_is_rd =
109
    rf_cmd == `CMD_3arg_add  || rf_cmd == `CMD_3arg_addu || rf_cmd == `CMD_3arg_and  || rf_cmd == `CMD_3arg_nor  ||
110
    rf_cmd == `CMD_3arg_or   || rf_cmd == `CMD_3arg_slt  || rf_cmd == `CMD_3arg_sltu || rf_cmd == `CMD_3arg_sub  ||
111
    rf_cmd == `CMD_3arg_subu || rf_cmd == `CMD_3arg_xor  || rf_cmd == `CMD_3arg_sllv || rf_cmd == `CMD_3arg_srav ||
112
    rf_cmd == `CMD_3arg_srlv || rf_cmd == `CMD_sll       || rf_cmd == `CMD_sra       || rf_cmd == `CMD_srl       ||
113
    rf_cmd == `CMD_jalr;
114
 
115
wire exe_cmd_next_is_rt =
116
    rf_cmd == `CMD_addi || rf_cmd == `CMD_addiu || rf_cmd == `CMD_andi || rf_cmd == `CMD_ori ||
117
    rf_cmd == `CMD_slti || rf_cmd == `CMD_sltiu || rf_cmd == `CMD_xori || rf_cmd == `CMD_lui;
118
 
119
wire exe_cmd_next_is_r31 = rf_cmd == `CMD_bgezal || rf_cmd == `CMD_bltzal || rf_cmd == `CMD_jal;
120
 
121
wire [4:0] exe_result_index_next =
122
    (exe_cmd_next_is_rd)?   rf_instr_rd :
123
    (exe_cmd_next_is_rt)?   rf_instr_rt :
124
    (exe_cmd_next_is_r31)?  5'd31 :
125
                            5'd0;
126
 
127
reg [4:0] exe_result_index_pre;
128
always @(posedge clk or negedge rst_n) begin
129
    if(rst_n == 1'b0)   exe_result_index_pre <= 5'd0;
130
    else                exe_result_index_pre <= exe_result_index_next;
131
end
132
 
133
reg exe_result_valid;
134
always @(posedge clk or negedge rst_n) begin
135
    if(rst_n == 1'b0)   exe_result_valid <= `FALSE;
136
    else                exe_result_valid <= ~(mem_stall) && ~(exception_start) && ~(exc_int_overflow);
137
end
138
 
139
assign exe_result_index = (exe_result_valid)? exe_result_index_pre : 5'd0;
140
 
141
//------------------------------------------------------------------------------
142
 
143
assign data_address_next = rf_a + { {16{rf_instr[15]}}, rf_instr[15:0] };
144
 
145
always @(posedge clk or negedge rst_n) begin
146
    if(rst_n == 1'b0)   data_address <= 32'd0;
147
    else                data_address <= data_address_next;
148
end
149
 
150
wire exc_load_address_error =
151
    ((rf_cmd == `CMD_lh || rf_cmd == `CMD_lhu) && data_address_next[0]) ||
152
    (rf_cmd == `CMD_lw && data_address_next[1:0] != 2'b00) ||
153
    (cmd_load && ~(config_kernel_mode) && data_address_next[31]);
154
 
155
wire exc_store_address_error =
156
    (rf_cmd == `CMD_sh && data_address_next[0]) ||
157
    (rf_cmd == `CMD_sw && data_address_next[1:0] != 2'b00) ||
158
    (cmd_store && ~(config_kernel_mode) && data_address_next[31]);
159
 
160
//------------------------------------------------------------------------------
161
 
162
wire write_buffer_empty = ~(exe_cmd_store) && write_buffer_counter == 5'd0;
163
 
164
assign branch_start = ~(mem_stall) && (
165
    rf_cmd == `CMD_jr || rf_cmd == `CMD_j || rf_cmd == `CMD_jal || rf_cmd == `CMD_jalr ||
166
    (rf_cmd == `CMD_beq      && rf_a == rf_b) ||
167
    (rf_cmd == `CMD_bne      && rf_a != rf_b) ||
168
    (rf_cmd == `CMD_bgez     && rf_a[31] == 1'b0) ||
169
    (rf_cmd == `CMD_bgtz     && rf_a[31] == 1'b0 && rf_a != 32'd0) ||
170
    (rf_cmd == `CMD_blez     && (rf_a[31] == 1'b1 || rf_a == 32'd0)) ||
171
    (rf_cmd == `CMD_bltz     && rf_a[31] == 1'b1) ||
172
    (rf_cmd == `CMD_bgezal   && rf_a[31] == 1'b0) ||
173
    (rf_cmd == `CMD_bltzal   && rf_a[31] == 1'b1) ||
174
    (rf_cmd == `CMD_cp0_bc0t && write_buffer_empty) ||
175
    (rf_cmd == `CMD_cp0_bc0f && ~(write_buffer_empty))
176
);
177
 
178
assign branch_address =
179
    (rf_cmd == `CMD_jal || rf_cmd == `CMD_j)?       { rf_pc_plus4[31:28], rf_instr[25:0], 2'b00 } :
180
    (rf_cmd == `CMD_jr  || rf_cmd == `CMD_jalr)?    rf_a :
181
                                                    rf_pc_plus4 + { {14{rf_instr[15]}}, rf_instr[15:0], 2'b00 };
182
 
183
always @(posedge clk or negedge rst_n) begin
184
    if(rst_n == 1'b0)                                       exe_branched <= 2'd0;
185
    else if(branch_start)                                   exe_branched <= 2'd1;
186
    else if(exe_cmd != `CMD_null && exe_branched == 2'd1)   exe_branched <= 2'd2;
187
    else if(exe_cmd != `CMD_null)                           exe_branched <= 2'd0;
188
end
189
 
190
always @(posedge clk or negedge rst_n) begin
191
    if(rst_n == 1'b0)       exe_branch_address <= 32'd0;
192
    else if(branch_start)   exe_branch_address <= branch_address;
193
end
194
 
195
always @(posedge clk or negedge rst_n) begin
196
    if(rst_n == 1'b0)   exe_badvpn <= 32'd0;
197
    else                exe_badvpn <= rf_badvpn;
198
end
199
 
200
//------------------------------------------------------------------------------
201
 
202
wire [31:0] rf_b_imm = (rf_cmd == `CMD_addi || rf_cmd == `CMD_addiu || rf_cmd == `CMD_slti || rf_cmd == `CMD_sltiu)? { {16{rf_instr[15]}}, rf_instr[15:0] } : rf_b;
203
 
204
wire [31:0] result_sum = rf_a + rf_b_imm;
205
wire [32:0] result_sub = rf_a - rf_b_imm;
206
 
207
wire [31:0] result =
208
    (rf_cmd == `CMD_3arg_add || rf_cmd == `CMD_addi || rf_cmd == `CMD_addiu || rf_cmd == `CMD_3arg_addu)?       result_sum :
209
    (rf_cmd == `CMD_3arg_and)?                                                                                  rf_a & rf_b :
210
    (rf_cmd == `CMD_andi)?                                                                                      { 16'd0, rf_a[15:0] & rf_instr[15:0] } :
211
    (rf_cmd == `CMD_3arg_nor)?                                                                                  ~(rf_a | rf_b) :
212
    (rf_cmd == `CMD_3arg_or)?                                                                                   rf_a | rf_b :
213
    (rf_cmd == `CMD_ori)?                                                                                       { rf_a[31:16], rf_a[15:0] | rf_instr[15:0] } :
214
    (rf_cmd == `CMD_sll || rf_cmd == `CMD_3arg_sllv)?                                                           shift_left :
215
    (rf_cmd == `CMD_sra || rf_cmd == `CMD_3arg_srav || rf_cmd == `CMD_srl || rf_cmd == `CMD_3arg_srlv)?         shift_right :
216
    (rf_cmd == `CMD_3arg_slt || rf_cmd == `CMD_slti)?                                                           { 31'b0, (rf_a[31] ^ rf_b_imm[31])? rf_a[31] : result_sub[31] } :
217
    (rf_cmd == `CMD_3arg_sltu || rf_cmd == `CMD_sltiu)?                                                         { 31'b0, result_sub[32] } :
218
    (rf_cmd == `CMD_3arg_sub || rf_cmd == `CMD_3arg_subu)?                                                      result_sub[31:0] :
219
    (rf_cmd == `CMD_3arg_xor)?                                                                                  rf_a ^ rf_b :
220
    (rf_cmd == `CMD_xori)?                                                                                      rf_a ^ { 16'd0, rf_instr[15:0] } :
221
    (rf_cmd == `CMD_lui)?                                                                                       { rf_instr[15:0], 16'd0 } :
222
                                                                                                                rf_pc_plus4 + 32'd4; //cmd_bgezal, cmd_bltzal, cmd_jal, cmd_jalr
223
 
224
//------------------------------------------------------------------------------ shift
225
//------------------------------------------------------------------------------
226
//------------------------------------------------------------------------------
227
 
228
wire [31:0] shift_left;
229
wire [31:0] shift_right;
230
 
231
block_shift block_shift_inst(
232
    .rf_cmd         (rf_cmd),       //input [6:0]
233
    .rf_instr       (rf_instr),     //input [31:0]
234
    .rf_a           (rf_a),         //input [31:0]
235
    .rf_b           (rf_b),         //input [31:0]
236
 
237
    .shift_left     (shift_left),   //output [31:0]
238
    .shift_right    (shift_right)   //output [31:0]
239
);
240
 
241
//------------------------------------------------------------------------------
242
 
243
endmodule

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.