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

Subversion Repositories amber

[/] [amber/] [trunk/] [hw/] [vlog/] [amber23/] [a23_decode.v] - Blame information for rev 89

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 csantifort
//////////////////////////////////////////////////////////////////
2
//                                                              //
3
//  Decode stage of Amber 2 Core                                //
4
//                                                              //
5
//  This file is part of the Amber project                      //
6
//  http://www.opencores.org/project,amber                      //
7
//                                                              //
8
//  Description                                                 //
9
//  This module is the most complex part of the Amber core      //
10
//  It decodes and sequences all instructions and handles all   //
11
//  interrupts                                                  //
12
//                                                              //
13
//  Author(s):                                                  //
14
//      - Conor Santifort, csantifort.amber@gmail.com           //
15
//                                                              //
16
//////////////////////////////////////////////////////////////////
17
//                                                              //
18
// Copyright (C) 2010 Authors and OPENCORES.ORG                 //
19
//                                                              //
20
// This source file may be used and distributed without         //
21
// restriction provided that this copyright statement is not    //
22
// removed from the file and that any derivative work contains  //
23
// the original copyright notice and the associated disclaimer. //
24
//                                                              //
25
// This source file is free software; you can redistribute it   //
26
// and/or modify it under the terms of the GNU Lesser General   //
27
// Public License as published by the Free Software Foundation; //
28
// either version 2.1 of the License, or (at your option) any   //
29
// later version.                                               //
30
//                                                              //
31
// This source is distributed in the hope that it will be       //
32
// useful, but WITHOUT ANY WARRANTY; without even the implied   //
33
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
34
// PURPOSE.  See the GNU Lesser General Public License for more //
35
// details.                                                     //
36
//                                                              //
37
// You should have received a copy of the GNU Lesser General    //
38
// Public License along with this source; if not, download it   //
39
// from http://www.opencores.org/lgpl.shtml                     //
40
//                                                              //
41
//////////////////////////////////////////////////////////////////
42 82 csantifort
`include "global_defines.vh"
43 2 csantifort
 
44 15 csantifort
module a23_decode
45 2 csantifort
(
46
input                       i_clk,
47
input       [31:0]          i_read_data,
48
input                       i_fetch_stall,                  // stall all stages of the cpu at the same time
49
input                       i_irq,                          // interrupt request
50
input                       i_firq,                         // Fast interrupt request
51
input                       i_dabt,                         // data abort interrupt request
52
input                       i_iabt,                         // instruction pre-fetch abort flag
53
input                       i_adex,                         // Address Exception
54
input       [31:0]          i_execute_address,              // Registered address output by execute stage
55 89 csantifort
                                                            // 2 LSBs of read address used for calculating
56 2 csantifort
                                                            // shift in LDRB ops
57
input       [7:0]           i_abt_status,                   // Abort status
58
input       [31:0]          i_execute_status_bits,          // current status bits values in execute stage
59
input                       i_multiply_done,                // multiply unit is nearly done
60
 
61
 
62
// --------------------------------------------------
63
// Control signals to execute stage
64
// --------------------------------------------------
65
output reg  [31:0]          o_read_data = 1'd0,
66
output reg  [4:0]           o_read_data_alignment = 1'd0,  // 2 LSBs of read address used for calculating shift in LDRB ops
67
 
68
output reg  [31:0]          o_imm32 = 'd0,
69
output reg  [4:0]           o_imm_shift_amount = 'd0,
70
output reg                  o_shift_imm_zero = 'd0,
71 89 csantifort
output wire [3:0]           o_condition,
72 2 csantifort
output reg                  o_exclusive_exec = 'd0,         // exclusive access request ( swap instruction )
73 89 csantifort
output reg                  o_data_access_exec = 'd0,       // high means the memory access is a read
74 2 csantifort
                                                            // read or write, low for instruction
75 89 csantifort
output wire [1:0]           o_status_bits_mode,
76
output wire                 o_status_bits_irq_mask,
77
output wire                 o_status_bits_firq_mask,
78 2 csantifort
 
79
output reg  [3:0]           o_rm_sel = 'd0,
80
output reg  [3:0]           o_rds_sel = 'd0,
81
output reg  [3:0]           o_rn_sel = 'd0,
82 71 csantifort
output      [3:0]           o_rm_sel_nxt,
83
output      [3:0]           o_rds_sel_nxt,
84
output      [3:0]           o_rn_sel_nxt,
85 2 csantifort
output reg  [1:0]           o_barrel_shift_amount_sel = 'd0,
86
output reg  [1:0]           o_barrel_shift_data_sel = 'd0,
87
output reg  [1:0]           o_barrel_shift_function = 'd0,
88
output reg  [8:0]           o_alu_function = 'd0,
89 83 csantifort
output reg                  o_use_carry_in = 'd0,
90 2 csantifort
output reg  [1:0]           o_multiply_function = 'd0,
91
output reg  [2:0]           o_interrupt_vector_sel = 'd0,
92 89 csantifort
output wire [3:0]           o_address_sel,
93
output wire [1:0]           o_pc_sel,
94 2 csantifort
output reg  [1:0]           o_byte_enable_sel = 'd0,        // byte, halfword or word write
95
output reg  [2:0]           o_status_bits_sel = 'd0,
96
output reg  [2:0]           o_reg_write_sel,
97
output reg                  o_user_mode_regs_load,
98
output reg                  o_user_mode_regs_store_nxt,
99
output reg                  o_firq_not_user_mode,
100
 
101
output reg                  o_write_data_wen = 'd0,
102
output reg                  o_base_address_wen = 'd0,       // save LDM base address register
103
                                                            // in case of data abort
104 89 csantifort
output wire                 o_pc_wen,
105 2 csantifort
output reg  [14:0]          o_reg_bank_wen = 'd0,
106 71 csantifort
output reg  [3:0]           o_reg_bank_wsel = 'd0,
107 2 csantifort
output reg                  o_status_bits_flags_wen = 'd0,
108
output reg                  o_status_bits_mode_wen = 'd0,
109
output reg                  o_status_bits_irq_mask_wen = 'd0,
110
output reg                  o_status_bits_firq_mask_wen = 'd0,
111
 
112
// --------------------------------------------------
113
// Co-Processor interface
114
// --------------------------------------------------
115
output reg  [2:0]           o_copro_opcode1 = 'd0,
116
output reg  [2:0]           o_copro_opcode2 = 'd0,
117 89 csantifort
output reg  [3:0]           o_copro_crn = 'd0,
118 2 csantifort
output reg  [3:0]           o_copro_crm = 'd0,
119
output reg  [3:0]           o_copro_num = 'd0,
120 89 csantifort
output reg  [1:0]           o_copro_operation = 'd0, // 0 = no operation,
121 2 csantifort
                                                     // 1 = Move to Amber Core Register from Coprocessor
122
                                                     // 2 = Move to Coprocessor from Amber Core Register
123
output reg                  o_copro_write_data_wen = 'd0,
124
output                      o_iabt_trigger,
125
output      [31:0]          o_iabt_address,
126
output      [7:0]           o_iabt_status,
127
output                      o_dabt_trigger,
128
output      [31:0]          o_dabt_address,
129 89 csantifort
output      [7:0]           o_dabt_status
130 2 csantifort
 
131
 
132
);
133
 
134 82 csantifort
`include "a23_localparams.vh"
135
`include "a23_functions.vh"
136 2 csantifort
 
137
localparam [4:0] RST_WAIT1      = 5'd0,
138
                 RST_WAIT2      = 5'd1,
139
                 INT_WAIT1      = 5'd2,
140
                 INT_WAIT2      = 5'd3,
141
                 EXECUTE        = 5'd4,
142
                 PRE_FETCH_EXEC = 5'd5,  // Execute the Pre-Fetched Instruction
143
                 MEM_WAIT1      = 5'd6,  // conditionally decode current instruction, in case
144
                                         // previous instruction does not execute in S2
145
                 MEM_WAIT2      = 5'd7,
146
                 PC_STALL1      = 5'd8,  // Program Counter altered
147
                                         // conditionally decude current instruction, in case
148
                                         // previous instruction does not execute in S2
149
                 PC_STALL2      = 5'd9,
150
                 MTRANS_EXEC1   = 5'd10,
151
                 MTRANS_EXEC2   = 5'd11,
152
                 MTRANS_EXEC3   = 5'd12,
153
                 MTRANS_EXEC3B  = 5'd13,
154
                 MTRANS_EXEC4   = 5'd14,
155
                 MTRANS5_ABORT  = 5'd15,
156
                 MULT_PROC1     = 5'd16,  // first cycle, save pre fetch instruction
157
                 MULT_PROC2     = 5'd17,  // do multiplication
158
                 MULT_STORE     = 5'd19,  // save RdLo
159
                 MULT_ACCUMU    = 5'd20,  // Accumulate add lower 32 bits
160
                 SWAP_WRITE     = 5'd22,
161
                 SWAP_WAIT1     = 5'd23,
162
                 SWAP_WAIT2     = 5'd24,
163
                 COPRO_WAIT     = 5'd25;
164 89 csantifort
 
165
 
166 2 csantifort
// ========================================================
167
// Internal signals
168
// ========================================================
169
wire    [31:0]         instruction;
170
wire                   instruction_iabt;        // abort flag, follows the instruction
171
wire                   instruction_adex;        // address exception flag, follows the instruction
172 89 csantifort
wire    [31:0]         instruction_address;     // instruction virtual address, follows
173 2 csantifort
                                                // the instruction
174
wire    [7:0]          instruction_iabt_status; // abort status, follows the instruction
175
wire    [1:0]          instruction_sel;
176 87 csantifort
reg     [3:0]          itype;
177 2 csantifort
wire    [3:0]          opcode;
178
wire    [7:0]          imm8;
179
wire    [31:0]         offset12;
180
wire    [31:0]         offset24;
181
wire    [4:0]          shift_imm;
182
 
183
wire                   opcode_compare;
184
wire                   mem_op;
185
wire                   load_op;
186
wire                   store_op;
187
wire                   write_pc;
188
wire                   immediate_shifter_operand;
189
wire                   rds_use_rs;
190
wire                   branch;
191
wire                   mem_op_pre_indexed;
192
wire                   mem_op_post_indexed;
193
 
194
// Flop inputs
195
wire    [31:0]         imm32_nxt;
196
wire    [4:0]          imm_shift_amount_nxt;
197
wire                   shift_imm_zero_nxt;
198
wire    [3:0]          condition_nxt;
199
reg                    exclusive_exec_nxt;
200
reg                    data_access_exec_nxt;
201 88 csantifort
wire                   shift_extend;
202 2 csantifort
 
203
reg     [1:0]          barrel_shift_function_nxt;
204
wire    [8:0]          alu_function_nxt;
205 83 csantifort
reg                    use_carry_in_nxt;
206 2 csantifort
reg     [1:0]          multiply_function_nxt;
207
reg     [1:0]          status_bits_mode_nxt;
208
reg                    status_bits_irq_mask_nxt;
209
reg                    status_bits_firq_mask_nxt;
210
 
211
reg     [1:0]          barrel_shift_amount_sel_nxt;
212
reg     [1:0]          barrel_shift_data_sel_nxt;
213
reg     [3:0]          address_sel_nxt;
214
reg     [1:0]          pc_sel_nxt;
215
reg     [1:0]          byte_enable_sel_nxt;
216
reg     [2:0]          status_bits_sel_nxt;
217
reg     [2:0]          reg_write_sel_nxt;
218
reg                    user_mode_regs_load_nxt;
219
wire                   firq_not_user_mode_nxt;
220
 
221
// ALU Function signals
222
reg                    alu_swap_sel_nxt;
223
reg                    alu_not_sel_nxt;
224
reg     [1:0]          alu_cin_sel_nxt;
225
reg                    alu_cout_sel_nxt;
226
reg     [3:0]          alu_out_sel_nxt;
227
 
228
reg                    write_data_wen_nxt;
229
reg                    copro_write_data_wen_nxt;
230
reg                    base_address_wen_nxt;
231
reg                    pc_wen_nxt;
232 71 csantifort
reg     [3:0]          reg_bank_wsel_nxt;
233 2 csantifort
reg                    status_bits_flags_wen_nxt;
234
reg                    status_bits_mode_wen_nxt;
235
reg                    status_bits_irq_mask_wen_nxt;
236
reg                    status_bits_firq_mask_wen_nxt;
237
 
238
reg                    saved_current_instruction_wen;   // saved load instruction
239
reg                    pre_fetch_instruction_wen;       // pre-fetch instruction
240
 
241
reg     [4:0]          control_state = RST_WAIT1;
242
reg     [4:0]          control_state_nxt;
243
 
244
 
245
wire                   dabt;
246
reg                    dabt_reg = 'd0;
247
reg                    dabt_reg_d1;
248
reg                    iabt_reg = 'd0;
249
reg                    adex_reg = 'd0;
250
reg     [31:0]         abt_address_reg = 'd0;
251
reg     [7:0]          abt_status_reg = 'd0;
252
reg     [31:0]         saved_current_instruction = 'd0;
253
reg                    saved_current_instruction_iabt = 'd0;          // access abort flag
254
reg                    saved_current_instruction_adex = 'd0;          // address exception
255
reg     [31:0]         saved_current_instruction_address = 'd0;       // virtual address of abort instruction
256
reg     [7:0]          saved_current_instruction_iabt_status = 'd0;   // status of abort instruction
257
reg     [31:0]         pre_fetch_instruction = 'd0;
258
reg                    pre_fetch_instruction_iabt = 'd0;              // access abort flag
259
reg                    pre_fetch_instruction_adex = 'd0;              // address exception
260
reg     [31:0]         pre_fetch_instruction_address = 'd0;           // virtual address of abort instruction
261
reg     [7:0]          pre_fetch_instruction_iabt_status = 'd0;       // status of abort instruction
262
 
263
wire                   instruction_valid;
264
wire                   instruction_execute;
265
 
266
reg     [3:0]          mtrans_reg;              // the current register being accessed as part of STM/LDM
267
reg     [3:0]          mtrans_reg_d1 = 'd0;     // delayed by 1 period
268
reg     [3:0]          mtrans_reg_d2 = 'd0;     // delayed by 2 periods
269
reg     [31:0]         mtrans_instruction_nxt;
270
 
271
wire   [31:0]          mtrans_base_reg_change;
272
wire   [4:0]           mtrans_num_registers;
273
wire                   use_saved_current_instruction;
274
wire                   use_pre_fetch_instruction;
275
wire                   interrupt;
276
wire   [1:0]           interrupt_mode;
277
wire   [2:0]           next_interrupt;
278
reg                    irq = 'd0;
279
reg                    firq = 'd0;
280
wire                   firq_request;
281
wire                   irq_request;
282
wire                   swi_request;
283
wire                   und_request;
284
wire                   dabt_request;
285
reg    [1:0]           copro_operation_nxt;
286
reg                    mtrans_r15 = 'd0;
287
reg                    mtrans_r15_nxt;
288
reg                    restore_base_address = 'd0;
289
reg                    restore_base_address_nxt;
290
 
291
wire                   regop_set_flags;
292
 
293
 
294
// ========================================================
295 89 csantifort
// registers for output ports with non-zero initial values
296
// ========================================================
297
reg  [3:0]           condition_r = 4'he;             // 4'he = al
298
reg  [1:0]           status_bits_mode_r = 2'b11;     // SVC
299
reg                  status_bits_irq_mask_r = 1'd1;
300
reg                  status_bits_firq_mask_r = 1'd1;
301
reg  [3:0]           address_sel_r = 4'd2;
302
reg  [1:0]           pc_sel_r = 2'd2;
303
reg                  pc_wen_r = 1'd1;
304
 
305
assign o_condition              = condition_r;
306
assign o_status_bits_mode       = status_bits_mode_r;
307
assign o_status_bits_irq_mask   = status_bits_irq_mask_r;
308
assign o_status_bits_firq_mask  = status_bits_firq_mask_r;
309
assign o_address_sel            = address_sel_r;
310
assign o_pc_sel                 = pc_sel_r;
311
assign o_pc_wen                 = pc_wen_r;
312
 
313
 
314
 
315
// ========================================================
316 2 csantifort
// Instruction Abort and Data Abort outputs
317
// ========================================================
318
 
319 89 csantifort
assign o_iabt_trigger     = instruction_iabt && status_bits_mode_r == SVC && control_state == INT_WAIT1;
320 2 csantifort
assign o_iabt_address     = instruction_address;
321
assign o_iabt_status      = instruction_iabt_status;
322
 
323
assign o_dabt_trigger     = dabt_reg && !dabt_reg_d1;
324
assign o_dabt_address     = abt_address_reg;
325
assign o_dabt_status      = abt_status_reg;
326
 
327
 
328
// ========================================================
329
// Instruction Decode
330
// ========================================================
331
 
332
// for instructions that take more than one cycle
333
// the instruction is saved in the 'saved_mem_instruction'
334
// register and then that register is used for the rest of
335
// the execution of the instruction.
336
// But if the instruction does not execute because of the
337
// condition, then need to select the next instruction to
338
// decode
339
assign use_saved_current_instruction =  instruction_execute &&
340
                          ( control_state == MEM_WAIT1     ||
341
                            control_state == MEM_WAIT2     ||
342
                            control_state == MTRANS_EXEC1  ||
343 89 csantifort
                            control_state == MTRANS_EXEC2  ||
344 2 csantifort
                            control_state == MTRANS_EXEC3  ||
345
                            control_state == MTRANS_EXEC3B ||
346
                            control_state == MTRANS_EXEC4  ||
347
                            control_state == MTRANS5_ABORT ||
348
                            control_state == MULT_PROC1    ||
349
                            control_state == MULT_PROC2    ||
350
                            control_state == MULT_ACCUMU   ||
351
                            control_state == MULT_STORE    ||
352
                            control_state == INT_WAIT1     ||
353
                            control_state == INT_WAIT2     ||
354
                            control_state == SWAP_WRITE    ||
355
                            control_state == SWAP_WAIT1    ||
356
                            control_state == SWAP_WAIT2    ||
357
                            control_state == COPRO_WAIT     );
358
 
359
assign use_pre_fetch_instruction = control_state == PRE_FETCH_EXEC;
360
 
361
 
362 89 csantifort
assign instruction_sel  =         use_saved_current_instruction  ? 2'd1 :  // saved_current_instruction
363
                                  use_pre_fetch_instruction      ? 2'd2 :  // pre_fetch_instruction
364
                                                                   2'd0 ;  // o_read_data
365 2 csantifort
 
366
assign instruction      =         instruction_sel == 2'd0 ? o_read_data               :
367
                                  instruction_sel == 2'd1 ? saved_current_instruction :
368
                                                            pre_fetch_instruction     ;
369
 
370
// abort flag
371
assign instruction_iabt =         instruction_sel == 2'd0 ? iabt_reg                       :
372
                                  instruction_sel == 2'd1 ? saved_current_instruction_iabt :
373
                                                            pre_fetch_instruction_iabt     ;
374 89 csantifort
 
375 2 csantifort
assign instruction_address =      instruction_sel == 2'd0 ? abt_address_reg                   :
376
                                  instruction_sel == 2'd1 ? saved_current_instruction_address :
377
                                                            pre_fetch_instruction_address     ;
378
 
379
assign instruction_iabt_status =  instruction_sel == 2'd0 ? abt_status_reg                        :
380
                                  instruction_sel == 2'd1 ? saved_current_instruction_iabt_status :
381
                                                            pre_fetch_instruction_iabt_status     ;
382
 
383
// instruction address exception
384
assign instruction_adex =         instruction_sel == 2'd0 ? adex_reg                       :
385
                                  instruction_sel == 2'd1 ? saved_current_instruction_adex :
386
                                                            pre_fetch_instruction_adex     ;
387
 
388
// Instruction Decode - Order is important!
389
always @*
390
    casez ({instruction[27:20], instruction[7:4]})
391 87 csantifort
        12'b00010?001001 : itype = SWAP;
392
        12'b000000??1001 : itype = MULT;
393
        12'b00?????????? : itype = REGOP;
394 89 csantifort
        12'b01?????????? : itype = TRANS;
395
        12'b100????????? : itype = MTRANS;
396
        12'b101????????? : itype = BRANCH;
397 87 csantifort
        12'b110????????? : itype = CODTRANS;
398 89 csantifort
        12'b1110???????0 : itype = COREGOP;
399
        12'b1110???????1 : itype = CORTRANS;
400 87 csantifort
        default:           itype = SWI;
401 2 csantifort
    endcase
402
 
403 89 csantifort
 
404 2 csantifort
// ========================================================
405
// Fixed fields within the instruction
406
// ========================================================
407 89 csantifort
 
408 2 csantifort
assign opcode        = instruction[24:21];
409
assign condition_nxt = instruction[31:28];
410
 
411 71 csantifort
assign o_rm_sel_nxt    = instruction[3:0];
412 89 csantifort
 
413 87 csantifort
assign o_rn_sel_nxt    = branch  ? 4'd15              : // Use PC to calculate branch destination
414
                                   instruction[19:16] ;
415 2 csantifort
 
416 71 csantifort
assign o_rds_sel_nxt   = control_state == SWAP_WRITE  ? instruction[3:0]   : // Rm gets written out to memory
417 87 csantifort
                         itype == MTRANS              ? mtrans_reg         :
418
                         branch                       ? 4'd15              : // Update the PC
419 89 csantifort
                         rds_use_rs                   ? instruction[11:8]  :
420 87 csantifort
                                                        instruction[15:12] ;
421 2 csantifort
 
422 89 csantifort
 
423 2 csantifort
assign shift_imm     = instruction[11:7];
424 87 csantifort
 
425
// this is used for RRX
426
assign shift_extend  = !instruction[25] && !instruction[4] && !(|instruction[11:7]) && instruction[6:5] == 2'b11;
427
 
428 2 csantifort
assign offset12      = { 20'h0, instruction[11:0]};
429
assign offset24      = {{6{instruction[23]}}, instruction[23:0], 2'd0 }; // sign extend
430
assign imm8          = instruction[7:0];
431
 
432
assign immediate_shifter_operand = instruction[25];
433 87 csantifort
assign rds_use_rs                = (itype == REGOP && !instruction[25] && instruction[4]) ||
434 89 csantifort
                                   (itype == MULT &&
435
                                    (control_state == MULT_PROC1  ||
436 2 csantifort
                                     control_state == MULT_PROC2  ||
437
                                     instruction_valid && !interrupt )) ;
438 87 csantifort
assign branch                    = itype == BRANCH;
439 2 csantifort
assign opcode_compare =
440 89 csantifort
            opcode == CMP ||
441
            opcode == CMN ||
442
            opcode == TEQ ||
443 2 csantifort
            opcode == TST ;
444 89 csantifort
 
445
 
446 87 csantifort
assign mem_op               = itype == TRANS;
447 2 csantifort
assign load_op              = mem_op && instruction[20];
448
assign store_op             = mem_op && !instruction[20];
449
assign write_pc             = pc_wen_nxt && pc_sel_nxt != 2'd0;
450 89 csantifort
assign regop_set_flags      = itype == REGOP && instruction[20];
451 2 csantifort
 
452
assign mem_op_pre_indexed   =  instruction[24] && instruction[21];
453
assign mem_op_post_indexed  = !instruction[24];
454
 
455
assign imm32_nxt            =  // add 0 to Rm
456 87 csantifort
                               itype == MULT               ? {  32'd0                      } :
457 89 csantifort
 
458 2 csantifort
                               // 4 x number of registers
459 87 csantifort
                               itype == MTRANS             ? {  mtrans_base_reg_change     } :
460
                               itype == BRANCH             ? {  offset24                   } :
461
                               itype == TRANS              ? {  offset12                   } :
462 2 csantifort
                               instruction[11:8] == 4'h0  ? {            24'h0, imm8[7:0] } :
463
                               instruction[11:8] == 4'h1  ? { imm8[1:0], 24'h0, imm8[7:2] } :
464
                               instruction[11:8] == 4'h2  ? { imm8[3:0], 24'h0, imm8[7:4] } :
465
                               instruction[11:8] == 4'h3  ? { imm8[5:0], 24'h0, imm8[7:6] } :
466
                               instruction[11:8] == 4'h4  ? { imm8[7:0], 24'h0            } :
467
                               instruction[11:8] == 4'h5  ? { 2'h0,  imm8[7:0], 22'h0     } :
468
                               instruction[11:8] == 4'h6  ? { 4'h0,  imm8[7:0], 20'h0     } :
469
                               instruction[11:8] == 4'h7  ? { 6'h0,  imm8[7:0], 18'h0     } :
470
                               instruction[11:8] == 4'h8  ? { 8'h0,  imm8[7:0], 16'h0     } :
471
                               instruction[11:8] == 4'h9  ? { 10'h0, imm8[7:0], 14'h0     } :
472
                               instruction[11:8] == 4'ha  ? { 12'h0, imm8[7:0], 12'h0     } :
473
                               instruction[11:8] == 4'hb  ? { 14'h0, imm8[7:0], 10'h0     } :
474
                               instruction[11:8] == 4'hc  ? { 16'h0, imm8[7:0], 8'h0      } :
475
                               instruction[11:8] == 4'hd  ? { 18'h0, imm8[7:0], 6'h0      } :
476
                               instruction[11:8] == 4'he  ? { 20'h0, imm8[7:0], 4'h0      } :
477
                                                            { 22'h0, imm8[7:0], 2'h0      } ;
478
 
479
 
480
assign imm_shift_amount_nxt = shift_imm ;
481
 
482 89 csantifort
       // This signal is encoded in the decode stage because
483 2 csantifort
       // it is on the critical path in the execute stage
484
assign shift_imm_zero_nxt   = imm_shift_amount_nxt == 5'd0 &&       // immediate amount = 0
485
                              barrel_shift_amount_sel_nxt == 2'd2;  // shift immediate amount
486
 
487 89 csantifort
assign alu_function_nxt     = { alu_swap_sel_nxt,
488
                                alu_not_sel_nxt,
489 2 csantifort
                                alu_cin_sel_nxt,
490 89 csantifort
                                alu_cout_sel_nxt,
491 2 csantifort
                                alu_out_sel_nxt  };
492 89 csantifort
 
493
 
494 2 csantifort
// ========================================================
495
// MTRANS Operations
496
// ========================================================
497 89 csantifort
 
498 2 csantifort
   // Bit 15 = r15
499
   // Bit 0  = R0
500 89 csantifort
   // In LDM and STM instructions R0 is loaded or stored first
501 2 csantifort
always @*
502
    casez (instruction[15:0])
503
    16'b???????????????1 : mtrans_reg = 4'h0 ;
504
    16'b??????????????10 : mtrans_reg = 4'h1 ;
505
    16'b?????????????100 : mtrans_reg = 4'h2 ;
506
    16'b????????????1000 : mtrans_reg = 4'h3 ;
507
    16'b???????????10000 : mtrans_reg = 4'h4 ;
508
    16'b??????????100000 : mtrans_reg = 4'h5 ;
509
    16'b?????????1000000 : mtrans_reg = 4'h6 ;
510
    16'b????????10000000 : mtrans_reg = 4'h7 ;
511
    16'b???????100000000 : mtrans_reg = 4'h8 ;
512
    16'b??????1000000000 : mtrans_reg = 4'h9 ;
513
    16'b?????10000000000 : mtrans_reg = 4'ha ;
514
    16'b????100000000000 : mtrans_reg = 4'hb ;
515
    16'b???1000000000000 : mtrans_reg = 4'hc ;
516
    16'b??10000000000000 : mtrans_reg = 4'hd ;
517
    16'b?100000000000000 : mtrans_reg = 4'he ;
518
    default              : mtrans_reg = 4'hf ;
519
    endcase
520
 
521 87 csantifort
 
522 2 csantifort
always @*
523
    casez (instruction[15:0])
524
    16'b???????????????1 : mtrans_instruction_nxt = {instruction[31:16], instruction[15: 1],  1'd0};
525 89 csantifort
    16'b??????????????10 : mtrans_instruction_nxt = {instruction[31:16], instruction[15: 2],  2'd0};
526
    16'b?????????????100 : mtrans_instruction_nxt = {instruction[31:16], instruction[15: 3],  3'd0};
527
    16'b????????????1000 : mtrans_instruction_nxt = {instruction[31:16], instruction[15: 4],  4'd0};
528
    16'b???????????10000 : mtrans_instruction_nxt = {instruction[31:16], instruction[15: 5],  5'd0};
529
    16'b??????????100000 : mtrans_instruction_nxt = {instruction[31:16], instruction[15: 6],  6'd0};
530
    16'b?????????1000000 : mtrans_instruction_nxt = {instruction[31:16], instruction[15: 7],  7'd0};
531
    16'b????????10000000 : mtrans_instruction_nxt = {instruction[31:16], instruction[15: 8],  8'd0};
532
    16'b???????100000000 : mtrans_instruction_nxt = {instruction[31:16], instruction[15: 9],  9'd0};
533
    16'b??????1000000000 : mtrans_instruction_nxt = {instruction[31:16], instruction[15:10], 10'd0};
534
    16'b?????10000000000 : mtrans_instruction_nxt = {instruction[31:16], instruction[15:11], 11'd0};
535
    16'b????100000000000 : mtrans_instruction_nxt = {instruction[31:16], instruction[15:12], 12'd0};
536
    16'b???1000000000000 : mtrans_instruction_nxt = {instruction[31:16], instruction[15:13], 13'd0};
537
    16'b??10000000000000 : mtrans_instruction_nxt = {instruction[31:16], instruction[15:14], 14'd0};
538
    16'b?100000000000000 : mtrans_instruction_nxt = {instruction[31:16], instruction[15   ], 15'd0};
539
    default              : mtrans_instruction_nxt = {instruction[31:16],                     16'd0};
540 2 csantifort
    endcase
541
 
542
 
543
// number of registers to be stored
544 89 csantifort
assign mtrans_num_registers =   {4'd0, instruction[15]} +
545
                                {4'd0, instruction[14]} +
546
                                {4'd0, instruction[13]} +
547 2 csantifort
                                {4'd0, instruction[12]} +
548
                                {4'd0, instruction[11]} +
549
                                {4'd0, instruction[10]} +
550
                                {4'd0, instruction[ 9]} +
551
                                {4'd0, instruction[ 8]} +
552
                                {4'd0, instruction[ 7]} +
553
                                {4'd0, instruction[ 6]} +
554
                                {4'd0, instruction[ 5]} +
555
                                {4'd0, instruction[ 4]} +
556
                                {4'd0, instruction[ 3]} +
557
                                {4'd0, instruction[ 2]} +
558
                                {4'd0, instruction[ 1]} +
559
                                {4'd0, instruction[ 0]} ;
560 89 csantifort
 
561 2 csantifort
// 4 x number of registers to be stored
562
assign mtrans_base_reg_change = {25'd0, mtrans_num_registers, 2'd0};
563
 
564
// ========================================================
565
// Interrupts
566
// ========================================================
567
 
568
assign firq_request = firq && !i_execute_status_bits[26];
569
assign irq_request  = irq  && !i_execute_status_bits[27];
570 87 csantifort
assign swi_request  = itype == SWI;
571 2 csantifort
assign dabt_request = dabt_reg;
572
 
573
// copro15 and copro13 only supports reg trans opcodes
574 89 csantifort
// all other opcodes involving co-processors cause an
575 2 csantifort
// undefined instrution interrupt
576 89 csantifort
assign und_request  =   itype == CODTRANS ||
577
                        itype == COREGOP  ||
578 87 csantifort
                      ( itype == CORTRANS && instruction[11:8] != 4'd15 );
579 2 csantifort
 
580
 
581 89 csantifort
  // in order of priority !!
582
  // Highest
583 2 csantifort
  // 1 Reset
584
  // 2 Data Abort (including data TLB miss)
585
  // 3 FIRQ
586
  // 4 IRQ
587
  // 5 Prefetch Abort (including prefetch TLB miss)
588
  // 6 Undefined instruction, SWI
589 89 csantifort
  // Lowest
590 2 csantifort
assign next_interrupt = dabt_request     ? 3'd1 :  // Data Abort
591
                        firq_request     ? 3'd2 :  // FIRQ
592
                        irq_request      ? 3'd3 :  // IRQ
593 89 csantifort
                        instruction_adex ? 3'd4 :  // Address Exception
594
                        instruction_iabt ? 3'd5 :  // PreFetch Abort, only triggered
595 2 csantifort
                                                   // if the instruction is used
596
                        und_request      ? 3'd6 :  // Undefined Instruction
597
                        swi_request      ? 3'd7 :  // SWI
598 89 csantifort
                                           3'd0 ;  // none
599 2 csantifort
 
600
        // SWI and undefined instructions do not cause an interrupt in the decode
601
        // stage. They only trigger interrupts if they arfe executed, so the
602
        // interrupt is triggered if the execute condition is met in the execute stage
603 89 csantifort
assign interrupt      = next_interrupt != 3'd0 &&
604 2 csantifort
                        next_interrupt != 3'd7 &&  // SWI
605
                        next_interrupt != 3'd6 ;   // undefined interrupt
606
 
607
 
608
assign interrupt_mode = next_interrupt == 3'd2 ? FIRQ :
609
                        next_interrupt == 3'd3 ? IRQ  :
610
                        next_interrupt == 3'd4 ? SVC  :
611
                        next_interrupt == 3'd5 ? SVC  :
612
                        next_interrupt == 3'd6 ? SVC  :
613
                        next_interrupt == 3'd7 ? SVC  :
614
                        next_interrupt == 3'd1 ? SVC  :
615
                                                 USR  ;
616
 
617
 
618
 
619
 
620
// ========================================================
621
// Generate control signals
622
// ========================================================
623
always @*
624
    begin
625
    // default mode
626
    status_bits_mode_nxt            = i_execute_status_bits[1:0];   // change to mode in execute stage get reflected
627
                                                                    // back to this stage automatically
628 89 csantifort
    status_bits_irq_mask_nxt        = status_bits_irq_mask_r;
629
    status_bits_firq_mask_nxt       = status_bits_firq_mask_r;
630 2 csantifort
    exclusive_exec_nxt              = 1'd0;
631
    data_access_exec_nxt            = 1'd0;
632
    copro_operation_nxt             = 'd0;
633 89 csantifort
 
634 2 csantifort
    // Save an instruction to use later
635
    saved_current_instruction_wen   = 1'd0;
636
    pre_fetch_instruction_wen       = 1'd0;
637
    mtrans_r15_nxt                  = mtrans_r15;
638
    restore_base_address_nxt        = restore_base_address;
639 89 csantifort
 
640 2 csantifort
    // default Mux Select values
641
    barrel_shift_amount_sel_nxt     = 'd0;  // don't shift the input
642
    barrel_shift_data_sel_nxt       = 'd0;  // immediate value
643
    barrel_shift_function_nxt       = 'd0;
644 83 csantifort
    use_carry_in_nxt                = 'd0;
645 2 csantifort
    multiply_function_nxt           = 'd0;
646 89 csantifort
    address_sel_nxt                 = 'd0;
647
    pc_sel_nxt                      = 'd0;
648
    byte_enable_sel_nxt             = 'd0;
649
    status_bits_sel_nxt             = 'd0;
650
    reg_write_sel_nxt               = 'd0;
651 71 csantifort
    user_mode_regs_load_nxt         = 'd0;
652 89 csantifort
    o_user_mode_regs_store_nxt      = 'd0;
653
 
654 2 csantifort
    // ALU Muxes
655 89 csantifort
    alu_swap_sel_nxt                = 'd0;
656
    alu_not_sel_nxt                 = 'd0;
657
    alu_cin_sel_nxt                 = 'd0;
658
    alu_cout_sel_nxt                = 'd0;
659
    alu_out_sel_nxt                 = 'd0;
660
 
661 2 csantifort
    // default Flop Write Enable values
662
    write_data_wen_nxt              = 'd0;
663
    copro_write_data_wen_nxt        = 'd0;
664
    base_address_wen_nxt            = 'd0;
665
    pc_wen_nxt                      = 'd1;
666 71 csantifort
    reg_bank_wsel_nxt               = 'hF;  // Don't select any
667 2 csantifort
    status_bits_flags_wen_nxt       = 'd0;
668
    status_bits_mode_wen_nxt        = 'd0;
669
    status_bits_irq_mask_wen_nxt    = 'd0;
670
    status_bits_firq_mask_wen_nxt   = 'd0;
671 89 csantifort
 
672 2 csantifort
    if ( instruction_valid && !interrupt )
673
        begin
674 87 csantifort
        if ( itype == REGOP )
675 2 csantifort
            begin
676
            if ( !opcode_compare )
677
                begin
678
                // Check is the load destination is the PC
679
                if (instruction[15:12]  == 4'd15)
680
                    begin
681
                    pc_sel_nxt      = 2'd1; // alu_out
682
                    address_sel_nxt = 4'd1; // alu_out
683
                    end
684 89 csantifort
                else
685 71 csantifort
                    reg_bank_wsel_nxt = instruction[15:12];
686 2 csantifort
                end
687 89 csantifort
 
688 2 csantifort
            if ( !immediate_shifter_operand )
689
                barrel_shift_function_nxt  = instruction[6:5];
690 89 csantifort
 
691 2 csantifort
            if ( !immediate_shifter_operand )
692
                barrel_shift_data_sel_nxt = 2'd2; // Shift value from Rm register
693 89 csantifort
 
694 2 csantifort
            if ( !immediate_shifter_operand && instruction[4] )
695
                barrel_shift_amount_sel_nxt = 2'd1; // Shift amount from Rs registter
696 89 csantifort
 
697
            if ( !immediate_shifter_operand && !instruction[4] )
698
                barrel_shift_amount_sel_nxt = 2'd2; // Shift immediate amount
699
 
700 82 csantifort
            // regops that do not change the overflow flag
701 89 csantifort
            if ( opcode == AND || opcode == EOR || opcode == TST || opcode == TEQ ||
702 82 csantifort
                 opcode == ORR || opcode == MOV || opcode == BIC || opcode == MVN )
703
                status_bits_sel_nxt = 3'd5;
704
 
705 2 csantifort
            if ( opcode == ADD || opcode == CMN )   // CMN is just like an ADD
706
                begin
707
                alu_out_sel_nxt  = 4'd1; // Add
708 87 csantifort
                use_carry_in_nxt = shift_extend;
709 2 csantifort
                end
710 89 csantifort
 
711 2 csantifort
            if ( opcode == ADC ) // Add with Carry
712
                begin
713
                alu_out_sel_nxt  = 4'd1; // Add
714
                alu_cin_sel_nxt  = 2'd2; // carry in from status_bits
715 87 csantifort
                use_carry_in_nxt = shift_extend;
716 2 csantifort
                end
717 89 csantifort
 
718 2 csantifort
            if ( opcode == SUB || opcode == CMP ) // Subtract
719
                begin
720
                alu_out_sel_nxt  = 4'd1; // Add
721
                alu_cin_sel_nxt  = 2'd1; // cin = 1
722
                alu_not_sel_nxt  = 1'd1; // invert B
723
                end
724 89 csantifort
 
725
            // SBC (Subtract with Carry) subtracts the value of its
726 2 csantifort
            // second operand and the value of NOT(Carry flag) from
727
            // the value of its first operand.
728
            //  Rd = Rn - shifter_operand - NOT(C Flag)
729
            if ( opcode == SBC ) // Subtract with Carry
730
                begin
731
                alu_out_sel_nxt  = 4'd1; // Add
732
                alu_cin_sel_nxt  = 2'd2; // carry in from status_bits
733
                alu_not_sel_nxt  = 1'd1; // invert B
734 83 csantifort
                use_carry_in_nxt = 1'd1;
735 2 csantifort
                end
736 89 csantifort
 
737 2 csantifort
            if ( opcode == RSB ) // Reverse Subtract
738
                begin
739
                alu_out_sel_nxt  = 4'd1; // Add
740
                alu_cin_sel_nxt  = 2'd1; // cin = 1
741
                alu_not_sel_nxt  = 1'd1; // invert B
742
                alu_swap_sel_nxt = 1'd1; // swap A and B
743
                end
744 89 csantifort
 
745 2 csantifort
            if ( opcode == RSC ) // Reverse Subtract with carry
746
                begin
747
                alu_out_sel_nxt  = 4'd1; // Add
748
                alu_cin_sel_nxt  = 2'd2; // carry in from status_bits
749
                alu_not_sel_nxt  = 1'd1; // invert B
750
                alu_swap_sel_nxt = 1'd1; // swap A and B
751 83 csantifort
                use_carry_in_nxt = 1'd1;
752 2 csantifort
                end
753 89 csantifort
 
754 2 csantifort
            if ( opcode == AND || opcode == TST ) // Logical AND, Test  (using AND operator)
755
                begin
756
                alu_out_sel_nxt  = 4'd8;  // AND
757
                alu_cout_sel_nxt = 1'd1;  // i_barrel_shift_carry
758
                end
759 89 csantifort
 
760 2 csantifort
            if ( opcode == EOR || opcode == TEQ ) // Logical Exclusive OR, Test Equivalence (using EOR operator)
761
                begin
762 87 csantifort
                alu_out_sel_nxt  = 4'd6; // XOR
763 2 csantifort
                alu_cout_sel_nxt = 1'd1; // i_barrel_shift_carry
764 87 csantifort
                use_carry_in_nxt = 1'd1;
765 2 csantifort
                end
766
 
767
            if ( opcode == ORR )
768
                begin
769
                alu_out_sel_nxt  = 4'd7; // OR
770 87 csantifort
                alu_cout_sel_nxt = 1'd1; // i_barrel_shift_carry
771
                use_carry_in_nxt = 1'd1;
772 2 csantifort
                end
773 89 csantifort
 
774 2 csantifort
            if ( opcode == BIC ) // Bit Clear (using AND & NOT operators)
775
                begin
776
                alu_out_sel_nxt  = 4'd8;  // AND
777
                alu_not_sel_nxt  = 1'd1;  // invert B
778
                alu_cout_sel_nxt = 1'd1;  // i_barrel_shift_carry
779 87 csantifort
                use_carry_in_nxt = 1'd1;
780 2 csantifort
                end
781 89 csantifort
 
782 2 csantifort
            if ( opcode == MOV ) // Move
783
                begin
784
                alu_cout_sel_nxt = 1'd1;  // i_barrel_shift_carry
785 87 csantifort
                use_carry_in_nxt = 1'd1;
786 2 csantifort
                end
787 89 csantifort
 
788 2 csantifort
            if ( opcode == MVN ) // Move NOT
789
                begin
790
                alu_not_sel_nxt  = 1'd1; // invert B
791 87 csantifort
                alu_cout_sel_nxt = 1'd1; // i_barrel_shift_carry
792
                use_carry_in_nxt = 1'd1;
793 2 csantifort
                end
794
            end
795 89 csantifort
 
796 2 csantifort
        // Load & Store instructions
797
        if ( mem_op )
798
            begin
799
            saved_current_instruction_wen   = 1'd1; // Save the memory access instruction to refer back to later
800
            pc_wen_nxt                      = 1'd0; // hold current PC value
801 89 csantifort
            data_access_exec_nxt            = 1'd1; // indicate that its a data read or write,
802 2 csantifort
                                                    // rather than an instruction fetch
803
            alu_out_sel_nxt                 = 4'd1; // Add
804 89 csantifort
 
805 2 csantifort
            if ( !instruction[23] )  // U: Subtract offset
806
                begin
807
                alu_cin_sel_nxt  = 2'd1; // cin = 1
808
                alu_not_sel_nxt  = 1'd1; // invert B
809
                end
810 89 csantifort
 
811 2 csantifort
            if ( store_op )
812
                begin
813
                write_data_wen_nxt = 1'd1;
814 87 csantifort
                if ( itype == TRANS && instruction[22] )
815 2 csantifort
                    byte_enable_sel_nxt = 2'd1;         // Save byte
816
                end
817 89 csantifort
 
818 2 csantifort
                // need to update the register holding the address ?
819
                // This is Rn bits [19:16]
820
            if ( mem_op_pre_indexed || mem_op_post_indexed )
821
                begin
822
                // Check is the load destination is the PC
823 71 csantifort
                if ( o_rn_sel_nxt  == 4'd15 )
824 89 csantifort
                    pc_sel_nxt = 2'd1;
825
                else
826 71 csantifort
                    reg_bank_wsel_nxt = o_rn_sel_nxt;
827 2 csantifort
                end
828 89 csantifort
 
829 2 csantifort
                // if post-indexed, then use Rn rather than ALU output, as address
830
            if ( mem_op_post_indexed )
831
               address_sel_nxt = 4'd4; // Rn
832 89 csantifort
            else
833 2 csantifort
               address_sel_nxt = 4'd1; // alu out
834 89 csantifort
 
835 87 csantifort
            if ( instruction[25] && itype ==  TRANS )
836 2 csantifort
                barrel_shift_data_sel_nxt = 2'd2; // Shift value from Rm register
837 89 csantifort
 
838
            if ( itype == TRANS && instruction[25] && shift_imm != 5'd0 )
839
                begin
840 2 csantifort
                barrel_shift_function_nxt   = instruction[6:5];
841
                barrel_shift_amount_sel_nxt = 2'd2; // imm_shift_amount
842
                end
843
            end
844 89 csantifort
 
845 87 csantifort
        if ( itype == BRANCH )
846 2 csantifort
            begin
847
            pc_sel_nxt      = 2'd1; // alu_out
848
            address_sel_nxt = 4'd1; // alu_out
849
            alu_out_sel_nxt = 4'd1; // Add
850 89 csantifort
 
851 2 csantifort
            if ( instruction[24] ) // Link
852
                begin
853 71 csantifort
                reg_bank_wsel_nxt  = 4'd14;  // Save PC to LR
854 2 csantifort
                reg_write_sel_nxt = 3'd1;            // pc - 32'd4
855
                end
856
            end
857 89 csantifort
 
858 87 csantifort
        if ( itype == MTRANS )
859 2 csantifort
            begin
860
            saved_current_instruction_wen   = 1'd1; // Save the memory access instruction to refer back to later
861
            pc_wen_nxt                      = 1'd0; // hold current PC value
862 89 csantifort
            data_access_exec_nxt            = 1'd1; // indicate that its a data read or write,
863 2 csantifort
                                                    // rather than an instruction fetch
864
            alu_out_sel_nxt                 = 4'd1; // Add
865
            mtrans_r15_nxt                  = instruction[15];  // load or save r15 ?
866
            base_address_wen_nxt            = 1'd1; // Save the value of the register used for the base address,
867 89 csantifort
                                                    // in case of a data abort, and need to restore the value
868 2 csantifort
 
869
            // The spec says -
870 89 csantifort
            // If the instruction would have overwritten the base with data
871 2 csantifort
            // (that is, it has the base in the transfer list), the overwriting is prevented.
872
            // This is true even when the abort occurs after the base word gets loaded
873 89 csantifort
            restore_base_address_nxt        = instruction[20] &&
874 2 csantifort
                                                (instruction[15:0] & (1'd1 << instruction[19:16]));
875
 
876
            // Increment or Decrement
877
            if ( instruction[23] ) // increment
878
                begin
879
                if ( instruction[24] )    // increment before
880
                    address_sel_nxt = 4'd7; // Rn + 4
881 89 csantifort
                else
882 2 csantifort
                    address_sel_nxt = 4'd4; // Rn
883
                end
884
            else // decrement
885
                begin
886
                alu_cin_sel_nxt  = 2'd1; // cin = 1
887
                alu_not_sel_nxt  = 1'd1; // invert B
888
                if ( !instruction[24] )    // decrement after
889
                    address_sel_nxt  = 4'd6; // alu out + 4
890
                else
891
                    address_sel_nxt  = 4'd1; // alu out
892
                end
893 89 csantifort
 
894 2 csantifort
            // Load or store ?
895
            if ( !instruction[20] )  // Store
896 89 csantifort
                write_data_wen_nxt = 1'd1;
897
 
898
            // LDM: load into user mode registers, when in priviledged mode
899
            // Don't use mtrans_r15 here because its not loaded yet
900 87 csantifort
            //if ( {instruction[22],instruction[20],instruction[15]} == 3'b110 )
901 89 csantifort
            if ( {instruction[22:20],instruction[15]} == 4'b1010 )
902 2 csantifort
                user_mode_regs_load_nxt = 1'd1;
903 87 csantifort
 
904 89 csantifort
            // SDM: store the user mode registers, when in priviledged mode
905
            //if ( {instruction[22],instruction[20]} == 3'b10 )
906 87 csantifort
            if ( {instruction[22:20]} == 3'b100 )
907 2 csantifort
                o_user_mode_regs_store_nxt = 1'd1;
908 89 csantifort
 
909 2 csantifort
            // update the base register ?
910
            if ( instruction[21] )  // the W bit
911 71 csantifort
                reg_bank_wsel_nxt  = o_rn_sel_nxt;
912 2 csantifort
            end
913 89 csantifort
 
914
 
915 87 csantifort
        if ( itype == MULT )
916 2 csantifort
            begin
917
            multiply_function_nxt[0]        = 1'd1; // set enable
918
                                                    // some bits can be changed just below
919 89 csantifort
            saved_current_instruction_wen   = 1'd1; // Save the Multiply instruction to
920 2 csantifort
                                                    // refer back to later
921
            pc_wen_nxt                      = 1'd0; // hold current PC value
922 89 csantifort
 
923 2 csantifort
            if ( instruction[21] )
924
                multiply_function_nxt[1]    = 1'd1; // accumulate
925
            end
926 89 csantifort
 
927
 
928 2 csantifort
        // swp - do read part first
929 87 csantifort
        if ( itype == SWAP )
930 2 csantifort
            begin
931
            saved_current_instruction_wen   = 1'd1; // Save the memory access instruction to refer back to later
932
            pc_wen_nxt                      = 1'd0; // hold current PC value
933 89 csantifort
            data_access_exec_nxt            = 1'd1; // indicate that its a data read or write,
934 2 csantifort
                                                    // rather than an instruction fetch
935
            barrel_shift_data_sel_nxt       = 2'd2; // Shift value from Rm register
936
            address_sel_nxt                 = 4'd4; // Rn
937
            exclusive_exec_nxt              = 1'd1; // signal an exclusive access
938
            end
939
 
940
 
941
        // mcr & mrc - takes two cycles
942 87 csantifort
        if ( itype == CORTRANS && !und_request )
943 2 csantifort
            begin
944
            saved_current_instruction_wen   = 1'd1; // Save the memory access instruction to refer back to later
945
            pc_wen_nxt                      = 1'd0; // hold current PC value
946
            address_sel_nxt                 = 4'd3; // pc  (not pc + 4)
947 89 csantifort
 
948 2 csantifort
            if ( instruction[20] ) // MRC
949
                copro_operation_nxt         = 2'd1;  // Register transfer from Co-Processor
950
            else // MCR
951
                begin
952
                 // Don't enable operation to Co-Processor until next period
953
                 // So it gets the Rd value from the execution stage at the same time
954
                copro_operation_nxt      = 2'd0;
955
                copro_write_data_wen_nxt = 1'd1;  // Rd register value to co-processor
956
                end
957
            end
958
 
959 89 csantifort
 
960 87 csantifort
        if ( itype == SWI || und_request )
961 2 csantifort
            begin
962
            // save address of next instruction to Supervisor Mode LR
963
            reg_write_sel_nxt               = 3'd1;            // pc -4
964 71 csantifort
            reg_bank_wsel_nxt               = 4'd14;  // LR
965 89 csantifort
 
966 2 csantifort
            address_sel_nxt                 = 4'd2;            // interrupt_vector
967
            pc_sel_nxt                      = 2'd2;            // interrupt_vector
968 89 csantifort
 
969 2 csantifort
            status_bits_mode_nxt            = interrupt_mode;  // e.g. Supervisor mode
970
            status_bits_mode_wen_nxt        = 1'd1;
971 89 csantifort
 
972 2 csantifort
            // disable normal interrupts
973
            status_bits_irq_mask_nxt        = 1'd1;
974
            status_bits_irq_mask_wen_nxt    = 1'd1;
975
            end
976
 
977 89 csantifort
 
978 2 csantifort
        if ( regop_set_flags )
979
            begin
980
            status_bits_flags_wen_nxt = 1'd1;
981 89 csantifort
 
982
            // If <Rd> is r15, the ALU output is copied to the Status Bits.
983
            // Not allowed to use r15 for mul or lma instructions
984 2 csantifort
            if ( instruction[15:12] == 4'd15 )
985
                begin
986
                status_bits_sel_nxt       = 3'd1; // alu out
987 89 csantifort
 
988 2 csantifort
                // Priviledged mode? Then also update the other status bits
989
                if ( i_execute_status_bits[1:0] != USR )
990
                    begin
991
                    status_bits_mode_wen_nxt      = 1'd1;
992
                    status_bits_irq_mask_wen_nxt  = 1'd1;
993
                    status_bits_firq_mask_wen_nxt = 1'd1;
994
                    end
995
                end
996
            end
997
 
998 89 csantifort
        end
999
 
1000 2 csantifort
    // Handle asynchronous interrupts.
1001
    // interrupts are processed only during execution states
1002
    // multicycle instructions must complete before the interrupt starts
1003
    // SWI, Address Exception and Undefined Instruction interrupts are only executed if the
1004
    // instruction that causes the interrupt is conditionally executed so
1005
    // its not handled here
1006
    if ( instruction_valid && interrupt &&  next_interrupt != 3'd6 )
1007
        begin
1008
        // Save the interrupt causing instruction to refer back to later
1009
        // This also saves the instruction abort vma and status, in the case of an
1010
        // instruction abort interrupt
1011 89 csantifort
        saved_current_instruction_wen   = 1'd1;
1012
 
1013 2 csantifort
        // save address of next instruction to Supervisor Mode LR
1014
        // Address Exception ?
1015
        if ( next_interrupt == 3'd4 )
1016
            reg_write_sel_nxt               = 3'd7;            // pc
1017
        else
1018
            reg_write_sel_nxt               = 3'd1;            // pc -4
1019 89 csantifort
 
1020 71 csantifort
        reg_bank_wsel_nxt               = 4'd14;           // LR
1021 89 csantifort
 
1022 2 csantifort
        address_sel_nxt                 = 4'd2;            // interrupt_vector
1023
        pc_sel_nxt                      = 2'd2;            // interrupt_vector
1024 89 csantifort
 
1025 2 csantifort
        status_bits_mode_nxt            = interrupt_mode;  // e.g. Supervisor mode
1026
        status_bits_mode_wen_nxt        = 1'd1;
1027 89 csantifort
 
1028 2 csantifort
        // disable normal interrupts
1029
        status_bits_irq_mask_nxt        = 1'd1;
1030
        status_bits_irq_mask_wen_nxt    = 1'd1;
1031
 
1032
        // disable fast interrupts
1033
        if ( next_interrupt == 3'd2 ) // FIRQ
1034
            begin
1035
            status_bits_firq_mask_nxt        = 1'd1;
1036
            status_bits_firq_mask_wen_nxt    = 1'd1;
1037
            end
1038
        end
1039
 
1040 89 csantifort
 
1041 2 csantifort
    // previous instruction was either ldr or sdr
1042 89 csantifort
    // if it is currently executing in the execute stage do the following
1043 2 csantifort
    if ( control_state == MEM_WAIT1 )
1044
        begin
1045
        // Save the next instruction to execute later
1046
        // Do this even if this instruction does not execute because of Condition
1047
        pre_fetch_instruction_wen   = 1'd1;
1048 89 csantifort
 
1049 2 csantifort
        if ( instruction_execute ) // conditional execution state
1050
            begin
1051
            address_sel_nxt             = 4'd3; // pc  (not pc + 4)
1052
            pc_wen_nxt                  = 1'd0; // hold current PC value
1053
            end
1054
        end
1055 89 csantifort
 
1056
 
1057
    // completion of load operation
1058 2 csantifort
    if ( control_state == MEM_WAIT2 && load_op )
1059
        begin
1060
        barrel_shift_data_sel_nxt   = 2'd1;  // load word from memory
1061
        barrel_shift_amount_sel_nxt = 2'd3;  // shift by address[1:0] x 8
1062 89 csantifort
 
1063 2 csantifort
        // shift needed
1064
        if ( i_execute_address[1:0] != 2'd0 )
1065
            barrel_shift_function_nxt = ROR;
1066 89 csantifort
 
1067
        // load a byte
1068 87 csantifort
        if ( itype == TRANS && instruction[22] )
1069 2 csantifort
            alu_out_sel_nxt             = 4'd3;  // zero_extend8
1070 89 csantifort
 
1071 2 csantifort
        if ( !dabt )  // dont load data there is an abort on the data read
1072 89 csantifort
            begin
1073 2 csantifort
            // Check if the load destination is the PC
1074
            if (instruction[15:12]  == 4'd15)
1075
                begin
1076
                pc_sel_nxt      = 2'd1; // alu_out
1077
                address_sel_nxt = 4'd1; // alu_out
1078
                end
1079 89 csantifort
            else
1080 71 csantifort
                reg_bank_wsel_nxt = instruction[15:12];
1081 2 csantifort
            end
1082
        end
1083 89 csantifort
 
1084
 
1085 2 csantifort
    // second cycle of multiple load or store
1086
    if ( control_state == MTRANS_EXEC1 )
1087
        begin
1088
        // Save the next instruction to execute later
1089
        // Do this even if this instruction does not execute because of Condition
1090
        pre_fetch_instruction_wen   = 1'd1;
1091 89 csantifort
 
1092 2 csantifort
        if ( instruction_execute ) // conditional execution state
1093
            begin
1094
            address_sel_nxt             = 4'd5;  // o_address
1095
            pc_wen_nxt                  = 1'd0;  // hold current PC value
1096 89 csantifort
            data_access_exec_nxt        = 1'd1;  // indicate that its a data read or write,
1097 2 csantifort
                                                 // rather than an instruction fetch
1098 89 csantifort
 
1099 2 csantifort
            if ( !instruction[20] ) // Store
1100
                write_data_wen_nxt = 1'd1;
1101 89 csantifort
 
1102
            // LDM: load into user mode registers, when in priviledged mode
1103 87 csantifort
            //if ( {instruction[22],instruction[20],mtrans_r15} == 3'b110 )
1104
            if ( {instruction[22:20],mtrans_r15} == 4'b1010 )
1105 2 csantifort
                user_mode_regs_load_nxt = 1'd1;
1106 89 csantifort
 
1107
            // SDM: store the user mode registers, when in priviledged mode
1108
            //if ( {instruction[22],instruction[20]} == 2'b10 )
1109 87 csantifort
            if ( {instruction[22:20]} == 3'b100 )
1110 2 csantifort
                o_user_mode_regs_store_nxt = 1'd1;
1111 89 csantifort
            end
1112
        end
1113
 
1114
 
1115 2 csantifort
        // third cycle of multiple load or store
1116
    if ( control_state == MTRANS_EXEC2 )
1117
        begin
1118
        address_sel_nxt             = 4'd5;  // o_address
1119
        pc_wen_nxt                  = 1'd0;  // hold current PC value
1120 89 csantifort
        data_access_exec_nxt        = 1'd1;  // indicate that its a data read or write,
1121 2 csantifort
                                             // rather than an instruction fetch
1122
        barrel_shift_data_sel_nxt   = 2'd1;  // load word from memory
1123 89 csantifort
 
1124 2 csantifort
        // Load or Store
1125
        if ( instruction[20] ) // Load
1126
            begin
1127
            // Can never be loading the PC in this state, as the PC is always
1128
            // the last register in the set to be loaded
1129
            if ( !dabt )
1130 71 csantifort
                reg_bank_wsel_nxt = mtrans_reg_d2;
1131 2 csantifort
            end
1132
        else // Store
1133
            write_data_wen_nxt = 1'd1;
1134 89 csantifort
 
1135
        // LDM: load into user mode registers, when in priviledged mode
1136 82 csantifort
        if ( {instruction[22],instruction[20],mtrans_r15} == 3'b110 )
1137 2 csantifort
            user_mode_regs_load_nxt = 1'd1;
1138 89 csantifort
 
1139
        // SDM: store the user mode registers, when in priviledged mode
1140
        if ( {instruction[22],instruction[20]} == 2'b10 )
1141 2 csantifort
            o_user_mode_regs_store_nxt = 1'd1;
1142
        end
1143 89 csantifort
 
1144
 
1145 2 csantifort
        // second or fourth cycle of multiple load or store
1146
    if ( control_state == MTRANS_EXEC3 && instruction_execute )
1147
        begin
1148
        address_sel_nxt             = 4'd3; // pc  (not pc + 4)
1149
        pc_wen_nxt                  = 1'd0;  // hold current PC value
1150
        barrel_shift_data_sel_nxt   = 2'd1;  // load word from memory
1151 89 csantifort
 
1152 2 csantifort
        // Can never be loading the PC in this state, as the PC is always
1153
        // the last register in the set to be loaded
1154
        if ( instruction[20] && !dabt ) // Load
1155 71 csantifort
            reg_bank_wsel_nxt = mtrans_reg_d2;
1156 89 csantifort
 
1157
        // LDM: load into user mode registers, when in priviledged mode
1158 82 csantifort
        if ( {instruction[22],instruction[20],mtrans_r15} == 3'b110 )
1159 2 csantifort
            user_mode_regs_load_nxt = 1'd1;
1160 89 csantifort
 
1161
        // SDM: store the user mode registers, when in priviledged mode
1162
        //if ( {instruction[22:20]} == 3'b100 )
1163
        if ( {instruction[22],instruction[20]} == 2'b10 )
1164 2 csantifort
            o_user_mode_regs_store_nxt = 1'd1;
1165
       end
1166
 
1167
    // state is used for LMD/STM of a single register
1168
    if ( control_state == MTRANS_EXEC3B && instruction_execute )
1169
        begin
1170
        // Save the next instruction to execute later
1171
        // Do this even if this instruction does not execute because of Condition
1172
        pre_fetch_instruction_wen   = 1'd1;
1173 89 csantifort
 
1174 2 csantifort
        address_sel_nxt             = 4'd3;  // pc  (not pc + 4)
1175
        pc_wen_nxt                  = 1'd0;  // hold current PC value
1176 89 csantifort
 
1177
        // LDM: load into user mode registers, when in priviledged mode
1178 82 csantifort
        if ( {instruction[22],instruction[20],mtrans_r15} == 3'b110 )
1179 2 csantifort
            user_mode_regs_load_nxt = 1'd1;
1180 89 csantifort
 
1181
        // SDM: store the user mode registers, when in priviledged mode
1182
        if ( {instruction[22],instruction[20]} == 2'b10 )
1183 2 csantifort
            o_user_mode_regs_store_nxt = 1'd1;
1184
        end
1185 89 csantifort
 
1186 2 csantifort
    if ( control_state == MTRANS_EXEC4 )
1187
        begin
1188
        barrel_shift_data_sel_nxt   = 2'd1;  // load word from memory
1189 89 csantifort
 
1190 2 csantifort
        if ( instruction[20] ) // Load
1191
            begin
1192
            if (!dabt) // dont overwrite registers or status if theres a data abort
1193
                begin
1194
                if ( mtrans_reg_d2 == 4'd15 ) // load new value into PC
1195
                    begin
1196
                    address_sel_nxt = 4'd1; // alu_out - read instructions using new PC value
1197
                    pc_sel_nxt      = 2'd1; // alu_out
1198
                    pc_wen_nxt      = 1'd1; // write PC
1199 89 csantifort
 
1200 2 csantifort
                    // ldm with S bit and pc: the Status bits are updated
1201
                    // Node this must be done only at the end
1202
                    // so the register set is the set in the mode before it
1203 89 csantifort
                    // gets changed.
1204
                    if ( instruction[22] )
1205 2 csantifort
                         begin
1206
                         status_bits_sel_nxt           = 3'd1; // alu out
1207
                         status_bits_flags_wen_nxt     = 1'd1;
1208 89 csantifort
 
1209 2 csantifort
                         // Can't change the mode or mask bits in User mode
1210 89 csantifort
                         if ( i_execute_status_bits[1:0] != USR )
1211 2 csantifort
                            begin
1212
                            status_bits_mode_wen_nxt      = 1'd1;
1213
                            status_bits_irq_mask_wen_nxt  = 1'd1;
1214
                            status_bits_firq_mask_wen_nxt = 1'd1;
1215
                            end
1216
                         end
1217
                    end
1218
                else
1219
                    begin
1220 71 csantifort
                    reg_bank_wsel_nxt = mtrans_reg_d2;
1221 2 csantifort
                    end
1222
                end
1223
            end
1224 89 csantifort
 
1225 2 csantifort
           // we have a data abort interrupt
1226
        if ( dabt )
1227 89 csantifort
            begin
1228 2 csantifort
            pc_wen_nxt = 1'd0;  // hold current PC value
1229
            end
1230 89 csantifort
 
1231
        // LDM: load into user mode registers, when in priviledged mode
1232 82 csantifort
        if ( {instruction[22],instruction[20],mtrans_r15} == 3'b110 )
1233 2 csantifort
            user_mode_regs_load_nxt = 1'd1;
1234 89 csantifort
 
1235
        // SDM: store the user mode registers, when in priviledged mode
1236
        if ( {instruction[22],instruction[20]} == 2'b10 )
1237 2 csantifort
            o_user_mode_regs_store_nxt = 1'd1;
1238
        end
1239 89 csantifort
 
1240
 
1241 2 csantifort
    // state is for when a data abort interrupt is triggered during an LDM
1242
    if ( control_state == MTRANS5_ABORT )
1243
        begin
1244
        // Restore the Base Address, if the base register is included in the
1245
        // list of registers being loaded
1246
        if (restore_base_address) // LDM with base address in register list
1247
            begin
1248
            reg_write_sel_nxt = 3'd6;                        // write base_register
1249 71 csantifort
            reg_bank_wsel_nxt  = instruction[19:16];         // to Rn
1250 2 csantifort
            end
1251
        end
1252 89 csantifort
 
1253
 
1254 2 csantifort
        // Multiply or Multiply-Accumulate
1255
    if ( control_state == MULT_PROC1 && instruction_execute )
1256
        begin
1257
        // Save the next instruction to execute later
1258
        // Do this even if this instruction does not execute because of Condition
1259
        pre_fetch_instruction_wen   = 1'd1;
1260
        pc_wen_nxt                  = 1'd0;  // hold current PC value
1261
        multiply_function_nxt       = o_multiply_function;
1262
        end
1263
 
1264 89 csantifort
 
1265 2 csantifort
        // Multiply or Multiply-Accumulate
1266
        // Do multiplication
1267
        // Wait for done or accumulate signal
1268
    if ( control_state == MULT_PROC2 )
1269
        begin
1270
        // Save the next instruction to execute later
1271
        // Do this even if this instruction does not execute because of Condition
1272
        pc_wen_nxt              = 1'd0;  // hold current PC value
1273
        address_sel_nxt         = 4'd3;  // pc  (not pc + 4)
1274
        multiply_function_nxt   = o_multiply_function;
1275
        end
1276
 
1277 89 csantifort
 
1278 2 csantifort
    // Save RdLo
1279
    // always last cycle of all multiply or multiply accumulate operations
1280
    if ( control_state == MULT_STORE )
1281
        begin
1282
        reg_write_sel_nxt     = 3'd2; // multiply_out
1283
        multiply_function_nxt = o_multiply_function;
1284 89 csantifort
 
1285 87 csantifort
        if ( itype == MULT ) // 32-bit
1286 71 csantifort
            reg_bank_wsel_nxt      = instruction[19:16]; // Rd
1287 2 csantifort
        else  // 64-bit / Long
1288 71 csantifort
            reg_bank_wsel_nxt      = instruction[15:12]; // RdLo
1289 89 csantifort
 
1290 2 csantifort
        if ( instruction[20] )  // the 'S' bit
1291
            begin
1292 89 csantifort
            status_bits_sel_nxt       = 3'd4; // { multiply_flags, status_bits_flags[1:0] }
1293 2 csantifort
            status_bits_flags_wen_nxt = 1'd1;
1294
            end
1295
        end
1296 89 csantifort
 
1297 2 csantifort
        // Add lower 32 bits to multiplication product
1298
    if ( control_state == MULT_ACCUMU )
1299
        begin
1300
        multiply_function_nxt = o_multiply_function;
1301
        pc_wen_nxt            = 1'd0;  // hold current PC value
1302
        address_sel_nxt       = 4'd3;  // pc  (not pc + 4)
1303
        end
1304 89 csantifort
 
1305 2 csantifort
    // swp - do write request in 2nd cycle
1306
    if ( control_state == SWAP_WRITE && instruction_execute )
1307
        begin
1308
        barrel_shift_data_sel_nxt       = 2'd2; // Shift value from Rm register
1309
        address_sel_nxt                 = 4'd4; // Rn
1310
        write_data_wen_nxt              = 1'd1;
1311 89 csantifort
        data_access_exec_nxt            = 1'd1; // indicate that its a data read or write,
1312 2 csantifort
                                                // rather than an instruction fetch
1313 89 csantifort
 
1314 2 csantifort
        if ( instruction[22] )
1315
            byte_enable_sel_nxt = 2'd1;         // Save byte
1316 89 csantifort
 
1317 2 csantifort
        if ( instruction_execute )                         // conditional execution state
1318
            pc_wen_nxt                  = 1'd0; // hold current PC value
1319 89 csantifort
 
1320 2 csantifort
        // Save the next instruction to execute later
1321
        // Do this even if this instruction does not execute because of Condition
1322
        pre_fetch_instruction_wen   = 1'd1;
1323 89 csantifort
 
1324 2 csantifort
        end
1325
 
1326 89 csantifort
 
1327 2 csantifort
    // swp - receive read response in 3rd cycle
1328 89 csantifort
    if ( control_state == SWAP_WAIT1 )
1329 2 csantifort
        begin
1330
        barrel_shift_data_sel_nxt   = 2'd1;  // load word from memory
1331
        barrel_shift_amount_sel_nxt = 2'd3;  // shift by address[1:0] x 8
1332 89 csantifort
 
1333 2 csantifort
        // shift needed
1334
        if ( i_execute_address[1:0] != 2'd0 )
1335
            barrel_shift_function_nxt = ROR;
1336 89 csantifort
 
1337 2 csantifort
        if ( instruction_execute ) // conditional execution state
1338
            begin
1339
            address_sel_nxt             = 4'd3; // pc  (not pc + 4)
1340
            pc_wen_nxt                  = 1'd0; // hold current PC value
1341
            end
1342 89 csantifort
 
1343
        // load a byte
1344 2 csantifort
        if ( instruction[22] )
1345
            alu_out_sel_nxt = 4'd3;  // zero_extend8
1346 89 csantifort
 
1347 2 csantifort
        if ( !dabt )
1348 89 csantifort
            begin
1349 2 csantifort
            // Check is the load destination is the PC
1350
            if ( instruction[15:12]  == 4'd15 )
1351
                begin
1352
                pc_sel_nxt      = 2'd1; // alu_out
1353
                address_sel_nxt = 4'd1; // alu_out
1354
                end
1355 89 csantifort
            else
1356 71 csantifort
                reg_bank_wsel_nxt = instruction[15:12];
1357 2 csantifort
            end
1358
        end
1359 89 csantifort
 
1360 2 csantifort
    // 1 cycle delay for Co-Processor Register access
1361
    if ( control_state == COPRO_WAIT && instruction_execute )
1362
        begin
1363
        pre_fetch_instruction_wen = 1'd1;
1364 89 csantifort
 
1365 2 csantifort
        if ( instruction[20] ) // mrc instruction
1366
            begin
1367
            // Check is the load destination is the PC
1368
            if ( instruction[15:12]  == 4'd15 )
1369
                begin
1370 89 csantifort
                // If r15 is specified for <Rd>, the condition code flags are
1371 2 csantifort
                // updated instead of a general-purpose register.
1372
                status_bits_sel_nxt           = 3'd3;  // i_copro_data
1373
                status_bits_flags_wen_nxt     = 1'd1;
1374 89 csantifort
 
1375 2 csantifort
                // Can't change these in USR mode
1376
                if ( i_execute_status_bits[1:0] != USR )
1377
                   begin
1378
                   status_bits_mode_wen_nxt      = 1'd1;
1379
                   status_bits_irq_mask_wen_nxt  = 1'd1;
1380
                   status_bits_firq_mask_wen_nxt = 1'd1;
1381
                   end
1382
                end
1383 89 csantifort
            else
1384 71 csantifort
                reg_bank_wsel_nxt = instruction[15:12];
1385 89 csantifort
 
1386 2 csantifort
            reg_write_sel_nxt = 3'd5;     // i_copro_data
1387
            end
1388
        else // mcr instruction
1389
            begin
1390 89 csantifort
            copro_operation_nxt      = 2'd2;  // Register transfer to Co-Processor
1391
            end
1392 2 csantifort
        end
1393
 
1394 89 csantifort
 
1395 2 csantifort
    // Have just changed the status_bits mode but this
1396
    // creates a 1 cycle gap with the old mode
1397
    // coming back from execute into instruction_decode
1398
    // So squash that old mode value during this
1399 89 csantifort
    // cycle of the interrupt transition
1400
    if ( control_state == INT_WAIT1 )
1401
        status_bits_mode_nxt            = status_bits_mode_r;   // Supervisor mode
1402 2 csantifort
 
1403
    end
1404
 
1405
 
1406
// Speed up the long path from u_decode/o_read_data to u_register_bank/r8_firq
1407
// This pre-encodes the firq_s3 signal thats used in u_register_bank
1408
assign firq_not_user_mode_nxt = !user_mode_regs_load_nxt && status_bits_mode_nxt == FIRQ;
1409
 
1410
 
1411
// ========================================================
1412
// Next State Logic
1413
// ========================================================
1414
 
1415
// this replicates the current value of the execute signal in the execute stage
1416 89 csantifort
assign instruction_execute = conditional_execute ( condition_r, i_execute_status_bits[31:28] );
1417 2 csantifort
 
1418
assign instruction_valid = (control_state == EXECUTE || control_state == PRE_FETCH_EXEC) ||
1419
                     // when last instruction was multi-cycle instruction but did not execute
1420
                     // because condition was false then act like you're in the execute state
1421 89 csantifort
                    (!instruction_execute && (control_state == PC_STALL1    ||
1422 2 csantifort
                                              control_state == MEM_WAIT1    ||
1423
                                              control_state == COPRO_WAIT   ||
1424
                                              control_state == SWAP_WRITE   ||
1425
                                              control_state == MULT_PROC1   ||
1426
                                              control_state == MTRANS_EXEC1 ||
1427
                                              control_state == MTRANS_EXEC3 ||
1428
                                              control_state == MTRANS_EXEC3B  ) );
1429
 
1430
 
1431
 always @*
1432
    begin
1433
    // default is to hold the current state
1434
    control_state_nxt = control_state;
1435 89 csantifort
 
1436 2 csantifort
    // Note: The order is important here
1437
    if ( control_state == RST_WAIT1 )     control_state_nxt = RST_WAIT2;
1438
    if ( control_state == RST_WAIT2 )     control_state_nxt = EXECUTE;
1439
    if ( control_state == INT_WAIT1 )     control_state_nxt = INT_WAIT2;
1440
    if ( control_state == INT_WAIT2 )     control_state_nxt = EXECUTE;
1441
    if ( control_state == COPRO_WAIT )    control_state_nxt = PRE_FETCH_EXEC;
1442
    if ( control_state == PC_STALL1 )     control_state_nxt = PC_STALL2;
1443 89 csantifort
    if ( control_state == PC_STALL2 )     control_state_nxt = EXECUTE;
1444
    if ( control_state == SWAP_WRITE )    control_state_nxt = SWAP_WAIT1;
1445
    if ( control_state == SWAP_WAIT1 )    control_state_nxt = SWAP_WAIT2;
1446
    if ( control_state == MULT_STORE )    control_state_nxt = PRE_FETCH_EXEC;
1447 2 csantifort
    if ( control_state == MTRANS5_ABORT ) control_state_nxt = PRE_FETCH_EXEC;
1448
 
1449
    if ( control_state == MEM_WAIT1 )
1450
        control_state_nxt = MEM_WAIT2;
1451
 
1452 89 csantifort
    if ( control_state == MEM_WAIT2   ||
1453 2 csantifort
        control_state == SWAP_WAIT2    )
1454
        begin
1455 89 csantifort
        if ( write_pc ) // writing to the PC!!
1456 2 csantifort
            control_state_nxt = PC_STALL1;
1457
        else
1458
            control_state_nxt = PRE_FETCH_EXEC;
1459
        end
1460 89 csantifort
 
1461
    if ( control_state == MTRANS_EXEC1 )
1462
        begin
1463 2 csantifort
        if (mtrans_instruction_nxt[15:0] != 16'd0)
1464
            control_state_nxt = MTRANS_EXEC2;
1465 89 csantifort
        else   // if the register list holds a single register
1466 2 csantifort
            control_state_nxt = MTRANS_EXEC3;
1467
        end
1468 89 csantifort
 
1469 2 csantifort
        // Stay in State MTRANS_EXEC2 until the full list of registers to
1470
        // load or store has been processed
1471
    if ( control_state == MTRANS_EXEC2 && mtrans_num_registers == 5'd1 )
1472
        control_state_nxt = MTRANS_EXEC3;
1473 89 csantifort
 
1474
    if ( control_state == MTRANS_EXEC3 )     control_state_nxt = MTRANS_EXEC4;
1475
 
1476 2 csantifort
    if ( control_state == MTRANS_EXEC3B )    control_state_nxt = MTRANS_EXEC4;
1477
 
1478
    if ( control_state == MTRANS_EXEC4  )
1479
        begin
1480
        if ( dabt ) // data abort
1481
            control_state_nxt = MTRANS5_ABORT;
1482 89 csantifort
        else if (write_pc) // writing to the PC!!
1483 2 csantifort
            control_state_nxt = PC_STALL1;
1484
        else
1485
            control_state_nxt = PRE_FETCH_EXEC;
1486
        end
1487 89 csantifort
 
1488 2 csantifort
    if ( control_state == MULT_PROC1 )
1489
        begin
1490
        if (!instruction_execute)
1491
            control_state_nxt = PRE_FETCH_EXEC;
1492
        else
1493
            control_state_nxt = MULT_PROC2;
1494
        end
1495 89 csantifort
 
1496 2 csantifort
    if ( control_state == MULT_PROC2 )
1497
        begin
1498
        if ( i_multiply_done )
1499
            if      ( o_multiply_function[1] )  // Accumulate ?
1500
                control_state_nxt = MULT_ACCUMU;
1501 89 csantifort
            else
1502 2 csantifort
                control_state_nxt = MULT_STORE;
1503
        end
1504 89 csantifort
 
1505
 
1506 2 csantifort
    if ( control_state == MULT_ACCUMU )
1507
        begin
1508
        control_state_nxt = MULT_STORE;
1509
        end
1510 89 csantifort
 
1511
 
1512 2 csantifort
    // This should come at the end, so that conditional execution works
1513
    // correctly
1514
    if ( instruction_valid )
1515
        begin
1516
        // default is to stay in execute state, or to move into this
1517
        // state from a conditional execute state
1518
        control_state_nxt = EXECUTE;
1519 89 csantifort
 
1520 2 csantifort
        if ( mem_op )  // load or store word or byte
1521
             control_state_nxt = MEM_WAIT1;
1522 89 csantifort
        if ( write_pc )
1523 2 csantifort
             control_state_nxt = PC_STALL1;
1524 87 csantifort
        if ( itype == MTRANS )
1525 2 csantifort
            begin
1526
            if ( mtrans_num_registers != 5'd0 )
1527
                begin
1528
                // check for LDM/STM of a single register
1529
                if ( mtrans_num_registers == 5'd1 )
1530
                    control_state_nxt = MTRANS_EXEC3B;
1531
                else
1532
                    control_state_nxt = MTRANS_EXEC1;
1533
                end
1534 89 csantifort
            else
1535 2 csantifort
                control_state_nxt = MTRANS_EXEC3;
1536
            end
1537
 
1538 87 csantifort
        if ( itype == MULT )
1539 2 csantifort
                control_state_nxt = MULT_PROC1;
1540
 
1541 89 csantifort
        if ( itype == SWAP )
1542 2 csantifort
                control_state_nxt = SWAP_WRITE;
1543
 
1544 89 csantifort
        if ( itype == CORTRANS && !und_request )
1545 2 csantifort
                control_state_nxt = COPRO_WAIT;
1546 89 csantifort
 
1547
         // interrupt overrides everything else so its last
1548
        if ( interrupt )
1549 2 csantifort
                control_state_nxt = INT_WAIT1;
1550
        end
1551
    end
1552
 
1553
 
1554
// ========================================================
1555
// Register Update
1556
// ========================================================
1557
always @ ( posedge i_clk )
1558 89 csantifort
    if (!i_fetch_stall)
1559
        begin
1560 2 csantifort
        o_read_data                 <= i_read_data;
1561 89 csantifort
        o_read_data_alignment       <= {i_execute_address[1:0], 3'd0};
1562 2 csantifort
        abt_address_reg             <= i_execute_address;
1563
        iabt_reg                    <= i_iabt;
1564
        adex_reg                    <= i_adex;
1565
        abt_status_reg              <= i_abt_status;
1566 89 csantifort
        status_bits_mode_r          <= status_bits_mode_nxt;
1567
        status_bits_irq_mask_r      <= status_bits_irq_mask_nxt;
1568
        status_bits_firq_mask_r     <= status_bits_firq_mask_nxt;
1569 2 csantifort
        o_imm32                     <= imm32_nxt;
1570
        o_imm_shift_amount          <= imm_shift_amount_nxt;
1571
        o_shift_imm_zero            <= shift_imm_zero_nxt;
1572 89 csantifort
 
1573 2 csantifort
                                        // when have an interrupt, execute the interrupt operation
1574
                                        // unconditionally in the execute stage
1575
                                        // ensures that status_bits register gets updated correctly
1576
                                        // Likewise when in middle of multi-cycle instructions
1577
                                        // execute them unconditionally
1578 89 csantifort
        condition_r                 <= instruction_valid && !interrupt ? condition_nxt : AL;
1579 2 csantifort
        o_exclusive_exec            <= exclusive_exec_nxt;
1580
        o_data_access_exec          <= data_access_exec_nxt;
1581 89 csantifort
 
1582 71 csantifort
        o_rm_sel                    <= o_rm_sel_nxt;
1583
        o_rds_sel                   <= o_rds_sel_nxt;
1584
        o_rn_sel                    <= o_rn_sel_nxt;
1585 2 csantifort
        o_barrel_shift_amount_sel   <= barrel_shift_amount_sel_nxt;
1586
        o_barrel_shift_data_sel     <= barrel_shift_data_sel_nxt;
1587
        o_barrel_shift_function     <= barrel_shift_function_nxt;
1588
        o_alu_function              <= alu_function_nxt;
1589 83 csantifort
        o_use_carry_in              <= use_carry_in_nxt;
1590 2 csantifort
        o_multiply_function         <= multiply_function_nxt;
1591
        o_interrupt_vector_sel      <= next_interrupt;
1592 89 csantifort
        address_sel_r               <= address_sel_nxt;
1593
        pc_sel_r                    <= pc_sel_nxt;
1594 2 csantifort
        o_byte_enable_sel           <= byte_enable_sel_nxt;
1595
        o_status_bits_sel           <= status_bits_sel_nxt;
1596
        o_reg_write_sel             <= reg_write_sel_nxt;
1597
        o_user_mode_regs_load       <= user_mode_regs_load_nxt;
1598
        o_firq_not_user_mode        <= firq_not_user_mode_nxt;
1599
        o_write_data_wen            <= write_data_wen_nxt;
1600
        o_base_address_wen          <= base_address_wen_nxt;
1601 89 csantifort
        pc_wen_r                    <= pc_wen_nxt;
1602 71 csantifort
        o_reg_bank_wsel             <= reg_bank_wsel_nxt;
1603
        o_reg_bank_wen              <= decode ( reg_bank_wsel_nxt );
1604 2 csantifort
        o_status_bits_flags_wen     <= status_bits_flags_wen_nxt;
1605
        o_status_bits_mode_wen      <= status_bits_mode_wen_nxt;
1606
        o_status_bits_irq_mask_wen  <= status_bits_irq_mask_wen_nxt;
1607
        o_status_bits_firq_mask_wen <= status_bits_firq_mask_wen_nxt;
1608 89 csantifort
 
1609 2 csantifort
        o_copro_opcode1             <= instruction[23:21];
1610
        o_copro_opcode2             <= instruction[7:5];
1611
        o_copro_crn                 <= instruction[19:16];
1612
        o_copro_crm                 <= instruction[3:0];
1613
        o_copro_num                 <= instruction[11:8];
1614
        o_copro_operation           <= copro_operation_nxt;
1615
        o_copro_write_data_wen      <= copro_write_data_wen_nxt;
1616
        mtrans_r15                  <= mtrans_r15_nxt;
1617
        restore_base_address        <= restore_base_address_nxt;
1618
        control_state               <= control_state_nxt;
1619
        mtrans_reg_d1               <= mtrans_reg;
1620
        mtrans_reg_d2               <= mtrans_reg_d1;
1621
        end
1622
 
1623
 
1624
 
1625
always @ ( posedge i_clk )
1626
    if ( !i_fetch_stall )
1627
        begin
1628
        // sometimes this is a pre-fetch instruction
1629
        // e.g. two ldr instructions in a row. The second ldr will be saved
1630
        // to the pre-fetch instruction register
1631
        // then when its decoded, a copy is saved to the saved_current_instruction
1632
        // register
1633 87 csantifort
        if      (itype == MTRANS)
1634 89 csantifort
            begin
1635 2 csantifort
            saved_current_instruction              <= mtrans_instruction_nxt;
1636
            saved_current_instruction_iabt         <= instruction_iabt;
1637
            saved_current_instruction_adex         <= instruction_adex;
1638
            saved_current_instruction_address      <= instruction_address;
1639
            saved_current_instruction_iabt_status  <= instruction_iabt_status;
1640
            end
1641 89 csantifort
        else if (saved_current_instruction_wen)
1642
            begin
1643 2 csantifort
            saved_current_instruction              <= instruction;
1644
            saved_current_instruction_iabt         <= instruction_iabt;
1645
            saved_current_instruction_adex         <= instruction_adex;
1646
            saved_current_instruction_address      <= instruction_address;
1647
            saved_current_instruction_iabt_status  <= instruction_iabt_status;
1648
            end
1649
 
1650 89 csantifort
        if      (pre_fetch_instruction_wen)
1651 2 csantifort
            begin
1652 89 csantifort
            pre_fetch_instruction                  <= o_read_data;
1653
            pre_fetch_instruction_iabt             <= iabt_reg;
1654
            pre_fetch_instruction_adex             <= adex_reg;
1655
            pre_fetch_instruction_address          <= abt_address_reg;
1656
            pre_fetch_instruction_iabt_status      <= abt_status_reg;
1657
            end
1658 2 csantifort
        end
1659
 
1660
 
1661 89 csantifort
 
1662 2 csantifort
always @ ( posedge i_clk )
1663
    if ( !i_fetch_stall )
1664
        begin
1665 89 csantifort
        irq   <= i_irq;
1666
        firq  <= i_firq;
1667
 
1668
        if ( control_state == INT_WAIT1 && status_bits_mode_r == SVC )
1669 2 csantifort
            begin
1670
            dabt_reg  <= 1'd0;
1671
            end
1672
        else
1673
            begin
1674 89 csantifort
            dabt_reg  <= dabt_reg || i_dabt;
1675 2 csantifort
            end
1676
 
1677 89 csantifort
        dabt_reg_d1  <= dabt_reg;
1678
        end
1679
 
1680 2 csantifort
assign dabt = dabt_reg || i_dabt;
1681
 
1682
 
1683
// ========================================================
1684
// Decompiler for debugging core - not synthesizable
1685
// ========================================================
1686
//synopsys translate_off
1687
 
1688 82 csantifort
`include "debug_functions.vh"
1689 2 csantifort
 
