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

Subversion Repositories zap

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 41 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 26 Revanth
//  This stage converts register indices into actual values. Register indices
24
//  are also pumped forward to allow resolution in the shift stage. PC
25
//  references must be resolved here since the value gives PC + 8. Instructions
26
//  requiring shifts stall if the target registers are in the outputs of this
27
//  stage. We do not issue a multiply if the source is still in the output of this 
28
//  stage just like shifts. That's to ensure incorrect registers are not
29
//  read.
30
// ----------------------------------------------------------------------------
31
 
32
`default_nettype none
33
 
34
module zap_issue_main
35
#(
36
        // Parameters.
37
 
38
        // Number of physical registers.
39
        parameter PHY_REGS = 46,
40
 
41
        // Although ARM mentions only 16 ALU operations, the processor
42
        // internally performs many more operations.
43
        parameter ALU_OPS   = 32,
44
 
45
        // Number of supported shift operations.
46
        parameter SHIFT_OPS = 5
47
)
48
(
49
        // Decompile path
50
        input   wire    [64*8-1:0]              i_decompile,
51
        output  reg     [64*8-1:0]              o_decompile,
52
 
53
        // PC in
54
        input wire [31:0]                       i_pc_ff,
55
        output reg [31:0]                       o_pc_ff,
56
 
57
        // BP signals.
58
        input wire   [1:0]                      i_taken_ff,
59
        output reg   [1:0]                      o_taken_ff,
60
 
61
        // Clock and reset.
62
        input  wire                             i_clk,    // ZAP clock.
63
        input  wire                             i_reset, // Active high sync.
64
 
65
        // CPSR.
66
        input wire       [31:0]                 i_cpu_mode,
67
 
68
        // Clear and stall signals.
69
        input wire                              i_clear_from_writeback,
70
        input wire                              i_data_stall,
71
        input wire                              i_clear_from_alu,
72
        input wire                              i_stall_from_shifter,
73
 
74
        // From decode
75
        input wire  [31:0]                      i_pc_plus_8_ff,
76
 
77
        // -----------------------------------
78
        // Inputs from decode.
79
        // Look at the decode stage for the 
80
        // meaning of these ports...
81
        // -----------------------------------        
82
 
83
        input wire      [3:0]                   i_condition_code_ff,
84
 
85
        input wire      [$clog2(PHY_REGS )-1:0] i_destination_index_ff,
86
 
87
        input wire      [32:0]                  i_alu_source_ff,
88
        input wire      [$clog2(ALU_OPS)-1:0]   i_alu_operation_ff,
89
 
90
        input wire      [32:0]                  i_shift_source_ff,
91
        input wire      [$clog2(SHIFT_OPS)-1:0] i_shift_operation_ff,
92
        input wire      [32:0]                  i_shift_length_ff,
93
 
94
        input wire                              i_flag_update_ff,
95
 
96
        input wire    [$clog2(PHY_REGS )-1:0]   i_mem_srcdest_index_ff,
97
        input wire                              i_mem_load_ff,
98
        input wire                              i_mem_store_ff,
99
        input wire                              i_mem_pre_index_ff,
100
        input wire                              i_mem_unsigned_byte_enable_ff,
101
        input wire                              i_mem_signed_byte_enable_ff,
102
        input wire                              i_mem_signed_halfword_enable_ff,
103
        input wire                              i_mem_unsigned_halfword_enable_ff,
104
        input wire                              i_mem_translate_ff,
105
 
106
        input wire                              i_irq_ff,
107
        input wire                              i_fiq_ff,
108
        input wire                              i_abt_ff,
109
        input wire                              i_swi_ff,
110
 
111
        // From register file. Read ports.
112
        input wire  [31:0]                      i_rd_data_0,
113
        input wire  [31:0]                      i_rd_data_1,
114
        input wire  [31:0]                      i_rd_data_2,
115
        input wire  [31:0]                      i_rd_data_3,
116
 
117
        // Force 32 bit address alignment.
118
        input wire                              i_force32align_ff,
119
        output reg                              o_force32align_ff,
120
 
121
        // For undefined instr.
122
        input wire                         i_und_ff,
123
        output reg                         o_und_ff,
124
 
125
        // ---------------------
126
        // Feedback Network
127
        // ---------------------
128
 
129
        //
130
        // Destination index feedback. Each stage is represented as
131
        // combinational logic followed by flops(FFs).
132
        //
133
 
134
        // The ALU never changes destination anyway. Destination from shifter.
135
        input wire  [$clog2(PHY_REGS )-1:0]     i_shifter_destination_index_ff,
136
 
137
        // Flopped destination from the ALU.
138
        input wire  [$clog2(PHY_REGS )-1:0]     i_alu_destination_index_ff,
139
 
140
        // Flopped destination from the memory stage.
141
        input wire  [$clog2(PHY_REGS )-1:0]     i_memory_destination_index_ff,
142
 
143
        //
144
        // Data valid(dav) for each stage in the pipeline. Used to validate the
145
        // pipeline vector when sniffing for register values yet to be written.
146
        //
147
 
148
        // Taken from alu_nxt instead of shifter_ff because ALU can invalidate
149
        // instructions.
150
        input wire                              i_alu_dav_nxt,
151
        input wire                              i_alu_dav_ff,
152
        input wire                              i_memory_dav_ff,
153
 
154
        //
155
        // The actual thing we need (i.e. data), 
156
        // the value of stuff we are looking for.
157
        //
158
 
159
        // Taken from alu_nxt since ALU can change this.
160
        input wire  [31:0]                      i_alu_destination_value_nxt,
161
 
162
        // ALU flopped result.
163
        input wire  [31:0]                      i_alu_destination_value_ff,
164
 
165
        // Result in the memory stage of the pipeline.
166
        input wire  [31:0]                      i_memory_destination_value_ff,
167
 
168
        //
169
        // For load-store locks and memory acceleration, we need srcdest
170
        // index. Memory loads can be accelerated with a direct load from
171
        // memory stage instead of register stage(WB).
172
        //
173
        input wire  [5:0]                       i_shifter_mem_srcdest_index_ff,
174
        input wire  [5:0]                       i_alu_mem_srcdest_index_ff,
175
        input wire  [5:0]                       i_memory_mem_srcdest_index_ff,
176
        input wire                              i_shifter_mem_load_ff,//1 if load.
177
        input wire                              i_alu_mem_load_ff,
178
        input wire                              i_memory_mem_load_ff,
179
 
180
        // Memory accelerator values for loads. External memory bys is
181
        // connected to this.
182
        input wire  [31:0]                      i_memory_mem_srcdest_value_ff,
183
 
184
        // ARM to compressed switch.
185
        input wire i_switch_ff,
186
        output reg o_switch_ff,
187
 
188
        // Outputs to register file.
189
        output reg      [$clog2(PHY_REGS )-1:0] o_rd_index_0,
190
        output reg      [$clog2(PHY_REGS )-1:0] o_rd_index_1,
191
        output reg      [$clog2(PHY_REGS )-1:0] o_rd_index_2,
192
        output reg      [$clog2(PHY_REGS )-1:0] o_rd_index_3,
193
 
194
        // Outputs to shifter stage.
195
        output reg       [3:0]                   o_condition_code_ff,
196
        output reg       [$clog2(PHY_REGS )-1:0] o_destination_index_ff,
197
        output reg       [$clog2(ALU_OPS)-1:0]   o_alu_operation_ff,
198
        output reg       [$clog2(SHIFT_OPS)-1:0] o_shift_operation_ff,
199
        output reg                               o_flag_update_ff,
200
 
201
        // Memory operation related.        
202
        output reg     [$clog2(PHY_REGS )-1:0]   o_mem_srcdest_index_ff,
203
        output reg                               o_mem_load_ff,
204
        output reg                               o_mem_store_ff,
205
        output reg                               o_mem_pre_index_ff,
206
        output reg                               o_mem_unsigned_byte_enable_ff,
207
        output reg                               o_mem_signed_byte_enable_ff,
208
        output reg                               o_mem_signed_halfword_enable_ff,
209
        output reg                               o_mem_unsigned_halfword_enable_ff,
210
        output reg                               o_mem_translate_ff,
211
 
212
        // Interrupts.
213
        output reg                               o_irq_ff,
214
        output reg                               o_fiq_ff,
215
        output reg                               o_abt_ff,
216
        output reg                               o_swi_ff,
217
 
218
        // Register values are given here.
219
 
220
        // ALU source value would be the value of non-shifted operand in ARM.
221
        output reg      [31:0]                  o_alu_source_value_ff,
222
 
223
        // Shifter source value would be the value of the operand to be shifted.
224
        output reg      [31:0]                  o_shift_source_value_ff,
225
 
226
        // Shift length i.e., amount to shift i.e, shamt.
227
        output reg      [31:0]                  o_shift_length_value_ff,
228
 
229
        // For stores, value to be stored.
230
        output reg      [31:0]                  o_mem_srcdest_value_ff,
231
 
232
        //
233
        // Indices/Immeds go here. It might seem odd that we are sending index
234
        // values and register values (above). The issue stage selects
235
        // the appropriate value. Note again that while the above are values,
236
        // these are indexes/immediates.
237
        //
238
        output reg      [32:0]                  o_alu_source_ff,
239
        output reg      [32:0]                  o_shift_source_ff,
240
 
241
        // Stall everything before this if 1.
242
        output reg                              o_stall_from_issue,
243
 
244
        // The PC value.
245
        output reg     [31:0]                   o_pc_plus_8_ff,
246
 
247
        //
248
        // Shifter disable. In the next stage, the output
249
        // will bypass the shifter. Not actually bypass it but will
250
        // go to the ALU value corrector unit via a MUX essentially bypassing
251
        // the shifter.
252
        //
253
        output reg                              o_shifter_disable_ff
254
);
255
 
256
`include "zap_defines.vh"
257
`include "zap_localparams.vh"
258
`include "zap_functions.vh"
259
 
