1 |
38 |
alirezamon |
/* ****************************************************************************
|
2 |
|
|
This Source Code Form is subject to the terms of the
|
3 |
|
|
Open Hardware Description License, v. 1.0. If a copy
|
4 |
|
|
of the OHDL was not distributed with this file, You
|
5 |
|
|
can obtain one at http://juliusbaxter.net/ohdl/ohdl.txt
|
6 |
|
|
|
7 |
|
|
Description: Cappuccino decode to execute module.
|
8 |
|
|
- Decode to execute stage signal passing.
|
9 |
|
|
- Branches are resolved (in decode stage).
|
10 |
|
|
- Hazards that can not be resolved by bypassing are detected and
|
11 |
|
|
bubbles are inserted on such conditions.
|
12 |
|
|
|
13 |
|
|
Generate valid signal when stage is done.
|
14 |
|
|
|
15 |
|
|
Copyright (C) 2012 Julius Baxter <juliusbaxter@gmail.com>
|
16 |
|
|
Copyright (C) 2013 Stefan Kristiansson <stefan.kristiansson@saunalahti.fi>
|
17 |
|
|
|
18 |
|
|
***************************************************************************** */
|
19 |
|
|
|
20 |
|
|
`include "mor1kx-defines.v"
|
21 |
|
|
|
22 |
|
|
module mor1kx_decode_execute_cappuccino
|
23 |
|
|
#(
|
24 |
|
|
parameter OPTION_OPERAND_WIDTH = 32,
|
25 |
|
|
parameter OPTION_RESET_PC = {{(OPTION_OPERAND_WIDTH-13){1'b0}},
|
26 |
|
|
`OR1K_RESET_VECTOR,8'd0},
|
27 |
|
|
|
28 |
|
|
parameter OPTION_RF_ADDR_WIDTH = 5,
|
29 |
|
|
|
30 |
|
|
parameter FEATURE_SYSCALL = "ENABLED",
|
31 |
|
|
parameter FEATURE_TRAP = "ENABLED",
|
32 |
|
|
parameter FEATURE_DELAY_SLOT = "ENABLED",
|
33 |
|
|
|
34 |
|
|
parameter FEATURE_MULTIPLIER = "THREESTAGE",
|
35 |
|
|
|
36 |
|
|
parameter FEATURE_INBUILT_CHECKERS = "ENABLED"
|
37 |
|
|
)
|
38 |
|
|
(
|
39 |
|
|
input clk,
|
40 |
|
|
input rst,
|
41 |
|
|
|
42 |
|
|
// pipeline control signal in
|
43 |
|
|
input padv_i,
|
44 |
|
|
input [OPTION_OPERAND_WIDTH-1:0] pc_decode_i,
|
45 |
|
|
|
46 |
|
|
// input from register file
|
47 |
|
|
input [OPTION_OPERAND_WIDTH-1:0] decode_rfb_i,
|
48 |
|
|
input [OPTION_OPERAND_WIDTH-1:0] execute_rfb_i,
|
49 |
|
|
|
50 |
|
|
// Branch prediction signals
|
51 |
|
|
input predicted_flag_i,
|
52 |
|
|
output reg execute_predicted_flag_o,
|
53 |
|
|
// The target pc that should be used in case of branch misprediction
|
54 |
|
|
output reg [OPTION_OPERAND_WIDTH-1:0] execute_mispredict_target_o,
|
55 |
|
|
|
56 |
|
|
input pipeline_flush_i,
|
57 |
|
|
|
58 |
|
|
// ALU related inputs from decode
|
59 |
|
|
input [`OR1K_ALU_OPC_WIDTH-1:0] decode_opc_alu_i,
|
60 |
|
|
input [`OR1K_ALU_OPC_WIDTH-1:0] decode_opc_alu_secondary_i,
|
61 |
|
|
|
62 |
|
|
input [`OR1K_IMM_WIDTH-1:0] decode_imm16_i,
|
63 |
|
|
input [OPTION_OPERAND_WIDTH-1:0] decode_immediate_i,
|
64 |
|
|
input decode_immediate_sel_i,
|
65 |
|
|
|
66 |
|
|
// ALU related outputs to execute
|
67 |
|
|
output reg [`OR1K_ALU_OPC_WIDTH-1:0] execute_opc_alu_o,
|
68 |
|
|
output reg [`OR1K_ALU_OPC_WIDTH-1:0] execute_opc_alu_secondary_o,
|
69 |
|
|
|
70 |
|
|
output reg [`OR1K_IMM_WIDTH-1:0] execute_imm16_o,
|
71 |
|
|
output reg [OPTION_OPERAND_WIDTH-1:0] execute_immediate_o,
|
72 |
|
|
output reg execute_immediate_sel_o,
|
73 |
|
|
|
74 |
|
|
// Adder control logic from decode
|
75 |
|
|
input decode_adder_do_sub_i,
|
76 |
|
|
input decode_adder_do_carry_i,
|
77 |
|
|
|
78 |
|
|
// Adder control logic to execute
|
79 |
|
|
output reg execute_adder_do_sub_o,
|
80 |
|
|
output reg execute_adder_do_carry_o,
|
81 |
|
|
|
82 |
|
|
// Upper 10 bits of immediate for jumps and branches
|
83 |
|
|
input [9:0] decode_immjbr_upper_i,
|
84 |
|
|
output reg [9:0] execute_immjbr_upper_o,
|
85 |
|
|
|
86 |
|
|
// GPR numbers
|
87 |
|
|
output reg [OPTION_RF_ADDR_WIDTH-1:0] execute_rfd_adr_o,
|
88 |
|
|
input [OPTION_RF_ADDR_WIDTH-1:0] decode_rfd_adr_i,
|
89 |
|
|
input [OPTION_RF_ADDR_WIDTH-1:0] decode_rfa_adr_i,
|
90 |
|
|
input [OPTION_RF_ADDR_WIDTH-1:0] decode_rfb_adr_i,
|
91 |
|
|
input [OPTION_RF_ADDR_WIDTH-1:0] ctrl_rfd_adr_i,
|
92 |
|
|
input ctrl_op_lsu_load_i,
|
93 |
|
|
input ctrl_op_mfspr_i,
|
94 |
|
|
input ctrl_op_mul_i,
|
95 |
|
|
|
96 |
|
|
// Control signal inputs from decode stage
|
97 |
|
|
input decode_rf_wb_i,
|
98 |
|
|
|
99 |
|
|
input decode_op_alu_i,
|
100 |
|
|
|
101 |
|
|
input decode_op_setflag_i,
|
102 |
|
|
|
103 |
|
|
input decode_op_jbr_i,
|
104 |
|
|
input decode_op_jr_i,
|
105 |
|
|
input decode_op_jal_i,
|
106 |
|
|
input decode_op_bf_i,
|
107 |
|
|
input decode_op_bnf_i,
|
108 |
|
|
input decode_op_brcond_i,
|
109 |
|
|
input decode_op_branch_i,
|
110 |
|
|
|
111 |
|
|
input decode_op_lsu_load_i,
|
112 |
|
|
input decode_op_lsu_store_i,
|
113 |
|
|
input decode_op_lsu_atomic_i,
|
114 |
|
|
input [1:0] decode_lsu_length_i,
|
115 |
|
|
input decode_lsu_zext_i,
|
116 |
|
|
|
117 |
|
|
input decode_op_mfspr_i,
|
118 |
|
|
input decode_op_mtspr_i,
|
119 |
|
|
|
120 |
|
|
input decode_op_rfe_i,
|
121 |
|
|
input decode_op_add_i,
|
122 |
|
|
input decode_op_mul_i,
|
123 |
|
|
input decode_op_mul_signed_i,
|
124 |
|
|
input decode_op_mul_unsigned_i,
|
125 |
|
|
input decode_op_div_i,
|
126 |
|
|
input decode_op_div_signed_i,
|
127 |
|
|
input decode_op_div_unsigned_i,
|
128 |
|
|
input decode_op_shift_i,
|
129 |
|
|
input decode_op_ffl1_i,
|
130 |
|
|
input decode_op_movhi_i,
|
131 |
|
|
|
132 |
|
|
input [`OR1K_OPCODE_WIDTH-1:0] decode_opc_insn_i,
|
133 |
|
|
|
134 |
|
|
// Control signal outputs to execute stage
|
135 |
|
|
output reg execute_rf_wb_o,
|
136 |
|
|
|
137 |
|
|
output reg execute_op_alu_o,
|
138 |
|
|
|
139 |
|
|
output reg execute_op_setflag_o,
|
140 |
|
|
|
141 |
|
|
output reg execute_op_jbr_o,
|
142 |
|
|
output reg execute_op_jr_o,
|
143 |
|
|
output reg execute_op_jal_o,
|
144 |
|
|
output reg execute_op_brcond_o,
|
145 |
|
|
output reg execute_op_branch_o,
|
146 |
|
|
|
147 |
|
|
output reg execute_op_lsu_load_o,
|
148 |
|
|
output reg execute_op_lsu_store_o,
|
149 |
|
|
output reg execute_op_lsu_atomic_o,
|
150 |
|
|
output reg [1:0] execute_lsu_length_o,
|
151 |
|
|
output reg execute_lsu_zext_o,
|
152 |
|
|
|
153 |
|
|
output reg execute_op_mfspr_o,
|
154 |
|
|
output reg execute_op_mtspr_o,
|
155 |
|
|
|
156 |
|
|
output reg execute_op_rfe_o,
|
157 |
|
|
output reg execute_op_add_o,
|
158 |
|
|
output reg execute_op_mul_o,
|
159 |
|
|
output reg execute_op_mul_signed_o,
|
160 |
|
|
output reg execute_op_mul_unsigned_o,
|
161 |
|
|
output reg execute_op_div_o,
|
162 |
|
|
output reg execute_op_div_signed_o,
|
163 |
|
|
output reg execute_op_div_unsigned_o,
|
164 |
|
|
output reg execute_op_shift_o,
|
165 |
|
|
output reg execute_op_ffl1_o,
|
166 |
|
|
output reg execute_op_movhi_o,
|
167 |
|
|
|
168 |
|
|
output reg [OPTION_OPERAND_WIDTH-1:0] execute_jal_result_o,
|
169 |
|
|
|
170 |
|
|
output reg [`OR1K_OPCODE_WIDTH-1:0] execute_opc_insn_o,
|
171 |
|
|
|
172 |
|
|
// branch detection
|
173 |
|
|
output decode_branch_o,
|
174 |
|
|
output [OPTION_OPERAND_WIDTH-1:0] decode_branch_target_o,
|
175 |
|
|
|
176 |
|
|
// exceptions in
|
177 |
|
|
input decode_except_ibus_err_i,
|
178 |
|
|
input decode_except_itlb_miss_i,
|
179 |
|
|
input decode_except_ipagefault_i,
|
180 |
|
|
input decode_except_illegal_i,
|
181 |
|
|
input decode_except_syscall_i,
|
182 |
|
|
input decode_except_trap_i,
|
183 |
|
|
|
184 |
|
|
// exception output -
|
185 |
|
|
output reg execute_except_ibus_err_o,
|
186 |
|
|
output reg execute_except_itlb_miss_o,
|
187 |
|
|
output reg execute_except_ipagefault_o,
|
188 |
|
|
output reg execute_except_illegal_o,
|
189 |
|
|
output reg execute_except_ibus_align_o,
|
190 |
|
|
output reg execute_except_syscall_o,
|
191 |
|
|
output reg execute_except_trap_o,
|
192 |
|
|
|
193 |
|
|
output reg [OPTION_OPERAND_WIDTH-1:0] pc_execute_o,
|
194 |
|
|
|
195 |
|
|
// output is valid, signal
|
196 |
|
|
output reg decode_valid_o,
|
197 |
|
|
|
198 |
|
|
output decode_bubble_o,
|
199 |
|
|
output reg execute_bubble_o
|
200 |
|
|
);
|
201 |
|
|
|
202 |
|
|
wire ctrl_to_decode_interlock;
|
203 |
|
|
wire branch_to_imm;
|
204 |
|
|
wire [OPTION_OPERAND_WIDTH-1:0] branch_to_imm_target;
|
205 |
|
|
wire branch_to_reg;
|
206 |
|
|
|
207 |
|
|
wire decode_except_ibus_align;
|
208 |
|
|
|
209 |
|
|
wire [OPTION_OPERAND_WIDTH-1:0] next_pc_after_branch_insn;
|
210 |
|
|
wire [OPTION_OPERAND_WIDTH-1:0] decode_mispredict_target;
|
211 |
|
|
|
212 |
|
|
// Op control signals to execute stage
|
213 |
|
|
always @(posedge clk `OR_ASYNC_RST)
|
214 |
|
|
if (rst) begin
|
215 |
|
|
execute_op_alu_o <= 1'b0;
|
216 |
|
|
execute_op_add_o <= 1'b0;
|
217 |
|
|
execute_op_mul_o <= 1'b0;
|
218 |
|
|
execute_op_mul_signed_o <= 1'b0;
|
219 |
|
|
execute_op_mul_unsigned_o <= 1'b0;
|
220 |
|
|
execute_op_div_o <= 1'b0;
|
221 |
|
|
execute_op_div_signed_o <= 1'b0;
|
222 |
|
|
execute_op_div_unsigned_o <= 1'b0;
|
223 |
|
|
execute_op_shift_o <= 1'b0;
|
224 |
|
|
execute_op_ffl1_o <= 1'b0;
|
225 |
|
|
execute_op_movhi_o <= 1'b0;
|
226 |
|
|
execute_op_mfspr_o <= 1'b0;
|
227 |
|
|
execute_op_mtspr_o <= 1'b0;
|
228 |
|
|
execute_op_lsu_load_o <= 1'b0;
|
229 |
|
|
execute_op_lsu_store_o <= 1'b0;
|
230 |
|
|
execute_op_lsu_atomic_o <= 1'b0;
|
231 |
|
|
execute_op_setflag_o <= 1'b0;
|
232 |
|
|
execute_op_jbr_o <= 1'b0;
|
233 |
|
|
execute_op_jr_o <= 1'b0;
|
234 |
|
|
execute_op_jal_o <= 1'b0;
|
235 |
|
|
execute_op_brcond_o <= 1'b0;
|
236 |
|
|
execute_op_branch_o <= 0;
|
237 |
|
|
end else if (pipeline_flush_i) begin
|
238 |
|
|
execute_op_alu_o <= 1'b0;
|
239 |
|
|
execute_op_add_o <= 1'b0;
|
240 |
|
|
execute_op_mul_o <= 1'b0;
|
241 |
|
|
execute_op_mul_signed_o <= 1'b0;
|
242 |
|
|
execute_op_mul_unsigned_o <= 1'b0;
|
243 |
|
|
execute_op_div_o <= 1'b0;
|
244 |
|
|
execute_op_div_signed_o <= 1'b0;
|
245 |
|
|
execute_op_div_unsigned_o <= 1'b0;
|
246 |
|
|
execute_op_shift_o <= 1'b0;
|
247 |
|
|
execute_op_ffl1_o <= 1'b0;
|
248 |
|
|
execute_op_movhi_o <= 1'b0;
|
249 |
|
|
execute_op_lsu_load_o <= 1'b0;
|
250 |
|
|
execute_op_lsu_store_o <= 1'b0;
|
251 |
|
|
execute_op_lsu_atomic_o <= 1'b0;
|
252 |
|
|
execute_op_setflag_o <= 1'b0;
|
253 |
|
|
execute_op_jbr_o <= 1'b0;
|
254 |
|
|
execute_op_jr_o <= 1'b0;
|
255 |
|
|
execute_op_jal_o <= 1'b0;
|
256 |
|
|
execute_op_brcond_o <= 1'b0;
|
257 |
|
|
execute_op_branch_o <= 1'b0;
|
258 |
|
|
end else if (padv_i) begin
|
259 |
|
|
execute_op_alu_o <= decode_op_alu_i;
|
260 |
|
|
execute_op_add_o <= decode_op_add_i;
|
261 |
|
|
execute_op_mul_o <= decode_op_mul_i;
|
262 |
|
|
execute_op_mul_signed_o <= decode_op_mul_signed_i;
|
263 |
|
|
execute_op_mul_unsigned_o <= decode_op_mul_unsigned_i;
|
264 |
|
|
execute_op_div_o <= decode_op_div_i;
|
265 |
|
|
execute_op_div_signed_o <= decode_op_div_signed_i;
|
266 |
|
|
execute_op_div_unsigned_o <= decode_op_div_unsigned_i;
|
267 |
|
|
execute_op_shift_o <= decode_op_shift_i;
|
268 |
|
|
execute_op_ffl1_o <= decode_op_ffl1_i;
|
269 |
|
|
execute_op_movhi_o <= decode_op_movhi_i;
|
270 |
|
|
execute_op_mfspr_o <= decode_op_mfspr_i;
|
271 |
|
|
execute_op_mtspr_o <= decode_op_mtspr_i;
|
272 |
|
|
execute_op_lsu_load_o <= decode_op_lsu_load_i;
|
273 |
|
|
execute_op_lsu_store_o <= decode_op_lsu_store_i;
|
274 |
|
|
execute_op_lsu_atomic_o <= decode_op_lsu_atomic_i;
|
275 |
|
|
execute_op_setflag_o <= decode_op_setflag_i;
|
276 |
|
|
execute_op_jbr_o <= decode_op_jbr_i;
|
277 |
|
|
execute_op_jr_o <= decode_op_jr_i;
|
278 |
|
|
execute_op_jal_o <= decode_op_jal_i;
|
279 |
|
|
execute_op_brcond_o <= decode_op_brcond_i;
|
280 |
|
|
execute_op_branch_o <= decode_op_branch_i;
|
281 |
|
|
if (decode_bubble_o) begin
|
282 |
|
|
execute_op_alu_o <= 1'b0;
|
283 |
|
|
execute_op_add_o <= 1'b0;
|
284 |
|
|
execute_op_mul_o <= 1'b0;
|
285 |
|
|
execute_op_mul_signed_o <= 1'b0;
|
286 |
|
|
execute_op_mul_unsigned_o <= 1'b0;
|
287 |
|
|
execute_op_div_o <= 1'b0;
|
288 |
|
|
execute_op_div_signed_o <= 1'b0;
|
289 |
|
|
execute_op_div_unsigned_o <= 1'b0;
|
290 |
|
|
execute_op_shift_o <= 1'b0;
|
291 |
|
|
execute_op_ffl1_o <= 1'b0;
|
292 |
|
|
execute_op_movhi_o <= 1'b0;
|
293 |
|
|
execute_op_mtspr_o <= 1'b0;
|
294 |
|
|
execute_op_mfspr_o <= 1'b0;
|
295 |
|
|
execute_op_lsu_load_o <= 1'b0;
|
296 |
|
|
execute_op_lsu_store_o <= 1'b0;
|
297 |
|
|
execute_op_lsu_atomic_o <= 1'b0;
|
298 |
|
|
execute_op_setflag_o <= 1'b0;
|
299 |
|
|
execute_op_jbr_o <= 1'b0;
|
300 |
|
|
execute_op_jr_o <= 1'b0;
|
301 |
|
|
execute_op_jal_o <= 1'b0;
|
302 |
|
|
execute_op_brcond_o <= 1'b0;
|
303 |
|
|
execute_op_branch_o <= 1'b0;
|
304 |
|
|
end
|
305 |
|
|
end
|
306 |
|
|
|
307 |
|
|
// rfe is a special case, instead of pushing the pipeline full
|
308 |
|
|
// of nops on a decode_bubble_o, we push it full of rfes.
|
309 |
|
|
// The reason for this is that we need the rfe to reach control
|
310 |
|
|
// stage so it will cause the branch.
|
311 |
|
|
// It will clear itself by the pipeline_flush_i that the rfe
|
312 |
|
|
// will generate.
|
313 |
|
|
always @(posedge clk `OR_ASYNC_RST)
|
314 |
|
|
if (rst)
|
315 |
|
|
execute_op_rfe_o <= 0;
|
316 |
|
|
else if (pipeline_flush_i)
|
317 |
|
|
execute_op_rfe_o <= 0;
|
318 |
|
|
else if (padv_i)
|
319 |
|
|
execute_op_rfe_o <= decode_op_rfe_i;
|
320 |
|
|
|
321 |
|
|
always @(posedge clk `OR_ASYNC_RST)
|
322 |
|
|
if (rst) begin
|
323 |
|
|
execute_rf_wb_o <= 0;
|
324 |
|
|
end else if (pipeline_flush_i) begin
|
325 |
|
|
execute_rf_wb_o <= 0;
|
326 |
|
|
end else if (padv_i) begin
|
327 |
|
|
execute_rf_wb_o <= decode_rf_wb_i;
|
328 |
|
|
if (decode_bubble_o)
|
329 |
|
|
execute_rf_wb_o <= 0;
|
330 |
|
|
end
|
331 |
|
|
|
332 |
|
|
always @(posedge clk)
|
333 |
|
|
if (padv_i)
|
334 |
|
|
execute_rfd_adr_o <= decode_rfd_adr_i;
|
335 |
|
|
|
336 |
|
|
always @(posedge clk)
|
337 |
|
|
if (padv_i) begin
|
338 |
|
|
execute_lsu_length_o <= decode_lsu_length_i;
|
339 |
|
|
execute_lsu_zext_o <= decode_lsu_zext_i;
|
340 |
|
|
end
|
341 |
|
|
|
342 |
|
|
always @(posedge clk)
|
343 |
|
|
if (padv_i) begin
|
344 |
|
|
execute_imm16_o <= decode_imm16_i;
|
345 |
|
|
execute_immediate_o <= decode_immediate_i;
|
346 |
|
|
execute_immediate_sel_o <= decode_immediate_sel_i;
|
347 |
|
|
end
|
348 |
|
|
|
349 |
|
|
always @(posedge clk)
|
350 |
|
|
if (padv_i )
|
351 |
|
|
execute_immjbr_upper_o <= decode_immjbr_upper_i;
|
352 |
|
|
|
353 |
|
|
always @(posedge clk)
|
354 |
|
|
if (padv_i) begin
|
355 |
|
|
execute_opc_alu_o <= decode_opc_alu_i;
|
356 |
|
|
execute_opc_alu_secondary_o <= decode_opc_alu_secondary_i;
|
357 |
|
|
end
|
358 |
|
|
|
359 |
|
|
always @(posedge clk `OR_ASYNC_RST)
|
360 |
|
|
if (rst) begin
|
361 |
|
|
execute_opc_insn_o <= `OR1K_OPCODE_NOP;
|
362 |
|
|
end else if (pipeline_flush_i) begin
|
363 |
|
|
execute_opc_insn_o <= `OR1K_OPCODE_NOP;
|
364 |
|
|
end else if (padv_i) begin
|
365 |
|
|
execute_opc_insn_o <= decode_opc_insn_i;
|
366 |
|
|
if (decode_bubble_o)
|
367 |
|
|
execute_opc_insn_o <= `OR1K_OPCODE_NOP;
|
368 |
|
|
end
|
369 |
|
|
|
370 |
|
|
always @(posedge clk `OR_ASYNC_RST)
|
371 |
|
|
if (rst) begin
|
372 |
|
|
execute_adder_do_sub_o <= 1'b0;
|
373 |
|
|
execute_adder_do_carry_o <= 1'b0;
|
374 |
|
|
end else if (pipeline_flush_i) begin
|
375 |
|
|
execute_adder_do_sub_o <= 1'b0;
|
376 |
|
|
execute_adder_do_carry_o <= 1'b0;
|
377 |
|
|
end else if (padv_i) begin
|
378 |
|
|
execute_adder_do_sub_o <= decode_adder_do_sub_i;
|
379 |
|
|
execute_adder_do_carry_o <= decode_adder_do_carry_i;
|
380 |
|
|
if (decode_bubble_o) begin
|
381 |
|
|
execute_adder_do_sub_o <= 1'b0;
|
382 |
|
|
execute_adder_do_carry_o <= 1'b0;
|
383 |
|
|
end
|
384 |
|
|
end
|
385 |
|
|
|
386 |
|
|
// Decode for system call exception
|
387 |
|
|
always @(posedge clk `OR_ASYNC_RST)
|
388 |
|
|
if (rst)
|
389 |
|
|
execute_except_syscall_o <= 0;
|
390 |
|
|
else if (padv_i && FEATURE_SYSCALL=="ENABLED")
|
391 |
|
|
execute_except_syscall_o <= decode_except_syscall_i;
|
392 |
|
|
|
393 |
|
|
// Decode for system call exception
|
394 |
|
|
always @(posedge clk `OR_ASYNC_RST)
|
395 |
|
|
if (rst)
|
396 |
|
|
execute_except_trap_o <= 0;
|
397 |
|
|
else if (padv_i && FEATURE_TRAP=="ENABLED")
|
398 |
|
|
execute_except_trap_o <= decode_except_trap_i;
|
399 |
|
|
|
400 |
|
|
// Decode Illegal instruction
|
401 |
|
|
always @(posedge clk `OR_ASYNC_RST)
|
402 |
|
|
if (rst)
|
403 |
|
|
execute_except_illegal_o <= 0;
|
404 |
|
|
else if (padv_i)
|
405 |
|
|
execute_except_illegal_o <= decode_except_illegal_i;
|
406 |
|
|
|
407 |
|
|
always @(posedge clk `OR_ASYNC_RST)
|
408 |
|
|
if (rst)
|
409 |
|
|
execute_except_ibus_err_o <= 1'b0;
|
410 |
|
|
else if (padv_i)
|
411 |
|
|
execute_except_ibus_err_o <= decode_except_ibus_err_i;
|
412 |
|
|
|
413 |
|
|
always @(posedge clk `OR_ASYNC_RST)
|
414 |
|
|
if (rst)
|
415 |
|
|
execute_except_itlb_miss_o <= 1'b0;
|
416 |
|
|
else if (padv_i)
|
417 |
|
|
execute_except_itlb_miss_o <= decode_except_itlb_miss_i;
|
418 |
|
|
|
419 |
|
|
always @(posedge clk `OR_ASYNC_RST)
|
420 |
|
|
if (rst)
|
421 |
|
|
execute_except_ipagefault_o <= 1'b0;
|
422 |
|
|
else if (padv_i)
|
423 |
|
|
execute_except_ipagefault_o <= decode_except_ipagefault_i;
|
424 |
|
|
|
425 |
|
|
always @(posedge clk `OR_ASYNC_RST)
|
426 |
|
|
if (rst)
|
427 |
|
|
execute_except_ibus_align_o <= 1'b0;
|
428 |
|
|
else if (padv_i)
|
429 |
|
|
execute_except_ibus_align_o <= decode_except_ibus_align;
|
430 |
|
|
|
431 |
|
|
always @(posedge clk `OR_ASYNC_RST)
|
432 |
|
|
if (rst)
|
433 |
|
|
decode_valid_o <= 0;
|
434 |
|
|
else
|
435 |
|
|
decode_valid_o <= padv_i;
|
436 |
|
|
|
437 |
|
|
always @(posedge clk `OR_ASYNC_RST)
|
438 |
|
|
if (padv_i)
|
439 |
|
|
pc_execute_o <= pc_decode_i;
|
440 |
|
|
|
441 |
|
|
// Branch detection
|
442 |
|
|
assign ctrl_to_decode_interlock = (ctrl_op_lsu_load_i | ctrl_op_mfspr_i |
|
443 |
|
|
ctrl_op_mul_i &
|
444 |
|
|
FEATURE_MULTIPLIER=="PIPELINED") &
|
445 |
|
|
((decode_rfa_adr_i == ctrl_rfd_adr_i) ||
|
446 |
|
|
(decode_rfb_adr_i == ctrl_rfd_adr_i));
|
447 |
|
|
|
448 |
|
|
assign branch_to_imm = (decode_op_jbr_i &
|
449 |
|
|
// l.j/l.jal
|
450 |
|
|
(!(|decode_opc_insn_i[2:1]) |
|
451 |
|
|
// l.bf/bnf and flag is right
|
452 |
|
|
(decode_opc_insn_i[2] == predicted_flag_i)));
|
453 |
|
|
|
454 |
|
|
assign branch_to_imm_target = pc_decode_i + {{4{decode_immjbr_upper_i[9]}},
|
455 |
|
|
decode_immjbr_upper_i,
|
456 |
|
|
decode_imm16_i,2'b00};
|
457 |
|
|
assign branch_to_reg = decode_op_jr_i &
|
458 |
|
|
!(ctrl_to_decode_interlock |
|
459 |
|
|
execute_rf_wb_o &
|
460 |
|
|
(decode_rfb_adr_i == execute_rfd_adr_o));
|
461 |
|
|
|
462 |
|
|
assign decode_branch_o = (branch_to_imm | branch_to_reg) &
|
463 |
|
|
!pipeline_flush_i;
|
464 |
|
|
|
465 |
|
|
assign decode_branch_target_o = branch_to_imm ?
|
466 |
|
|
branch_to_imm_target :
|
467 |
|
|
// If a bubble have been pushed out to get
|
468 |
|
|
// the instruction that will write the
|
469 |
|
|
// branch target to control stage, then we
|
470 |
|
|
// need to use the register result from
|
471 |
|
|
// execute stage instead of decode stage.
|
472 |
|
|
execute_bubble_o | execute_op_jr_o ?
|
473 |
|
|
execute_rfb_i : decode_rfb_i;
|
474 |
|
|
|
475 |
|
|
assign decode_except_ibus_align = decode_branch_o &
|
476 |
|
|
(|decode_branch_target_o[1:0]);
|
477 |
|
|
|
478 |
|
|
assign next_pc_after_branch_insn = FEATURE_DELAY_SLOT == "ENABLED" ?
|
479 |
|
|
pc_decode_i + 8 : pc_decode_i + 4;
|
480 |
|
|
|
481 |
|
|
assign decode_mispredict_target = decode_op_bf_i & !predicted_flag_i |
|
482 |
|
|
decode_op_bnf_i & predicted_flag_i ?
|
483 |
|
|
branch_to_imm_target :
|
484 |
|
|
next_pc_after_branch_insn;
|
485 |
|
|
|
486 |
|
|
// Forward branch prediction signals to execute stage
|
487 |
|
|
always @(posedge clk)
|
488 |
|
|
if (padv_i & decode_op_brcond_i)
|
489 |
|
|
execute_mispredict_target_o <= decode_mispredict_target;
|
490 |
|
|
|
491 |
|
|
always @(posedge clk)
|
492 |
|
|
if (padv_i & decode_op_brcond_i)
|
493 |
|
|
execute_predicted_flag_o <= predicted_flag_i;
|
494 |
|
|
|
495 |
|
|
// Calculate the link register result
|
496 |
|
|
// TODO: investigate if the ALU adder can be used for this without
|
497 |
|
|
// introducing critical paths
|
498 |
|
|
always @(posedge clk)
|
499 |
|
|
if (padv_i)
|
500 |
|
|
execute_jal_result_o <= next_pc_after_branch_insn;
|
501 |
|
|
|
502 |
|
|
// Detect the situation where there is an instruction in execute stage
|
503 |
|
|
// that will produce it's result in control stage (i.e. load and mfspr),
|
504 |
|
|
// and an instruction currently in decode stage needing it's result as
|
505 |
|
|
// input in execute stage.
|
506 |
|
|
// Also detect the situation where there is a jump to register in decode
|
507 |
|
|
// stage and an instruction in execute stage that will write to that
|
508 |
|
|
// register.
|
509 |
|
|
//
|
510 |
|
|
// A bubble is also inserted when an rfe instruction is in decode stage,
|
511 |
|
|
// the main purpose of this is to stall fetch while the rfe is propagating
|
512 |
|
|
// up to ctrl stage.
|
513 |
|
|
|
514 |
|
|
assign decode_bubble_o = (
|
515 |
|
|
// load/mfspr/mul
|
516 |
|
|
(execute_op_lsu_load_o | execute_op_mfspr_o |
|
517 |
|
|
execute_op_mul_o &
|
518 |
|
|
FEATURE_MULTIPLIER=="PIPELINED") &
|
519 |
|
|
(decode_rfa_adr_i == execute_rfd_adr_o ||
|
520 |
|
|
decode_rfb_adr_i == execute_rfd_adr_o) |
|
521 |
|
|
// mul
|
522 |
|
|
FEATURE_MULTIPLIER=="PIPELINED" &
|
523 |
|
|
(decode_op_mul_i &
|
524 |
|
|
(ctrl_to_decode_interlock |
|
525 |
|
|
execute_rf_wb_o &
|
526 |
|
|
(decode_rfa_adr_i == execute_rfd_adr_o ||
|
527 |
|
|
decode_rfb_adr_i == execute_rfd_adr_o))) |
|
528 |
|
|
// jr
|
529 |
|
|
decode_op_jr_i &
|
530 |
|
|
(ctrl_to_decode_interlock |
|
531 |
|
|
execute_rf_wb_o &
|
532 |
|
|
(decode_rfb_adr_i == execute_rfd_adr_o)) |
|
533 |
|
|
// atomic store
|
534 |
|
|
execute_op_lsu_store_o & execute_op_lsu_atomic_o |
|
535 |
|
|
// rfe
|
536 |
|
|
decode_op_rfe_i
|
537 |
|
|
) & padv_i;
|
538 |
|
|
|
539 |
|
|
always @(posedge clk `OR_ASYNC_RST)
|
540 |
|
|
if (rst)
|
541 |
|
|
execute_bubble_o <= 0;
|
542 |
|
|
else if (pipeline_flush_i)
|
543 |
|
|
execute_bubble_o <= 0;
|
544 |
|
|
else if (padv_i)
|
545 |
|
|
execute_bubble_o <= decode_bubble_o;
|
546 |
|
|
|
547 |
|
|
endmodule // mor1kx_decode_execute_cappuccino
|