1690 15 csantifort
a23_decompile  u_decompile (
1691 2 csantifort
    .i_clk                      ( i_clk                            ),
1692
    .i_fetch_stall              ( i_fetch_stall                    ),
1693
    .i_instruction              ( instruction                      ),
1694
    .i_instruction_valid        ( instruction_valid                ),
1695
    .i_instruction_execute      ( instruction_execute              ),
1696
    .i_instruction_address      ( instruction_address              ),
1697
    .i_interrupt                ( {3{interrupt}} & next_interrupt  ),
1698
    .i_interrupt_state          ( control_state == INT_WAIT2       ),
1699
    .i_instruction_undefined    ( und_request                      ),
1700 89 csantifort
    .i_pc_sel                   ( pc_sel_r                         ),
1701
    .i_pc_wen                   ( pc_wen_r                         ));
1702 2 csantifort
 
1703
 
1704 89 csantifort
 
1705 2 csantifort
wire    [(15*8)-1:0]    xCONTROL_STATE;
1706
wire    [(15*8)-1:0]    xMODE;
1707
 
1708 89 csantifort
assign xCONTROL_STATE        =
1709 2 csantifort
                               control_state == RST_WAIT1      ? "RST_WAIT1"      :
1710
                               control_state == RST_WAIT2      ? "RST_WAIT2"      :