260
reg o_shifter_disable_nxt;
261
 
262
reg [31:0] o_alu_source_value_nxt,
263
           o_shift_source_value_nxt,
264
           o_shift_length_value_nxt,
265
           o_mem_srcdest_value_nxt;
266
 
267
// Individual lock signals. These are ORed to get the final lock.
268
reg shift_lock;
269
reg load_lock;
270
 
271
 
272
reg lock;               // Asserted when an instruction cannot be issued and 
273
                        // leads to all stages before it stalling.
274
 
275
always @*
276
        lock = shift_lock | load_lock;
277
 
278
task clear;
279
begin
280
        o_condition_code_ff               <= NV;
281
        o_irq_ff                          <= 0;
282
        o_fiq_ff                          <= 0;
283
        o_abt_ff                          <= 0;
284
        o_swi_ff                          <= 0;
285
        o_und_ff                          <= 0;
286
        o_flag_update_ff                  <= 0;
287
end
288
endtask
289
 
290
always @ (posedge i_clk)
291
begin
292
        if ( i_reset )
293
        begin
294
                clear;
295
        end
296
        else if ( i_clear_from_writeback )
297
        begin
298
                clear;
299
        end
300
        else if ( i_data_stall )
301
        begin
302
                // Preserve values.
303
        end
