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

Subversion Repositories zap

[/] [zap/] [trunk/] [src/] [rtl/] [cpu/] [zap_decode.v] - Blame information for rev 51

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 26 Revanth
// -----------------------------------------------------------------------------
2
// --                                                                         --
3
// --                   (C) 2016-2018 Revanth Kamaraj.                        --
4
// --                                                                         -- 
5
// -- --------------------------------------------------------------------------
6
// --                                                                         --
7
// -- This program is free software; you can redistribute it and/or           --
8
// -- modify it under the terms of the GNU General Public License             --
9
// -- as published by the Free Software Foundation; either version 2          --
10
// -- of the License, or (at your option) any later version.                  --
11
// --                                                                         --
12
// -- This program is distributed in the hope that it will be useful,         --
13
// -- but WITHOUT ANY WARRANTY; without even the implied warranty of          --
14
// -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           --
15
// -- GNU General Public License for more details.                            --
16
// --                                                                         --
17
// -- You should have received a copy of the GNU General Public License       --
18
// -- along with this program; if not, write to the Free Software             --
19
// -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA           --
20
// -- 02110-1301, USA.                                                        --
21
// --                                                                         --
22
// -----------------------------------------------------------------------------
23
// --                                                                         --
24
// -- This module performs core ARM instruction decoding by translating ARM   --
25
// -- instructions into an internal long format that can be processed by core --
26
// -- logic. Note that the predecode stage must change the 32-bit instr. to   --
27
// -- 36-bit before feeding it into this unit.                                --
28
// --                                                                         --
29
// -----------------------------------------------------------------------------
30
 
31
 
32
`default_nettype none
33
 
34
module zap_decode (
35
 
36
i_irq,  // IRQ request from previous stage.
37
i_fiq,  // FIQ request from previous stage.
38
i_abt,  // Code abort flagged from previous stage.
39
 
40
// Instruction input from pre-decode.
41
i_instruction,
42
i_instruction_valid,
43
 
44
//
45
// CPU mode from active CPSR. Required to prevent CPSR change on MSR 
46
// instruction in USR mode.
47
//
48
i_cpsr_ff_mode,
49
 
50
//
51
// Bits related to decoded instruction...
52
// 
53
 
54
o_condition_code,       // 4-bit CC.
55
o_destination_index,    // Destination register.
56
o_alu_source,           // ALU source register.
57
o_alu_operation,        // ALU operation to be performed.
58
o_shift_source,         // Register to be treated as input to shifter.
59
o_shift_operation,      // Shift operation to perform.
60
o_shift_length,         // Length of the shift operation.
61
o_flag_update,          // 1 means flags must be updated.
62
 
63
// Memory related.
64
o_mem_srcdest_index,            // Data register.
65
o_mem_load,                     // Load operation.
66
o_mem_store,                    // Store operation.
67
o_mem_pre_index,                // Pre-Index.
68
o_mem_unsigned_byte_enable,     // Access treated as uint8_t.
69
o_mem_signed_byte_enable,       // Access treated as int8_t.
70
o_mem_signed_halfword_enable,   // Access treated as int16_t.
71
o_mem_unsigned_halfword_enable, // Access treated as uint16_t.
72
o_mem_translate,                // Force user view of memory.
73
 
74
o_und,   // Declare as undecodable. 
75
o_switch // Switch between ARM and Thumb may be needed if this is 1.
76
 
77
);
78
 
79
// ----------------------------------------------------------------------------
80
 
81
        // Number of architectural registers.
82
        parameter ARCH_REGS = 32;
83
 
84
        // Number of opcodes.
85
        parameter ALU_OPS   = 32;
86
 
87
        // Number of shift operations.
88
        parameter SHIFT_OPS = 6;
89
 
90
 
91
                // I/O Ports.
92
                input   wire                            i_irq, i_fiq, i_abt;
93
                input    wire   [35:0]                  i_instruction;
94
                input    wire                           i_instruction_valid;
95
                input   wire    [4:0]                   i_cpsr_ff_mode;
96
                output   reg    [3:0]                   o_condition_code;
97
                output   reg    [$clog2(ARCH_REGS)-1:0] o_destination_index;
98
                output   reg    [32:0]                  o_alu_source;
99
                output   reg    [$clog2(ALU_OPS)-1:0]   o_alu_operation;
100
                output   reg    [32:0]                  o_shift_source;
101
                output   reg    [$clog2(SHIFT_OPS)-1:0] o_shift_operation;
102
                output   reg    [32:0]                  o_shift_length;
103
                output  reg                             o_flag_update;
104
                output  reg   [$clog2(ARCH_REGS)-1:0]   o_mem_srcdest_index;
105
                output  reg                             o_mem_load;
106
                output  reg                             o_mem_store;
107
                output  reg                             o_mem_pre_index;
108
                output  reg                             o_mem_unsigned_byte_enable;
109
                output  reg                             o_mem_signed_byte_enable;
110
                output  reg                             o_mem_signed_halfword_enable;
111
                output  reg                             o_mem_unsigned_halfword_enable;
112
                output  reg                             o_mem_translate;
113
                output  reg                             o_und;
114
                output  reg                             o_switch;
115
 
116
// ----------------------------------------------------------------------------
117
 
118
`include "zap_defines.vh"
119
`include "zap_localparams.vh"
120
`include "zap_functions.vh"
121
 
