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

Subversion Repositories amber

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

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

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

powered by: WebSVN 2.1.0

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