1711
 
1712
 
1713
                               control_state == INT_WAIT1      ? "INT_WAIT1"      :
1714
                               control_state == INT_WAIT2      ? "INT_WAIT2"      :
1715
                               control_state == EXECUTE        ? "EXECUTE"        :
1716
                               control_state == PRE_FETCH_EXEC ? "PRE_FETCH_EXEC" :
1717
                               control_state == MEM_WAIT1      ? "MEM_WAIT1"      :
1718
                               control_state == MEM_WAIT2      ? "MEM_WAIT2"      :
1719
                               control_state == PC_STALL1      ? "PC_STALL1"      :
1720
                               control_state == PC_STALL2      ? "PC_STALL2"      :
1721
                               control_state == MTRANS_EXEC1   ? "MTRANS_EXEC1"   :
1722
                               control_state == MTRANS_EXEC2   ? "MTRANS_EXEC2"   :
1723
                               control_state == MTRANS_EXEC3   ? "MTRANS_EXEC3"   :
1724
                               control_state == MTRANS_EXEC3B  ? "MTRANS_EXEC3B"  :
1725
                               control_state == MTRANS_EXEC4   ? "MTRANS_EXEC4"   :
1726
                               control_state == MTRANS5_ABORT  ? "MTRANS5_ABORT"  :