304
        else if ( i_clear_from_alu )
305
        begin
306
                clear;
307
        end
308
        else if ( i_stall_from_shifter )
309
        begin
310
                // Preserve values.
311
        end
312
        else if ( lock )
313
        begin
314
                clear;
315
        end
316
        else
317
        begin
318
                o_condition_code_ff               <= i_condition_code_ff;
319
                o_destination_index_ff            <= i_destination_index_ff;
320
                o_alu_operation_ff                <= i_alu_operation_ff;
321
                o_shift_operation_ff              <= i_shift_operation_ff;
322
                o_flag_update_ff                  <= i_flag_update_ff;
323
                o_mem_srcdest_index_ff            <= i_mem_srcdest_index_ff;
324
                o_mem_load_ff                     <= i_mem_load_ff;
325
                o_mem_store_ff                    <= i_mem_store_ff;
326
                o_mem_pre_index_ff                <= i_mem_pre_index_ff;
327
                o_mem_unsigned_byte_enable_ff     <= i_mem_unsigned_byte_enable_ff;
328
                o_mem_signed_byte_enable_ff       <= i_mem_signed_byte_enable_ff;
329
                o_mem_signed_halfword_enable_ff   <= i_mem_signed_halfword_enable_ff;
330
                o_mem_unsigned_halfword_enable_ff <= i_mem_unsigned_halfword_enable_ff;
331
                o_mem_translate_ff                <= i_mem_translate_ff;
