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 41

Go to most recent revision | 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
`ifdef ISSUE_DEBUG
505
        $display($time, "Received index as %d and rd_port %d", index, rd_port);
506
`endif
507
 
508
        if   ( index[32] )                 // Catch constant here.
509
        begin
510
`ifdef ISSUE_DEBUG
511
                        $display($time, "Constant detect. Returning %x", index[31:0]);
512
`endif
513
 
514
                        get = index[31:0];
515
        end
516
        else if ( index == PHY_RAZ_REGISTER )   // Catch RAZ here.
517
        begin
518
               // Return 0. 
519
`ifdef ISSUE_DEBUG
520
               $display($time, "RAZ returned 0...");
521
`endif
522
                get = 32'd0;
523
        end
524
        else if   ( index == ARCH_PC )  // Catch PC here. ARCH index = PHY index so no problem.
525
        begin
526
                 get = i_pc_plus_8_ff;
527
`ifdef ISSUE_DEBUG
528
                 $display($time, "PC requested... given as %x", get);
529
`endif
530
        end
531
        else if ( index == PHY_CPSR )   // Catch CPSR here.
532
        begin
533
                get = i_cpu_mode;
534
        end
535
 
536
        // Match in ALU stage.
537
        else if   ( index == i_shifter_destination_index_ff && i_alu_dav_nxt  )
538
        begin   // ALU effectively never changes destination so no need to look at _nxt.
539
                        get =  i_alu_destination_value_nxt;
540
`ifdef ISSUE_DEBUG
541
                        $display($time, "Matched shifter destination index %x ... given as %x", i_shifter_destination_index_ff, get);
542
`endif
543
        end
544
 
545
        // Match in output of ALU stage.
546
        else if   ( index == i_alu_destination_index_ff && i_alu_dav_ff       )
547
        begin
548
                        get =  i_alu_destination_value_ff;
549
`ifdef ISSUE_DEBUG
550
                        $display($time, "Matched ALU destination index %x ... given as %x", i_alu_destination_index_ff, get);
551
`endif
552
        end
553
 
554
        // Match in output of memory stage.
555
        else if   ( index == i_memory_destination_index_ff && i_memory_dav_ff )
556
        begin
557
                        get =  i_memory_destination_value_ff;
558
`ifdef ISSUE_DEBUG
559
                        $display($time, "Matched memory destination index %x ... given as %x", i_memory_destination_index_ff, get);
560
`endif
561
        end
562
        else    // Index not found in the pipeline, fallback to register access.                     
563
        begin
564
`ifdef ISSUE_DEBUG
565
                $display($time, "Register read on rd_port %x", rd_port );
566
`endif
567
 
568
                case ( rd_port )
569
                        0: get = i_rd_data_0;
570
                        1: get = i_rd_data_1;
571
                        2: get = i_rd_data_2;
572
                        3: get = i_rd_data_3;
573
                endcase
574
`ifdef ISSUE_DEBUG
575
                $display($time, "Reg read -> Returned value %x", get);
576
`endif
577
        end
578
 
579
        // The memory accelerator. If the required stuff is present in the memory unit, short circuit.
580
        if ( index == i_memory_mem_srcdest_index_ff && i_memory_mem_load_ff && i_memory_dav_ff )
581
        begin
582
`ifdef ISSUE_DEBUG
583
                $display($time, "Memory accelerator gets value %x", i_memory_mem_srcdest_value_ff);
584
`endif
585
 
586
                get = i_memory_mem_srcdest_value_ff;
587
        end
588
 
589
        get_register_value = get;
590
end
591
endfunction
592
 
593
 
594
// Stall all previous stages if a lock occurs.
595
always @*
596
begin
597
        o_stall_from_issue = lock;
598
end
599
 
600
 
601
always @*
602
begin
603
        // Look for reads from registers to be loaded from memory. Four
604
        // register sources may cause a load lock.
605
        load_lock =     determine_load_lock
606
                        ( i_alu_source_ff  ,
607
                        o_mem_srcdest_index_ff,
608
                        o_condition_code_ff,
609
                        o_mem_load_ff,
610
                        i_shifter_mem_srcdest_index_ff,
611
                        i_alu_dav_nxt,
612
                        i_shifter_mem_load_ff,
613
                        i_alu_mem_srcdest_index_ff,
614
                        i_alu_dav_ff,
615
                        i_alu_mem_load_ff )
616
                        ||
617
                        determine_load_lock
618
                        (
619
                        i_shift_source_ff,
620
                        o_mem_srcdest_index_ff,
621
                        o_condition_code_ff,
622
                        o_mem_load_ff,
623
                        i_shifter_mem_srcdest_index_ff,
624
                        i_alu_dav_nxt,
625
                        i_shifter_mem_load_ff,
626
                        i_alu_mem_srcdest_index_ff,
627
                        i_alu_dav_ff,
628
                        i_alu_mem_load_ff )
629
                        ||
630
                        determine_load_lock
631
                        ( i_shift_length_ff,
632
                        o_mem_srcdest_index_ff,
633
                        o_condition_code_ff,
634
                        o_mem_load_ff,
635
                        i_shifter_mem_srcdest_index_ff,
636
                        i_alu_dav_nxt,
637
                        i_shifter_mem_load_ff,
638
                        i_alu_mem_srcdest_index_ff,
639
                        i_alu_dav_ff,
640
                        i_alu_mem_load_ff )
641
                        ||
642
                        determine_load_lock
