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

Subversion Repositories amber

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

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

powered by: WebSVN 2.1.0

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