332
                o_irq_ff                          <= i_irq_ff;
333
                o_fiq_ff                          <= i_fiq_ff;
334
                o_abt_ff                          <= i_abt_ff;
335
                o_swi_ff                          <= i_swi_ff;
336
                o_pc_plus_8_ff                    <= i_pc_plus_8_ff;
337
                o_shifter_disable_ff              <= o_shifter_disable_nxt;
338
                o_alu_source_ff                   <= i_alu_source_ff;
339
                o_shift_source_ff                 <= i_shift_source_ff;
340
                o_alu_source_value_ff             <= o_alu_source_value_nxt;
341
                o_shift_source_value_ff           <= o_shift_source_value_nxt;
342
                o_shift_length_value_ff           <= o_shift_length_value_nxt;
343
                o_mem_srcdest_value_ff            <= o_mem_srcdest_value_nxt;
344
                o_switch_ff                       <= i_switch_ff;
345
                o_force32align_ff                 <= i_force32align_ff;
346
                o_und_ff                          <= i_und_ff;
347
                o_taken_ff                        <= i_taken_ff;
348
                o_pc_ff                           <= i_pc_ff;
349
 
350
                // For debug
351
                o_decompile                       <= i_decompile;
352
        end
353
end
354
 
355
// Get values from the feedback network.
356
always @*
357
begin
358
 
359
 
360
        o_alu_source_value_nxt  =
361
        get_register_value (    i_alu_source_ff,
362
                                0,
363
                                i_shifter_destination_index_ff,
364
                                i_alu_dav_nxt,
365
                                i_alu_destination_value_nxt,
366
                                i_alu_destination_value_ff,
367
                                i_alu_destination_index_ff,
368
                                i_alu_dav_ff,
369
                                i_memory_destination_index_ff,
370
                                i_memory_dav_ff,
371
                                i_memory_mem_srcdest_index_ff,
372
                                i_memory_mem_load_ff,
373
                                i_rd_data_0,
374
                                i_rd_data_1,
375
                                i_rd_data_2,
376
                                i_rd_data_3, i_memory_mem_srcdest_value_ff, i_cpu_mode, i_pc_plus_8_ff
377
        );
378
 
379
 
380
        o_shift_source_value_nxt=
381
        get_register_value (    i_shift_source_ff,
382
                                1,
383
                                i_shifter_destination_index_ff,
384
                                i_alu_dav_nxt,
385
                                i_alu_destination_value_nxt,
386
                                i_alu_destination_value_ff,
387
                                i_alu_destination_index_ff,
388
                                i_alu_dav_ff,
389
                                i_memory_destination_index_ff,
390
                                i_memory_dav_ff,
391
                                i_memory_mem_srcdest_index_ff,
392
                                i_memory_mem_load_ff,
393
                                i_rd_data_0,
394
                                i_rd_data_1,
395
                                i_rd_data_2,
396
                                i_rd_data_3, i_memory_mem_srcdest_value_ff, i_cpu_mode, i_pc_plus_8_ff
397
        );
398
 
399
        o_shift_length_value_nxt=
400
        get_register_value (    i_shift_length_ff,
401
                                2,
402
                                i_shifter_destination_index_ff,
403
                                i_alu_dav_nxt,
404
                                i_alu_destination_value_nxt,
405
                                i_alu_destination_value_ff,
406
                                i_alu_destination_index_ff,
407
                                i_alu_dav_ff,
408
                                i_memory_destination_index_ff,
409
                                i_memory_dav_ff,
410
                                i_memory_mem_srcdest_index_ff,
411
                                i_memory_mem_load_ff,
412
                                i_rd_data_0,
413
                                i_rd_data_1,
414
                                i_rd_data_2,
415
                                i_rd_data_3, i_memory_mem_srcdest_value_ff, i_cpu_mode, i_pc_plus_8_ff
416
        );
417
 
418
        // Value of a register index, never an immediate.
419
        o_mem_srcdest_value_nxt =