1727
                               control_state == MULT_PROC1     ? "MULT_PROC1"     :
1728
                               control_state == MULT_PROC2     ? "MULT_PROC2"     :
1729
                               control_state == MULT_STORE     ? "MULT_STORE"     :
1730
                               control_state == MULT_ACCUMU    ? "MULT_ACCUMU"    :
1731
                               control_state == SWAP_WRITE     ? "SWAP_WRITE"     :
1732
                               control_state == SWAP_WAIT1     ? "SWAP_WAIT1"     :
1733
                               control_state == SWAP_WAIT2     ? "SWAP_WAIT2"     :
1734
                               control_state == COPRO_WAIT     ? "COPRO_WAIT"     :
1735
                                                                 "UNKNOWN "       ;
1736
 
1737 89 csantifort
assign xMODE  = mode_name ( status_bits_mode_r );
1738 2 csantifort
 
1739
always @( posedge i_clk )
1740
    if (control_state == EXECUTE && ((instruction[0] === 1'bx) || (instruction[31] === 1'bx)))
1741
        begin
1742
        `TB_ERROR_MESSAGE
1743
        $display("Instruction with x's =%08h", instruction);
1744
        end
1745
//synopsys translate_on
1746
 
1747
endmodule
1748
 
1749
 

powered by: WebSVN 2.1.0

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