122
// Related to memory operations.
123
localparam [1:0] SIGNED_BYTE            = 2'd0;
124
localparam [1:0] UNSIGNED_HALF_WORD     = 2'd1;
125
localparam [1:0] SIGNED_HALF_WORD       = 2'd2;
126
 
127
// ----------------------------------------------------------------------------
128
 
129
always @*
130
begin: mainBlk1
131
        // If an unrecognized instruction enters this, the output
132
        // signals an NV state i.e., invalid.
133
        o_condition_code                = NV;
134
        o_destination_index             = 0;
135
        o_alu_source                    = 0;
136
        o_alu_operation                 = 0;
137
        o_shift_source                  = 0;
138
        o_shift_operation               = 0;
139
        o_shift_length                  = 0;
140
        o_flag_update                   = 0;
141
        o_mem_srcdest_index             = RAZ_REGISTER;
142
        o_mem_load                      = 0;
143
        o_mem_store                     = 0;
144
        o_mem_translate                 = 0;
145
        o_mem_pre_index                 = 0;
146
        o_mem_unsigned_byte_enable      = 0;
147
        o_mem_signed_byte_enable        = 0;
148
        o_mem_signed_halfword_enable    = 0;
149
        o_mem_unsigned_halfword_enable  = 0;
150
        o_mem_translate                 = 0;
151
        o_und                           = 0;
152
        o_switch                        = 0;
153
 
154
 
155
                // Based on our pattern match, call the appropriate task
156
                if ( i_fiq || i_irq || i_abt )
157
                begin
158
                        // Generate LR = PC - 4.
159
                        o_condition_code    = AL;
160
                        o_alu_operation     = SUB;
161
                        o_alu_source        = ARCH_PC;
162
                        o_alu_source[32]    = INDEX_EN;
163
                        o_destination_index = ARCH_LR;
164
                        o_shift_source      = 4;
165
                        o_shift_source[32]  = IMMED_EN;
166
                        o_shift_operation   = LSL;
167
                        o_shift_length      = 0;
168
                        o_shift_length[32]  = IMMED_EN;
169
                end
170
                else if ( i_instruction_valid )
171
                casez ( i_instruction[31:0] )
172 37 Revanth
                CLZ_INSTRUCTION:              decode_clz ( i_instruction );
173
                BX_INST:                      decode_bx  ( i_instruction );
174 26 Revanth
                MRS:                          decode_mrs ( i_instruction );
175
                MSR,MSR_IMMEDIATE:            decode_msr ( i_instruction );
176
 
177
                DATA_PROCESSING_IMMEDIATE,
178
                DATA_PROCESSING_REGISTER_SPECIFIED_SHIFT,