420
        get_register_value (    i_mem_srcdest_index_ff,
421
                                3,
422
                                i_shifter_destination_index_ff,
423
                                i_alu_dav_nxt,
424
                                i_alu_destination_value_nxt,
425
                                i_alu_destination_value_ff,
426
                                i_alu_destination_index_ff,
427
                                i_alu_dav_ff,
428
                                i_memory_destination_index_ff,
429
                                i_memory_dav_ff,
430
                                i_memory_mem_srcdest_index_ff,
431
                                i_memory_mem_load_ff,
432
                                i_rd_data_0,
433
                                i_rd_data_1,
434
                                i_rd_data_2,
435
                                i_rd_data_3, i_memory_mem_srcdest_value_ff, i_cpu_mode, i_pc_plus_8_ff
436
        );
437
 
438
end
439
 
440
 
441
// Apply index to register file.
442
always @*
443
begin
444
        o_rd_index_0 = i_alu_source_ff;
445
        o_rd_index_1 = i_shift_source_ff;
446
        o_rd_index_2 = i_shift_length_ff;
447
        o_rd_index_3 = i_mem_srcdest_index_ff;
448
end
449
 
450
 
451
//
452
// Straightforward read feedback function. Looks at all stages of the pipeline
453
// to extract the latest value of the register. 
454
// There is some complexity here to perform accelerated memory reads. 
455
//
456
function [31:0] get_register_value (
457
 
458
        // The register inex to search for. This might be a constant too.
459
        input [32:0]                    index,
460
 
461
        // Register read port activated for this function.
462
        input [1:0]                     rd_port,
463
 
464
        // Destination on the output of the shifter stage.
465
        input [32:0]                    i_shifter_destination_index_ff,
466
 
467
        // ALU output is valid.
468
        input                           i_alu_dav_nxt,
469
 
470
        // ALU output.
471
        input [31:0]                    i_alu_destination_value_nxt,
472
 
473
        // ALU flopped result.
474
        input [31:0]                    i_alu_destination_value_ff,
475
 
476
        // ALU flopped destination index.
477
        input [$clog2(PHY_REGS)-1:0]    i_alu_destination_index_ff,
478
 
479
        // Valid flopped (EX stage).
480
        input                           i_alu_dav_ff,
481
 
482
        // Memory stage destination index (pointer)
483
        input [$clog2(PHY_REGS)-1:0]    i_memory_destination_index_ff,
484
 
485
        // Memory stage valid.
486
        input                           i_memory_dav_ff,
487
 
488
        // Memory stage srcdest index. The srcdest is basically the data
489
        // register index.
490
        input [$clog2(PHY_REGS)-1:0]    i_memory_mem_srcdest_index_ff,
491
 
492
        // Memory load instruction in memory stage.    
493
        input                           i_memory_mem_load_ff,
494
 
495
        // Data read from register file.
496
        input [31:0]                    i_rd_data_0, i_rd_data_1, i_rd_data_2, i_rd_data_3,
497
                                        i_memory_mem_srcdest_value_ff, i_cpu_mode, i_pc_plus_8_ff
498
);
499
 
500
reg [31:0] get;
501
 
502
begin
503
 
504
 
505
        if   ( index[32] )                 // Catch constant here.
506
        begin
507
                        get = index[31:0];
508
        end
509
        else if ( index == PHY_RAZ_REGISTER )   // Catch RAZ here.
510
        begin
511
               // Return 0. 
512
                get = 32'd0;
513
        end
514
        else if   ( index == ARCH_PC )  // Catch PC here. ARCH index = PHY index so no problem.
515
        begin
516
                 get = i_pc_plus_8_ff;
517
        end
518
        else if ( index == PHY_CPSR )   // Catch CPSR here.
519
        begin
520
                get = i_cpu_mode;
521
        end
522
 
523
        // Match in ALU stage.
524
        else if   ( index == i_shifter_destination_index_ff && i_alu_dav_nxt  )
525
        begin   // ALU effectively never changes destination so no need to look at _nxt.
526
                        get =  i_alu_destination_value_nxt;
527
        end
528
 
529
        // Match in output of ALU stage.
530
        else if   ( index == i_alu_destination_index_ff && i_alu_dav_ff       )
531
        begin
532
                        get =  i_alu_destination_value_ff;
533
        end
534
 
535
        // Match in output of memory stage.
536
        else if   ( index == i_memory_destination_index_ff && i_memory_dav_ff )
537
        begin
538
                        get =  i_memory_destination_value_ff;
539
        end
540
        else    // Index not found in the pipeline, fallback to register access.                     
541
        begin
542
                case ( rd_port )
