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

Subversion Repositories amber

[/] [amber/] [trunk/] [hw/] [vlog/] [amber25/] [a25_decode.v] - Blame information for rev 16

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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