179
                DATA_PROCESSING_INSTRUCTION_SPECIFIED_SHIFT:
180
                                      decode_data_processing ( i_instruction );
181
 
182
                BRANCH_INSTRUCTION:    decode_branch ( i_instruction );
183
 
184
                LS_INSTRUCTION_SPECIFIED_SHIFT,
185
                LS_IMMEDIATE:    decode_ls ( i_instruction );
186
 
187
                MULT_INST:              decode_mult ( i_instruction );
188
                LMULT_INST:             decode_lmult( i_instruction );
189
                HALFWORD_LS:            decode_halfword_ls ( i_instruction );
190
                SOFTWARE_INTERRUPT:     decode_swi ( i_instruction );
191
 
192
                default:
193
                begin
194
                        decode_und ( i_instruction );
195
                end
196
                endcase
197
end
198
 
199
// ----------------------------------------------------------------------------
200
 
201
// =============================
202 37 Revanth
// Decode CLZ
203
// =============================
204
task decode_clz ( input [35:0] i_instruction );
205
begin: tskDecodeClz
206
        o_condition_code        =       i_instruction[31:28];
207
        o_flag_update           =       1'd0; // Instruction does not update any flags.
208
        o_alu_operation         =       CLZ;  // Added.
209
 
210
        // Rn = 0.
211
        o_alu_source            =       0;
212
        o_alu_source[32]        =       IMMED_EN;
213
 
214
        // Rm = register whose CLZ must be found.
215
        o_shift_source          =       {i_instruction[`DP_RB_EXTEND], i_instruction[`DP_RB]}; // Rm
216
        o_shift_source[32]      =       INDEX_EN;
217
        o_shift_operation       =       LSL;
218
        o_shift_length          =       0;
219
        o_shift_length[32]      =       IMMED_EN; // Shift length is 0 of course.
220
end
221
endtask
222
 
223
// =============================
224 26 Revanth
// Decode long multiplication.
225
// =============================
226
task decode_lmult ( input [35:0] i_instruction ); // Uses bit 35. rm.rs + {rh, rn}
227
begin: tskLDecodeMult
228
 
229
        o_condition_code        =       i_instruction[31:28];
230
        o_flag_update           =       i_instruction[20];
231
 
232
        // ARM rd.