543
                        0: get = i_rd_data_0;
544
                        1: get = i_rd_data_1;
545
                        2: get = i_rd_data_2;
546
                        3: get = i_rd_data_3;
547
                endcase
548
        end
549
 
550
        // The memory accelerator. If the required stuff is present in the memory unit, short circuit.
551
        if ( index == i_memory_mem_srcdest_index_ff && i_memory_mem_load_ff && i_memory_dav_ff )
552
        begin
553
                get = i_memory_mem_srcdest_value_ff;
554
        end
555
 
556
        get_register_value = get;
557
end
558
endfunction
559
 
560
 
561
// Stall all previous stages if a lock occurs.
562
always @*
563
begin
564
        o_stall_from_issue = lock;
565
end
566
 
567
 
568
always @*
569
begin
570
        // Look for reads from registers to be loaded from memory. Four
571
        // register sources may cause a load lock.
572
        load_lock =     determine_load_lock
573
                        ( i_alu_source_ff  ,
574
                        o_mem_srcdest_index_ff,
575
                        o_condition_code_ff,
576
                        o_mem_load_ff,
577
                        i_shifter_mem_srcdest_index_ff,
578
                        i_alu_dav_nxt,
579
                        i_shifter_mem_load_ff,
580
                        i_alu_mem_srcdest_index_ff,
581
                        i_alu_dav_ff,
582
                        i_alu_mem_load_ff )
583
                        ||
584
                        determine_load_lock
585
                        (
586
                        i_shift_source_ff,
587
                        o_mem_srcdest_index_ff,
588
                        o_condition_code_ff,
589
                        o_mem_load_ff,
590
                        i_shifter_mem_srcdest_index_ff,
591
                        i_alu_dav_nxt,
592
                        i_shifter_mem_load_ff,
593
                        i_alu_mem_srcdest_index_ff,
594
                        i_alu_dav_ff,
595
                        i_alu_mem_load_ff )
596
                        ||
597
                        determine_load_lock
598
                        ( i_shift_length_ff,
599
                        o_mem_srcdest_index_ff,
600
                        o_condition_code_ff,
601
                        o_mem_load_ff,
602
                        i_shifter_mem_srcdest_index_ff,
603
                        i_alu_dav_nxt,
604
                        i_shifter_mem_load_ff,
605
                        i_alu_mem_srcdest_index_ff,
606
                        i_alu_dav_ff,
607
                        i_alu_mem_load_ff )
608
                        ||
609
                        determine_load_lock
610
                        ( i_mem_srcdest_index_ff,
611
                        o_mem_srcdest_index_ff,
612
                        o_condition_code_ff,
613
                        o_mem_load_ff,
614
                        i_shifter_mem_srcdest_index_ff,
615
                        i_alu_dav_nxt,
616
                        i_shifter_mem_load_ff,
617
                        i_alu_mem_srcdest_index_ff,
618
                        i_alu_dav_ff,
619
                        i_alu_mem_load_ff );
620
 
621
        // A shift lock occurs if the current instruction requires a shift amount as a register
622
        // other than LSL #0 or RORI if the operands are right on the output of this
623
        // stage because in that case we do not have the register value and thus
624
        // a shift lock.
625
        shift_lock =    (!(
626
                                i_shift_operation_ff    == LSL &&
627
                                i_shift_length_ff[31:0] == 32'd0 &&
628
                                i_shift_length_ff[32]   == IMMED_EN
629
                        )
630
                        && // If it is not LSL #0 AND...
631
                        !(
632
                                i_shift_operation_ff == RORI // The amount to rotate and rotate are self contained.
633
                        )
634
                        && // If it is not RORI AND...
635
                        (
636
                                // Stuff is locked.
637
                                shifter_lock_check ( i_shift_source_ff, o_destination_index_ff, o_condition_code_ff ) ||
638
                                shifter_lock_check ( i_shift_length_ff, o_destination_index_ff, o_condition_code_ff ) ||
639
                                shifter_lock_check ( i_alu_source_ff  , o_destination_index_ff, o_condition_code_ff )
640
                        )) ||