643
                        ( i_mem_srcdest_index_ff,
644
                        o_mem_srcdest_index_ff,
645
                        o_condition_code_ff,
646
                        o_mem_load_ff,
647
                        i_shifter_mem_srcdest_index_ff,
648
                        i_alu_dav_nxt,
649
                        i_shifter_mem_load_ff,
650
                        i_alu_mem_srcdest_index_ff,
651
                        i_alu_dav_ff,
652
                        i_alu_mem_load_ff );
653
 
654
        // A shift lock occurs if the current instruction requires a shift amount as a register
655
        // other than LSL #0 or RORI if the operands are right on the output of this
656
        // stage because in that case we do not have the register value and thus
657
        // a shift lock.
658
        shift_lock =    (!(
659
                                i_shift_operation_ff    == LSL &&
660
                                i_shift_length_ff[31:0] == 32'd0 &&
661
                                i_shift_length_ff[32]   == IMMED_EN
662
                        )
663
                        && // If it is not LSL #0 AND...
664
                        !(
665
                                i_shift_operation_ff == RORI // The amount to rotate and rotate are self contained.
666
                        )
667
                        && // If it is not RORI AND...
668
                        (
669
                                // Stuff is locked.
670
                                shifter_lock_check ( i_shift_source_ff, o_destination_index_ff, o_condition_code_ff ) ||
671
                                shifter_lock_check ( i_shift_length_ff, o_destination_index_ff, o_condition_code_ff ) ||
672
                                shifter_lock_check ( i_alu_source_ff  , o_destination_index_ff, o_condition_code_ff )
673
                        )) ||
674
                        (
675
                                // If it is a multiply and stuff is locked.
676
                                (i_alu_operation_ff == UMLALL ||
677
                                 i_alu_operation_ff == UMLALH ||
678
                                 i_alu_operation_ff == SMLALL ||
679
                                 i_alu_operation_ff == SMLALH) &&
680
                                (
681
                                        shifter_lock_check ( i_shift_source_ff, o_destination_index_ff, o_condition_code_ff ) ||
682
                                        shifter_lock_check ( i_shift_length_ff, o_destination_index_ff, o_condition_code_ff ) ||
683
                                        shifter_lock_check ( i_alu_source_ff  , o_destination_index_ff, o_condition_code_ff ) ||
684
                                        shifter_lock_check ( i_mem_srcdest_index_ff, o_destination_index_ff, o_condition_code_ff )
685
                                )
686
                        ) // If it is multiply (MAC). 
687
 
688
                        ||
689
                        (       // If the instruction is not LSL #0 and previous instruction has flag
690
                                // updates, we stall.
691
 
692
                               !o_shifter_disable_nxt &&
693
                                o_flag_update_ff
694
                        );
695
end
696
 
697
always @*
698
begin
699
        // Shifter disable.
700
        o_shifter_disable_nxt = (
701
                                        i_shift_operation_ff    == LSL &&
702
                                        i_shift_length_ff[31:0] == 32'd0 &&
703
                                        i_shift_length_ff[32]   == IMMED_EN
704
                                );
705
        // If it is LSL #0, we can disable the shifter.
706
end
707
 
708
// ----------------------------------------------------------------------------
709
 
710
// Shifter lock check.
711
function shifter_lock_check (
712
        input [32:0] index,
713
        input [$clog2(PHY_REGS)-1:0] o_destination_index_ff,
714
        input [3:0] o_condition_code_ff
715
);
716
begin
717
        // Simply check if the operand index is on the output of this unit
718
        // and that the output is valid.
719
        if ( o_destination_index_ff == index && o_condition_code_ff != NV )
720
                shifter_lock_check = 1'd1;
721
        else
722
                shifter_lock_check = 1'd0;
723
 
724
        // If immediate, no lock obviously.
725
        if ( index[32] == IMMED_EN || index == PHY_RAZ_REGISTER )
726
                shifter_lock_check = 1'd0;
727
end
728
endfunction
729
 
730
// ----------------------------------------------------------------------------
731
 
732
// Load lock. Activated when a read from a register follows a load to that
733
// register.
734
function determine_load_lock (
735
input [32:0]                    index,
736
input [$clog2(PHY_REGS)-1:0]    o_mem_srcdest_index_ff,
737
input [3:0]                     o_condition_code_ff,
738
input                           o_mem_load_ff,
739
input  [$clog2(PHY_REGS)-1:0]   i_shifter_mem_srcdest_index_ff,
740
input                           i_alu_dav_nxt,
741
input                           i_shifter_mem_load_ff,
742
input  [$clog2(PHY_REGS)-1:0]   i_alu_mem_srcdest_index_ff,
743
input                           i_alu_dav_ff,
744
input                           i_alu_mem_load_ff
745
);
746
begin
747
        determine_load_lock = 1'd0;
748
 
749
        // Look for that load instruction in the required pipeline stages. 
750
        // If found, we cannot issue the current instruction since old value 
751
        // will be read.
752
        if (
753
                ( index == o_mem_srcdest_index_ff          &&
754
                  o_condition_code_ff != NV                &&
755
                  o_mem_load_ff )                          ||
756
                ( index == i_shifter_mem_srcdest_index_ff  &&
757
                   i_alu_dav_nxt                           &&
758
                   i_shifter_mem_load_ff )                 ||
759
                (  index == i_alu_mem_srcdest_index_ff     &&
760
                   i_alu_dav_ff                            &&
761
                   i_alu_mem_load_ff )
762
        )
763
                determine_load_lock = 1'd1;
764
 
765
        // Locks occur only for indices...
766
        if ( index[32] == IMMED_EN || index == PHY_RAZ_REGISTER )
767
                determine_load_lock = 1'd0;
768
end
769
endfunction
770
 
771
endmodule // zap_issue_main.v
772
`default_nettype wire

powered by: WebSVN 2.1.0

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