233
        o_destination_index     =       {i_instruction[`DP_RD_EXTEND],
234
                                         i_instruction[19:16]};
235
        // For MUL, Rd and Rn are interchanged. 
236
        // For 64bit, this is normally high register.
237
 
238
        o_alu_source            =       i_instruction[11:8]; // ARM rs
239
        o_alu_source[32]        =       INDEX_EN;
240
 
241
        o_shift_source          =       {i_instruction[`DP_RB_EXTEND],
242
                                         i_instruction[`DP_RB]};
243
        o_shift_source[32]      =       INDEX_EN;            // ARM rm 
244
 
245
        // ARM rn
246
        o_shift_length          =       i_instruction[24] ?
247
                                        {i_instruction[`DP_RA_EXTEND],
248
                                         i_instruction[`DP_RD]} : 32'd0;
249
 
250
        o_shift_length[32]      =       i_instruction[24] ? INDEX_EN:IMMED_EN;
251
 
252
 
253
        // We need to generate output code.
254
        case ( i_instruction[22:21] )
255
        2'b00:
256
        begin
257
                // Unsigned MULT64
258
                o_alu_operation = UMLALH;
259
                o_mem_srcdest_index = RAZ_REGISTER; // rh.
260
        end
261
        2'b01:
262
        begin
263
                // Unsigned MAC64. Need mem_srcdest as source for RdHi.
264
                o_alu_operation = UMLALH;
265
                o_mem_srcdest_index = i_instruction[19:16];
266
        end
267
        2'b10:
268
        begin
269
                // Signed MULT64
270
                o_alu_operation = SMLALH;
271
                o_mem_srcdest_index = RAZ_REGISTER;
272
        end
273
        2'b11:
274
        begin
275
                // Signed MAC64. Need mem_srcdest as source of RdHi.
276
                o_alu_operation = SMLALH;
277
                o_mem_srcdest_index = i_instruction[19:16];
278
        end
279
        endcase
280
 
281
        if ( i_instruction[`OPCODE_EXTEND] == 1'd0 ) // Low request.
282
        begin
283
                        o_destination_index = i_instruction[15:12]; // Low register.
284
                        o_alu_operation[0]  = 1'd0;                 // Request low operation.
285
        end
286
end
287
endtask
288
 
289
// ----------------------------------------------------------------------------
290
 
291
// ===============================
292
// Decode undefined instructions.
293
// ===============================
294
task decode_und( input [34:0] i_instruction );
295
begin
296
        // Say instruction is undefined.
297
        o_und = 1;
298
 
299
        // Generate LR = PC - 4
300
        o_condition_code    = AL;
301
        o_alu_operation     = SUB;
302
        o_alu_source        = ARCH_PC;
303
        o_alu_source[32]    = INDEX_EN;
304
        o_destination_index = ARCH_LR;
305
        o_shift_source      = 4;
306
        o_shift_source[32]  = IMMED_EN;
307
        o_shift_operation   = LSL;
308
        o_shift_length      = 0;
309
        o_shift_length[32]  = IMMED_EN;
310
end
311
endtask
312
 
313
// ----------------------------------------------------------------------------
314
 
315
// ===========================================
316
// Decode software interrupt instructions.
317
// ===========================================
318
task decode_swi( input [34:0] i_instruction );
319
begin: tskDecodeSWI
320
 
321
        // Generate LR = PC - 4
322
        o_condition_code    = AL;
323
        o_alu_operation     = SUB;
324
        o_alu_source        = ARCH_PC;
325
        o_alu_source[32]    = INDEX_EN;
326
        o_destination_index = ARCH_LR;
327
        o_shift_source      = 4;
328
        o_shift_source[32]  = IMMED_EN;
329
        o_shift_operation   = LSL;
330
        o_shift_length      = 0;
331
        o_shift_length[32]  = IMMED_EN;
332
end
333
endtask
334
 
335
// ----------------------------------------------------------------------------
336
 
337
// ============================
338
// Decode halfword LOAD/STORE.
339
// ============================
340
task decode_halfword_ls( input [34:0] i_instruction );
341
begin: tskDecodeHalfWordLs
342
        reg [11:0] temp, temp1;
343
 
344
        temp = i_instruction;
345
        temp1 = i_instruction;
346
 
347
        o_condition_code = i_instruction[31:28];
348
 
349
        temp[7:4] = temp[11:8];
350
        temp[11:8] = 0;
351
        temp1[11:4] = 0;
352
 
353
        if ( i_instruction[22] ) // immediate
354
        begin
355
                process_immediate ( temp );
356
        end
357
        else
358
        begin
359
                process_instruction_specified_shift ( temp1 );
360
        end
361
 
362
        o_alu_operation     = i_instruction[23] ? ADD : SUB;
363
        o_alu_source        = { i_instruction[`BASE_EXTEND],
364
                                i_instruction[`BASE]}; // Pointer register.
365
        o_alu_source[32]    = INDEX_EN;
366
        o_mem_load          = i_instruction[20];
367
        o_mem_store         = !o_mem_load;
368
        o_mem_pre_index     = i_instruction[24];
369
 
370
        // If post-index is used or pre-index is used with writeback,
371
        // take is as a request to update the base register.
372
        o_destination_index = (i_instruction[21] || !o_mem_pre_index) ?
373
                                o_alu_source :
374
                                RAZ_REGISTER; // Pointer register already added.
375
 
376
        o_mem_srcdest_index = {i_instruction[`SRCDEST_EXTEND],
377
                               i_instruction[`SRCDEST]};
378
 
379
        // Transfer size.
380
 
381
        o_mem_unsigned_byte_enable      = 0;
382
        o_mem_unsigned_halfword_enable  = 0;
383
        o_mem_signed_halfword_enable    = 0;
384
 
385
        case ( i_instruction[6:5] )
386
        SIGNED_BYTE:            o_mem_signed_byte_enable = 1;
387
        UNSIGNED_HALF_WORD:     o_mem_unsigned_halfword_enable = 1;
388
        SIGNED_HALF_WORD:       o_mem_signed_halfword_enable = 1;
389
        default:
390
        begin
391
                o_mem_unsigned_byte_enable      = 0;
392
                o_mem_unsigned_halfword_enable  = 0;
393
                o_mem_signed_halfword_enable    = 0;
394
        end
395
        endcase
396
end
397
endtask
398
 
399
// ----------------------------------------------------------------------------
400
 
401
// ==============================
402
// Decode short multiplication.
403
// ==============================
404
task decode_mult( input [34:0] i_instruction );
405
begin: tskDecodeMult
406
 
407
 
408
        o_condition_code        =       i_instruction[31:28];
409
        o_flag_update           =       i_instruction[20];
410
        o_alu_operation         =       UMLALL;
411
        o_destination_index     =       {i_instruction[`DP_RD_EXTEND],
412
                                         i_instruction[19:16]};
413
 
414
        // For MUL, Rd and Rn are interchanged.
415
        o_alu_source            =       i_instruction[11:8]; // ARM rs
416
        o_alu_source[32]        =       INDEX_EN;
417
 
418
        o_shift_source          =       {i_instruction[`DP_RB_EXTEND],
419
                                         i_instruction[`DP_RB]};
420
        o_shift_source[32]      =       INDEX_EN;            // ARM rm 
421
 
422
        // ARM rn - Set for accumulate.
423
        o_shift_length          =       i_instruction[21] ?
424
                                        {i_instruction[`DP_RA_EXTEND],
425
                                         i_instruction[`DP_RD]} : 32'd0;
426
 
427
        o_shift_length[32]      =       i_instruction[21] ? INDEX_EN : IMMED_EN;
428
 
429
        // Set rh = 0.
430
        o_mem_srcdest_index = RAZ_REGISTER;
431
end
432
endtask
433
 
434
// ----------------------------------------------------------------------------
435
 
436
// =============================
437
// BX decode.
438
// =============================
439
// Converted into a MOV to PC. The task of setting the T-bit in the CPSR is
440
// the job of the writeback stage.
441
task decode_bx( input [34:0] i_instruction );
442
begin: tskDecodeBx
443 37 Revanth
        reg [34:0] temp;
444
 
445 26 Revanth
        temp = i_instruction[31:0];
446 37 Revanth
        temp[31:4] = 0; // Zero out stuff to avoid conflicts in the function.
447 26 Revanth
 
448 37 Revanth
        process_instruction_specified_shift(temp);
449 26 Revanth
 
450
        // The RAW ALU source does not matter.
451
        o_condition_code        = i_instruction[31:28];
452
        o_alu_operation         = MOV;
453
        o_destination_index     = ARCH_PC;
454
 
455
        // We will force an immediate in alu source to prevent unwanted locks.
456
        o_alu_source            = 0;
457
        o_alu_source[32]        = IMMED_EN;
458
 
459
        // Indicate switch. This is a primary differentiator. 
460
        o_switch = 1;
461
end
462
endtask
463
 
464
// ----------------------------------------------------------------------------
465
 
466
// =============================================
467
// Task for decoding load-store instructions.
468
// =============================================
469
task decode_ls( input [34:0] i_instruction );
470
begin: tskDecodeLs
471
 
472
 
473
        o_condition_code = i_instruction[31:28];
474
 
475
        if ( !i_instruction[25] ) // immediate
476
        begin
477
                o_shift_source          = i_instruction[11:0];
478
                o_shift_source[32]      = IMMED_EN;
479
                o_shift_length          = 0;
480
                o_shift_length[32]      = IMMED_EN;
481
                o_shift_operation       = LSL;
482
        end
483
        else
484
        begin
485
              process_instruction_specified_shift ( i_instruction[11:0] );
486
        end
487
 
488
        o_alu_operation = i_instruction[23] ? ADD : SUB;
489
 
490
        // Pointer register.
491
        o_alu_source    = {i_instruction[`BASE_EXTEND], i_instruction[`BASE]};
492
        o_alu_source[32] = INDEX_EN;
493
        o_mem_load          = i_instruction[20];
494
        o_mem_store         = !o_mem_load;
495
        o_mem_pre_index     = i_instruction[24];
496
 
497
        // If post-index is used or pre-index is used with writeback,
498
        // take is as a request to update the base register.
499
        o_destination_index = (i_instruction[21] || !o_mem_pre_index) ?
500
                                o_alu_source :
501
                                RAZ_REGISTER; // Pointer register already added.
502
        o_mem_unsigned_byte_enable = i_instruction[22];
503
 
504
        o_mem_srcdest_index = {i_instruction[`SRCDEST_EXTEND], i_instruction[`SRCDEST]};
505
 
506
        if ( !o_mem_pre_index ) // Post-index, writeback has no meaning.
507
        begin
508
                if ( i_instruction[21] )
509
                begin
510
                        // Use it for force usr mode memory mappings.
511
                        o_mem_translate = 1'd1;
512
                end
513
        end
514
end
515
endtask
516
 
517
// ----------------------------------------------------------------------------
518
 
519
task decode_mrs( input [34:0] i_instruction );
520
begin
521
 
522
        process_immediate ( i_instruction[11:0] );
523
 
524
        o_condition_code    = i_instruction[31:28];
525
        o_destination_index = {i_instruction[`DP_RD_EXTEND], i_instruction[`DP_RD]};
526
        o_alu_source        = i_instruction[22] ? ARCH_CURR_SPSR : ARCH_CPSR;
527
        o_alu_source[32]    = INDEX_EN;
528
        o_alu_operation     = ADD;
529
end
530
endtask
531
 
532
// ----------------------------------------------------------------------------
533
 
534
task decode_msr( input [34:0] i_instruction );
535
begin
536
 
537
        if ( i_instruction[25] ) // Immediate present.
538
        begin
539
                process_immediate ( i_instruction[11:0] );
540
        end
541
        else
542
        begin
543
                process_instruction_specified_shift ( i_instruction[11:0] );
544
        end
545
 
546
        // Destination.
547
        o_destination_index = i_instruction[22] ? ARCH_CURR_SPSR : ARCH_CPSR;
548
 
549
        o_condition_code = i_instruction[31:28];
550
 
551
        // Make srcdest as SPSR. useful for MMOV.
552
        o_mem_srcdest_index = ARCH_CURR_SPSR;
553
 
554
        // Select SPSR or CPSR.
555
        o_alu_operation  = i_instruction[22] ? MMOV : FMOV;
556
 
557
        o_alu_source     = i_instruction[19:16];
558
        o_alu_source[32] = IMMED_EN;
559
 
560
        // Part of the instruction will silently fail when changing mode bits
561
        // in user mode. This is as per the ARM spec.
562
        if  ( i_cpsr_ff_mode == USR )
563
        begin
564
                o_alu_source[2:0] = 3'b0;
565
        end
566
end
567
endtask
568
 
569
// ----------------------------------------------------------------------------
570
 
571
// ========================
572
// Decode B
573
// ========================
574
task decode_branch( input [34:0] i_instruction );
575
begin
576
        // A branch is decayed into PC = PC + $signed(immed)
577
        o_condition_code        = i_instruction[31:28];
578
        o_alu_operation         = ADD;
579
        o_destination_index     = ARCH_PC;
580
        o_alu_source            = ARCH_PC;
581
        o_alu_source[32]        = INDEX_EN;
582
        o_shift_source          = ($signed(i_instruction[23:0]));
583
        o_shift_source[32]      = IMMED_EN;
584
        o_shift_operation       = LSL;
585
        o_shift_length          = i_instruction[34] ? 1 : 2; // Thumb branches sometimes need only a shift of 1.
586
        o_shift_length[32]      = IMMED_EN;
587
end
588
endtask
589
 
590
// ----------------------------------------------------------------------------
591
 
592
//
593
// Common data processing handles the common section of all 3 data processing
594
// formats.
595
//
596
task decode_data_processing( input [34:0] i_instruction );
597
begin
598
        o_condition_code        = i_instruction[31:28];
599
        o_alu_operation         = i_instruction[24:21];
600
        o_flag_update           = i_instruction[20];
601
        o_destination_index     = {i_instruction[`DP_RD_EXTEND], i_instruction[`DP_RD]};
602
        o_alu_source            = i_instruction[`DP_RA];
603
        o_alu_source[32]        = INDEX_EN;
604
        o_mem_srcdest_index     = ARCH_CURR_SPSR;
605
 
606
        if (    o_alu_operation == CMP ||
607
                o_alu_operation == CMN ||
608
                o_alu_operation == TST ||
609
                o_alu_operation == TEQ )
610
        begin
611
                o_destination_index = RAZ_REGISTER;
612
        end
613
 
614
        casez ( {i_instruction[25],i_instruction[7],i_instruction[4]} )
615
        3'b1zz: process_immediate ( i_instruction );
616
        3'b0z0: process_instruction_specified_shift ( i_instruction );
617
        3'b001: process_register_specified_shift ( i_instruction );
618
        default:
619
        begin
620
                $display("Error : Decoder Error.");
621
                $finish;
622
        end
623
        endcase
624
end
625
endtask
626
 
627
// ----------------------------------------------------------------------------
628
 
629
//
630
// If an immediate value is to be rotated right by an 
631
// immediate value, this mode is used.
632
//
633
task process_immediate ( input [34:0] instruction );
634
begin
635
        o_shift_length          = instruction[11:8] << 1'd1;
636
        o_shift_length[32]      = IMMED_EN;
637
        o_shift_source          = instruction[7:0];
638
        o_shift_source[32]      = IMMED_EN;
639
        o_shift_operation       = RORI;
640
end
641
endtask
642
 
643
// ----------------------------------------------------------------------------
644
 
645
//
646
// The shifter source is a register but the 
647
// amount to shift is in the instruction itself.
648
//
649
task process_instruction_specified_shift ( input [34:0] instruction );
650
begin
651
        // ROR #0 = RRC, ASR #0 = ASR #32, LSL #0 = LSL #0, LSR #0 = LSR #32 
652
        // ROR #n = ROR_1 #n ( n > 0 )
653
        o_shift_length          = instruction[11:7];
654
        o_shift_length[32]      = IMMED_EN;
655
        o_shift_source          = {i_instruction[`DP_RB_EXTEND],instruction[`DP_RB]};
656
        o_shift_source[32]      = INDEX_EN;
657
        o_shift_operation       = instruction[6:5];
658
 
659
        case ( o_shift_operation )
660
                LSR: if ( !o_shift_length[31:0] ) o_shift_length[31:0] = 32;
661
                ASR: if ( !o_shift_length[31:0] ) o_shift_length[31:0] = 32;
662
                ROR:
663
                begin
664
                        if ( !o_shift_length[31:0] )
665
                                o_shift_operation    = RRC;
666
                        else
667
                                o_shift_operation    = ROR_1;
668
                                // Differs in carry generation behavior.
669
                end
670
                default: // For lint.
671
                begin
672
                end
673
        endcase
674
 
675
        // Reinforce the fact.
676
        o_shift_length[32] = IMMED_EN;
677
end
678
endtask
679
 
680
// ----------------------------------------------------------------------------
681
 
682
// The source register and the amount of shift are both in registers.
683
task process_register_specified_shift ( input [34:0] instruction );
684
begin
685
        o_shift_length          = instruction[11:8];
686
        o_shift_length[32]      = INDEX_EN;
687
        o_shift_source          = {i_instruction[`DP_RB_EXTEND], instruction[`DP_RB]};
688
        o_shift_source[32]      = INDEX_EN;
689
        o_shift_operation       = instruction[6:5];
690
end
691
endtask
692
 
693
endmodule // zap_decode.v
694
`default_nettype wire

powered by: WebSVN 2.1.0

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