641
                        (
642
                                // If it is a multiply and stuff is locked.
643
                                (i_alu_operation_ff == UMLALL ||
644
                                 i_alu_operation_ff == UMLALH ||
645
                                 i_alu_operation_ff == SMLALL ||
646
                                 i_alu_operation_ff == SMLALH) &&
647
                                (
648
                                        shifter_lock_check ( i_shift_source_ff, o_destination_index_ff, o_condition_code_ff ) ||
649
                                        shifter_lock_check ( i_shift_length_ff, o_destination_index_ff, o_condition_code_ff ) ||
650
                                        shifter_lock_check ( i_alu_source_ff  , o_destination_index_ff, o_condition_code_ff ) ||
651
                                        shifter_lock_check ( i_mem_srcdest_index_ff, o_destination_index_ff, o_condition_code_ff )
652
                                )
653
                        ) // If it is multiply (MAC). 
654
 
655
                        ||
656
                        (       // If the instruction is not LSL #0 and previous instruction has flag
657
                                // updates, we stall.
658
 
659
                               !o_shifter_disable_nxt &&
660
                                o_flag_update_ff
661
                        );
662
end
663
 
664
always @*
665
begin
666
        // Shifter disable.
667
        o_shifter_disable_nxt = (
668
                                        i_shift_operation_ff    == LSL &&
669
                                        i_shift_length_ff[31:0] == 32'd0 &&
670
                                        i_shift_length_ff[32]   == IMMED_EN
671
                                );
672
        // If it is LSL #0, we can disable the shifter.
673
end
674
 
675
// ----------------------------------------------------------------------------
676
 
677
// Shifter lock check.
678
function shifter_lock_check (
679
        input [32:0] index,
680
        input [$clog2(PHY_REGS)-1:0] o_destination_index_ff,
681
        input [3:0] o_condition_code_ff
682
);
683
begin
684
        // Simply check if the operand index is on the output of this unit
685
        // and that the output is valid.
686
        if ( o_destination_index_ff == index && o_condition_code_ff != NV )
687
                shifter_lock_check = 1'd1;
688
        else
689
                shifter_lock_check = 1'd0;
690
 
691
        // If immediate, no lock obviously.
692
        if ( index[32] == IMMED_EN || index == PHY_RAZ_REGISTER )
693
                shifter_lock_check = 1'd0;
694
end
695
endfunction
696
 
697
// ----------------------------------------------------------------------------
698
 
699
// Load lock. Activated when a read from a register follows a load to that
700
// register.
701
function determine_load_lock (
702
input [32:0]                    index,
703
input [$clog2(PHY_REGS)-1:0]    o_mem_srcdest_index_ff,
704
input [3:0]                     o_condition_code_ff,
705
input                           o_mem_load_ff,
706
input  [$clog2(PHY_REGS)-1:0]   i_shifter_mem_srcdest_index_ff,
707
input                           i_alu_dav_nxt,
708
input                           i_shifter_mem_load_ff,
709
input  [$clog2(PHY_REGS)-1:0]   i_alu_mem_srcdest_index_ff,
710
input                           i_alu_dav_ff,
711
input                           i_alu_mem_load_ff
712
);
713
begin
714
        determine_load_lock = 1'd0;
715
 
716
        // Look for that load instruction in the required pipeline stages. 
717
        // If found, we cannot issue the current instruction since old value 
718
        // will be read.
719
        if (
720
                ( index == o_mem_srcdest_index_ff          &&
721
                  o_condition_code_ff != NV                &&
722
                  o_mem_load_ff )                          ||
723
                ( index == i_shifter_mem_srcdest_index_ff  &&
724
                   i_alu_dav_nxt                           &&
725
                   i_shifter_mem_load_ff )                 ||
726
                (  index == i_alu_mem_srcdest_index_ff     &&
727
                   i_alu_dav_ff                            &&
728
                   i_alu_mem_load_ff )
729
        )
730
                determine_load_lock = 1'd1;
731
 
732
        // Locks occur only for indices...
733
        if ( index[32] == IMMED_EN || index == PHY_RAZ_REGISTER )
734
                determine_load_lock = 1'd0;
735
end
736
endfunction
737
 
738
endmodule // zap_issue_main.v
739 51 Revanth
 
740 26 Revanth
`default_nettype wire
741 51 Revanth
 
742
// ----------------------------------------------------------------------------
743
// EOF
744
// ----------------------------------------------------------------------------

powered by: WebSVN 2.1.0

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