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

Subversion Repositories thor

[/] [thor/] [trunk/] [rtl/] [verilog/] [Thor.v] - Blame information for rev 3

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

Line No. Rev Author Line
1 3 robfinch
//
2
//      COPYRIGHT 2000 by Bruce L. Jacob
3
//      (contact info: http://www.ece.umd.edu/~blj/)
4
//
5
//      You are welcome to use, modify, copy, and/or redistribute this implementation, provided:
6
//        1. you share with the author (Bruce Jacob) any changes you make;
7
//        2. you properly credit the author (Bruce Jacob) if used within a larger work; and
8
//        3. you do not modify, delete, or in any way obscure the implementation's copyright 
9
//           notice or following comments (i.e. the first 3-4 dozen lines of this file).
10
//
11
//      RiSC-16
12
//
13
//      This is an out-of-order implementation of the RiSC-16, a teaching instruction-set used by
14
//      the author at the University of Maryland, and which is a blatant (but sanctioned) rip-off
15
//      of the Little Computer (LC-896) developed by Peter Chen at the University of Michigan.
16
//      The primary differences include the following:
17
//        1. a move from 17-bit to 16-bit instructions; and
18
//        2. the replacement of the NOP and HALT opcodes by ADDI and LUI ... HALT and NOP are
19
//           now simply special instances of other instructions: NOP is a do-nothing ADD, and
20
//           HALT is a subset of JALR.
21
//
22
//      RiSC stands for Ridiculously Simple Computer, which makes sense in the context in which
23
//      the instruction-set is normally used -- to teach simple organization and architecture to
24
//      undergraduates who do not yet know how computers work.  This implementation was targetted
25
//      towards more advanced undergraduates doing design & implementation and was intended to 
26
//      demonstrate some high-performance concepts on a small scale -- an 8-entry reorder buffer,
27
//      eight opcodes, two ALUs, two-way issue, two-way commit, etc.  However, the out-of-order 
28
//      core is much more complex than I anticipated, and I hope that its complexity does not 
29
//      obscure its underlying structure.  We'll see how well it flies in class ...
30
//
31
//      CAVEAT FREELOADER: This Verilog implementation was developed and debugged in a (somewhat
32
//      frantic) 2-week period before the start of the Fall 2000 semester.  Not surprisingly, it
33
//      still contains many bugs and some horrible, horrible logic.  The logic is also written so
34
//      as to be debuggable and/or explain its function, rather than to be efficient -- e.g. in
35
//      several places, signals are over-constrained so that they are easy to read in the debug
36
//      output ... also, you will see statements like
37
//
38
//          if (xyz[`INSTRUCTION_OP] == `BEQ || xyz[`INSTRUCTION_OP] == `SW)
39
//
40
//      instead of and/nand combinations of bits ... sorry; can't be helped.  Use at your own risk.
41
//
42
//      DOCUMENTATION: Documents describing the RiSC-16 in all its forms (sequential, pipelined,
43
//      as well as out-of-order) can be found on the author's website at the following URL:
44
//
45
//          http://www.ece.umd.edu/~blj/RiSC/
46
//
47
//      If you do not find what you are looking for, please feel free to email me with suggestions
48
//      for more/different/modified documents.  Same goes for bug fixes.
49
//
50
//
51
//      KNOWN PROBLEMS (i.e., bugs I haven't got around to fixing yet)
52
//
53
//      - If the target of a backwards branch is a backwards branch, the fetchbuf steering logic
54
//        will get confused.  This can be fixed by having a separate did_branchback status register
55
//        for each of the fetch buffers.
56
//
57
// ============================================================================
58
//        __
59
//   \\__/ o\    (C) 2013,2015  Robert Finch, Stratford
60
//    \  __ /    All rights reserved.
61
//     \/_//     robfinch<remove>@finitron.ca
62
//       ||
63
//
64
// This source file is free software: you can redistribute it and/or modify 
65
// it under the terms of the GNU Lesser General Public License as published 
66
// by the Free Software Foundation, either version 3 of the License, or     
67
// (at your option) any later version.                                      
68
//                                                                          
69
// This source file is distributed in the hope that it will be useful,      
70
// but WITHOUT ANY WARRANTY; without even the implied warranty of           
71
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            
72
// GNU General Public License for more details.                             
73
//                                                                          
74
// You should have received a copy of the GNU General Public License        
75
// along with this program.  If not, see <http://www.gnu.org/licenses/>.    
76
//
77
//
78
// Thor Superscaler
79
//
80
// This work is starting with the RiSC-16 as noted in the copyright statement
81
// above. Hopefully it will be possible to run this processor in real hardware
82
// (FPGA) as opposed to just simulation. To the RiSC-16 are added:
83
//
84
//      64/32 bit datapath rather than 16 bit
85
//   64 general purpose registers
86
//   16 code address registers
87
//   16 predicate registers / predicated instruction execution
88
//    8 segment registers
89
//      A branch history table, and a (2,2) correlating branch predictor added
90
//      variable length instruction encodings (code density)
91
//      support for interrupts
92
//      The instruction set is changed completely with many new instructions.
93
//      An instruction and data cache were added.
94
//      A WISHBONE bus interface was added,
95
//
96
// 52,635 (84,500 LC's)
97
// with segmentation
98
// no bitfield, stack or FP ops
99
//
100
// ============================================================================
101
//
102
`include "Thor_defines.v"
103
 
104
module Thor(corenum, rst_i, clk_i, clk_o, km, nmi_i, irq_i, vec_i, bte_o, cti_o, bl_o, lock_o, resv_o, resv_i, cres_o,
105
    cyc_o, stb_o, ack_i, err_i, we_o, sel_o, adr_o, dat_i, dat_o);
106
parameter DBW = 32;         // databus width
107
parameter ABW = 32;         // address bus width
108
parameter RSTADDR = 64'hFFFFFFFFFFFFEFF0;
109
localparam AMSB = ABW-1;
110
parameter QENTRIES = 8;
111
parameter ALU1BIG = 0;
112
parameter RESET1 = 4'd0;
113
parameter RESET2 = 4'd1;
114
parameter IDLE = 4'd2;
115
parameter ICACHE1 = 4'd3;
116
parameter DCACHE1 = 4'd4;
117
parameter IBUF1 = 4'd5;
118
parameter IBUF2 = 4'd6;
119
parameter IBUF3 = 4'd7;
120
parameter IBUF4 = 4'd8;
121
parameter IBUF5 = 4'd9;
122
parameter NREGS = 127;
123
parameter PF = 4'd0;
124
parameter PT = 4'd1;
125
parameter PEQ = 4'd2;
126
parameter PNE = 4'd3;
127
parameter PLE = 4'd4;
128
parameter PGT = 4'd5;
129
parameter PGE = 4'd6;
130
parameter PLT = 4'd7;
131
parameter PLEU = 4'd8;
132
parameter PGTU = 4'd9;
133
parameter PGEU = 4'd10;
134
parameter PLTU = 4'd11;
135
input [63:0] corenum;
136
input rst_i;
137
input clk_i;
138
output clk_o;
139
output km;
140
input nmi_i;
141
input irq_i;
142
input [7:0] vec_i;
143
output reg [1:0] bte_o;
144
output reg [2:0] cti_o;
145
output reg [4:0] bl_o;
146
output reg lock_o;
147
output reg resv_o;
148
input resv_i;
149
output reg cres_o;
150
output reg cyc_o;
151
output reg stb_o;
152
input ack_i;
153
input err_i;
154
output reg we_o;
155
output reg [DBW/8-1:0] sel_o;
156
output reg [ABW-1:0] adr_o;
157
input [DBW-1:0] dat_i;
158
output reg [DBW-1:0] dat_o;
159
 
160
integer n,i;
161
reg [DBW/8-1:0] rsel;
162
reg [3:0] cstate;
163
reg [ABW+3:0] pc;                                // program counter (virtual)
164
wire [DBW-1:0] ppc;                              // physical pc address
165
reg [ABW-1:0] interrupt_pc;     // working register for interrupt pc
166
reg [DBW-1:0] vadr;                              // data virtual address
167
reg [3:0] panic;         // indexes the message structure
168
reg [128:0] message [0:15];       // indexed by panic
169
reg [DBW-1:0] cregs [0:15];               // code address registers
170
reg [ 3:0] pregs [0:15];          // predicate registers
171
`ifdef SEGMENTATION
172
reg [DBW-1:12] sregs [0:7];              // segment registers
173
reg [DBW-1:12] sregs_lmt [0:7];
174
`endif
175
reg [2:0] rrmapno;                               // register rename map number
176
wire ITLBMiss;
177
wire DTLBMiss;
178
wire uncached;
179
wire [DBW-1:0] cdat;
180
reg pwe;
181
wire [DBW-1:0] pea;
182
reg [DBW-1:0] tick;
183
reg [DBW-1:0] lc;                                // loop counter
184
reg [DBW-1:0] rfoa0,rfoa1;
185
reg [DBW-1:0] rfob0,rfob1;
186
reg [DBW-1:0] rfoc0,rfoc1;
187
reg [DBW-1:0] rfot0,rfot1;
188
reg ic_invalidate,dc_invalidate;
189
reg ic_invalidate_line,dc_invalidate_line;
190
reg [ABW-1:0] ic_lineno,dc_lineno;
191
reg ierr,derr;                                  // err_i during icache load
192
wire insnerr;                                   // err_i during icache load
193
wire [127:0] insn;
194
wire iuncached;
195
reg [NREGS:0] rf_v;
196
//reg [15:0] pf_v;
197
reg im,imb;
198
reg fxe;
199
reg nmi1,nmi_edge;
200
reg StatusHWI;
201
reg [7:0] StatusEXL;
202
assign km = StatusHWI | |StatusEXL;
203
reg [7:0] GM;            // register group mask
204
reg [7:0] GMB;
205
wire [63:0] sr = {32'd0,imb,7'b0,GMB,im,1'b0,km,fxe,4'b0,GM};
206
wire int_commit;
207
wire int_pending;
208
wire sys_commit;
209
`ifdef SEGMENTATION
210
wire [DBW-1:0] spc = (pc[ABW+3:ABW]==4'hF) ? pc[ABW-1:0] :
211
                     (pc[ABW-1:ABW-4]==4'hF) ? pc[ABW-1:0] : {sregs[7],12'h000} + pc[ABW-1:0];
212
`else
213
wire [DBW-1:0] spc = pc;
214
`endif
215
wire [DBW-1:0] ppcp16 = ppc + 64'd16;
216
reg [DBW-1:0] string_pc;
217
reg stmv_flag;
218
reg [7:0] asid;
219
 
220
wire clk;
221
 
222
// Operand registers
223
wire take_branch;
224
wire take_branch0;
225
wire take_branch1;
226
 
227
reg [3:0] rf_source [0:NREGS];
228
//reg [3:0] pf_source [15:0];
229
 
230
// instruction queue (ROB)
231
reg iq_cmt[0:7];
232
reg [7:0]  iqentry_v;                    // entry valid?  -- this should be the first bit
233
reg        iqentry_out  [0:7];   // instruction has been issued to an ALU ... 
234
reg        iqentry_done [0:7];   // instruction result valid
235
reg [7:0]  iqentry_cmt;                  // commit result to machine state
236
reg        iqentry_bt   [0:7];   // branch-taken (used only for branches)
237
reg        iqentry_agen [0:7];  // memory address is generated
238
reg        iqentry_mem  [0:7];   // touches memory: 1 if LW/SW
239
reg        iqentry_jmp  [0:7];   // changes control flow: 1 if BEQ/JALR
240
reg        iqentry_fp   [0:7];  // is an floating point operation
241
reg        iqentry_rfw  [0:7];   // writes to register file
242
reg [DBW-1:0] iqentry_res        [0:7];   // instruction result
243
reg  [3:0] iqentry_insnsz [0:7];  // the size of the instruction
244
reg  [3:0] iqentry_cond [0:7];    // predicating condition
245
reg  [3:0] iqentry_pred [0:7];    // predicate value
246
reg        iqentry_p_v  [0:7];   // predicate is valid
247
reg  [3:0] iqentry_p_s  [0:7];    // predicate source
248
reg  [7:0] iqentry_op    [0:7];   // instruction opcode
249
reg  [5:0] iqentry_fn   [0:7];  // instruction function
250
reg  [2:0] iqentry_renmapno [0:7];        // register rename map number
251
reg  [6:0] iqentry_tgt   [0:7];   // Rt field or ZERO -- this is the instruction's target (if any)
252
reg [DBW-1:0] iqentry_a0 [0:7];   // argument 0 (immediate)
253
reg [DBW-1:0] iqentry_a1 [0:7];   // argument 1
254
reg        iqentry_a1_v [0:7];   // arg1 valid
255
reg  [3:0] iqentry_a1_s  [0:7];   // arg1 source (iq entry # with top bit representing ALU/DRAM bus)
256
reg [DBW-1:0] iqentry_a2 [0:7];   // argument 2
257
reg        iqentry_a2_v [0:7];   // arg2 valid
258
reg  [3:0] iqentry_a2_s  [0:7];   // arg2 source (iq entry # with top bit representing ALU/DRAM bus)
259
reg [DBW-1:0] iqentry_a3 [0:7];   // argument 3
260
reg        iqentry_a3_v [0:7];   // arg3 valid
261
reg  [3:0] iqentry_a3_s  [0:7];   // arg3 source (iq entry # with top bit representing ALU/DRAM bus)
262
reg [DBW-1:0] iqentry_T [0:7];
263
reg        iqentry_T_v [0:7];
264
reg  [3:0] iqentry_T_s [0:7];
265
reg [DBW-1:0] iqentry_pc [0:7];   // program counter for this instruction
266
 
267
wire  iqentry_source [0:7];
268
wire  iqentry_imm [0:7];
269
wire  iqentry_memready [0:7];
270
wire  iqentry_memopsvalid [0:7];
271
reg qstomp;
272
 
273
wire stomp_all;
274
reg  [7:0] iqentry_fpissue;
275
reg  [7:0] iqentry_memissue;
276
wire iqentry_memissue_head0;
277
wire iqentry_memissue_head1;
278
wire iqentry_memissue_head2;
279
wire iqentry_memissue_head3;
280
wire iqentry_memissue_head4;
281
wire iqentry_memissue_head5;
282
wire iqentry_memissue_head6;
283
wire iqentry_memissue_head7;
284
wire  [7:0] iqentry_stomp;
285
reg  [7:0] iqentry_issue;
286
wire  [1:0] iqentry_0_islot;
287
wire  [1:0] iqentry_1_islot;
288
wire  [1:0] iqentry_2_islot;
289
wire  [1:0] iqentry_3_islot;
290
wire  [1:0] iqentry_4_islot;
291
wire  [1:0] iqentry_5_islot;
292
wire  [1:0] iqentry_6_islot;
293
wire  [1:0] iqentry_7_islot;
294
reg  [1:0] iqentry_islot[0:7];
295
reg [1:0] iqentry_fpislot[0:7];
296
 
297
reg queued1,queued2;
298
reg queued3;    // for three-way config
299
reg allowq;
300
 
301
wire  [NREGS:1] livetarget;
302
wire  [NREGS:1] iqentry_0_livetarget;
303
wire  [NREGS:1] iqentry_1_livetarget;
304
wire  [NREGS:1] iqentry_2_livetarget;
305
wire  [NREGS:1] iqentry_3_livetarget;
306
wire  [NREGS:1] iqentry_4_livetarget;
307
wire  [NREGS:1] iqentry_5_livetarget;
308
wire  [NREGS:1] iqentry_6_livetarget;
309
wire  [NREGS:1] iqentry_7_livetarget;
310
wire  [NREGS:1] iqentry_0_latestID;
311
wire  [NREGS:1] iqentry_1_latestID;
312
wire  [NREGS:1] iqentry_2_latestID;
313
wire  [NREGS:1] iqentry_3_latestID;
314
wire  [NREGS:1] iqentry_4_latestID;
315
wire  [NREGS:1] iqentry_5_latestID;
316
wire  [NREGS:1] iqentry_6_latestID;
317
wire  [NREGS:1] iqentry_7_latestID;
318
wire  [NREGS:1] iqentry_0_cumulative;
319
wire  [NREGS:1] iqentry_1_cumulative;
320
wire  [NREGS:1] iqentry_2_cumulative;
321
wire  [NREGS:1] iqentry_3_cumulative;
322
wire  [NREGS:1] iqentry_4_cumulative;
323
wire  [NREGS:1] iqentry_5_cumulative;
324
wire  [NREGS:1] iqentry_6_cumulative;
325
wire  [NREGS:1] iqentry_7_cumulative;
326
 
327
 
328
reg  [2:0] tail0;
329
reg  [2:0] tail1;
330
reg  [2:0] tail2;   // used only for three-way config
331
reg  [2:0] head0;
332
reg  [2:0] head1;
333
reg  [2:0] head2;        // used only to determine memory-access ordering
334
reg  [2:0] head3;        // used only to determine memory-access ordering
335
reg  [2:0] head4;        // used only to determine memory-access ordering
336
reg  [2:0] head5;        // used only to determine memory-access ordering
337
reg  [2:0] head6;        // used only to determine memory-access ordering
338
reg  [2:0] head7;        // used only to determine memory-access ordering
339
reg  [2:0] headinc;
340
 
341
wire  [2:0] missid;
342
reg   fetchbuf;         // determines which pair to read from & write to
343
 
344
reg  [63:0] fetchbuf0_instr;
345
reg  [DBW-1:0] fetchbuf0_pc;
346
reg         fetchbuf0_v;
347
wire        fetchbuf0_mem;
348
wire        fetchbuf0_jmp;
349
wire            fetchbuf0_fp;
350
wire        fetchbuf0_rfw;
351
wire        fetchbuf0_pfw;
352
reg  [63:0] fetchbuf1_instr;
353
reg  [DBW-1:0] fetchbuf1_pc;
354
reg        fetchbuf1_v;
355
wire        fetchbuf1_mem;
356
wire        fetchbuf1_jmp;
357
wire            fetchbuf1_fp;
358
wire        fetchbuf1_rfw;
359
wire        fetchbuf1_pfw;
360
wire        fetchbuf1_bfw;
361
reg  [63:0] fetchbuf2_instr;
362
reg  [DBW-1:0] fetchbuf2_pc;
363
reg        fetchbuf2_v;
364
wire        fetchbuf2_mem;
365
wire        fetchbuf2_jmp;
366
wire            fetchbuf2_fp;
367
wire        fetchbuf2_rfw;
368
wire        fetchbuf2_pfw;
369
wire        fetchbuf2_bfw;
370
 
371
reg [63:0] fetchbufA_instr;
372
reg [DBW-1:0] fetchbufA_pc;
373
reg        fetchbufA_v;
374
reg [63:0] fetchbufB_instr;
375
reg [DBW-1:0] fetchbufB_pc;
376
reg        fetchbufB_v;
377
reg [63:0] fetchbufC_instr;
378
reg [DBW-1:0] fetchbufC_pc;
379
reg        fetchbufC_v;
380
reg [63:0] fetchbufD_instr;
381
reg [DBW-1:0] fetchbufD_pc;
382
reg        fetchbufD_v;
383
 
384
reg        did_branchback;
385
reg             did_branchback0;
386
reg                     did_branchback1;
387
 
388
reg        alu0_ld;
389
reg        alu0_available;
390
reg        alu0_dataready;
391
reg  [3:0] alu0_sourceid;
392
reg  [3:0] alu0_insnsz;
393
reg  [7:0] alu0_op;
394
reg  [5:0] alu0_fn;
395
reg  [3:0] alu0_cond;
396
reg        alu0_bt;
397
reg        alu0_cmt;
398
reg [DBW-1:0] alu0_argA;
399
reg [DBW-1:0] alu0_argB;
400
reg [DBW-1:0] alu0_argC;
401
reg [DBW-1:0] alu0_argT;
402
reg [DBW-1:0] alu0_argI;
403
reg  [3:0] alu0_pred;
404
reg [DBW-1:0] alu0_pc;
405
reg [DBW-1:0] alu0_bus;
406
reg  [3:0] alu0_id;
407
wire  [3:0] alu0_exc;
408
reg        alu0_v;
409
wire        alu0_branchmiss;
410
reg [ABW+3:0] alu0_misspc;
411
 
412
reg        alu1_ld;
413
reg        alu1_available;
414
reg        alu1_dataready;
415
reg  [3:0] alu1_sourceid;
416
reg  [3:0] alu1_insnsz;
417
reg  [7:0] alu1_op;
418
reg  [5:0] alu1_fn;
419
reg  [3:0] alu1_cond;
420
reg        alu1_bt;
421
reg        alu1_cmt;
422
reg [DBW-1:0] alu1_argA;
423
reg [DBW-1:0] alu1_argB;
424
reg [DBW-1:0] alu1_argC;
425
reg [DBW-1:0] alu1_argT;
426
reg [DBW-1:0] alu1_argI;
427
reg  [3:0] alu1_pred;
428
reg [DBW-1:0] alu1_pc;
429
reg [DBW-1:0] alu1_bus;
430
reg  [3:0] alu1_id;
431
wire  [3:0] alu1_exc;
432
reg        alu1_v;
433
wire        alu1_branchmiss;
434
reg [ABW+3:0] alu1_misspc;
435
 
436
wire mem_stringmiss;
437
wire        branchmiss;
438
wire [ABW+3:0] misspc;
439
 
440
`ifdef FLOATING_POINT
441
reg        fp0_ld;
442
reg        fp0_available;
443
reg        fp0_dataready;
444
reg  [3:0] fp0_sourceid;
445
reg  [7:0] fp0_op;
446
reg  [5:0] fp0_fn;
447
reg  [3:0] fp0_cond;
448
wire        fp0_cmt;
449
reg             fp0_done;
450
reg [DBW-1:0] fp0_argA;
451
reg [DBW-1:0] fp0_argB;
452
reg [DBW-1:0] fp0_argC;
453
reg [DBW-1:0] fp0_argI;
454
reg  [3:0] fp0_pred;
455
reg [DBW-1:0] fp0_pc;
456
wire [DBW-1:0] fp0_bus;
457
wire  [3:0] fp0_id;
458
wire  [7:0] fp0_exc;
459
wire        fp0_v;
460
`endif
461
 
462
wire        dram_avail;
463
reg      [2:0] dram0;    // state of the DRAM request (latency = 4; can have three in pipeline)
464
reg      [2:0] dram1;    // state of the DRAM request (latency = 4; can have three in pipeline)
465
reg      [2:0] dram2;    // state of the DRAM request (latency = 4; can have three in pipeline)
466
reg  [2:0] tlb_state;
467
reg [3:0] tlb_id;
468
reg [3:0] tlb_op;
469
reg [3:0] tlb_regno;
470
reg [8:0] tlb_tgt;
471
reg [DBW-1:0] tlb_data;
472
 
473
wire [DBW-1:0] tlb_dato;
474
reg dram0_owns_bus;
475
reg [DBW-1:0] dram0_data;
476
reg [DBW-1:0] dram0_datacmp;
477
reg [DBW-1:0] dram0_addr;
478
reg [DBW-1:0] dram0_seg;        // value of segment register associated with memory operation
479
reg [ABW-1:12] dram0_lmt;       // value of segment limit associated with memory operation
480
reg  [7:0] dram0_op;
481
reg  [5:0] dram0_fn;
482
reg  [8:0] dram0_tgt;
483
reg  [3:0] dram0_id;
484
reg  [3:0] dram0_exc;
485
reg dram1_owns_bus;
486
reg [DBW-1:0] dram1_data;
487
reg [DBW-1:0] dram1_datacmp;
488
reg [DBW-1:0] dram1_addr;
489
reg  [7:0] dram1_op;
490
reg  [5:0] dram1_fn;
491
reg  [6:0] dram1_tgt;
492
reg  [3:0] dram1_id;
493
reg  [3:0] dram1_exc;
494
reg [DBW-1:0] dram2_data;
495
reg [DBW-1:0] dram2_datacmp;
496
reg [DBW-1:0] dram2_addr;
497
reg  [7:0] dram2_op;
498
reg  [5:0] dram2_fn;
499
reg  [6:0] dram2_tgt;
500
reg  [3:0] dram2_id;
501
reg  [3:0] dram2_exc;
502
 
503
reg [DBW-1:0] dram_bus;
504
reg  [6:0] dram_tgt;
505
reg  [3:0] dram_id;
506
reg  [3:0] dram_exc;
507
reg        dram_v;
508
 
509
reg [DBW-1:0] index;
510
reg [DBW-1:0] src_addr,dst_addr;
511
wire mem_issue;
512
 
513
wire        outstanding_stores;
514
reg [DBW-1:0] I; // instruction count
515
 
516
wire        commit0_v;
517
wire  [3:0] commit0_id;
518
wire  [6:0] commit0_tgt;
519
wire [DBW-1:0] commit0_bus;
520
wire        commit1_v;
521
wire  [3:0] commit1_id;
522
wire  [6:0] commit1_tgt;
523
wire [DBW-1:0] commit1_bus;
524
wire limit_cmt;
525
wire committing2;
526
 
527
wire [63:0] alu0_divq;
528
wire [63:0] alu0_rem;
529
wire alu0_div_done;
530
 
531
wire [63:0] alu1_divq;
532
wire [63:0] alu1_rem;
533
wire alu1_div_done;
534
 
535
wire [127:0] alu0_prod;
536
wire alu0_mult_done;
537
wire [127:0] alu1_prod;
538
wire alu1_mult_done;
539
 
540
//-----------------------------------------------------------------------------
541
// Debug
542
//-----------------------------------------------------------------------------
543
 
544
wire [DBW-1:0] dbg_stat;
545
reg [DBW-1:0] dbg_ctrl;
546
reg [ABW-1:0] dbg_adr0;
547
reg [ABW-1:0] dbg_adr1;
548
reg [ABW-1:0] dbg_adr2;
549
reg [ABW-1:0] dbg_adr3;
550
reg dbg_imatchA0,dbg_imatchA1,dbg_imatchA2,dbg_imatchA3,dbg_imatchA;
551
reg dbg_imatchB0,dbg_imatchB1,dbg_imatchB2,dbg_imatchB3,dbg_imatchB;
552
 
553
wire dbg_lmatch0 =
554
                        dbg_ctrl[0] && dbg_ctrl[17:16]==2'b11 && dram0_addr[AMSB:3]==dbg_adr0[AMSB:3] &&
555
                                ((dbg_ctrl[19:18]==2'b00 && dram0_addr[2:0]==dbg_adr0[2:0]) ||
556
                                 (dbg_ctrl[19:18]==2'b01 && dram0_addr[2:1]==dbg_adr0[2:1]) ||
557
                                 (dbg_ctrl[19:18]==2'b10 && dram0_addr[2]==dbg_adr0[2]) ||
558
                                 dbg_ctrl[19:18]==2'b11)
559
                                 ;
560
wire dbg_lmatch1 =
561
             dbg_ctrl[1] && dbg_ctrl[21:20]==2'b11 && dram0_addr[AMSB:3]==dbg_adr1[AMSB:3] &&
562
                 ((dbg_ctrl[23:22]==2'b00 && dram0_addr[2:0]==dbg_adr1[2:0]) ||
563
                  (dbg_ctrl[23:22]==2'b01 && dram0_addr[2:1]==dbg_adr1[2:1]) ||
564
                  (dbg_ctrl[23:22]==2'b10 && dram0_addr[2]==dbg_adr1[2]) ||
565
                  dbg_ctrl[23:22]==2'b11)
566
                  ;
567
wire dbg_lmatch2 =
568
               dbg_ctrl[2] && dbg_ctrl[25:24]==2'b11 && dram0_addr[AMSB:3]==dbg_adr2[AMSB:3] &&
569
                   ((dbg_ctrl[27:26]==2'b00 && dram0_addr[2:0]==dbg_adr2[2:0]) ||
570
                    (dbg_ctrl[27:26]==2'b01 && dram0_addr[2:1]==dbg_adr2[2:1]) ||
571
                    (dbg_ctrl[27:26]==2'b10 && dram0_addr[2]==dbg_adr2[2]) ||
572
                    dbg_ctrl[27:26]==2'b11)
573
                    ;
574
wire dbg_lmatch3 =
575
                 dbg_ctrl[3] && dbg_ctrl[29:28]==2'b11 && dram0_addr[AMSB:3]==dbg_adr3[AMSB:3] &&
576
                     ((dbg_ctrl[31:30]==2'b00 && dram0_addr[2:0]==dbg_adr3[2:0]) ||
577
                      (dbg_ctrl[31:30]==2'b01 && dram0_addr[2:1]==dbg_adr3[2:1]) ||
578
                      (dbg_ctrl[31:30]==2'b10 && dram0_addr[2]==dbg_adr3[2]) ||
579
                      dbg_ctrl[31:30]==2'b11)
580
                      ;
581
wire dbg_lmatch = dbg_lmatch0|dbg_lmatch1|dbg_lmatch2|dbg_lmatch3;
582
 
583
wire dbg_smatch0 =
584
                        dbg_ctrl[0] && dbg_ctrl[17:16]==2'b11 && dram0_addr[AMSB:3]==dbg_adr0[AMSB:3] &&
585
                                ((dbg_ctrl[19:18]==2'b00 && dram0_addr[2:0]==dbg_adr0[2:0]) ||
586
                                 (dbg_ctrl[19:18]==2'b01 && dram0_addr[2:1]==dbg_adr0[2:1]) ||
587
                                 (dbg_ctrl[19:18]==2'b10 && dram0_addr[2]==dbg_adr0[2]) ||
588
                                 dbg_ctrl[19:18]==2'b11)
589
                                 ;
590
wire dbg_smatch1 =
591
             dbg_ctrl[1] && dbg_ctrl[21:20]==2'b11 && dram0_addr[AMSB:3]==dbg_adr1[AMSB:3] &&
592
                 ((dbg_ctrl[23:22]==2'b00 && dram0_addr[2:0]==dbg_adr1[2:0]) ||
593
                  (dbg_ctrl[23:22]==2'b01 && dram0_addr[2:1]==dbg_adr1[2:1]) ||
594
                  (dbg_ctrl[23:22]==2'b10 && dram0_addr[2]==dbg_adr1[2]) ||
595
                  dbg_ctrl[23:22]==2'b11)
596
                  ;
597
wire dbg_smatch2 =
598
               dbg_ctrl[2] && dbg_ctrl[25:24]==2'b11 && dram0_addr[AMSB:3]==dbg_adr2[AMSB:3] &&
599
                   ((dbg_ctrl[27:26]==2'b00 && dram0_addr[2:0]==dbg_adr2[2:0]) ||
600
                    (dbg_ctrl[27:26]==2'b01 && dram0_addr[2:1]==dbg_adr2[2:1]) ||
601
                    (dbg_ctrl[27:26]==2'b10 && dram0_addr[2]==dbg_adr2[2]) ||
602
                    dbg_ctrl[27:26]==2'b11)
603
                    ;
604
wire dbg_smatch3 =
605
                 dbg_ctrl[3] && dbg_ctrl[29:28]==2'b11 && dram0_addr[AMSB:3]==dbg_adr3[AMSB:3] &&
606
                     ((dbg_ctrl[31:30]==2'b00 && dram0_addr[2:0]==dbg_adr3[2:0]) ||
607
                      (dbg_ctrl[31:30]==2'b01 && dram0_addr[2:1]==dbg_adr3[2:1]) ||
608
                      (dbg_ctrl[31:30]==2'b10 && dram0_addr[2]==dbg_adr3[2]) ||
609
                      dbg_ctrl[31:30]==2'b11)
610
                      ;
611
wire dbg_smatch = dbg_smatch0|dbg_smatch1|dbg_smatch2|dbg_smatch3;
612
 
613
wire dbg_stat0 = dbg_imatchA0 | dbg_imatchB0 | dbg_lmatch0 | dbg_smatch0;
614
wire dbg_stat1 = dbg_imatchA1 | dbg_imatchB1 | dbg_lmatch1 | dbg_smatch1;
615
wire dbg_stat2 = dbg_imatchA2 | dbg_imatchB2 | dbg_lmatch2 | dbg_smatch2;
616
wire dbg_stat3 = dbg_imatchA3 | dbg_imatchB3 | dbg_lmatch3 | dbg_smatch3;
617
assign dbg_stat = {dbg_stat3,dbg_stat2,dbg_stat1,dbg_stat0};
618
 
619
 
620
reg [11:0] spr_bir;
621
 
622
//
623
// BRANCH-MISS LOGIC: livetarget
624
//
625
// livetarget implies that there is a not-to-be-stomped instruction that targets the register in question
626
// therefore, if it is zero it implies the rf_v value should become VALID on a branchmiss
627
// 
628
 
629
Thor_livetarget #(NREGS) ultgt1
630
(
631
        iqentry_v,
632
        iqentry_stomp,
633
        iqentry_cmt,
634
        iqentry_tgt[0],
635
        iqentry_tgt[1],
636
        iqentry_tgt[2],
637
        iqentry_tgt[3],
638
        iqentry_tgt[4],
639
        iqentry_tgt[5],
640
        iqentry_tgt[6],
641
        iqentry_tgt[7],
642
        livetarget,
643
        iqentry_0_livetarget,
644
        iqentry_1_livetarget,
645
        iqentry_2_livetarget,
646
        iqentry_3_livetarget,
647
        iqentry_4_livetarget,
648
        iqentry_5_livetarget,
649
        iqentry_6_livetarget,
650
        iqentry_7_livetarget
651
);
652
 
653
//
654
// BRANCH-MISS LOGIC: latestID
655
//
656
// latestID is the instruction queue ID of the newest instruction (latest) that targets
657
// a particular register.  looks a lot like scheduling logic, but in reverse.
658
// 
659
 
660
assign iqentry_0_latestID = ((missid == 3'd0)|| ((iqentry_0_livetarget & iqentry_1_cumulative) == {NREGS{1'b0}}))
661
                                ? iqentry_0_livetarget
662
                                : {NREGS{1'b0}};
663
assign iqentry_0_cumulative = (missid == 3'd0)
664
                                ? iqentry_0_livetarget
665
                                : iqentry_0_livetarget | iqentry_1_cumulative;
666
 
667
assign iqentry_1_latestID = ((missid == 3'd1)|| ((iqentry_1_livetarget & iqentry_2_cumulative) == {NREGS{1'b0}}))
668
                                ? iqentry_1_livetarget
669
                                : {NREGS{1'b0}};
670
assign iqentry_1_cumulative = (missid == 3'd1)
671
                                ? iqentry_1_livetarget
672
                                : iqentry_1_livetarget | iqentry_2_cumulative;
673
 
674
assign iqentry_2_latestID = ((missid == 3'd2) || ((iqentry_2_livetarget & iqentry_3_cumulative) == {NREGS{1'b0}}))
675
                                ? iqentry_2_livetarget
676
                                : {NREGS{1'b0}};
677
assign iqentry_2_cumulative = (missid == 3'd2)
678
                                ? iqentry_2_livetarget
679
                                : iqentry_2_livetarget | iqentry_3_cumulative;
680
 
681
assign iqentry_3_latestID = ((missid == 3'd3)|| ((iqentry_3_livetarget & iqentry_4_cumulative) == {NREGS{1'b0}}))
682
                                ? iqentry_3_livetarget
683
                                : {NREGS{1'b0}};
684
assign iqentry_3_cumulative = (missid == 3'd3)
685
                                ? iqentry_3_livetarget
686
                                : iqentry_3_livetarget | iqentry_4_cumulative;
687
 
688
assign iqentry_4_latestID = ((missid == 3'd4) || ((iqentry_4_livetarget & iqentry_5_cumulative) == {NREGS{1'b0}}))
689
                                ? iqentry_4_livetarget
690
                                : {NREGS{1'b0}};
691
assign iqentry_4_cumulative = (missid == 3'd4)
692
                                ? iqentry_4_livetarget
693
                                : iqentry_4_livetarget | iqentry_5_cumulative;
694
 
695
assign iqentry_5_latestID = ((missid == 3'd5)|| ((iqentry_5_livetarget & iqentry_6_cumulative) == {NREGS{1'b0}}))
696
                                ? iqentry_5_livetarget
697
                                : 287'd0;
698
assign iqentry_5_cumulative = (missid == 3'd5)
699
                                ? iqentry_5_livetarget
700
                                : iqentry_5_livetarget | iqentry_6_cumulative;
701
 
702
assign iqentry_6_latestID = ((missid == 3'd6) || ((iqentry_6_livetarget & iqentry_7_cumulative) == {NREGS{1'b0}}))
703
                                ? iqentry_6_livetarget
704
                                : {NREGS{1'b0}};
705
assign iqentry_6_cumulative = (missid == 3'd6)
706
                                ? iqentry_6_livetarget
707
                                : iqentry_6_livetarget | iqentry_7_cumulative;
708
 
709
assign iqentry_7_latestID = ((missid == 3'd7) || ((iqentry_7_livetarget & iqentry_0_cumulative) == {NREGS{1'b0}}))
710
                                ? iqentry_7_livetarget
711
                                : {NREGS{1'b0}};
712
assign iqentry_7_cumulative = (missid==3'd7)
713
                                ? iqentry_7_livetarget
714
                                : iqentry_7_livetarget | iqentry_0_cumulative;
715
 
716
assign
717
        iqentry_source[0] = | iqentry_0_latestID,
718
        iqentry_source[1] = | iqentry_1_latestID,
719
        iqentry_source[2] = | iqentry_2_latestID,
720
        iqentry_source[3] = | iqentry_3_latestID,
721
        iqentry_source[4] = | iqentry_4_latestID,
722
        iqentry_source[5] = | iqentry_5_latestID,
723
        iqentry_source[6] = | iqentry_6_latestID,
724
        iqentry_source[7] = | iqentry_7_latestID;
725
 
726
 
727
//assign iqentry_0_islot = iqentry_islot[0];
728
//assign iqentry_1_islot = iqentry_islot[1];
729
//assign iqentry_2_islot = iqentry_islot[2];
730
//assign iqentry_3_islot = iqentry_islot[3];
731
//assign iqentry_4_islot = iqentry_islot[4];
732
//assign iqentry_5_islot = iqentry_islot[5];
733
//assign iqentry_6_islot = iqentry_islot[6];
734
//assign iqentry_7_islot = iqentry_islot[7];
735
 
736
// A single instruction can require 3 read ports. Only a total of four read
737
// ports are supported because most of the time that's enough.
738
// If there aren't enough read ports available then the second instruction
739
// isn't enqueued (it'll be enqueued in the next cycle).
740
reg [1:0] ports_avail;  // available read ports for instruction #3.
741
reg [6:0] pRa0,pRb0,pRa1,pRb1,pRt0,pRt1;
742
wire [DBW-1:0] prfoa0,prfob0,prfoa1,prfob1;
743
wire [DBW-1:0] prfot0,prfot1;
744
 
745
wire [6:0] Ra0 = fnRa(fetchbuf0_instr);
746
wire [6:0] Rb0 = fnRb(fetchbuf0_instr);
747
wire [6:0] Rc0 = fnRc(fetchbuf0_instr);
748
wire [6:0] Ra1 = fnRa(fetchbuf1_instr);
749
wire [6:0] Rb1 = fnRb(fetchbuf1_instr);
750
wire [6:0] Rc1 = fnRc(fetchbuf1_instr);
751
wire [6:0] Rt0 = fnTargetReg(fetchbuf0_instr);
752
wire [6:0] Rt1 = fnTargetReg(fetchbuf1_instr);
753
always @*
754
begin
755
    pRt0 = Rt0;
756
    pRt1 = Rt1;
757
    rfot0 = prfot0;
758
    rfot1 = prfot1;
759
    case(fetchbuf0_v ? fnNumReadPorts(fetchbuf0_instr) : 2'd0)
760
    2'd0:   begin
761
            pRa0 = 7'd0;
762
            pRb0 = Rc1;
763
            pRa1 = Ra1;
764
            pRb1 = Rb1;
765
            rfoa0 = 64'd0;
766
            rfob0 = 64'd0;
767
            rfoc0 = 64'd0;
768
            rfoa1 = prfoa1;
769
            rfob1 = prfob1;
770
            rfoc1 = prfob0;
771
            ports_avail = 2'd3;
772
            end
773
    2'd1:   begin
774
            pRa0 = Ra0;
775
            pRb0 = Rc1;
776
            pRa1 = Ra1;
777
            pRb1 = Rb1;
778
            rfoa0 = prfoa0;
779
            rfob0 = 64'd0;
780
            rfoc0 = 64'd0;
781
            rfoa1 = prfoa1;
782
            rfob1 = prfob1;
783
            rfoc1 = prfob0;
784
            ports_avail = 2'd3;
785
            end
786
    2'd2:   begin
787
            pRa0 = Ra0;
788
            pRb0 = Rb0;
789
            pRa1 = Ra1;
790
            pRb1 = Rb1;
791
            rfoa0 = prfoa0;
792
            rfob0 = prfob0;
793
            rfoc0 = 64'd0;
794
            rfoa1 = prfoa1;
795
            rfob1 = prfob1;
796
            rfoc1 = 64'd0;
797
            ports_avail = 2'd2;
798
            end
799
    2'd3:   begin
800
            pRa0 = Ra0;
801
            pRb0 = Rb0;
802
            pRa1 = Rc0;
803
            pRb1 = Ra1;
804
            rfoa0 = prfoa0;
805
            rfob0 = prfob0;
806
            rfoc0 = prfoa1;
807
            rfoa1 = prfob1;
808
            rfob1 = 64'd0;
809
            rfoc1 = 64'd0;
810
            ports_avail = 2'd1;
811
            end
812
    endcase
813
end
814
 
815
/*
816
wire [8:0] Rb0 = ((fnNumReadPorts(fetchbuf0_instr) < 3'd2) || !fetchbuf0_v) ? {1'b0,fetchbuf1_instr[`INSTRUCTION_RC]} :
817
                                fnRb(fetchbuf0_instr);
818
wire [8:0] Ra1 = (!fetchbuf0_v || fnNumReadPorts(fetchbuf0_instr) < 3'd3) ? fnRa(fetchbuf1_instr) :
819
                                        fetchbuf0_instr[`INSTRUCTION_RC];
820
wire [8:0] Rb1 = (fnNumReadPorts(fetchbuf1_instr) < 3'd2 && fetchbuf0_v) ? fnRa(fetchbuf1_instr):fnRb(fetchbuf1_instr);
821
*/
822
function [7:0] fnOpcode;
823
input [63:0] ins;
824
fnOpcode = (ins[3:0]==4'h0 && ins[7:4] > 4'h1 && ins[7:4] < 4'h9) ? `IMM :
825
                                                ins[7:0]==8'h10 ? `NOP :
826
                                                ins[7:0]==8'h11 ? `RTS : ins[15:8];
827
endfunction
828
 
829
wire [7:0] opcode0 = fnOpcode(fetchbuf0_instr);
830
wire [7:0] opcode1 = fnOpcode(fetchbuf1_instr);
831
wire [3:0] cond0 = fetchbuf0_instr[3:0];
832
wire [3:0] cond1 = fetchbuf1_instr[3:0];
833
wire [3:0] Pn0 = fetchbuf0_instr[7:4];
834
wire [3:0] Pt0 = fetchbuf0_instr[11:8];
835
wire [3:0] Pn1 = fetchbuf1_instr[7:4];
836
wire [3:0] Pt1 = fetchbuf1_instr[11:8];
837
 
838
function [6:0] fnRa;
839
input [63:0] insn;
840
case(insn[7:0])
841
8'h11:  fnRa = 7'h51;    // RTS short form
842
default:
843
        case(insn[15:8])
844
        `RTI:   fnRa = 7'h5E;
845
        `RTD:   fnRa = 7'h5B;
846
        `RTE:   fnRa = 7'h5D;
847
        `JSR,`JSRS,`JSRZ,`SYS,`INT,`RTS,`RTS2:
848
                fnRa = {3'h5,insn[23:20]};
849
        `TLB:  fnRa = {1'b0,insn[29:24]};
850
        `P:    fnRa = 7'h70;
851
//      `PUSH,`PEA,`POP,`LINK:   fnRa = 7'd27;
852
        default:        fnRa = {1'b0,insn[`INSTRUCTION_RA]};
853
        endcase
854
endcase
855
endfunction
856
 
857
function [6:0] fnRb;
858
input [63:0] insn;
859
if (insn[7:0]==8'h11)    // RTS short form
860
        fnRb = 7'h51;
861
else
862
        case(insn[15:8])
863
        `RTI:   fnRb = 7'h5E;
864
        `RTD:   fnRb = 7'h5B;
865
        `RTE:   fnRb = 7'h5D;
866
        `RTS2:  fnRb = 7'd27;
867
        `RTS,`STP,`TLB,`POP:   fnRb = 7'd0;
868
        `LOOP:  fnRb = 7'h73;
869
        `JSR,`JSRS,`JSRZ,`SYS,`INT:
870
                fnRb = {3'h5,insn[23:20]};
871
        `SWS:   fnRb = {1'b1,insn[27:22]};
872
`ifdef STACKOPS
873
        `PUSH:  fnRb = insn[22:16];
874
        `LINK:  fnRb = {1'b0,insn[27:22]};
875
        `PEA:   fnRb = {1'b0,insn[21:16]};
876
`endif
877
        default:        fnRb = {1'b0,insn[`INSTRUCTION_RB]};
878
        endcase
879
endfunction
880
 
881
function [6:0] fnRc;
882
input [63:0] insn;
883
fnRc = {1'b0,insn[`INSTRUCTION_RC]};
884
endfunction
885
 
886
function [3:0] fnCar;
887
input [63:0] insn;
888
if (insn[7:0]==8'h11)    // RTS short form
889
        fnCar = 4'h1;
890
else
891
        case(insn[15:8])
892
        `RTI:   fnCar = 4'hE;
893
        `RTD:   fnCar = 4'hB;
894
        `RTE:   fnCar = 4'hD;
895
        `JSR,`JSRS,`JSRZ,`SYS,`INT,`RTS,`RTS2:
896
                fnCar = {insn[23:20]};
897
        default:        fnCar = 4'h0;
898
        endcase
899
endfunction
900
 
901
function [5:0] fnFunc;
902
input [63:0] insn;
903
if (insn[7:0]==8'h11)   // RTS short form
904
    fnFunc = 6'h00;     // func is used as a small immediate
905
else
906
casex(insn[15:8])
907
`BITFIELD:      fnFunc = insn[43:40];
908
`CMP:   fnFunc = insn[31:28];
909
`TST:   fnFunc = insn[23:22];
910
`INC:   fnFunc = insn[24:22];
911
`RTS,`RTS2: fnFunc = insn[19:16];   // used to pass a small immediate
912
`CACHE: fnFunc = insn[31:26];
913
default:
914
        fnFunc = insn[39:34];
915
endcase
916
endfunction
917
 
918
// Returns true if the operation is limited to ALU #0
919
function fnIsAlu0Op;
920
input [7:0] opcode;
921
input [5:0] func;
922
case(opcode)
923
`R:
924
    case(func)
925
    `CNTLZ,`CNTLO,`CNTPOP:  fnIsAlu0Op = `TRUE;
926
    `ABS,`SGN,`ZXB,`ZXC,`ZXH,`SXB,`SXC,`SXH:  fnIsAlu0Op = `TRUE;
927
    default:    fnIsAlu0Op = `FALSE;
928
    endcase
929
`RR:
930
    case(func)
931
    `DIV,`DIVU: fnIsAlu0Op = `TRUE;
932
    `MIN,`MAX:  fnIsAlu0Op = `TRUE;
933
    default:    fnIsAlu0Op = `FALSE;
934
    endcase
935
`BCD:       fnIsAlu0Op = `TRUE;
936
`DIVI,`DIVUI:   fnIsAlu0Op = `TRUE;
937
//`DOUBLE:    fnIsAlu0Op = `TRUE;
938
`SHIFT:     fnIsAlu0Op = `TRUE;
939
`BITFIELD:  fnIsAlu0Op = `TRUE;
940
default:    fnIsAlu0Op = `FALSE;
941
endcase
942
endfunction
943
 
944
// Returns TRUE if the alu will be valid immediately
945
//
946
function fnAluValid;
947
input [7:0] opcode;
948
input [5:0] func;
949
case(opcode)
950
`R: fnAluValid = `TRUE;
951
`RR:
952
    case(func)
953
    `MUL,`MULU,`DIV,`DIVU: fnAluValid = `FALSE;
954
    default:    fnAluValid = `TRUE;
955
    endcase
956
`MULI,`MULUI,`DIVI,`DIVUI:   fnAluValid = `FALSE;
957
default:    fnAluValid = `TRUE;
958
endcase
959
endfunction
960
 
961
Thor_regfile2w6r #(DBW) urf1
962
(
963
        .clk(clk),
964
        .rclk(~clk),
965
        .wr0(commit0_v && ~commit0_tgt[6] && iqentry_op[head0]!=`MTSPR),
966
        .wr1(commit1_v && ~commit1_tgt[6] && iqentry_op[head1]!=`MTSPR),
967
        .wa0(commit0_tgt[5:0]),
968
        .wa1(commit1_tgt[5:0]),
969
        .ra0(pRa0[5:0]),
970
        .ra1(pRb0[5:0]),
971
        .ra2(pRa1[5:0]),
972
        .ra3(pRb1[5:0]),
973
        .ra4(pRt0[5:0]),
974
        .ra5(pRt1[5:0]),
975
        .i0(commit0_bus),
976
        .i1(commit1_bus),
977
        .o0(prfoa0),
978
        .o1(prfob0),
979
        .o2(prfoa1),
980
        .o3(prfob1),
981
        .o4(prfot0),
982
        .o5(prfot1)
983
);
984
 
985
wire [63:0] cregs0 = fnCar(fetchbuf0_instr)==4'd0 ? 64'd0 : fnCar(fetchbuf0_instr)==4'hF ? fetchbuf0_pc : cregs[fnCar(fetchbuf0_instr)];
986
wire [63:0] cregs1 = fnCar(fetchbuf1_instr)==4'd0 ? 64'd0 : fnCar(fetchbuf1_instr)==4'hF ? fetchbuf1_pc : cregs[fnCar(fetchbuf1_instr)];
987
//
988
// 1 if the the operand is automatically valid, 
989
// 0 if we need a RF value
990
function fnSource1_v;
991
input [7:0] opcode;
992
        casex(opcode)
993
        `SEI,`CLI,`MEMSB,`MEMDB,`SYNC,`NOP,`STP:
994
                                        fnSource1_v = 1'b1;
995
        `BR,`LOOP:              fnSource1_v = 1'b1;
996
        `LDI,`LDIS,`IMM:        fnSource1_v = 1'b1;
997
        default:                fnSource1_v = 1'b0;
998
        endcase
999
endfunction
1000
 
1001
//
1002
// 1 if the the operand is automatically valid, 
1003
// 0 if we need a RF value
1004
function fnSource2_v;
1005
input [7:0] opcode;
1006
input [5:0] func;
1007
        casex(opcode)
1008
        `R,`P:          fnSource2_v = 1'b1;
1009
        `LDI,`STI,`LDIS,`IMM,`NOP,`STP:         fnSource2_v = 1'b1;
1010
        `SEI,`CLI,`MEMSB,`MEMDB,`SYNC:
1011
                                        fnSource2_v = 1'b1;
1012
        `RTI,`RTD,`RTE: fnSource2_v = 1'b1;
1013
        `TST:                   fnSource2_v = 1'b1;
1014
        `ADDI,`ADDUI,`ADDUIS:
1015
                        fnSource2_v = 1'b1;
1016
        `_2ADDUI,`_4ADDUI,`_8ADDUI,`_16ADDUI:
1017
                                        fnSource2_v = 1'b1;
1018
        `SUBI,`SUBUI:   fnSource2_v = 1'b1;
1019
        `CMPI:                  fnSource2_v = 1'b1;
1020
        `MULI,`MULUI,`DIVI,`DIVUI:
1021
                                        fnSource2_v = 1'b1;
1022
        `ANDI,`BITI:    fnSource2_v = 1'b1;
1023
        `ORI:                   fnSource2_v = 1'b1;
1024
        `EORI:                  fnSource2_v = 1'b1;
1025
        `SHIFT:
1026
                   if (func>=6'h10)
1027
                       fnSource2_v = `TRUE;
1028
                   else
1029
                       fnSource2_v = `FALSE;
1030
        `CACHE,`LCL,`TLB,
1031
        `LVB,`LVC,`LVH,`LVW,`LVWAR,
1032
        `LB,`LBU,`LC,`LCU,`LH,`LHU,`LW,`LWS,`LEA,`STI,`INC:
1033
                        fnSource2_v = 1'b1;
1034
        `JSR,`JSRS,`JSRZ,`SYS,`INT,`RTS,`BR:
1035
                        fnSource2_v = 1'b1;
1036
        `MTSPR,`MFSPR,`POP,`UNLINK:
1037
                                fnSource2_v = 1'b1;
1038
//      `BFSET,`BFCLR,`BFCHG,`BFEXT,`BFEXTU:    // but not BFINS
1039
//                              fnSource2_v = 1'b1;
1040
        default:        fnSource2_v = 1'b0;
1041
        endcase
1042
endfunction
1043
 
1044
 
1045
// Source #3 valid
1046
// Since most instructions don't use a third source the default it to return 
1047
// a valid status.
1048
// 1 if the the operand is automatically valid, 
1049
// 0 if we need a RF value
1050
function fnSource3_v;
1051
input [7:0] opcode;
1052
        casex(opcode)
1053
        `SBX,`SCX,`SHX,`SWX,`CAS,`STMV,`STCMP,`STFND:   fnSource3_v = 1'b0;
1054
        `MUX:   fnSource3_v = 1'b0;
1055
        default:        fnSource3_v = 1'b1;
1056
        endcase
1057
endfunction
1058
 
1059
function fnSourceT_v;
1060
input [7:0] opcode;
1061
    casex(opcode)
1062
    `BR,
1063
    `SB,`SC,`SH,`SW,`SBX,`SCX,`SHX,`SWX,`SWS,
1064
    `CACHE,
1065
    `SEI,`CLI,`NOP,`STP,
1066
    `MEMSB,`MEMDB,`SYNC:
1067
            fnSourceT_v = 1'b1;
1068
    default:    fnSourceT_v = 1'b0;
1069
    endcase
1070
endfunction
1071
 
1072
// Return the number of register read ports required for an instruction.
1073
function [2:0] fnNumReadPorts;
1074
input [63:0] ins;
1075
casex(fnOpcode(ins))
1076
`SEI,`CLI,`MEMSB,`MEMDB,`SYNC,`NOP,`MOVS,`STP:
1077
                                        fnNumReadPorts = 3'd0;
1078
`BR:                fnNumReadPorts = 3'd0;
1079
`LOOP:                          fnNumReadPorts = 3'd0;
1080
`LDI,`LDIS,`IMM:                fnNumReadPorts = 3'd0;
1081
`R,`P,`STI:             fnNumReadPorts = 3'd1;
1082
`RTI,`RTD,`RTE:         fnNumReadPorts = 3'd1;
1083
`TST:                           fnNumReadPorts = 3'd1;
1084
`ADDI,`ADDUI,`ADDUIS:
1085
                    fnNumReadPorts = 3'd1;
1086
`_2ADDUI,`_4ADDUI,`_8ADDUI,`_16ADDUI:
1087
                                        fnNumReadPorts = 3'd1;
1088
`SUBI,`SUBUI:           fnNumReadPorts = 3'd1;
1089
`CMPI:                          fnNumReadPorts = 3'd1;
1090
`MULI,`MULUI,`DIVI,`DIVUI:
1091
                                        fnNumReadPorts = 3'd1;
1092
`BITI,
1093
`ANDI,`ORI,`EORI:       fnNumReadPorts = 3'd1;
1094
`SHIFT:
1095
                    if (ins[39:38]==2'h1)   // shift immediate
1096
                                           fnNumReadPorts = 3'd1;
1097
                                        else
1098
                                           fnNumReadPorts = 3'd2;
1099
`RTS2,`CACHE,`LCL,`TLB,
1100
`LB,`LBU,`LC,`LCU,`LH,`LHU,`LW,`LVB,`LVC,`LVH,`LVW,`LVWAR,`LWS,`LEA,`INC:
1101
                                        fnNumReadPorts = 3'd1;
1102
`JSR,`JSRS,`JSRZ,`SYS,`INT,`RTS,`BR,`LOOP:
1103
                                        fnNumReadPorts = 3'd1;
1104
`SBX,`SCX,`SHX,`SWX,
1105
`MUX,`CAS,`STMV,`STCMP:
1106
                                        fnNumReadPorts = 3'd3;
1107
`MTSPR,`MFSPR,`POP,`UNLINK:     fnNumReadPorts = 3'd1;
1108
`STFND:    fnNumReadPorts = 3'd2;       // *** TLB reads on Rb we say 2 for simplicity
1109
`BITFIELD:
1110
    case(ins[43:40])
1111
    `BFSET,`BFCLR,`BFCHG,`BFEXT,`BFEXTU:
1112
                                        fnNumReadPorts = 3'd1;
1113
    `BFINS:         fnNumReadPorts = 3'd2;
1114
    default:        fnNumReadPorts = 3'd0;
1115
    endcase
1116
default:                        fnNumReadPorts = 3'd2;
1117
endcase
1118
endfunction
1119
 
1120
function fnIsBranch;
1121
input [7:0] opcode;
1122
casex(opcode)
1123
`BR:    fnIsBranch = `TRUE;
1124
default:        fnIsBranch = `FALSE;
1125
endcase
1126
endfunction
1127
 
1128
function fnIsPush;
1129
input [63:0] insn;
1130
fnIsPush = insn[15:8]==`PUSH || insn[15:8]==`PEA;
1131
endfunction
1132
 
1133
function fnIsPop;
1134
input [63:0] insn;
1135
fnIsPop = insn[15:8]==`POP;
1136
endfunction
1137
 
1138
function fnIsStoreString;
1139
input [7:0] opcode;
1140
fnIsStoreString =
1141
        opcode==`STS;
1142
endfunction
1143
 
1144
wire xbr = (iqentry_op[head0]==`BR) || (iqentry_op[head1]==`BR);
1145
wire takb = (iqentry_op[head0]==`BR) ? commit0_v : commit1_v;
1146
wire [DBW-1:0] xbrpc = (iqentry_op[head0]==`BR) ? iqentry_pc[head0] : iqentry_pc[head1];
1147
 
1148
wire predict_takenA,predict_takenB,predict_takenC,predict_takenD;
1149
 
1150
// There are really only two branch tables required one for fetchbuf0 and one
1151
// for fetchbuf1. Synthesis removes the extra tables.
1152
//
1153
Thor_BranchHistory #(DBW) ubhtA
1154
(
1155
        .rst(rst_i),
1156
        .clk(clk),
1157
        .advanceX(xbr),
1158
        .xisBranch(xbr),
1159
        .pc(pc),
1160
        .xpc(xbrpc),
1161
        .takb(takb),
1162
        .predict_taken(predict_takenA)
1163
);
1164
 
1165
Thor_BranchHistory #(DBW) ubhtB
1166
(
1167
        .rst(rst_i),
1168
        .clk(clk),
1169
        .advanceX(xbr),
1170
        .xisBranch(xbr),
1171
        .pc(pc+fnInsnLength(insn)),
1172
        .xpc(xbrpc),
1173
        .takb(takb),
1174
        .predict_taken(predict_takenB)
1175
);
1176
 
1177
Thor_BranchHistory #(DBW) ubhtC
1178
(
1179
        .rst(rst_i),
1180
        .clk(clk),
1181
        .advanceX(xbr),
1182
        .xisBranch(xbr),
1183
        .pc(pc),
1184
        .xpc(xbrpc),
1185
        .takb(takb),
1186
        .predict_taken(predict_takenC)
1187
);
1188
 
1189
Thor_BranchHistory #(DBW) ubhtD
1190
(
1191
        .rst(rst_i),
1192
        .clk(clk),
1193
        .advanceX(xbr),
1194
        .xisBranch(xbr),
1195
        .pc(pc+fnInsnLength(insn)),
1196
        .xpc(xbrpc),
1197
        .takb(takb),
1198
        .predict_taken(predict_takenD)
1199
);
1200
 
1201
`ifdef THREEWAY
1202
Thor_BranchHistory #(DBW) ubhtE
1203
(
1204
        .rst(rst_i),
1205
        .clk(clk),
1206
        .advanceX(xbr),
1207
        .xisBranch(xbr),
1208
        .pc(pc+fnInsnLength(insn)+fnInsnLength1(insn)),
1209
        .xpc(xbrpc),
1210
        .takb(takb),
1211
        .predict_taken(predict_takenE)
1212
);
1213
Thor_BranchHistory #(DBW) ubhtF
1214
(
1215
        .rst(rst_i),
1216
        .clk(clk),
1217
        .advanceX(xbr),
1218
        .xisBranch(xbr),
1219
        .pc(pc+fnInsnLength(insn)+fnInsnLength1(insn)),
1220
        .xpc(xbrpc),
1221
        .takb(takb),
1222
        .predict_taken(predict_takenF)
1223
);
1224
`endif
1225
 
1226
Thor_icachemem #(DBW) uicm1
1227
(
1228
        .wclk(clk),
1229
        .wce(cstate==ICACHE1),
1230
        .wr(ack_i|err_i),
1231
        .wa(adr_o),
1232
        .wd({err_i,dat_i}),
1233
        .rclk(~clk),
1234
        .pc(ppc),
1235
        .insn(insn)
1236
);
1237
 
1238
wire hit0,hit1;
1239
reg ic_ld;
1240
reg [31:0] ic_ld_cntr;
1241
Thor_itagmem #(DBW-1) uitm1
1242
(
1243
        .wclk(clk),
1244
        .wce((cstate==ICACHE1 && cti_o==3'b111)|ic_ld),
1245
        .wr(ack_i|err_i|ic_ld),
1246
        .wa(adr_o|ic_ld_cntr),
1247
        .err_i(err_i|ierr),
1248
        .invalidate(ic_invalidate),
1249
        .invalidate_line(ic_invalidate_line),
1250
        .invalidate_lineno(ic_lineno),
1251
        .rclk(~clk),
1252
        .rce(1'b1),
1253
        .pc(ppc),
1254
        .hit0(hit0),
1255
        .hit1(hit1),
1256
        .err_o(insnerr)
1257
);
1258
 
1259
wire ihit = hit0 & hit1;
1260
wire do_pcinc = ihit;// && !((nmi_edge & ~StatusHWI & ~int_commit) || (irq_i & ~im & ~StatusHWI & ~int_commit));
1261
wire ld_fetchbuf = ihit || (nmi_edge & !StatusHWI)||(irq_i & ~im & !StatusHWI);
1262
 
1263
wire whit;
1264
 
1265
Thor_dcachemem_1w1r #(DBW) udcm1
1266
(
1267
        .wclk(clk),
1268
        .wce(whit || cstate==DCACHE1),
1269
        .wr(ack_i|err_i),
1270
        .sel(whit ? sel_o : 8'hFF),
1271
        .wa(adr_o),
1272
        .wd(whit ? dat_o : dat_i),
1273
        .rclk(~clk),
1274
        .rce(1'b1),
1275
        .ra(pea),
1276
        .o(cdat)
1277
);
1278
 
1279
Thor_dtagmem #(DBW-1) udtm1
1280
(
1281
        .wclk(clk),
1282
        .wce(cstate==DCACHE1 && cti_o==3'b111),
1283
        .wr(ack_i|err_i),
1284
        .wa(adr_o),
1285
        .err_i(err_i|derr),
1286
        .invalidate(dc_invalidate),
1287
        .invalidate_line(dc_invalidate_line),
1288
    .invalidate_lineno(dc_lineno),
1289
        .rclk(~clk),
1290
        .rce(1'b1),
1291
        .ra(pea),
1292
        .whit(whit),
1293
        .rhit(rhit),
1294
        .err_o()
1295
);
1296
 
1297
wire [DBW-1:0] shfto0,shfto1;
1298
 
1299
function fnIsShiftiop;
1300
input [63:0] insn;
1301
fnIsShiftiop =  insn[15:8]==`SHIFT && (
1302
                insn[39:34]==`SHLI || insn[39:34]==`SHLUI ||
1303
                                insn[39:34]==`SHRI || insn[39:34]==`SHRUI ||
1304
                                insn[39:34]==`ROLI || insn[39:34]==`RORI
1305
                                )
1306
                                ;
1307
endfunction
1308
 
1309
function fnIsShiftop;
1310
input [7:0] opcode;
1311
fnIsShiftop = opcode==`SHL || opcode==`SHLI || opcode==`SHLU || opcode==`SHLUI ||
1312
                                opcode==`SHR || opcode==`SHRI || opcode==`SHRU || opcode==`SHRUI ||
1313
                                opcode==`ROL || opcode==`ROLI || opcode==`ROR || opcode==`RORI
1314
                                ;
1315
endfunction
1316
 
1317
function fnIsFP;
1318
input [7:0] opcode;
1319
fnIsFP =        opcode==`DOUBLE_R||opcode==`FLOAT||opcode==`SINGLE_R;
1320
//            opcode==`ITOF || opcode==`FTOI || opcode==`FNEG || opcode==`FSIGN || /*opcode==`FCMP || */ opcode==`FABS ||
1321
//                      opcode==`FADD || opcode==`FSUB || opcode==`FMUL || opcode==`FDIV
1322
//                      ;
1323
endfunction
1324
 
1325
function fnIsFPCtrl;
1326
input [63:0] insn;
1327
fnIsFPCtrl = (insn[15:8]==`SINGLE_R && (insn[31:28]==`FTX||insn[31:28]==`FCX||insn[31:28]==`FDX||insn[31:28]==`FEX)) ||
1328
             (insn[15:8]==`DOUBLE_R && (insn[31:28]==`FRM))
1329
             ;
1330
endfunction
1331
 
1332
function fnIsBitfield;
1333
input [7:0] opcode;
1334
fnIsBitfield = opcode==`BFSET || opcode==`BFCLR || opcode==`BFCHG || opcode==`BFINS || opcode==`BFEXT || opcode==`BFEXTU;
1335
endfunction
1336
 
1337
//wire [3:0] Pn = ir[7:4];
1338
 
1339
// Set the target register
1340
// 00-3F = general register file
1341
// 40-4F = predicate register
1342
// 50-5F = code address register
1343
// 60-67 = segment base register
1344
// 70 = predicate register horizontal
1345
// 73 = loop counter
1346
function [6:0] fnTargetReg;
1347
input [63:0] ir;
1348
begin
1349
        if (ir[3:0]==4'h0)       // Process special predicates
1350
                fnTargetReg = 7'h000;
1351
        else
1352
                casex(fnOpcode(ir))
1353
                `POP: fnTargetReg = ir[22:16];
1354
                `LDI,`ADDUIS,`STS,`LINK,`UNLINK:
1355
                        fnTargetReg = {1'b0,ir[21:16]};
1356
                `LDIS:
1357
                        fnTargetReg = {1'b1,ir[21:16]};
1358
                `RR:
1359
                        fnTargetReg = {1'b0,ir[33:28]};
1360
                `BCD,
1361
                `LOGIC,`FLOAT,
1362
                `LWX,`LBX,`LBUX,`LCX,`LCUX,`LHX,`LHUX,`STMV,`STCMP,`STFND:
1363
                        fnTargetReg = {1'b0,ir[33:28]};
1364
                `SHIFT:
1365
                        fnTargetReg = {1'b0,ir[33:28]};
1366
                `R,`DOUBLE_R,`SINGLE_R,
1367
                `ADDI,`ADDUI,`SUBI,`SUBUI,`MULI,`MULUI,`DIVI,`DIVUI,
1368
                `_2ADDUI,`_4ADDUI,`_8ADDUI,`_16ADDUI,
1369
                `ANDI,`ORI,`EORI,
1370
                `LVB,`LVC,`LVH,`LVW,`LVWAR,
1371
                `LB,`LBU,`LC,`LCU,`LH,`LHU,`LW,`LEA,`LINK:
1372
                        fnTargetReg = {1'b0,ir[27:22]};
1373
                `CAS:
1374
                        fnTargetReg = {1'b0,ir[39:34]};
1375
                `BITFIELD:
1376
                        fnTargetReg = {1'b0,ir[27:22]};
1377
                `TLB:
1378
                        if (ir[19:16]==`TLB_RDREG)
1379
                                fnTargetReg = {1'b0,ir[29:24]};
1380
                        else
1381
                                fnTargetReg = 7'h00;
1382
                `MFSPR:
1383
                        fnTargetReg = {1'b0,ir[27:22]};
1384
                `BITI:
1385
                      fnTargetReg = {3'h4,ir[25:22]};
1386
                `CMP,`CMPI,`TST:
1387
                    begin
1388
                        fnTargetReg = {3'h4,ir[11:8]};
1389
                        end
1390
                `SWCR:    fnTargetReg = {3'h4,4'h0};
1391
                `JSR,`JSRZ,`JSRS,`SYS,`INT:
1392
                        fnTargetReg = {3'h5,ir[19:16]};
1393
                `MTSPR,`MOVS,`LWS:
1394
                    fnTargetReg = {1'b1,ir[27:22]};
1395
/*
1396
                        if (ir[27:26]==2'h1)            // Move to code address register
1397
                                fnTargetReg = {3'h5,ir[25:22]};
1398
                        else if (ir[27:26]==2'h2)       // Move to seg. reg.
1399
                                fnTargetReg = {3'h6,ir[25:22]};
1400
                        else if (ir[27:22]==6'h04)
1401
                                fnTargetReg = 7'h70;
1402
                        else
1403
                                fnTargetReg = 7'h00;
1404
*/
1405
        `RTS2:      fnTargetReg = 7'd27;
1406
        `LOOP:      fnTargetReg = 7'h73;
1407
        `STP:       fnTargetReg = 7'h7F;
1408
        `P:         fnTargetReg = 7'h70;
1409
                default:        fnTargetReg = 7'h00;
1410
                endcase
1411
end
1412
endfunction
1413
/*
1414
function fnAllowedReg;
1415
input [8:0] regno;
1416
fnAllowedReg = allowedRegs[regno] ? regno : 9'h000;
1417
endfunction
1418
*/
1419
function fnTargetsCa;
1420
input [63:0] ir;
1421
begin
1422
if (ir[3:0]==4'h0)
1423
        fnTargetsCa = `FALSE;
1424
else begin
1425
        case(fnOpcode(ir))
1426
        `JSR,`JSRZ,`JSRS,`SYS,`INT:
1427
               fnTargetsCa = `TRUE;
1428
        `LWS:
1429
                if (ir[27:26]==2'h1)
1430
                        fnTargetsCa = `TRUE;
1431
                else
1432
                        fnTargetsCa = `FALSE;
1433
        `LDIS:
1434
                if (ir[21:20]==2'h1)
1435
                        fnTargetsCa = `TRUE;
1436
                else
1437
                        fnTargetsCa = `FALSE;
1438
        `MTSPR,`MOVS:
1439
                begin
1440
                        if (ir[27:26]==2'h1)
1441
                                fnTargetsCa = `TRUE;
1442
                        else
1443
                                fnTargetsCa = `FALSE;
1444
                end
1445
        default:        fnTargetsCa = `FALSE;
1446
        endcase
1447
end
1448
end
1449
endfunction
1450
 
1451
function fnTargetsSegreg;
1452
input [63:0] ir;
1453
if (ir[3:0]==4'h0)
1454
        fnTargetsSegreg = `FALSE;
1455
else
1456
        case(fnOpcode(ir))
1457
        `LWS:
1458
                if (ir[27:26]==2'h2)
1459
                        fnTargetsSegreg = `TRUE;
1460
                else
1461
                        fnTargetsSegreg = `FALSE;
1462
        `LDIS:
1463
                if (ir[21:20]==2'h2)
1464
                        fnTargetsSegreg = `TRUE;
1465
                else
1466
                        fnTargetsSegreg = `FALSE;
1467
        `MTSPR,`MOVS:
1468
                if (ir[27:26]==2'h2)
1469
                        fnTargetsSegreg = `TRUE;
1470
                else
1471
                        fnTargetsSegreg = `FALSE;
1472
        default:        fnTargetsSegreg = `FALSE;
1473
        endcase
1474
endfunction
1475
 
1476
function fnHasConst;
1477
input [7:0] opcode;
1478
        casex(opcode)
1479
        `BFCLR,`BFSET,`BFCHG,`BFEXT,`BFEXTU,`BFINS,
1480
        `LDI,`LDIS,`ADDUIS,
1481
        `ADDI,`SUBI,`ADDUI,`SUBUI,`MULI,`MULUI,`DIVI,`DIVUI,
1482
        `_2ADDUI,`_4ADDUI,`_8ADDUI,`_16ADDUI,
1483
        `CMPI,
1484
        `ANDI,`ORI,`EORI,`BITI,
1485
//      `SHLI,`SHLUI,`SHRI,`SHRUI,`ROLI,`RORI,
1486
        `LB,`LBU,`LC,`LCU,`LH,`LHU,`LW,`LWS,`LEA,`INC,
1487
        `LVB,`LVC,`LVH,`LVW,`LVWAR,`STI,
1488
        `SB,`SC,`SH,`SW,`SWCR,`CAS,`SWS,
1489
        `JSR,`JSRS,`SYS,`INT,`BR,`RTS2,`LOOP,`PEA,`LINK,`UNLINK:
1490
                fnHasConst = 1'b1;
1491
        default:
1492
                fnHasConst = 1'b0;
1493
        endcase
1494
endfunction
1495
 
1496
function fnIsFlowCtrl;
1497
input [7:0] opcode;
1498
begin
1499
casex(opcode)
1500
`JSR,`JSRS,`JSRZ,`SYS,`INT,`LOOP,`BR,`RTS,`RTS2,`RTI,`RTD,`RTE:
1501
        fnIsFlowCtrl = 1'b1;
1502
default:        fnIsFlowCtrl = 1'b0;
1503
endcase
1504
end
1505
endfunction
1506
 
1507
// fnCanException
1508
// Used by issue logic.
1509
// Returns TRUE if the instruction can cause an exception
1510
//
1511
function fnCanException;
1512
input [7:0] op;
1513
input [5:0] func;
1514
case(op)
1515
`FLOAT:
1516
    case(func)
1517
    `FDIVS,`FMULS,`FADDS,`FSUBS,
1518
    `FDIV,`FMUL,`FADD,`FSUB:
1519
        fnCanException = `TRUE;
1520
    endcase
1521
`SINGLE_R:
1522
    if (func==`FTX) fnCanException = `TRUE;
1523
`ADD,`ADDI,`SUB,`SUBI,`DIV,`DIVI,`MUL,`MULI:
1524
    fnCanException = `TRUE;
1525
`TLB,`RTI,`RTD,`RTE,`CLI,`SEI:
1526
    fnCanException = `TRUE;
1527
default:
1528
    fnCanException = fnIsMem(op);
1529
endcase
1530
endfunction
1531
 
1532
// fnInsnLength
1533
// Used by fetch logic.
1534
// Return the length of an instruction.
1535
//
1536
function [3:0] fnInsnLength;
1537
input [127:0] insn;
1538
casex(insn[15:0])
1539
16'bxxxxxxxx00000000:   fnInsnLength = 4'd1;    // BRK
1540
16'bxxxxxxxx00010000:   fnInsnLength = 4'd1;    // NOP
1541
16'bxxxxxxxx00100000:   fnInsnLength = 4'd2;
1542
16'bxxxxxxxx00110000:   fnInsnLength = 4'd3;
1543
16'bxxxxxxxx01000000:   fnInsnLength = 4'd4;
1544
16'bxxxxxxxx01010000:   fnInsnLength = 4'd5;
1545
16'bxxxxxxxx01100000:   fnInsnLength = 4'd6;
1546
16'bxxxxxxxx01110000:   fnInsnLength = 4'd7;
1547
16'bxxxxxxxx10000000:   fnInsnLength = 4'd8;
1548
16'bxxxxxxxx00010001:   fnInsnLength = 4'd1;    // RTS short form
1549
default:
1550
        casex(insn[15:8])
1551
        `NOP,`SEI,`CLI,`RTI,`RTD,`RTE,`MEMSB,`MEMDB,`SYNC:
1552
                fnInsnLength = 4'd2;
1553
        `TST,`BR,`JSRZ,`RTS,`CACHE,`LOOP,`PUSH,`POP,`UNLINK:
1554
                fnInsnLength = 4'd3;
1555
        `SYS,`CMP,`CMPI,`MTSPR,`MFSPR,`LDI,`LDIS,`ADDUIS,`R,`TLB,`MOVS,`RTS2,`STP:
1556
                fnInsnLength = 4'd4;
1557
        `BITFIELD,`JSR,`MUX,`BCD,`INC:
1558
                fnInsnLength = 4'd6;
1559
        `CAS:
1560
                fnInsnLength = 4'd6;
1561
        default:
1562
                fnInsnLength = 4'd5;
1563
        endcase
1564
endcase
1565
endfunction
1566
 
1567
function [3:0] fnInsnLength1;
1568
input [127:0] insn;
1569
case(fnInsnLength(insn))
1570
4'd1:   fnInsnLength1 = fnInsnLength(insn[127: 8]);
1571
4'd2:   fnInsnLength1 = fnInsnLength(insn[127:16]);
1572
4'd3:   fnInsnLength1 = fnInsnLength(insn[127:24]);
1573
4'd4:   fnInsnLength1 = fnInsnLength(insn[127:32]);
1574
4'd5:   fnInsnLength1 = fnInsnLength(insn[127:40]);
1575
4'd6:   fnInsnLength1 = fnInsnLength(insn[127:48]);
1576
4'd7:   fnInsnLength1 = fnInsnLength(insn[127:56]);
1577
4'd8:   fnInsnLength1 = fnInsnLength(insn[127:64]);
1578
default:        fnInsnLength1 = 4'd0;
1579
endcase
1580
endfunction
1581
 
1582
function [3:0] fnInsnLength2;
1583
input [127:0] insn;
1584
case(fnInsnLength(insn)+fnInsnLength1(insn))
1585
4'd2:   fnInsnLength2 = fnInsnLength(insn[127:16]);
1586
4'd3:   fnInsnLength2 = fnInsnLength(insn[127:24]);
1587
4'd4:   fnInsnLength2 = fnInsnLength(insn[127:32]);
1588
4'd5:   fnInsnLength2 = fnInsnLength(insn[127:40]);
1589
4'd6:   fnInsnLength2 = fnInsnLength(insn[127:48]);
1590
4'd7:   fnInsnLength2 = fnInsnLength(insn[127:56]);
1591
4'd8:   fnInsnLength2 = fnInsnLength(insn[127:64]);
1592
4'd9:   fnInsnLength2 = fnInsnLength(insn[127:72]);
1593
4'd10:  fnInsnLength2 = fnInsnLength(insn[127:80]);
1594
4'd11:  fnInsnLength2 = fnInsnLength(insn[127:88]);
1595
4'd12:  fnInsnLength2 = fnInsnLength(insn[127:96]);
1596
4'd13:  fnInsnLength2 = fnInsnLength(insn[127:104]);
1597
4'd14:  fnInsnLength2 = fnInsnLength(insn[127:112]);
1598
4'd15:  fnInsnLength2 = fnInsnLength(insn[127:120]);
1599
default:        fnInsnLength2 = 4'd0;
1600
endcase
1601
endfunction
1602
 
1603
wire [5:0] total_insn_length = fnInsnLength(insn) + fnInsnLength1(insn) + fnInsnLength2(insn);
1604
wire [5:0] insn_length12 = fnInsnLength(insn) + fnInsnLength1(insn);
1605
wire insn3_will_fit = total_insn_length < 6'd16;
1606
 
1607
always @(fetchbuf or fetchbufA_instr or fetchbufA_v or fetchbufA_pc
1608
 or fetchbufB_instr or fetchbufB_v or fetchbufB_pc
1609
 or fetchbufC_instr or fetchbufC_v or fetchbufC_pc
1610
 or fetchbufD_instr or fetchbufD_v or fetchbufD_pc
1611
`ifdef THREEWAY
1612
 or fetchbufE_instr or fetchbufE_v or fetchbufE_pc
1613
 or fetchbufF_instr or fetchbufF_v or fetchbufF_pc
1614
`endif
1615
)
1616
begin
1617
        fetchbuf0_instr <= (fetchbuf == 1'b0) ? fetchbufA_instr : fetchbufC_instr;
1618
        fetchbuf0_v     <= (fetchbuf == 1'b0) ? fetchbufA_v     : fetchbufC_v    ;
1619
 
1620
        if (int_pending && string_pc!=64'd0)
1621
                fetchbuf0_pc <= string_pc;
1622
        else
1623
        fetchbuf0_pc    <= (fetchbuf == 1'b0) ? fetchbufA_pc    : fetchbufC_pc   ;
1624
 
1625
        fetchbuf1_instr <= (fetchbuf == 1'b0) ? fetchbufB_instr : fetchbufD_instr;
1626
        fetchbuf1_v     <= (fetchbuf == 1'b0) ? fetchbufB_v     : fetchbufD_v    ;
1627
 
1628
        if (int_pending && string_pc != 64'd0)
1629
                fetchbuf1_pc <= string_pc;
1630
        else
1631
        fetchbuf1_pc    <= (fetchbuf == 1'b0) ? fetchbufB_pc    : fetchbufD_pc   ;
1632
end
1633
 
1634
wire [7:0] opcodeA = fetchbufA_instr[`OPCODE];
1635
wire [7:0] opcodeB = fetchbufB_instr[`OPCODE];
1636
wire [7:0] opcodeC = fetchbufC_instr[`OPCODE];
1637
wire [7:0] opcodeD = fetchbufD_instr[`OPCODE];
1638
 
1639
function fnIsMem;
1640
input [7:0] opcode;
1641
fnIsMem =       opcode==`LB || opcode==`LBU || opcode==`LC || opcode==`LCU || opcode==`LH || opcode==`LHU || opcode==`LW ||
1642
                        opcode==`LBX || opcode==`LWX || opcode==`LBUX || opcode==`LHX || opcode==`LHUX || opcode==`LCX || opcode==`LCUX ||
1643
                        opcode==`SB || opcode==`SC || opcode==`SH || opcode==`SW ||
1644
                        opcode==`SBX || opcode==`SCX || opcode==`SHX || opcode==`SWX ||
1645
                        opcode==`STS || opcode==`LCL ||
1646
                        opcode==`LVB || opcode==`LVC || opcode==`LVH || opcode==`LVW || opcode==`LVWAR || opcode==`SWCR ||
1647
                        opcode==`TLB || opcode==`CAS || opcode==`STMV || opcode==`STCMP || opcode==`STFND ||
1648
                        opcode==`LWS || opcode==`SWS || opcode==`STI ||
1649
                        opcode==`INC ||
1650
                        opcode==`PUSH || opcode==`POP || opcode==`PEA || opcode==`LINK || opcode==`UNLINK
1651
                        ;
1652
endfunction
1653
 
1654
function fnIsNdxd;
1655
input [7:0] opcode;
1656
fnIsNdxd = opcode==`LBX || opcode==`LWX || opcode==`LBUX || opcode==`LHX || opcode==`LHUX || opcode==`LCX || opcode==`LCUX ||
1657
           opcode==`SBX || opcode==`SCX || opcode==`SHX || opcode==`SWX
1658
           ;
1659
endfunction
1660
 
1661
// Determines which instruction write to the register file
1662
function fnIsRFW;
1663
input [7:0] opcode;
1664
input [63:0] ir;
1665
begin
1666
fnIsRFW =       // General registers
1667
                        opcode==`LB || opcode==`LBU || opcode==`LC || opcode==`LCU || opcode==`LH || opcode==`LHU || opcode==`LW ||
1668
                        opcode==`LBX || opcode==`LBUX || opcode==`LCX || opcode==`LCUX || opcode==`LHX || opcode==`LHUX || opcode==`LWX ||
1669
                        opcode==`LVB || opcode==`LVH || opcode==`LVC || opcode==`LVW || opcode==`LVWAR || opcode==`SWCR ||
1670
                        opcode==`RTS2 || opcode==`STP ||
1671
                        opcode==`CAS || opcode==`LWS || opcode==`STMV || opcode==`STCMP || opcode==`STFND ||
1672
                        opcode==`STS || opcode==`POP || opcode==`LINK || opcode==`UNLINK ||
1673
                        opcode==`ADDI || opcode==`SUBI || opcode==`ADDUI || opcode==`SUBUI || opcode==`MULI || opcode==`MULUI || opcode==`DIVI || opcode==`DIVUI ||
1674
                        opcode==`ANDI || opcode==`ORI || opcode==`EORI ||
1675
                        opcode==`ADD || opcode==`SUB || opcode==`ADDU || opcode==`SUBU || opcode==`MUL || opcode==`MULU || opcode==`DIV || opcode==`DIVU ||
1676
                        opcode==`AND || opcode==`OR || opcode==`EOR || opcode==`NAND || opcode==`NOR || opcode==`ENOR || opcode==`ANDC || opcode==`ORC ||
1677
                        opcode==`SHIFT ||
1678
                        opcode==`R || opcode==`RR || opcode==`LEA || opcode==`P ||
1679
                        opcode==`LDI || opcode==`LDIS || opcode==`ADDUIS || opcode==`MFSPR ||
1680
                        // Branch registers / Segment registers
1681
                        ((opcode==`MTSPR || opcode==`MOVS) /*&& (fnTargetsCa(ir) || fnTargetsSegreg(ir))*/) ||
1682
                        opcode==`JSR || opcode==`JSRS || opcode==`JSRZ || opcode==`SYS || opcode==`INT ||
1683
                        // predicate registers
1684
                        (opcode[7:4] < 4'h3) ||
1685
                        (opcode==`TLB && ir[19:16]==`TLB_RDREG) ||
1686
                        opcode==`BCD
1687
                        ;
1688
end
1689
endfunction
1690
 
1691
function fnIsStore;
1692
input [7:0] opcode;
1693
fnIsStore =     opcode==`SB || opcode==`SC || opcode==`SH || opcode==`SW ||
1694
                                opcode==`SBX || opcode==`SCX || opcode==`SHX || opcode==`SWX ||
1695
                                opcode==`STS || opcode==`SWCR ||
1696
                                opcode==`SWS || opcode==`STI ||
1697
                                opcode==`PUSH || opcode==`PEA || opcode==`LINK;
1698
endfunction
1699
 
1700
function fnIsLoad;
1701
input [7:0] opcode;
1702
fnIsLoad =      opcode==`LB || opcode==`LBU || opcode==`LC || opcode==`LCU || opcode==`LH || opcode==`LHU || opcode==`LW ||
1703
                        opcode==`LBX || opcode==`LBUX || opcode==`LCX || opcode==`LCUX || opcode==`LHX || opcode==`LHUX || opcode==`LWX ||
1704
                        opcode==`LVB || opcode==`LVC || opcode==`LVH || opcode==`LVW || opcode==`LVWAR || opcode==`LCL ||
1705
                        opcode==`LWS || opcode==`UNLINK ||
1706
                        opcode==`POP;
1707
endfunction
1708
 
1709
function fnIsLoadV;
1710
input [7:0] opcode;
1711
fnIsLoadV = opcode==`LVB || opcode==`LVC || opcode==`LVH || opcode==`LVW || opcode==`LVWAR || opcode==`LCL;
1712
endfunction
1713
 
1714
function fnIsIndexed;
1715
input [7:0] opcode;
1716
fnIsIndexed = opcode==`LBX || opcode==`LBUX || opcode==`LCX || opcode==`LCUX || opcode==`LHX || opcode==`LHUX || opcode==`LWX ||
1717
                                opcode==`SBX || opcode==`SCX || opcode==`SHX || opcode==`SWX;
1718
endfunction
1719
 
1720
// *** check these
1721
function fnIsPFW;
1722
input [7:0] opcode;
1723
fnIsPFW =       opcode[7:4]<4'h3 || opcode==`BITI || opcode==`P;//opcode==`CMP || opcode==`CMPI || opcode==`TST;
1724
endfunction
1725
 
1726
function [7:0] fnSelect;
1727
input [7:0] opcode;
1728
input [5:0] fn;
1729
input [DBW-1:0] adr;
1730
begin
1731
if (DBW==32)
1732
        case(opcode)
1733
        `STS,`STMV,`STCMP,`STFND,`INC:
1734
           case(fn[2:0])
1735
           3'd0:
1736
           case(adr[1:0])
1737
           3'd0:    fnSelect = 8'h11;
1738
           3'd1:    fnSelect = 8'h22;
1739
           3'd2:    fnSelect = 8'h44;
1740
           3'd3:    fnSelect = 8'h88;
1741
           endcase
1742
       3'd1:
1743
                   case(adr[1])
1744
           1'd0:    fnSelect = 8'h33;
1745
           1'd1:    fnSelect = 8'hCC;
1746
           endcase
1747
       3'd2:
1748
                fnSelect = 8'hFF;
1749
       default: fnSelect = 8'h00;
1750
       endcase
1751
        `LB,`LBU,`LBX,`LBUX,`SB,`SBX,`LVB:
1752
                case(adr[1:0])
1753
                3'd0:   fnSelect = 8'h11;
1754
                3'd1:   fnSelect = 8'h22;
1755
                3'd2:   fnSelect = 8'h44;
1756
                3'd3:   fnSelect = 8'h88;
1757
                endcase
1758
        `LC,`LCU,`SC,`LVC,`LCX,`LCUX,`SCX:
1759
                case(adr[1])
1760
                1'd0:   fnSelect = 8'h33;
1761
                1'd1:   fnSelect = 8'hCC;
1762
                endcase
1763
        `LH,`LHU,`SH,`LVH,`LHX,`LHUX,`SHX:
1764
                fnSelect = 8'hFF;
1765
        `LW,`LWX,`SW,`SWCR,`LVW,`LVWAR,`SWX,`CAS,`LWS,`SWS,`STI,`LCL,
1766
        `PUSH,`PEA,`POP,`LINK,`UNLINK:
1767
                fnSelect = 8'hFF;
1768
        default:        fnSelect = 8'h00;
1769
        endcase
1770
else
1771
        case(opcode)
1772
        `STS,`STMV,`STCMP,`STFND,`INC:
1773
       case(fn[2:0])
1774
       3'd0:
1775
           case(adr[2:0])
1776
           3'd0:    fnSelect = 8'h01;
1777
           3'd1:    fnSelect = 8'h02;
1778
           3'd2:    fnSelect = 8'h04;
1779
           3'd3:    fnSelect = 8'h08;
1780
           3'd4:    fnSelect = 8'h10;
1781
           3'd5:    fnSelect = 8'h20;
1782
           3'd6:    fnSelect = 8'h40;
1783
           3'd7:    fnSelect = 8'h80;
1784
           endcase
1785
       3'd1:
1786
           case(adr[2:1])
1787
           2'd0:    fnSelect = 8'h03;
1788
           2'd1:    fnSelect = 8'h0C;
1789
           2'd2:    fnSelect = 8'h30;
1790
           2'd3:    fnSelect = 8'hC0;
1791
           endcase
1792
       3'd2:
1793
           case(adr[2])
1794
           1'b0:    fnSelect = 8'h0F;
1795
           1'b1:    fnSelect = 8'hF0;
1796
           endcase
1797
       3'd3:
1798
           fnSelect = 8'hFF;
1799
       default: fnSelect = 8'h00;
1800
       endcase
1801
        `LB,`LBU,`LBX,`SB,`LVB,`LBUX,`SBX:
1802
                case(adr[2:0])
1803
                3'd0:   fnSelect = 8'h01;
1804
                3'd1:   fnSelect = 8'h02;
1805
                3'd2:   fnSelect = 8'h04;
1806
                3'd3:   fnSelect = 8'h08;
1807
                3'd4:   fnSelect = 8'h10;
1808
                3'd5:   fnSelect = 8'h20;
1809
                3'd6:   fnSelect = 8'h40;
1810
                3'd7:   fnSelect = 8'h80;
1811
                endcase
1812
        `LC,`LCU,`SC,`LVC,`LCX,`LCUX,`SCX:
1813
                case(adr[2:1])
1814
                2'd0:   fnSelect = 8'h03;
1815
                2'd1:   fnSelect = 8'h0C;
1816
                2'd2:   fnSelect = 8'h30;
1817
                2'd3:   fnSelect = 8'hC0;
1818
                endcase
1819
        `LH,`LHU,`SH,`LVH,`LHX,`LHUX,`SHX:
1820
                case(adr[2])
1821
                1'b0:   fnSelect = 8'h0F;
1822
                1'b1:   fnSelect = 8'hF0;
1823
                endcase
1824
        `LW,`LWX,`SW,`SWCR,`LVW,`LVWAR,`SWX,`CAS,`LWS,`SWS,`STI,`LCL,
1825
        `PUSH,`PEA,`POP,`LINK,`UNLINK:
1826
                fnSelect = 8'hFF;
1827
        default:        fnSelect = 8'h00;
1828
        endcase
1829
end
1830
endfunction
1831
 
1832
function [DBW-1:0] fnDatai;
1833
input [7:0] opcode;
1834
input [5:0] func;
1835
input [DBW-1:0] dat;
1836
input [7:0] sel;
1837
begin
1838
if (DBW==32)
1839
        case(opcode)
1840
        `STMV,`STCMP,`STFND,`INC:
1841
           case(func[2:0])
1842
           3'd0,3'd4:
1843
                case(sel[3:0])
1844
        4'h1:    fnDatai = dat[7:0];
1845
        4'h2:    fnDatai = dat[15:8];
1846
        4'h4:    fnDatai = dat[23:16];
1847
        4'h8:    fnDatai = dat[31:24];
1848
        default:    fnDatai = {DBW{1'b1}};
1849
        endcase
1850
       3'd1,3'd5:
1851
                case(sel[3:0])
1852
        4'h3:    fnDatai = dat[15:0];
1853
        4'hC:    fnDatai = dat[31:16];
1854
        default:    fnDatai = {DBW{1'b1}};
1855
        endcase
1856
       default:
1857
                fnDatai = dat[31:0];
1858
           endcase
1859
        `LB,`LBX,`LVB:
1860
                case(sel[3:0])
1861
                8'h1:   fnDatai = {{24{dat[7]}},dat[7:0]};
1862
                8'h2:   fnDatai = {{24{dat[15]}},dat[15:8]};
1863
                8'h4:   fnDatai = {{24{dat[23]}},dat[23:16]};
1864
                8'h8:   fnDatai = {{24{dat[31]}},dat[31:24]};
1865
                default:        fnDatai = {DBW{1'b1}};
1866
                endcase
1867
        `LBU,`LBUX:
1868
                case(sel[3:0])
1869
                4'h1:   fnDatai = dat[7:0];
1870
                4'h2:   fnDatai = dat[15:8];
1871
                4'h4:   fnDatai = dat[23:16];
1872
                4'h8:   fnDatai = dat[31:24];
1873
                default:        fnDatai = {DBW{1'b1}};
1874
                endcase
1875
        `LC,`LVC,`LCX:
1876
                case(sel[3:0])
1877
                4'h3:   fnDatai = {{16{dat[15]}},dat[15:0]};
1878
                4'hC:   fnDatai = {{16{dat[31]}},dat[31:16]};
1879
                default:        fnDatai = {DBW{1'b1}};
1880
                endcase
1881
        `LCU,`LCUX:
1882
                case(sel[3:0])
1883
                4'h3:   fnDatai = dat[15:0];
1884
                4'hC:   fnDatai = dat[31:16];
1885
                default:        fnDatai = {DBW{1'b1}};
1886
                endcase
1887
        `LH,`LHU,`LW,`LWX,`LVH,`LVW,`LVWAR,`LHX,`LHUX,`CAS,`LWS,`LCL,`POP,`UNLINK:
1888
                fnDatai = dat[31:0];
1889
        default:        fnDatai = {DBW{1'b1}};
1890
        endcase
1891
else
1892
        case(opcode)
1893
        `STMV,`STCMP,`STFND,`INC:
1894
           case(func[2:0])
1895
           3'd0,3'd4:
1896
                case(sel)
1897
        8'h01:    fnDatai = dat[DBW*1/8-1:0];
1898
        8'h02:    fnDatai = dat[DBW*2/8-1:DBW*1/8];
1899
        8'h04:    fnDatai = dat[DBW*3/8-1:DBW*2/8];
1900
        8'h08:    fnDatai = dat[DBW*4/8-1:DBW*3/8];
1901
        8'h10:    fnDatai = dat[DBW*5/8-1:DBW*4/8];
1902
        8'h20:    fnDatai = dat[DBW*6/8-1:DBW*5/8];
1903
        8'h40:    fnDatai = dat[DBW*7/8-1:DBW*6/8];
1904
        8'h80:    fnDatai = dat[DBW-1:DBW*7/8];
1905
        default:    fnDatai = {DBW{1'b1}};
1906
        endcase
1907
       3'd1,3'd5:
1908
                case(sel)
1909
        8'h03:    fnDatai = dat[DBW/4-1:0];
1910
        8'h0C:    fnDatai = dat[DBW/2-1:DBW/4];
1911
        8'h30:    fnDatai = dat[DBW*3/4-1:DBW/2];
1912
        8'hC0:    fnDatai = dat[DBW-1:DBW*3/4];
1913
        default:    fnDatai = {DBW{1'b1}};
1914
        endcase
1915
       3'd2,3'd6:
1916
                case(sel)
1917
        8'h0F:    fnDatai = dat[DBW/2-1:0];
1918
        8'hF0:    fnDatai = dat[DBW-1:DBW/2];
1919
        default:    fnDatai = {DBW{1'b1}};
1920
        endcase
1921
       3'd3,3'd7:   fnDatai = dat;
1922
           endcase
1923
        `LB,`LBX,`LVB:
1924
                case(sel)
1925
                8'h01:  fnDatai = {{DBW*7/8{dat[DBW*1/8-1]}},dat[DBW*1/8-1:0]};
1926
                8'h02:  fnDatai = {{DBW*7/8{dat[DBW*2/8-1]}},dat[DBW*2/8-1:DBW*1/8]};
1927
                8'h04:  fnDatai = {{DBW*7/8{dat[DBW*3/8-1]}},dat[DBW*3/8-1:DBW*2/8]};
1928
                8'h08:  fnDatai = {{DBW*7/8{dat[DBW*4/8-1]}},dat[DBW*4/8-1:DBW*3/8]};
1929
                8'h10:  fnDatai = {{DBW*7/8{dat[DBW*5/8-1]}},dat[DBW*5/8-1:DBW*4/8]};
1930
                8'h20:  fnDatai = {{DBW*7/8{dat[DBW*6/8-1]}},dat[DBW*6/8-1:DBW*5/8]};
1931
                8'h40:  fnDatai = {{DBW*7/8{dat[DBW*7/8-1]}},dat[DBW*7/8-1:DBW*6/8]};
1932
                8'h80:  fnDatai = {{DBW*7/8{dat[DBW-1]}},dat[DBW-1:DBW*7/8]};
1933
                default:        fnDatai = {DBW{1'b1}};
1934
                endcase
1935
        `LBU,`LBUX:
1936
                case(sel)
1937
                8'h01:  fnDatai = dat[DBW*1/8-1:0];
1938
                8'h02:  fnDatai = dat[DBW*2/8-1:DBW*1/8];
1939
                8'h04:  fnDatai = dat[DBW*3/8-1:DBW*2/8];
1940
                8'h08:  fnDatai = dat[DBW*4/8-1:DBW*3/8];
1941
                8'h10:  fnDatai = dat[DBW*5/8-1:DBW*4/8];
1942
                8'h20:  fnDatai = dat[DBW*6/8-1:DBW*5/8];
1943
                8'h40:  fnDatai = dat[DBW*7/8-1:DBW*6/8];
1944
                8'h80:  fnDatai = dat[DBW-1:DBW*7/8];
1945
                default:        fnDatai = {DBW{1'b1}};
1946
                endcase
1947
        `LC,`LVC,`LCX:
1948
                case(sel)
1949
                8'h03:  fnDatai = {{DBW*3/4{dat[DBW/4-1]}},dat[DBW/4-1:0]};
1950
                8'h0C:  fnDatai = {{DBW*3/4{dat[DBW/2-1]}},dat[DBW/2-1:DBW/4]};
1951
                8'h30:  fnDatai = {{DBW*3/4{dat[DBW*3/4-1]}},dat[DBW*3/4-1:DBW/2]};
1952
                8'hC0:  fnDatai = {{DBW*3/4{dat[DBW-1]}},dat[DBW-1:DBW*3/4]};
1953
                default:        fnDatai = {DBW{1'b1}};
1954
                endcase
1955
        `LCU,`LCUX:
1956
                case(sel)
1957
                8'h03:  fnDatai = dat[DBW/4-1:0];
1958
                8'h0C:  fnDatai = dat[DBW/2-1:DBW/4];
1959
                8'h30:  fnDatai = dat[DBW*3/4-1:DBW/2];
1960
                8'hC0:  fnDatai = dat[DBW-1:DBW*3/4];
1961
                default:        fnDatai = {DBW{1'b1}};
1962
                endcase
1963
        `LH,`LVH,`LHX:
1964
                case(sel)
1965
                8'h0F:  fnDatai = {{DBW/2{dat[DBW/2-1]}},dat[DBW/2-1:0]};
1966
                8'hF0:  fnDatai = {{DBW/2{dat[DBW-1]}},dat[DBW-1:DBW/2]};
1967
                default:        fnDatai = {DBW{1'b1}};
1968
                endcase
1969
        `LHU,`LHUX:
1970
                case(sel)
1971
                8'h0F:  fnDatai = dat[DBW/2-1:0];
1972
                8'hF0:  fnDatai = dat[DBW-1:DBW/2];
1973
                default:        fnDatai = {DBW{1'b1}};
1974
                endcase
1975
        `LW,`LWX,`LVW,`LVWAR,`CAS,`LWS,`LCL,`POP,`UNLINK:
1976
                case(sel)
1977
                8'hFF:  fnDatai = dat;
1978
                default:        fnDatai = {DBW{1'b1}};
1979
                endcase
1980
        default:        fnDatai = {DBW{1'b1}};
1981
        endcase
1982
end
1983
endfunction
1984
 
1985
function [DBW-1:0] fnDatao;
1986
input [7:0] opcode;
1987
input [5:0] func;
1988
input [DBW-1:0] dat;
1989
if (DBW==32)
1990
        case(opcode)
1991
        `STMV,`INC:
1992
           case(func[2:0])
1993
           3'd0,3'd4:  fnDatao = {4{dat[7:0]}};
1994
           3'd1,3'd5:  fnDatao = {2{dat[15:8]}};
1995
           default:    fnDatao = dat;
1996
           endcase
1997
        `SW,`SWCR,`SWX,`CAS,`SWS,`STI,
1998
        `PUSH,`PEA,`LINK:       fnDatao = dat;
1999
        `SH,`SHX:       fnDatao = dat;
2000
        `SC,`SCX:       fnDatao = {2{dat[15:0]}};
2001
        `SB,`SBX:       fnDatao = {4{dat[7:0]}};
2002
        default:        fnDatao = dat;
2003
        endcase
2004
else
2005
        case(opcode)
2006
        `STMV,`INC:
2007
           case(func[2:0])
2008
           3'd0,3'd4:  fnDatao = {8{dat[DBW/8-1:0]}};
2009
           3'd1,3'd5:  fnDatao = {4{dat[DBW/4-1:0]}};
2010
           3'd2,3'd6:  fnDatao = {2{dat[DBW/2-1:0]}};
2011
           3'd3,3'd7:  fnDatao = dat;
2012
           endcase
2013
        `SW,`SWCR,`SWX,`CAS,`SWS,`STI,
2014
        `PUSH,`PEA,`LINK:       fnDatao = dat;
2015
        `SH,`SHX:       fnDatao = {2{dat[DBW/2-1:0]}};
2016
        `SC,`SCX:       fnDatao = {4{dat[DBW/4-1:0]}};
2017
        `SB,`SBX:       fnDatao = {8{dat[DBW/8-1:0]}};
2018
        default:        fnDatao = dat;
2019
        endcase
2020
endfunction
2021
 
2022
assign fetchbuf0_mem    = fetchbuf ? fnIsMem(opcodeC) : fnIsMem(opcodeA);
2023
assign fetchbuf0_jmp   = fnIsFlowCtrl(opcode0);
2024
assign fetchbuf0_fp             = fnIsFP(opcode0);
2025
assign fetchbuf0_rfw    = fetchbuf ? fnIsRFW(opcodeC,fetchbufC_instr) : fnIsRFW(opcodeA,fetchbufA_instr);
2026
assign fetchbuf0_pfw    = fetchbuf ? fnIsPFW(opcodeC) : fnIsPFW(opcodeA);
2027
assign fetchbuf1_mem    = fetchbuf ? fnIsMem(opcodeD) : fnIsMem(opcodeB);
2028
assign fetchbuf1_jmp   = fnIsFlowCtrl(opcode1);
2029
assign fetchbuf1_fp             = fnIsFP(opcode1);
2030
assign fetchbuf1_rfw    = fetchbuf ? fnIsRFW(opcodeD,fetchbufD_instr) : fnIsRFW(opcodeB,fetchbufB_instr);
2031
assign fetchbuf1_pfw    = fetchbuf ? fnIsPFW(opcodeD) : fnIsPFW(opcodeB);
2032
 
2033
wire predict_taken0 = fetchbuf ? predict_takenC : predict_takenA;
2034
wire predict_taken1 = fetchbuf ? predict_takenD : predict_takenB;
2035
//
2036
// set branchback and backpc values ... ignore branches in fetchbuf slots not ready for enqueue yet
2037
//
2038
assign take_branch0 = ({fetchbuf0_v, fnIsBranch(opcode0), predict_taken0}  == {`VAL, `TRUE, `TRUE}) ||
2039
                      ({fetchbuf0_v, opcode0==`LOOP}  == {`VAL, `TRUE})
2040
                        ;
2041
assign take_branch1 = ({fetchbuf1_v, fnIsBranch(opcode1), predict_taken1}  == {`VAL, `TRUE, `TRUE}) ||
2042
                      ({fetchbuf1_v, opcode1==`LOOP}  == {`VAL, `TRUE})
2043
                        ;
2044
assign take_branch = take_branch0 || take_branch1
2045
        ;
2046
 
2047
reg [DBW-1:0] branch_pc;// =
2048
//              ({fetchbuf0_v, fnIsBranch(opcode0), predict_taken0}  == {`VAL, `TRUE, `TRUE}) ? (ihit ?
2049
//                      fetchbuf0_pc + {{DBW-12{fetchbuf0_instr[11]}},fetchbuf0_instr[11:8],fetchbuf0_instr[23:16]} + 64'd3 : fetchbuf0_pc):
2050
//                      (ihit ? fetchbuf1_pc + {{DBW-12{fetchbuf1_instr[11]}},fetchbuf1_instr[11:8],fetchbuf1_instr[23:16]} + 64'd3 : fetchbuf1_pc);
2051
always @*
2052
if (fnIsBranch(opcode0) && fetchbuf0_v && predict_taken0) begin
2053
    if (ihit)
2054
        branch_pc <= fetchbuf0_pc + {{ABW-12{fetchbuf0_instr[11]}},fetchbuf0_instr[11:8],fetchbuf0_instr[23:16]} + 64'd3;
2055
    else
2056
        branch_pc <= fetchbuf0_pc;
2057
end
2058
else if (opcode0==`LOOP && fetchbuf0_v) begin
2059
    if (ihit)
2060
        branch_pc <= fetchbuf0_pc + {{ABW-8{fetchbuf0_instr[23]}},fetchbuf0_instr[23:16]} + 64'd3;
2061
    else
2062
        branch_pc <= fetchbuf0_pc;
2063
end
2064
else if (fnIsBranch(opcode1) && fetchbuf1_v && predict_taken1) begin
2065
    if (ihit)
2066
        branch_pc <= fetchbuf1_pc + {{ABW-12{fetchbuf1_instr[11]}},fetchbuf1_instr[11:8],fetchbuf1_instr[23:16]} + 64'd3;
2067
    else
2068
        branch_pc <= fetchbuf1_pc;
2069
end
2070
else if (opcode1==`LOOP && fetchbuf1_v) begin
2071
    if (ihit)
2072
        branch_pc <= fetchbuf1_pc + {{ABW-8{fetchbuf1_instr[23]}},fetchbuf1_instr[23:16]} + 64'd3;
2073
    else
2074
        branch_pc <= fetchbuf1_pc;
2075
end
2076
else begin
2077
    branch_pc <= {{ABW-8{1'b1}},8'h80};  // set to something to prevent a latch
2078
end
2079
 
2080
assign int_pending = (nmi_edge & ~StatusHWI & ~int_commit) || (irq_i & ~im & ~StatusHWI & ~int_commit);
2081
 
2082
assign mem_stringmiss = ((dram0_op==`STS || dram0_op==`STFND) && int_pending && lc != 0) ||
2083
                        ((dram0_op==`STMV || dram0_op==`STCMP) && int_pending && lc != 0 && stmv_flag);
2084
 
2085
// "Stream" interrupt instructions into the instruction stream until an INT
2086
// instruction commits. This avoids the problem of an INT instruction being
2087
// stomped on by a previous branch instruction.
2088
// Populate the instruction buffers with INT instructions for a hardware interrupt
2089
// Also populate the instruction buffers with a call to the instruction error vector
2090
// if an error occurred during instruction load time.
2091
// Translate the BRK opcode to a syscall.
2092
 
2093
// There is a one cycle delay in setting the StatusHWI that allowed an extra INT
2094
// instruction to sneek into the queue. This is NOPped out by the int_commit
2095
// signal.
2096
 
2097
// On a cache miss the instruction buffers are loaded with NOPs this prevents
2098
// the PC from being trashed by invalid branch instructions.
2099
reg [63:0] insn1a,insn2a;
2100
reg [63:0] insn0,insn1,insn2;
2101
always @*
2102
//if (int_commit)
2103
//      insn0 <= {8{8'h10}};    // load with NOPs
2104
//else
2105
if (nmi_edge & ~StatusHWI & ~int_commit)
2106
        insn0 <= {8'hFE,8'hCE,8'hA6,8'h01,8'hFE,8'hCE,8'hA6,8'h01};
2107
else if (ITLBMiss)
2108
        insn0 <= {8'hF9,8'hCE,8'hA6,8'h01,8'hF9,8'hCE,8'hA6,8'h01};
2109
else if (insnerr)
2110
        insn0 <= {8'hFC,8'hCE,8'hA6,8'h01,8'hFC,8'hCE,8'hA6,8'h01};
2111
else if (irq_i & ~im & ~StatusHWI & ~int_commit)
2112
        insn0 <= {vec_i,8'hCE,8'hA6,8'h01,vec_i,8'hCE,8'hA6,8'h01};
2113
else if (ihit) begin
2114
        if (insn[7:0]==8'h00)
2115
                insn0 <= {8'h00,8'hCD,8'hA5,8'h01,8'h00,8'hCD,8'hA5,8'h01};
2116
        else
2117
        insn0 <= insn[63:0];
2118
end
2119
else
2120
        insn0 <= {8{8'h10}};    // load with NOPs
2121
 
2122
 
2123
always @*
2124
//if (int_commit)
2125
//      insn1 <= {8{8'h10}};    // load with NOPs
2126
//else
2127
if (nmi_edge & ~StatusHWI & ~int_commit)
2128
        insn1 <= {8'hFE,8'hCE,8'hA6,8'h01,8'hFE,8'hCE,8'hA6,8'h01};
2129
else if (ITLBMiss)
2130
        insn1 <= {8'hF9,8'hCE,8'hA6,8'h01,8'hF9,8'hCE,8'hA6,8'h01};
2131
else if (insnerr)
2132
        insn1 <= {8'hFC,8'hCE,8'hA6,8'h01,8'hFC,8'hCE,8'hA6,8'h01};
2133
else if (irq_i & ~im & ~StatusHWI & ~int_commit)
2134
        insn1 <= {vec_i,8'hCE,8'hA6,8'h01,vec_i,8'hCE,8'hA6,8'h01};
2135
else if (ihit) begin
2136
        if (insn1a[7:0]==8'h00)
2137
                insn1 <= {8'h00,8'hCD,8'hA5,8'h01,8'h00,8'hCD,8'hA5,8'h01};
2138
        else
2139
                insn1 <= insn1a;
2140
end
2141
else
2142
        insn1 <= {8{8'h10}};    // load with NOPs
2143
 
2144
 
2145
// Find the second instruction in the instruction line.
2146
always @(insn)
2147
        case(fnInsnLength(insn))
2148
        4'd1:   insn1a <= insn[71: 8];
2149
        4'd2:   insn1a <= insn[79:16];
2150
        4'd3:   insn1a <= insn[87:24];
2151
        4'd4:   insn1a <= insn[95:32];
2152
        4'd5:   insn1a <= insn[103:40];
2153
        4'd6:   insn1a <= insn[111:48];
2154
        4'd7:   insn1a <= insn[119:56];
2155
        4'd8:   insn1a <= insn[127:64];
2156
        default:        insn1a <= {8{8'h10}};   // NOPs
2157
        endcase
2158
 
2159
// Return the immediate field of an instruction
2160
function [63:0] fnImm;
2161
input [127:0] insn;
2162
casex(insn[15:0])
2163
16'bxxxxxxxx00010001:   // RTS short form
2164
    fnImm = 64'd0;
2165
default:
2166
casex(insn[15:8])
2167
`P:     fnImm = insn[33:16];
2168
`CAS:   fnImm = {{56{insn[47]}},insn[47:40]};
2169
`BCD:   fnImm = insn[47:40];
2170
`TLB:   fnImm = insn[23:16];
2171
`LOOP:  fnImm = {{56{insn[23]}},insn[23:16]};
2172
`STP:   fnImm = insn[31:16];
2173
`JSR:   fnImm = {{40{insn[47]}},insn[47:24]};
2174
`JSRS:  fnImm = {{48{insn[39]}},insn[39:24]};
2175
`BITFIELD:      fnImm = insn[47:32];
2176
`SYS,`INT:      fnImm = insn[31:24];
2177
`RTS2:  fnImm = {insn[31:27],3'b000};
2178
`CMPI,`LDI,`LDIS,`ADDUIS:
2179
        fnImm = {{54{insn[31]}},insn[31:22]};
2180
`RTS:   fnImm = insn[19:16];
2181
`RTD,`RTE,`RTI,`JSRZ,`STMV,`STCMP,`STFND,`CACHE,`STS:   fnImm = 8'h00;
2182
`STI:   fnImm = {{58{insn[33]}},insn[33:28]};
2183
//`LINK:  fnImm = {insn[39:28],3'b000};
2184
`LB,`LBU,`LC,`LCU,`LH,`LHU,`LW,`LVB,`LVC,`LVH,`LVW,`LVWAR,
2185
`SB,`SC,`SH,`SW,`SWCR,`LWS,`SWS,`INC,`LCL,`PEA:
2186
        fnImm = {{55{insn[36]}},insn[36:28]};
2187
default:
2188
        fnImm = {{52{insn[39]}},insn[39:28]};
2189
endcase
2190
endcase
2191
 
2192
endfunction
2193
 
2194
function [7:0] fnImm8;
2195
input [127:0] insn;
2196
if (insn[7:0]==8'h11)
2197
    fnImm8 = 8'h00;
2198
else
2199
casex(insn[15:8])
2200
`CAS:   fnImm8 = insn[47:40];
2201
`BCD:   fnImm8 = insn[47:40];
2202
`TLB:   fnImm8 = insn[23:16];
2203
`LOOP:  fnImm8 = insn[23:16];
2204
`STP:   fnImm8 = insn[23:16];
2205
`JSR,`JSRS,`RTS2:       fnImm8 = insn[31:24];
2206
`BITFIELD:      fnImm8 = insn[39:32];
2207
`SYS,`INT:      fnImm8 = insn[31:24];
2208
`CMPI,`LDI,`LDIS,`ADDUIS:       fnImm8 = insn[29:22];
2209
`RTS:   fnImm8 = insn[19:16];
2210
`RTD,`RTE,`RTI,`JSRZ,`STMV,`STCMP,`STFND,`CACHE,`STS:   fnImm8 = 8'h00;
2211
`STI:   fnImm8 = insn[35:28];
2212
//`LINK:  fnImm8 = {insn[32:28],3'b000};
2213
`LB,`LBU,`LC,`LCU,`LH,`LHU,`LW,`LVB,`LVC,`LVH,`LVW,`LVWAR,
2214
`SB,`SC,`SH,`SW,`SWCR,`LWS,`SWS,`INC,`LCL,`PEA:
2215
        fnImm8 = insn[35:28];
2216
default:        fnImm8 = insn[35:28];
2217
endcase
2218
endfunction
2219
 
2220
// Return MSB of immediate value for instruction
2221
function fnImmMSB;
2222
input [127:0] insn;
2223
if (insn[7:0]==8'h11)
2224
    fnImmMSB = 1'b0;
2225
else
2226
casex(insn[15:8])
2227
`CAS:   fnImmMSB = insn[47];
2228
`TLB,`BCD,`STP:
2229
        fnImmMSB = 1'b0;                // TLB regno is unsigned
2230
`LOOP:
2231
        fnImmMSB = insn[23];
2232
`JSR:
2233
        fnImmMSB = insn[47];
2234
`JSRS:
2235
    fnImmMSB = insn[39];
2236
`CMPI,`LDI,`LDIS,`ADDUIS:
2237
        fnImmMSB = insn[31];
2238
`SYS,`INT,`CACHE,`LINK:
2239
        fnImmMSB = 1'b0;                // SYS,INT are unsigned
2240
`RTS,`RTD,`RTE,`RTI,`JSRZ,`STMV,`STCMP,`STFND,`RTS2,`STS:
2241
        fnImmMSB = 1'b0;                // RTS is unsigned
2242
`LBX,`LBUX,`LCX,`LCUX,`LHX,`LHUX,`LWX,
2243
`SBX,`SCX,`SHX,`SWX:
2244
        fnImmMSB = insn[47];
2245
`LB,`LBU,`LC,`LCU,`LH,`LHU,`LW,`LVB,`LVC,`LVH,`LVW,
2246
`SB,`SC,`SH,`SW,`SWCR,`STI,`LWS,`SWS,`INC,`LCL,`PEA:
2247
        fnImmMSB = insn[36];
2248
default:
2249
        fnImmMSB = insn[39];
2250
endcase
2251
 
2252
endfunction
2253
 
2254
function [63:0] fnImmImm;
2255
input [63:0] insn;
2256
case(insn[7:4])
2257
4'd2:   fnImmImm = {{48{insn[15]}},insn[15:8],8'h00};
2258
4'd3:   fnImmImm = {{40{insn[23]}},insn[23:8],8'h00};
2259
4'd4:   fnImmImm = {{32{insn[31]}},insn[31:8],8'h00};
2260
4'd5:   fnImmImm = {{24{insn[39]}},insn[39:8],8'h00};
2261
4'd6:   fnImmImm = {{16{insn[47]}},insn[47:8],8'h00};
2262
4'd7:   fnImmImm = {{ 8{insn[55]}},insn[55:8],8'h00};
2263
4'd8:   fnImmImm = {insn[63:8],8'h00};
2264
default:        fnImmImm = 64'd0;
2265
endcase
2266
endfunction
2267
 
2268
function [63:0] fnOpa;
2269
input [7:0] opcode;
2270
input [63:0] ins;
2271
input [63:0] rfo;
2272
input [63:0] epc;
2273
begin
2274
`ifdef BITFIELDOPS
2275
    if (opcode==`BITFIELD && ins[43:40]==4'd6) // BFINSI
2276
        fnOpa = ins[21:16];
2277
    else
2278
`endif
2279
    if (opcode==`RTS) begin
2280
        fnOpa = (commit1_v && commit1_tgt[6:0]==7'h51) ? commit1_bus :
2281
                (commit0_v && commit0_tgt[6:0]==7'h51) ? commit0_bus :
2282
                cregs[3'd1];
2283
    end
2284
        else if (opcode==`LOOP)
2285
                fnOpa = epc;
2286
        else if (fnIsFlowCtrl(opcode))
2287
                fnOpa = fnCar(ins)==4'd0 ? 64'd0 : fnCar(ins)==4'd15 ? epc :
2288
                        (commit1_v && commit1_tgt[6:4]==3'h5 && commit1_tgt[3:0]==fnCar(ins)) ? commit1_bus :
2289
                        (commit0_v && commit0_tgt[6:4]==3'h5 && commit0_tgt[3:0]==fnCar(ins)) ? commit0_bus :
2290
                        cregs[fnCar(ins)];
2291
    else if (opcode==`P)
2292
        fnOpa = fnSpr(6'h30,epc);
2293
        else if (opcode==`MFSPR || opcode==`MOVS)
2294
            fnOpa = fnSpr(ins[`INSTRUCTION_RA],epc);
2295
/*
2296
                casex(ins[21:16])
2297
                `TICK:  fnOpa = tick;
2298
                `LCTR:  fnOpa = lc;
2299
                `PREGS_ALL:
2300
                                begin
2301
                                        fnOpa[3:0] = pregs[0];
2302
                                        fnOpa[7:4] = pregs[1];
2303
                                        fnOpa[11:8] = pregs[2];
2304
                                        fnOpa[15:12] = pregs[3];
2305
                                        fnOpa[19:16] = pregs[4];
2306
                                        fnOpa[23:20] = pregs[5];
2307
                                        fnOpa[27:24] = pregs[6];
2308
                                        fnOpa[31:28] = pregs[7];
2309
                                        fnOpa[35:32] = pregs[8];
2310
                                        fnOpa[39:36] = pregs[9];
2311
                                        fnOpa[43:40] = pregs[10];
2312
                                        fnOpa[47:44] = pregs[11];
2313
                                        fnOpa[51:48] = pregs[12];
2314
                                        fnOpa[55:52] = pregs[13];
2315
                                        fnOpa[59:56] = pregs[14];
2316
                                        fnOpa[63:60] = pregs[15];
2317
                                end
2318
                `ASID:  fnOpa = asid;
2319
                `SR:    fnOpa = sr;
2320
                6'h1x:  fnOpa = ins[19:16]==4'h0 ? 64'd0 : ins[19:16]==4'hF ? epc :
2321
                                                (commit0_v && commit0_tgt[6:4]==3'h5 && commit0_tgt[3:0]==ins[19:16]) ? commit0_bus :
2322
                                                cregs[ins[19:16]];
2323
`ifdef SEGMENTATION
2324
                6'h2x:  fnOpa =
2325
                        (commit0_v && commit0_tgt[6:4]==3'h6 && commit0_tgt[3:0]==ins[18:16]) ? {commit0_bus[DBW-1:12],12'h000} :
2326
                        {sregs[ins[18:16]],12'h000};
2327
`endif
2328
                default:        fnOpa = 64'h0;
2329
                endcase
2330
*/
2331
        else
2332
                fnOpa = rfo;
2333
end
2334
endfunction
2335
 
2336
function fnIsKMOnly;
2337
input [7:0] op;
2338
    fnIsKMOnly = op==`RTI || op==`RTE || op==`RTD || op==`TLB || op==`CLI || op==`SEI ||
2339
                 op==`STP
2340
                ;
2341
endfunction
2342
 
2343
function [15:0] fnRegstrGrp;
2344
input [6:0] Rn;
2345
if (!Rn[6]) begin
2346
        fnRegstrGrp="GP";
2347
end
2348
else
2349
        case(Rn[5:4])
2350
        2'h0:   fnRegstrGrp="PR";
2351
        2'h1:   fnRegstrGrp="CA";
2352
        2'h2:   fnRegstrGrp="SG";
2353
        2'h3:
2354
               case(Rn[3:0])
2355
               3'h0:   fnRegstrGrp="PA";
2356
               3'h3:   fnRegstrGrp="LC";
2357
               endcase
2358
        endcase
2359
 
2360
endfunction
2361
 
2362
function [7:0] fnRegstr;
2363
input [6:0] Rn;
2364
begin
2365
if (!Rn[6]) begin
2366
        fnRegstr = Rn[5:0];
2367
end
2368
else
2369
        fnRegstr = Rn[3:0];
2370
end
2371
endfunction
2372
 
2373
initial begin
2374
        //
2375
        // set up panic messages
2376
        message[ `PANIC_NONE ]                  = "NONE            ";
2377
        message[ `PANIC_FETCHBUFBEQ ]           = "FETCHBUFBEQ     ";
2378
        message[ `PANIC_INVALIDISLOT ]          = "INVALIDISLOT    ";
2379
        message[ `PANIC_IDENTICALDRAMS ]        = "IDENTICALDRAMS  ";
2380
        message[ `PANIC_OVERRUN ]               = "OVERRUN         ";
2381
        message[ `PANIC_HALTINSTRUCTION ]       = "HALTINSTRUCTION ";
2382
        message[ `PANIC_INVALIDMEMOP ]          = "INVALIDMEMOP    ";
2383
        message[ `PANIC_INVALIDFBSTATE ]        = "INVALIDFBSTATE  ";
2384
        message[ `PANIC_INVALIDIQSTATE ]        = "INVALIDIQSTATE  ";
2385
        message[ `PANIC_BRANCHBACK ]            = "BRANCHBACK      ";
2386
        message[ `PANIC_MEMORYRACE ]            = "MEMORYRACE      ";
2387
end
2388
 
2389
//`include "Thor_issue_combo.v"
2390
/*
2391
assign  iqentry_imm[0] = fnHasConst(iqentry_op[0]),
2392
        iqentry_imm[1] = fnHasConst(iqentry_op[1]),
2393
        iqentry_imm[2] = fnHasConst(iqentry_op[2]),
2394
        iqentry_imm[3] = fnHasConst(iqentry_op[3]),
2395
        iqentry_imm[4] = fnHasConst(iqentry_op[4]),
2396
        iqentry_imm[5] = fnHasConst(iqentry_op[5]),
2397
        iqentry_imm[6] = fnHasConst(iqentry_op[6]),
2398
        iqentry_imm[7] = fnHasConst(iqentry_op[7]);
2399
*/
2400
//
2401
// additional logic for ISSUE
2402
//
2403
// for the moment, we look at ALU-input buffers to allow back-to-back issue of 
2404
// dependent instructions ... we do not, however, look ahead for DRAM requests 
2405
// that will become valid in the next cycle.  instead, these have to propagate
2406
// their results into the IQ entry directly, at which point it becomes issue-able
2407
//
2408
 
2409
always @*
2410
for (n = 0; n < QENTRIES; n = n + 1)
2411
    iq_cmt[n] <= fnPredicate(iqentry_pred[n], iqentry_cond[n]) ||
2412
        (iqentry_cond[n] < 4'h2 && ({iqentry_pred[n],iqentry_cond[n]}!=8'h90));
2413
 
2414
wire [QENTRIES-1:0] args_valid;
2415
wire [QENTRIES-1:0] could_issue;
2416
 
2417
genvar g;
2418
generate
2419
begin : argsv
2420
 
2421
for (g = 0; g < QENTRIES; g = g + 1)
2422
begin
2423
assign  iqentry_imm[g] = fnHasConst(iqentry_op[g]);
2424
 
2425
assign args_valid[g] =
2426
                        (iqentry_p_v[g]
2427
                                || (iqentry_p_s[g]==alu0_sourceid && alu0_v)
2428
                                || (iqentry_p_s[g]==alu1_sourceid && alu1_v))
2429
                        && (iqentry_a1_v[g]
2430
//                              || (iqentry_mem[g] && !iqentry_agen[g] && iqentry_op[g]!=`TLB)
2431
                                || (iqentry_a1_s[g] == alu0_sourceid && alu0_v)
2432
                                || (iqentry_a1_s[g] == alu1_sourceid && alu1_v))
2433
                        && (iqentry_a2_v[g]
2434
                                || (iqentry_a2_s[g] == alu0_sourceid && alu0_v)
2435
                                || (iqentry_a2_s[g] == alu1_sourceid && alu1_v))
2436
                        && (iqentry_a3_v[g]
2437
                                || (iqentry_a3_s[g] == alu0_sourceid && alu0_v)
2438
                                || (iqentry_a3_s[g] == alu1_sourceid && alu1_v))
2439
                        && (iqentry_T_v[g]
2440
                                || (iqentry_T_s[g] == alu0_sourceid && alu0_v)
2441
                || (iqentry_T_s[g] == alu1_sourceid && alu1_v))
2442
                        ;
2443
 
2444
assign could_issue[g] = iqentry_v[g] && !iqentry_done[g] && !iqentry_out[g] && args_valid[g] &&
2445
                         (iqentry_mem[g] ? !iqentry_agen[g] : 1'b1);// && iq_cmt[g];
2446
 
2447
end
2448
end
2449
endgenerate
2450
 
2451
// The (old) simulator didn't handle the asynchronous race loop properly in the 
2452
// original code. It would issue two instructions to the same islot. So the
2453
// issue logic has been re-written to eliminate the asynchronous loop.
2454
always @*//(could_issue or head0 or head1 or head2 or head3 or head4 or head5 or head6 or head7)
2455
begin
2456
        iqentry_issue = 8'h00;
2457
        iqentry_islot[0] = 2'b00;
2458
        iqentry_islot[1] = 2'b00;
2459
        iqentry_islot[2] = 2'b00;
2460
        iqentry_islot[3] = 2'b00;
2461
        iqentry_islot[4] = 2'b00;
2462
        iqentry_islot[5] = 2'b00;
2463
        iqentry_islot[6] = 2'b00;
2464
        iqentry_islot[7] = 2'b00;
2465
        if (could_issue[head0] & !iqentry_fp[head0]) begin
2466
                iqentry_issue[head0] = `TRUE;
2467
                iqentry_islot[head0] = 2'b00;
2468
        end
2469
        else if (could_issue[head1] & !iqentry_fp[head1]
2470
        && !(iqentry_v[head0] && iqentry_op[head0]==`SYNC))
2471
        begin
2472
                iqentry_issue[head1] = `TRUE;
2473
                iqentry_islot[head1] = 2'b00;
2474
        end
2475
        else if (could_issue[head2] & !iqentry_fp[head2]
2476
        && !(iqentry_v[head0] && iqentry_op[head0]==`SYNC)
2477
        && !(iqentry_v[head1] && iqentry_op[head1]==`SYNC)
2478
        )
2479
        begin
2480
                iqentry_issue[head2] = `TRUE;
2481
                iqentry_islot[head2] = 2'b00;
2482
        end
2483
        else if (could_issue[head3] & !iqentry_fp[head3]
2484
        && !(iqentry_v[head0] && iqentry_op[head0]==`SYNC)
2485
        && !(iqentry_v[head1] && iqentry_op[head1]==`SYNC)
2486
        && !(iqentry_v[head2] && iqentry_op[head2]==`SYNC)
2487
        ) begin
2488
                iqentry_issue[head3] = `TRUE;
2489
                iqentry_islot[head3] = 2'b00;
2490
        end
2491
        else if (could_issue[head4] & !iqentry_fp[head4]
2492
        && !(iqentry_v[head0] && iqentry_op[head0]==`SYNC)
2493
        && !(iqentry_v[head1] && iqentry_op[head1]==`SYNC)
2494
        && !(iqentry_v[head2] && iqentry_op[head2]==`SYNC)
2495
        && !(iqentry_v[head3] && iqentry_op[head3]==`SYNC)
2496
        ) begin
2497
                iqentry_issue[head4] = `TRUE;
2498
                iqentry_islot[head4] = 2'b00;
2499
        end
2500
        else if (could_issue[head5] & !iqentry_fp[head5]
2501
        && !(iqentry_v[head0] && iqentry_op[head0]==`SYNC)
2502
        && !(iqentry_v[head1] && iqentry_op[head1]==`SYNC)
2503
        && !(iqentry_v[head2] && iqentry_op[head2]==`SYNC)
2504
        && !(iqentry_v[head3] && iqentry_op[head3]==`SYNC)
2505
        && !(iqentry_v[head4] && iqentry_op[head4]==`SYNC)
2506
        ) begin
2507
                iqentry_issue[head5] = `TRUE;
2508
                iqentry_islot[head5] = 2'b00;
2509
        end
2510
        else if (could_issue[head6] & !iqentry_fp[head6]
2511
        && !(iqentry_v[head0] && iqentry_op[head0]==`SYNC)
2512
        && !(iqentry_v[head1] && iqentry_op[head1]==`SYNC)
2513
        && !(iqentry_v[head2] && iqentry_op[head2]==`SYNC)
2514
        && !(iqentry_v[head3] && iqentry_op[head3]==`SYNC)
2515
        && !(iqentry_v[head4] && iqentry_op[head4]==`SYNC)
2516
        && !(iqentry_v[head5] && iqentry_op[head5]==`SYNC)
2517
        ) begin
2518
                iqentry_issue[head6] = `TRUE;
2519
                iqentry_islot[head6] = 2'b00;
2520
        end
2521
        else if (could_issue[head7] & !iqentry_fp[head7]
2522
        && !(iqentry_v[head0] && iqentry_op[head0]==`SYNC)
2523
        && !(iqentry_v[head1] && iqentry_op[head1]==`SYNC)
2524
        && !(iqentry_v[head2] && iqentry_op[head2]==`SYNC)
2525
        && !(iqentry_v[head3] && iqentry_op[head3]==`SYNC)
2526
        && !(iqentry_v[head4] && iqentry_op[head4]==`SYNC)
2527
        && !(iqentry_v[head5] && iqentry_op[head5]==`SYNC)
2528
        && !(iqentry_v[head6] && iqentry_op[head6]==`SYNC)
2529
        ) begin
2530
                iqentry_issue[head7] = `TRUE;
2531
                iqentry_islot[head7] = 2'b00;
2532
        end
2533
 
2534
    // Don't bother checking head0, it should have issued to the first
2535
    // instruction.
2536
        if (could_issue[head1] && !iqentry_fp[head1] && !iqentry_issue[head1]
2537
        && !fnIsAlu0Op(iqentry_op[head1],iqentry_fn[head1])
2538
        && !(iqentry_v[head0] && iqentry_op[head0]==`SYNC))
2539
        begin
2540
                iqentry_issue[head1] = `TRUE;
2541
                iqentry_islot[head1] = 2'b01;
2542
        end
2543
        else if (could_issue[head2] && !iqentry_fp[head2] && !iqentry_issue[head2]
2544
        && !fnIsAlu0Op(iqentry_op[head2],iqentry_fn[head2])
2545
        && !(iqentry_v[head0] && iqentry_op[head0]==`SYNC)
2546
        && !(iqentry_v[head1] && iqentry_op[head1]==`SYNC)
2547
        )
2548
        begin
2549
                iqentry_issue[head2] = `TRUE;
2550
                iqentry_islot[head2] = 2'b01;
2551
        end
2552
        else if (could_issue[head3] & !iqentry_fp[head3] && !iqentry_issue[head3]
2553
        && !fnIsAlu0Op(iqentry_op[head3],iqentry_fn[head3])
2554
        && !(iqentry_v[head0] && iqentry_op[head0]==`SYNC)
2555
        && !(iqentry_v[head1] && iqentry_op[head1]==`SYNC)
2556
        && !(iqentry_v[head2] && iqentry_op[head2]==`SYNC)
2557
        ) begin
2558
                iqentry_issue[head3] = `TRUE;
2559
                iqentry_islot[head3] = 2'b01;
2560
        end
2561
        else if (could_issue[head4] & !iqentry_fp[head4] && !iqentry_issue[head4]
2562
        && !fnIsAlu0Op(iqentry_op[head4],iqentry_fn[head4])
2563
        && !(iqentry_v[head0] && iqentry_op[head0]==`SYNC)
2564
        && !(iqentry_v[head1] && iqentry_op[head1]==`SYNC)
2565
        && !(iqentry_v[head2] && iqentry_op[head2]==`SYNC)
2566
        && !(iqentry_v[head3] && iqentry_op[head3]==`SYNC)
2567
        ) begin
2568
                iqentry_issue[head4] = `TRUE;
2569
                iqentry_islot[head4] = 2'b01;
2570
        end
2571
        else if (could_issue[head5] & !iqentry_fp[head5] && !iqentry_issue[head5]
2572
        && !fnIsAlu0Op(iqentry_op[head5],iqentry_fn[head5])
2573
        && !(iqentry_v[head0] && iqentry_op[head0]==`SYNC)
2574
        && !(iqentry_v[head1] && iqentry_op[head1]==`SYNC)
2575
        && !(iqentry_v[head2] && iqentry_op[head2]==`SYNC)
2576
        && !(iqentry_v[head3] && iqentry_op[head3]==`SYNC)
2577
        && !(iqentry_v[head4] && iqentry_op[head4]==`SYNC)
2578
        ) begin
2579
                iqentry_issue[head5] = `TRUE;
2580
                iqentry_islot[head5] = 2'b01;
2581
        end
2582
        else if (could_issue[head6] & !iqentry_fp[head6] && !iqentry_issue[head6]
2583
        && !fnIsAlu0Op(iqentry_op[head6],iqentry_fn[head6])
2584
        && !(iqentry_v[head0] && iqentry_op[head0]==`SYNC)
2585
        && !(iqentry_v[head1] && iqentry_op[head1]==`SYNC)
2586
        && !(iqentry_v[head2] && iqentry_op[head2]==`SYNC)
2587
        && !(iqentry_v[head3] && iqentry_op[head3]==`SYNC)
2588
        && !(iqentry_v[head4] && iqentry_op[head4]==`SYNC)
2589
        && !(iqentry_v[head5] && iqentry_op[head5]==`SYNC)
2590
        ) begin
2591
                iqentry_issue[head6] = `TRUE;
2592
                iqentry_islot[head6] = 2'b01;
2593
        end
2594
        else if (could_issue[head7] & !iqentry_fp[head7] && !iqentry_issue[head7]
2595
        && !fnIsAlu0Op(iqentry_op[head7],iqentry_fn[head7])
2596
        && !(iqentry_v[head0] && iqentry_op[head0]==`SYNC)
2597
        && !(iqentry_v[head1] && iqentry_op[head1]==`SYNC)
2598
        && !(iqentry_v[head2] && iqentry_op[head2]==`SYNC)
2599
        && !(iqentry_v[head3] && iqentry_op[head3]==`SYNC)
2600
        && !(iqentry_v[head4] && iqentry_op[head4]==`SYNC)
2601
        && !(iqentry_v[head5] && iqentry_op[head5]==`SYNC)
2602
        && !(iqentry_v[head6] && iqentry_op[head6]==`SYNC)
2603
        ) begin
2604
                iqentry_issue[head7] = `TRUE;
2605
                iqentry_islot[head7] = 2'b01;
2606
        end
2607
end
2608
 
2609
 
2610
`ifdef FLOATING_POINT
2611
reg [3:0] fpispot;
2612
always @(could_issue or head0 or head1 or head2 or head3 or head4 or head5 or head6 or head7)
2613
begin
2614
        iqentry_fpissue = 8'h00;
2615
        iqentry_fpislot[0] = 2'b00;
2616
        iqentry_fpislot[1] = 2'b00;
2617
        iqentry_fpislot[2] = 2'b00;
2618
        iqentry_fpislot[3] = 2'b00;
2619
        iqentry_fpislot[4] = 2'b00;
2620
        iqentry_fpislot[5] = 2'b00;
2621
        iqentry_fpislot[6] = 2'b00;
2622
        iqentry_fpislot[7] = 2'b00;
2623
        fpispot = head0;
2624
        if (could_issue[head0] & iqentry_fp[head0]) begin
2625
                iqentry_fpissue[head0] = `TRUE;
2626
                iqentry_fpislot[head0] = 2'b00;
2627
                fpispot = head0;
2628
        end
2629
        else if (could_issue[head1] & iqentry_fp[head1]
2630
        && !(iqentry_v[head0] && iqentry_op[head0]==`SYNC))
2631
        begin
2632
                iqentry_fpissue[head1] = `TRUE;
2633
                iqentry_fpislot[head1] = 2'b00;
2634
                fpispot = head1;
2635
        end
2636
        else if (could_issue[head2] & iqentry_fp[head2]
2637
        && !(iqentry_v[head0] && iqentry_op[head0]==`SYNC)
2638
        && !(iqentry_v[head1] && iqentry_op[head1]==`SYNC)
2639
        )
2640
        begin
2641
                iqentry_fpissue[head2] = `TRUE;
2642
                iqentry_fpislot[head2] = 2'b00;
2643
                fpispot = head2;
2644
        end
2645
        else if (could_issue[head3] & iqentry_fp[head3]
2646
        && !(iqentry_v[head0] && iqentry_op[head0]==`SYNC)
2647
        && !(iqentry_v[head1] && iqentry_op[head1]==`SYNC)
2648
        && !(iqentry_v[head2] && iqentry_op[head2]==`SYNC)
2649
        ) begin
2650
                iqentry_fpissue[head3] = `TRUE;
2651
                iqentry_fpislot[head3] = 2'b00;
2652
                fpispot = head3;
2653
        end
2654
        else if (could_issue[head4] & iqentry_fp[head4]
2655
        && !(iqentry_v[head0] && iqentry_op[head0]==`SYNC)
2656
        && !(iqentry_v[head1] && iqentry_op[head1]==`SYNC)
2657
        && !(iqentry_v[head2] && iqentry_op[head2]==`SYNC)
2658
        && !(iqentry_v[head3] && iqentry_op[head3]==`SYNC)
2659
        ) begin
2660
                iqentry_fpissue[head4] = `TRUE;
2661
                iqentry_fpislot[head4] = 2'b00;
2662
                fpispot = head4;
2663
        end
2664
        else if (could_issue[head5] & iqentry_fp[head5]
2665
        && !(iqentry_v[head0] && iqentry_op[head0]==`SYNC)
2666
        && !(iqentry_v[head1] && iqentry_op[head1]==`SYNC)
2667
        && !(iqentry_v[head2] && iqentry_op[head2]==`SYNC)
2668
        && !(iqentry_v[head3] && iqentry_op[head3]==`SYNC)
2669
        && !(iqentry_v[head4] && iqentry_op[head4]==`SYNC)
2670
        ) begin
2671
                iqentry_fpissue[head5] = `TRUE;
2672
                iqentry_fpislot[head5] = 2'b00;
2673
                fpispot = head5;
2674
        end
2675
        else if (could_issue[head6] & iqentry_fp[head6]
2676
        && !(iqentry_v[head0] && iqentry_op[head0]==`SYNC)
2677
        && !(iqentry_v[head1] && iqentry_op[head1]==`SYNC)
2678
        && !(iqentry_v[head2] && iqentry_op[head2]==`SYNC)
2679
        && !(iqentry_v[head3] && iqentry_op[head3]==`SYNC)
2680
        && !(iqentry_v[head4] && iqentry_op[head4]==`SYNC)
2681
        && !(iqentry_v[head5] && iqentry_op[head5]==`SYNC)
2682
        ) begin
2683
                iqentry_fpissue[head6] = `TRUE;
2684
                iqentry_fpislot[head6] = 2'b00;
2685
                fpispot = head6;
2686
        end
2687
        else if (could_issue[head7] & iqentry_fp[head7]
2688
        && !(iqentry_v[head0] && iqentry_op[head0]==`SYNC)
2689
        && !(iqentry_v[head1] && iqentry_op[head1]==`SYNC)
2690
        && !(iqentry_v[head2] && iqentry_op[head2]==`SYNC)
2691
        && !(iqentry_v[head3] && iqentry_op[head3]==`SYNC)
2692
        && !(iqentry_v[head4] && iqentry_op[head4]==`SYNC)
2693
        && !(iqentry_v[head5] && iqentry_op[head5]==`SYNC)
2694
        && !(iqentry_v[head6] && iqentry_op[head6]==`SYNC)
2695
        ) begin
2696
                iqentry_fpissue[head7] = `TRUE;
2697
                iqentry_fpislot[head7] = 2'b00;
2698
                fpispot = head7;
2699
        end
2700
        else
2701
                fpispot = 4'd8;
2702
 
2703
end
2704
`endif
2705
 
2706
// 
2707
// additional logic for handling a branch miss (STOMP logic)
2708
//
2709
assign iqentry_stomp[0] = branchmiss & (iqentry_v[0] && head0 != 3'd0 && (missid == 3'd7 || iqentry_stomp[7]));
2710
assign iqentry_stomp[1] = branchmiss & (iqentry_v[1] && head0 != 3'd1 && (missid == 3'd0 || iqentry_stomp[0]));
2711
assign iqentry_stomp[2] = branchmiss & (iqentry_v[2] && head0 != 3'd2 && (missid == 3'd1 || iqentry_stomp[1]));
2712
assign iqentry_stomp[3] = branchmiss & (iqentry_v[3] && head0 != 3'd3 && (missid == 3'd2 || iqentry_stomp[2]));
2713
assign iqentry_stomp[4] = branchmiss & (iqentry_v[4] && head0 != 3'd4 && (missid == 3'd3 || iqentry_stomp[3]));
2714
assign iqentry_stomp[5] = branchmiss & (iqentry_v[5] && head0 != 3'd5 && (missid == 3'd4 || iqentry_stomp[4]));
2715
assign iqentry_stomp[6] = branchmiss & (iqentry_v[6] && head0 != 3'd6 && (missid == 3'd5 || iqentry_stomp[5]));
2716
assign iqentry_stomp[7] = branchmiss & (iqentry_v[7] && head0 != 3'd7 && (missid == 3'd6 || iqentry_stomp[6]));
2717
 
2718
assign alu0_issue = (!(iqentry_v[0] && iqentry_stomp[0]) && iqentry_issue[0] && iqentry_islot[0]==2'd0) ||
2719
                        (!(iqentry_v[1] && iqentry_stomp[1]) && iqentry_issue[1] && iqentry_islot[1]==2'd0) ||
2720
                        (!(iqentry_v[2] && iqentry_stomp[2]) && iqentry_issue[2] && iqentry_islot[2]==2'd0) ||
2721
                        (!(iqentry_v[3] && iqentry_stomp[3]) && iqentry_issue[3] && iqentry_islot[3]==2'd0) ||
2722
                        (!(iqentry_v[4] && iqentry_stomp[4]) && iqentry_issue[4] && iqentry_islot[4]==2'd0) ||
2723
                        (!(iqentry_v[5] && iqentry_stomp[5]) && iqentry_issue[5] && iqentry_islot[5]==2'd0) ||
2724
                        (!(iqentry_v[6] && iqentry_stomp[6]) && iqentry_issue[6] && iqentry_islot[6]==2'd0) ||
2725
                        (!(iqentry_v[7] && iqentry_stomp[7]) && iqentry_issue[7] && iqentry_islot[7]==2'd0)
2726
                        ;
2727
 
2728
assign alu1_issue = (!(iqentry_v[0] && iqentry_stomp[0]) && iqentry_issue[0] && iqentry_islot[0]==2'd1) ||
2729
                        (!(iqentry_v[1] && iqentry_stomp[1]) && iqentry_issue[1] && iqentry_islot[1]==2'd1) ||
2730
                        (!(iqentry_v[2] && iqentry_stomp[2]) && iqentry_issue[2] && iqentry_islot[2]==2'd1) ||
2731
                        (!(iqentry_v[3] && iqentry_stomp[3]) && iqentry_issue[3] && iqentry_islot[3]==2'd1) ||
2732
                        (!(iqentry_v[4] && iqentry_stomp[4]) && iqentry_issue[4] && iqentry_islot[4]==2'd1) ||
2733
                        (!(iqentry_v[5] && iqentry_stomp[5]) && iqentry_issue[5] && iqentry_islot[5]==2'd1) ||
2734
                        (!(iqentry_v[6] && iqentry_stomp[6]) && iqentry_issue[6] && iqentry_islot[6]==2'd1) ||
2735
                        (!(iqentry_v[7] && iqentry_stomp[7]) && iqentry_issue[7] && iqentry_islot[7]==2'd1)
2736
                        ;
2737
 
2738
`ifdef FLOATING_POINT
2739
assign fp0_issue = (!(iqentry_v[0] && iqentry_stomp[0]) && iqentry_fpissue[0] && iqentry_islot[0]==2'd0) ||
2740
                        (!(iqentry_v[1] && iqentry_stomp[1]) && iqentry_fpissue[1] && iqentry_islot[1]==2'd0) ||
2741
                        (!(iqentry_v[2] && iqentry_stomp[2]) && iqentry_fpissue[2] && iqentry_islot[2]==2'd0) ||
2742
                        (!(iqentry_v[3] && iqentry_stomp[3]) && iqentry_fpissue[3] && iqentry_islot[3]==2'd0) ||
2743
                        (!(iqentry_v[4] && iqentry_stomp[4]) && iqentry_fpissue[4] && iqentry_islot[4]==2'd0) ||
2744
                        (!(iqentry_v[5] && iqentry_stomp[5]) && iqentry_fpissue[5] && iqentry_islot[5]==2'd0) ||
2745
                        (!(iqentry_v[6] && iqentry_stomp[6]) && iqentry_fpissue[6] && iqentry_islot[6]==2'd0) ||
2746
                        (!(iqentry_v[7] && iqentry_stomp[7]) && iqentry_fpissue[7] && iqentry_islot[7]==2'd0)
2747
                        ;
2748
`endif
2749
 
2750
wire dcache_access_pending = dram0 == 3'd6 && (!rhit || (dram0_op==`LCL && dram0_tgt==7'd1));
2751
 
2752
//
2753
// determine if the instructions ready to issue can, in fact, issue.
2754
// "ready" means that the instruction has valid operands but has not gone yet
2755
//
2756
// Stores can only issue if there is no possibility of a change of program flow.
2757
// That means no flow control operations or instructions that can cause an
2758
// exception can be before the store.
2759
assign iqentry_memissue_head0 = iqentry_memready[ head0 ] && cstate==IDLE && !dcache_access_pending && dram0==0;         // first in line ... go as soon as ready
2760
 
2761
assign iqentry_memissue_head1 = ~iqentry_stomp[head1] && iqentry_memready[ head1 ]              // addr and data are valid
2762
                                // ... and no preceding instruction is ready to go
2763
                                && ~iqentry_memready[head0]
2764
                                // ... and there is no address-overlap with any preceding instruction
2765
                                && (!iqentry_mem[head0] || (iqentry_agen[head0] & iqentry_out[head0])
2766
                                        || (iqentry_a1_v[head0] && iqentry_a1[head1][DBW-1:3] != iqentry_a1[head0][DBW-1:3]))
2767
                                // ... and, if it is a SW, there is no chance of it being undone
2768
                                && (fnIsStore(iqentry_op[head1]) ? !fnIsFlowCtrl(iqentry_op[head0])
2769
                                && !fnCanException(iqentry_op[head0],iqentry_fn[head0]) : `TRUE)
2770
                                && (iqentry_op[head1]!=`CAS)
2771
                                && !(iqentry_v[head0] && fnIsMem(iqentry_op[head0]) && iqentry_op[head0]==`MEMDB)
2772
                                && !(iqentry_v[head0] && iqentry_op[head0]==`MEMSB)
2773
                                && cstate==IDLE && !dcache_access_pending && dram0==0
2774
                                ;
2775
 
2776
assign iqentry_memissue_head2 = ~iqentry_stomp[head2] && iqentry_memready[ head2 ]              // addr and data are valid
2777
                                // ... and no preceding instruction is ready to go
2778
                                && ~iqentry_memready[head0]
2779
                                && ~iqentry_memready[head1]
2780
                                // ... and there is no address-overlap with any preceding instruction
2781
                                && (!iqentry_mem[head0] || (iqentry_agen[head0] & iqentry_out[head0])
2782
                                        || (iqentry_a1_v[head0] && iqentry_a1[head2][DBW-1:3] != iqentry_a1[head0][DBW-1:3]))
2783
                                && (!iqentry_mem[head1] || (iqentry_agen[head1] & iqentry_out[head1])
2784
                                        || (iqentry_a1_v[head1] && iqentry_a1[head2][DBW-1:3] != iqentry_a1[head1][DBW-1:3]))
2785
                                // ... and, if it is a SW, there is no chance of it being undone
2786
                                && (fnIsStore(iqentry_op[head2]) ?
2787
                                    !fnIsFlowCtrl(iqentry_op[head0]) && !fnCanException(iqentry_op[head0],iqentry_fn[head0]) &&
2788
                                    !fnIsFlowCtrl(iqentry_op[head1]) && !fnCanException(iqentry_op[head1],iqentry_fn[head1])
2789
                                    : `TRUE)
2790
                                && (iqentry_op[head2]!=`CAS)
2791
                                && !(iqentry_v[head0] && fnIsMem(iqentry_op[head0]) && iqentry_op[head0]==`MEMDB)
2792
                                && !(iqentry_v[head1] && fnIsMem(iqentry_op[head1]) && iqentry_op[head1]==`MEMDB)
2793
                                // ... and there is no instruction barrier
2794
                                && !(iqentry_v[head0] && iqentry_op[head0]==`MEMSB)
2795
                                && !(iqentry_v[head1] && iqentry_op[head1]==`MEMSB)
2796
                                && cstate==IDLE && !dcache_access_pending && dram0==0
2797
                                ;
2798
//                                      (   !fnIsFlowCtrl(iqentry_op[head0])
2799
//                                       && !fnIsFlowCtrl(iqentry_op[head1])));
2800
 
2801
assign iqentry_memissue_head3 = ~iqentry_stomp[head3] && iqentry_memready[ head3 ]      // addr and data are valid
2802
                                // ... and no preceding instruction is ready to go
2803
                                && ~iqentry_memready[head0]
2804
                                && ~iqentry_memready[head1]
2805
                                && ~iqentry_memready[head2]
2806
                                // ... and there is no address-overlap with any preceding instruction
2807
                                && (!iqentry_mem[head0] || (iqentry_agen[head0] & iqentry_out[head0])
2808
                                        || (iqentry_a1_v[head0] && iqentry_a1[head3][DBW-1:3] != iqentry_a1[head0][DBW-1:3]))
2809
                                && (!iqentry_mem[head1] || (iqentry_agen[head1] & iqentry_out[head1])
2810
                                        || (iqentry_a1_v[head1] && iqentry_a1[head3][DBW-1:3] != iqentry_a1[head1][DBW-1:3]))
2811
                                && (!iqentry_mem[head2] || (iqentry_agen[head2] & iqentry_out[head2])
2812
                                        || (iqentry_a1_v[head2] && iqentry_a1[head3][DBW-1:3] != iqentry_a1[head2][DBW-1:3]))
2813
                                // ... and, if it is a SW, there is no chance of it being undone
2814
                                && (fnIsStore(iqentry_op[head3]) ?
2815
                    !fnIsFlowCtrl(iqentry_op[head0]) && !fnCanException(iqentry_op[head0],iqentry_fn[head0]) &&
2816
                    !fnIsFlowCtrl(iqentry_op[head1]) && !fnCanException(iqentry_op[head1],iqentry_fn[head1]) &&
2817
                    !fnIsFlowCtrl(iqentry_op[head2]) && !fnCanException(iqentry_op[head2],iqentry_fn[head2])
2818
                    : `TRUE)
2819
                                && (iqentry_op[head3]!=`CAS)
2820
                                // ... and there is no memory barrier
2821
                                && !(iqentry_v[head0] && fnIsMem(iqentry_op[head0]) && iqentry_op[head0]==`MEMDB)
2822
                                && !(iqentry_v[head1] && fnIsMem(iqentry_op[head1]) && iqentry_op[head1]==`MEMDB)
2823
                                && !(iqentry_v[head2] && fnIsMem(iqentry_op[head2]) && iqentry_op[head2]==`MEMDB)
2824
                                // ... and there is no instruction barrier
2825
                                && !(iqentry_v[head0] && iqentry_op[head0]==`MEMSB)
2826
                && !(iqentry_v[head1] && iqentry_op[head1]==`MEMSB)
2827
                && !(iqentry_v[head2] && iqentry_op[head2]==`MEMSB)
2828
                                && cstate==IDLE && !dcache_access_pending && dram0==0
2829
                                ;
2830
/*                                      (   !fnIsFlowCtrl(iqentry_op[head0])
2831
                                         && !fnIsFlowCtrl(iqentry_op[head1])
2832
                                         && !fnIsFlowCtrl(iqentry_op[head2])));
2833
*/
2834
assign iqentry_memissue_head4 = ~iqentry_stomp[head4] && iqentry_memready[ head4 ]              // addr and data are valid
2835
                                // ... and no preceding instruction is ready to go
2836
                                && ~iqentry_memready[head0]
2837
                                && ~iqentry_memready[head1]
2838
                                && ~iqentry_memready[head2]
2839
                                && ~iqentry_memready[head3]
2840
                                // ... and there is no address-overlap with any preceding instruction
2841
                                && (!iqentry_mem[head0] || (iqentry_agen[head0] & iqentry_out[head0])
2842
                                        || (iqentry_a1_v[head0] && iqentry_a1[head4][DBW-1:3] != iqentry_a1[head0][DBW-1:3]))
2843
                                && (!iqentry_mem[head1] || (iqentry_agen[head1] & iqentry_out[head1])
2844
                                        || (iqentry_a1_v[head1] && iqentry_a1[head4][DBW-1:3] != iqentry_a1[head1][DBW-1:3]))
2845
                                && (!iqentry_mem[head2] || (iqentry_agen[head2] & iqentry_out[head2])
2846
                                        || (iqentry_a1_v[head2] && iqentry_a1[head4][DBW-1:3] != iqentry_a1[head2][DBW-1:3]))
2847
                                && (!iqentry_mem[head3] || (iqentry_agen[head3] & iqentry_out[head3])
2848
                                        || (iqentry_a1_v[head3] && iqentry_a1[head4][DBW-1:3] != iqentry_a1[head3][DBW-1:3]))
2849
                                // ... and, if it is a SW, there is no chance of it being undone
2850
                                && (fnIsStore(iqentry_op[head4]) ?
2851
                    !fnIsFlowCtrl(iqentry_op[head0]) && !fnCanException(iqentry_op[head0],iqentry_fn[head0]) &&
2852
                    !fnIsFlowCtrl(iqentry_op[head1]) && !fnCanException(iqentry_op[head1],iqentry_fn[head1]) &&
2853
                    !fnIsFlowCtrl(iqentry_op[head2]) && !fnCanException(iqentry_op[head2],iqentry_fn[head2]) &&
2854
                    !fnIsFlowCtrl(iqentry_op[head3]) && !fnCanException(iqentry_op[head3],iqentry_fn[head3])
2855
                    : `TRUE)
2856
                                && (iqentry_op[head4]!=`CAS)
2857
                                // ... and there is no memory barrier
2858
                                && !(iqentry_v[head0] && fnIsMem(iqentry_op[head0]) && iqentry_op[head0]==`MEMDB)
2859
                                && !(iqentry_v[head1] && fnIsMem(iqentry_op[head1]) && iqentry_op[head1]==`MEMDB)
2860
                                && !(iqentry_v[head2] && fnIsMem(iqentry_op[head2]) && iqentry_op[head2]==`MEMDB)
2861
                                && !(iqentry_v[head3] && fnIsMem(iqentry_op[head3]) && iqentry_op[head3]==`MEMDB)
2862
                                // ... and there is no instruction barrier
2863
                                && !(iqentry_v[head0] && iqentry_op[head0]==`MEMSB)
2864
                && !(iqentry_v[head1] && iqentry_op[head1]==`MEMSB)
2865
                && !(iqentry_v[head2] && iqentry_op[head2]==`MEMSB)
2866
                && !(iqentry_v[head3] && iqentry_op[head3]==`MEMSB)
2867
                                && cstate==IDLE && !dcache_access_pending && dram0==0
2868
                                ;
2869
/* ||
2870
                                        (   !fnIsFlowCtrl(iqentry_op[head0])
2871
                                         && !fnIsFlowCtrl(iqentry_op[head1])
2872
                                         && !fnIsFlowCtrl(iqentry_op[head2])
2873
                                         && !fnIsFlowCtrl(iqentry_op[head3])));
2874
*/
2875
assign iqentry_memissue_head5 = ~iqentry_stomp[head5] && iqentry_memready[ head5 ]              // addr and data are valid
2876
                                // ... and no preceding instruction is ready to go
2877
                                && ~iqentry_memready[head0]
2878
                                && ~iqentry_memready[head1]
2879
                                && ~iqentry_memready[head2]
2880
                                && ~iqentry_memready[head3]
2881
                                && ~iqentry_memready[head4]
2882
                                // ... and there is no address-overlap with any preceding instruction
2883
                                && (!iqentry_mem[head0] || (iqentry_agen[head0] & iqentry_out[head0])
2884
                                        || (iqentry_a1_v[head0] && iqentry_a1[head5][DBW-1:3] != iqentry_a1[head0][DBW-1:3]))
2885
                                && (!iqentry_mem[head1] || (iqentry_agen[head1] & iqentry_out[head1])
2886
                                        || (iqentry_a1_v[head1] && iqentry_a1[head5][DBW-1:3] != iqentry_a1[head1][DBW-1:3]))
2887
                                && (!iqentry_mem[head2] || (iqentry_agen[head2] & iqentry_out[head2])
2888
                                        || (iqentry_a1_v[head2] && iqentry_a1[head5][DBW-1:3] != iqentry_a1[head2][DBW-1:3]))
2889
                                && (!iqentry_mem[head3] || (iqentry_agen[head3] & iqentry_out[head3])
2890
                                        || (iqentry_a1_v[head3] && iqentry_a1[head5][DBW-1:3] != iqentry_a1[head3][DBW-1:3]))
2891
                                && (!iqentry_mem[head4] || (iqentry_agen[head4] & iqentry_out[head4])
2892
                                        || (iqentry_a1_v[head4] && iqentry_a1[head5][DBW-1:3] != iqentry_a1[head4][DBW-1:3]))
2893
                                // ... and, if it is a SW, there is no chance of it being undone
2894
                                && (fnIsStore(iqentry_op[head5]) ?
2895
                    !fnIsFlowCtrl(iqentry_op[head0]) && !fnCanException(iqentry_op[head0],iqentry_fn[head0]) &&
2896
                    !fnIsFlowCtrl(iqentry_op[head1]) && !fnCanException(iqentry_op[head1],iqentry_fn[head1]) &&
2897
                    !fnIsFlowCtrl(iqentry_op[head2]) && !fnCanException(iqentry_op[head2],iqentry_fn[head2]) &&
2898
                    !fnIsFlowCtrl(iqentry_op[head3]) && !fnCanException(iqentry_op[head3],iqentry_fn[head3]) &&
2899
                    !fnIsFlowCtrl(iqentry_op[head4]) && !fnCanException(iqentry_op[head4],iqentry_fn[head4])
2900
                    : `TRUE)
2901
                                && (iqentry_op[head5]!=`CAS)
2902
                                // ... and there is no memory barrier
2903
                                && !(iqentry_v[head0] && fnIsMem(iqentry_op[head0]) && iqentry_op[head0]==`MEMDB)
2904
                                && !(iqentry_v[head1] && fnIsMem(iqentry_op[head1]) && iqentry_op[head1]==`MEMDB)
2905
                                && !(iqentry_v[head2] && fnIsMem(iqentry_op[head2]) && iqentry_op[head2]==`MEMDB)
2906
                                && !(iqentry_v[head3] && fnIsMem(iqentry_op[head3]) && iqentry_op[head3]==`MEMDB)
2907
                                && !(iqentry_v[head4] && fnIsMem(iqentry_op[head4]) && iqentry_op[head4]==`MEMDB)
2908
                                // ... and there is no instruction barrier
2909
                                && !(iqentry_v[head0] && iqentry_op[head0]==`MEMSB)
2910
                && !(iqentry_v[head1] && iqentry_op[head1]==`MEMSB)
2911
                && !(iqentry_v[head2] && iqentry_op[head2]==`MEMSB)
2912
                && !(iqentry_v[head3] && iqentry_op[head3]==`MEMSB)
2913
                && !(iqentry_v[head4] && iqentry_op[head4]==`MEMSB)
2914
                                && cstate==IDLE && !dcache_access_pending && dram0==0
2915
                                ;
2916
/*||
2917
                                        (   !fnIsFlowCtrl(iqentry_op[head0])
2918
                                         && !fnIsFlowCtrl(iqentry_op[head1])
2919
                                         && !fnIsFlowCtrl(iqentry_op[head2])
2920
                                         && !fnIsFlowCtrl(iqentry_op[head3])
2921
                                         && !fnIsFlowCtrl(iqentry_op[head4])));
2922
*/
2923
assign iqentry_memissue_head6 = ~iqentry_stomp[head6] && iqentry_memready[ head6 ]              // addr and data are valid
2924
                                // ... and no preceding instruction is ready to go
2925
                                && ~iqentry_memready[head0]
2926
                                && ~iqentry_memready[head1]
2927
                                && ~iqentry_memready[head2]
2928
                                && ~iqentry_memready[head3]
2929
                                && ~iqentry_memready[head4]
2930
                                && ~iqentry_memready[head5]
2931
                                // ... and there is no address-overlap with any preceding instruction
2932
                                && (!iqentry_mem[head0] || (iqentry_agen[head0] & iqentry_out[head0])
2933
                                        || (iqentry_a1_v[head0] && iqentry_a1[head6][DBW-1:3] != iqentry_a1[head0][DBW-1:3]))
2934
                                && (!iqentry_mem[head1] || (iqentry_agen[head1] & iqentry_out[head1])
2935
                                        || (iqentry_a1_v[head1] && iqentry_a1[head6][DBW-1:3] != iqentry_a1[head1][DBW-1:3]))
2936
                                && (!iqentry_mem[head2] || (iqentry_agen[head2] & iqentry_out[head2])
2937
                                        || (iqentry_a1_v[head2] && iqentry_a1[head6][DBW-1:3] != iqentry_a1[head2][DBW-1:3]))
2938
                                && (!iqentry_mem[head3] || (iqentry_agen[head3] & iqentry_out[head3])
2939
                                        || (iqentry_a1_v[head3] && iqentry_a1[head6][DBW-1:3] != iqentry_a1[head3][DBW-1:3]))
2940
                                && (!iqentry_mem[head4] || (iqentry_agen[head4] & iqentry_out[head4])
2941
                                        || (iqentry_a1_v[head4] && iqentry_a1[head6][DBW-1:3] != iqentry_a1[head4][DBW-1:3]))
2942
                                && (!iqentry_mem[head5] || (iqentry_agen[head5] & iqentry_out[head5])
2943
                                        || (iqentry_a1_v[head5] && iqentry_a1[head6][DBW-1:3] != iqentry_a1[head5][DBW-1:3]))
2944
                                // ... and, if it is a SW, there is no chance of it being undone
2945
                                && (fnIsStore(iqentry_op[head6]) ?
2946
                    !fnIsFlowCtrl(iqentry_op[head0]) && !fnCanException(iqentry_op[head0],iqentry_fn[head0]) &&
2947
                    !fnIsFlowCtrl(iqentry_op[head1]) && !fnCanException(iqentry_op[head1],iqentry_fn[head1]) &&
2948
                    !fnIsFlowCtrl(iqentry_op[head2]) && !fnCanException(iqentry_op[head2],iqentry_fn[head2]) &&
2949
                    !fnIsFlowCtrl(iqentry_op[head3]) && !fnCanException(iqentry_op[head3],iqentry_fn[head3]) &&
2950
                    !fnIsFlowCtrl(iqentry_op[head4]) && !fnCanException(iqentry_op[head4],iqentry_fn[head4]) &&
2951
                    !fnIsFlowCtrl(iqentry_op[head5]) && !fnCanException(iqentry_op[head5],iqentry_fn[head5])
2952
                    : `TRUE)
2953
                                && (iqentry_op[head6]!=`CAS)
2954
                                // ... and there is no memory barrier
2955
                                && !(iqentry_v[head0] && fnIsMem(iqentry_op[head0]) && iqentry_op[head0]==`MEMDB)
2956
                                && !(iqentry_v[head1] && fnIsMem(iqentry_op[head1]) && iqentry_op[head1]==`MEMDB)
2957
                                && !(iqentry_v[head2] && fnIsMem(iqentry_op[head2]) && iqentry_op[head2]==`MEMDB)
2958
                                && !(iqentry_v[head3] && fnIsMem(iqentry_op[head3]) && iqentry_op[head3]==`MEMDB)
2959
                                && !(iqentry_v[head4] && fnIsMem(iqentry_op[head4]) && iqentry_op[head4]==`MEMDB)
2960
                                && !(iqentry_v[head5] && fnIsMem(iqentry_op[head5]) && iqentry_op[head5]==`MEMDB)
2961
                                // ... and there is no instruction barrier
2962
                                && !(iqentry_v[head0] && iqentry_op[head0]==`MEMSB)
2963
                && !(iqentry_v[head1] && iqentry_op[head1]==`MEMSB)
2964
                && !(iqentry_v[head2] && iqentry_op[head2]==`MEMSB)
2965
                && !(iqentry_v[head3] && iqentry_op[head3]==`MEMSB)
2966
                && !(iqentry_v[head4] && iqentry_op[head4]==`MEMSB)
2967
                && !(iqentry_v[head5] && iqentry_op[head5]==`MEMSB)
2968
                                && cstate==IDLE && !dcache_access_pending && dram0==0
2969
                                ;
2970
                                /*||
2971
                                        (   !fnIsFlowCtrl(iqentry_op[head0])
2972
                                         && !fnIsFlowCtrl(iqentry_op[head1])
2973
                                         && !fnIsFlowCtrl(iqentry_op[head2])
2974
                                         && !fnIsFlowCtrl(iqentry_op[head3])
2975
                                         && !fnIsFlowCtrl(iqentry_op[head4])
2976
                                         && !fnIsFlowCtrl(iqentry_op[head5])));
2977
*/
2978
assign iqentry_memissue_head7 = ~iqentry_stomp[head7] && iqentry_memready[ head7 ]              // addr and data are valid
2979
                                // ... and no preceding instruction is ready to go
2980
                                && ~iqentry_memready[head0]
2981
                                && ~iqentry_memready[head1]
2982
                                && ~iqentry_memready[head2]
2983
                                && ~iqentry_memready[head3]
2984
                                && ~iqentry_memready[head4]
2985
                                && ~iqentry_memready[head5]
2986
                                && ~iqentry_memready[head6]
2987
                                // ... and there is no address-overlap with any preceding instruction
2988
                                && (!iqentry_mem[head0] || (iqentry_agen[head0] & iqentry_out[head0])
2989
                                        || (iqentry_a1_v[head0] && iqentry_a1[head7][DBW-1:3] != iqentry_a1[head0][DBW-1:3]))
2990
                                && (!iqentry_mem[head1] || (iqentry_agen[head1] & iqentry_out[head1])
2991
                                        || (iqentry_a1_v[head1] && iqentry_a1[head7][DBW-1:3] != iqentry_a1[head1][DBW-1:3]))
2992
                                && (!iqentry_mem[head2] || (iqentry_agen[head2] & iqentry_out[head2])
2993
                                        || (iqentry_a1_v[head2] && iqentry_a1[head7][DBW-1:3] != iqentry_a1[head2][DBW-1:3]))
2994
                                && (!iqentry_mem[head3] || (iqentry_agen[head3] & iqentry_out[head3])
2995
                                        || (iqentry_a1_v[head3] && iqentry_a1[head7][DBW-1:3] != iqentry_a1[head3][DBW-1:3]))
2996
                                && (!iqentry_mem[head4] || (iqentry_agen[head4] & iqentry_out[head4])
2997
                                        || (iqentry_a1_v[head4] && iqentry_a1[head7][DBW-1:3] != iqentry_a1[head4][DBW-1:3]))
2998
                                && (!iqentry_mem[head5] || (iqentry_agen[head5] & iqentry_out[head5])
2999
                                        || (iqentry_a1_v[head5] && iqentry_a1[head7][DBW-1:3] != iqentry_a1[head5][DBW-1:3]))
3000
                                && (!iqentry_mem[head6] || (iqentry_agen[head6] & iqentry_out[head6])
3001
                                        || (iqentry_a1_v[head6] && iqentry_a1[head7][DBW-1:3] != iqentry_a1[head6][DBW-1:3]))
3002
                                // ... and, if it is a SW, there is no chance of it being undone
3003
                                && (fnIsStore(iqentry_op[head7]) ?
3004
                    !fnIsFlowCtrl(iqentry_op[head0]) && !fnCanException(iqentry_op[head0],iqentry_fn[head0]) &&
3005
                    !fnIsFlowCtrl(iqentry_op[head1]) && !fnCanException(iqentry_op[head1],iqentry_fn[head1]) &&
3006
                    !fnIsFlowCtrl(iqentry_op[head2]) && !fnCanException(iqentry_op[head2],iqentry_fn[head2]) &&
3007
                    !fnIsFlowCtrl(iqentry_op[head3]) && !fnCanException(iqentry_op[head3],iqentry_fn[head3]) &&
3008
                    !fnIsFlowCtrl(iqentry_op[head4]) && !fnCanException(iqentry_op[head4],iqentry_fn[head4]) &&
3009
                    !fnIsFlowCtrl(iqentry_op[head5]) && !fnCanException(iqentry_op[head5],iqentry_fn[head5]) &&
3010
                    !fnIsFlowCtrl(iqentry_op[head6]) && !fnCanException(iqentry_op[head6],iqentry_fn[head6])
3011
                    : `TRUE)
3012
                                && (iqentry_op[head7]!=`CAS)
3013
                                // ... and there is no memory barrier
3014
                                && !(iqentry_v[head0] && fnIsMem(iqentry_op[head0]) && iqentry_op[head0]==`MEMDB)
3015
                                && !(iqentry_v[head1] && fnIsMem(iqentry_op[head1]) && iqentry_op[head1]==`MEMDB)
3016
                                && !(iqentry_v[head2] && fnIsMem(iqentry_op[head2]) && iqentry_op[head2]==`MEMDB)
3017
                                && !(iqentry_v[head3] && fnIsMem(iqentry_op[head3]) && iqentry_op[head3]==`MEMDB)
3018
                                && !(iqentry_v[head4] && fnIsMem(iqentry_op[head4]) && iqentry_op[head4]==`MEMDB)
3019
                                && !(iqentry_v[head5] && fnIsMem(iqentry_op[head5]) && iqentry_op[head5]==`MEMDB)
3020
                                && !(iqentry_v[head6] && fnIsMem(iqentry_op[head6]) && iqentry_op[head6]==`MEMDB)
3021
                                // ... and there is no instruction barrier
3022
                                && !(iqentry_v[head0] && iqentry_op[head0]==`MEMSB)
3023
                && !(iqentry_v[head1] && iqentry_op[head1]==`MEMSB)
3024
                && !(iqentry_v[head2] && iqentry_op[head2]==`MEMSB)
3025
                && !(iqentry_v[head3] && iqentry_op[head3]==`MEMSB)
3026
                && !(iqentry_v[head4] && iqentry_op[head4]==`MEMSB)
3027
                && !(iqentry_v[head5] && iqentry_op[head5]==`MEMSB)
3028
                && !(iqentry_v[head6] && iqentry_op[head6]==`MEMSB)
3029
                                && cstate==IDLE && !dcache_access_pending && dram0==0
3030
                                ;
3031
 
3032
`include "Thor_execute_combo.v"
3033
//`include "Thor_memory_combo.v"
3034
// additional DRAM-enqueue logic
3035
 
3036
Thor_TLB #(DBW) utlb1
3037
(
3038
        .rst(rst_i),
3039
        .clk(clk),
3040
        .km(km),
3041
        .pc(spc),
3042
        .ea(dram0_addr),
3043
        .ppc(ppc),
3044
        .pea(pea),
3045
        .iuncached(iuncached),
3046
        .uncached(uncached),
3047
        .m1IsStore(we_o),
3048
        .ASID(asid),
3049
        .op(tlb_op),
3050
        .state(tlb_state),
3051
        .regno(tlb_regno),
3052
        .dati(tlb_data),
3053
        .dato(tlb_dato),
3054
        .ITLBMiss(ITLBMiss),
3055
        .DTLBMiss(DTLBMiss),
3056
        .HTLBVirtPageo()
3057
);
3058
 
3059
assign dram_avail = (dram0 == `DRAMSLOT_AVAIL || dram1 == `DRAMSLOT_AVAIL || dram2 == `DRAMSLOT_AVAIL);
3060
 
3061
generate
3062
begin : memr
3063
    for (g = 0; g < QENTRIES; g = g + 1)
3064
    begin
3065
assign iqentry_memopsvalid[g] = (iqentry_mem[g] & iqentry_a2_v[g] & iqentry_a3_v[g] & iqentry_agen[g]);
3066
assign iqentry_memready[g] = (iqentry_v[g] & iqentry_memopsvalid[g] & ~iqentry_memissue[g] & !iqentry_issue[g] & ~iqentry_done[g] & ~iqentry_out[g] & ~iqentry_stomp[g]);
3067
    end
3068
end
3069
endgenerate
3070
 
3071
/*
3072
assign
3073
    iqentry_memopsvalid[0] = (iqentry_mem[0] & iqentry_a2_v[0] & iqentry_a3_v[0] & iqentry_agen[0]),
3074
        iqentry_memopsvalid[1] = (iqentry_mem[1] & iqentry_a2_v[1] & iqentry_a3_v[1] & iqentry_agen[1]),
3075
        iqentry_memopsvalid[2] = (iqentry_mem[2] & iqentry_a2_v[2] & iqentry_a3_v[2] & iqentry_agen[2]),
3076
        iqentry_memopsvalid[3] = (iqentry_mem[3] & iqentry_a2_v[3] & iqentry_a3_v[3] & iqentry_agen[3]),
3077
        iqentry_memopsvalid[4] = (iqentry_mem[4] & iqentry_a2_v[4] & iqentry_a3_v[4] & iqentry_agen[4]),
3078
        iqentry_memopsvalid[5] = (iqentry_mem[5] & iqentry_a2_v[5] & iqentry_a3_v[5] & iqentry_agen[5]),
3079
        iqentry_memopsvalid[6] = (iqentry_mem[6] & iqentry_a2_v[6] & iqentry_a3_v[6] & iqentry_agen[6]),
3080
        iqentry_memopsvalid[7] = (iqentry_mem[7] & iqentry_a2_v[7] & iqentry_a3_v[7] & iqentry_agen[7]);
3081
 
3082
assign
3083
    iqentry_memready[0] = (iqentry_v[0] & iqentry_memopsvalid[0] & ~iqentry_memissue[0] & ~iqentry_done[0] & ~iqentry_out[0] & ~iqentry_stomp[0]),
3084
        iqentry_memready[1] = (iqentry_v[1] & iqentry_memopsvalid[1] & ~iqentry_memissue[1] & ~iqentry_done[1] & ~iqentry_out[1] & ~iqentry_stomp[1]),
3085
        iqentry_memready[2] = (iqentry_v[2] & iqentry_memopsvalid[2] & ~iqentry_memissue[2] & ~iqentry_done[2] & ~iqentry_out[2] & ~iqentry_stomp[2]),
3086
        iqentry_memready[3] = (iqentry_v[3] & iqentry_memopsvalid[3] & ~iqentry_memissue[3] & ~iqentry_done[3] & ~iqentry_out[3] & ~iqentry_stomp[3]),
3087
        iqentry_memready[4] = (iqentry_v[4] & iqentry_memopsvalid[4] & ~iqentry_memissue[4] & ~iqentry_done[4] & ~iqentry_out[4] & ~iqentry_stomp[4]),
3088
        iqentry_memready[5] = (iqentry_v[5] & iqentry_memopsvalid[5] & ~iqentry_memissue[5] & ~iqentry_done[5] & ~iqentry_out[5] & ~iqentry_stomp[5]),
3089
        iqentry_memready[6] = (iqentry_v[6] & iqentry_memopsvalid[6] & ~iqentry_memissue[6] & ~iqentry_done[6] & ~iqentry_out[6] & ~iqentry_stomp[6]),
3090
        iqentry_memready[7] = (iqentry_v[7] & iqentry_memopsvalid[7] & ~iqentry_memissue[7] & ~iqentry_done[7] & ~iqentry_out[7] & ~iqentry_stomp[7]);
3091
*/
3092
assign outstanding_stores = (dram0 && fnIsStore(dram0_op)) || (dram1 && fnIsStore(dram1_op)) || (dram2 && fnIsStore(dram2_op));
3093
 
3094
// This signal needed to stave off an instruction cache access.
3095
assign mem_issue =
3096
    iqentry_memissue_head0 |
3097
    iqentry_memissue_head1 |
3098
    iqentry_memissue_head2 |
3099
    iqentry_memissue_head3 |
3100
    iqentry_memissue_head4 |
3101
    iqentry_memissue_head5 |
3102
    iqentry_memissue_head6 |
3103
    iqentry_memissue_head7
3104
    ;
3105
 
3106
wire [DBW-1:0] argA      = iqentry_a1_v[n] ? iqentry_a1[n]
3107
                                        : (iqentry_a1_s[n] == alu0_id) ? alu0_bus
3108
                                        : (iqentry_a1_s[n] == alu1_id) ? alu1_bus
3109
                                        : (iqentry_a1_s[n] == commit1_id) ? commit1_bus
3110
                                        : (iqentry_a1_s[n] == commit0_id) ? commit0_bus
3111
                                        : 64'hDEADDEADDEADDEAD;
3112
 
3113
//`include "Thor_commit_combo.v"
3114
// If trying to write to two branch registers at once, or trying to write 
3115
// to two predicate registers at once, then limit the processor to single
3116
// commit.
3117
// The processor does not support writing two registers in the same register
3118
// group at the same time for anything other than the general purpose
3119
// registers. It is possible for the processor to write to two diffent groups
3120
// at the same time.
3121
//assign limit_cmt = (iqentry_rfw[head0] && iqentry_rfw[head1] && iqentry_tgt[head0][8]==1'b1 && iqentry_tgt[head1][8]==1'b1);
3122
assign limit_cmt = 1'b0;
3123
//assign committing2 = (iqentry_v[head0] && iqentry_v[head1] && !limit_cmt) || (head0 != tail0 && head1 != tail0);
3124
 
3125
assign commit0_v = ({iqentry_v[head0], iqentry_done[head0]} == 2'b11 && ~|panic);
3126
assign commit1_v = ({iqentry_v[head0], iqentry_done[head0]} != 2'b10
3127
                && {iqentry_v[head1], iqentry_done[head1]} == 2'b11 && ~|panic && !limit_cmt);
3128
 
3129
assign commit0_id = {iqentry_mem[head0], head0};        // if a memory op, it has a DRAM-bus id
3130
assign commit1_id = {iqentry_mem[head1], head1};        // if a memory op, it has a DRAM-bus id
3131
 
3132
assign commit0_tgt = iqentry_tgt[head0];
3133
assign commit1_tgt = iqentry_tgt[head1];
3134
 
3135
assign commit0_bus = iqentry_res[head0];
3136
assign commit1_bus = iqentry_res[head1];
3137
 
3138
// If the target register is code address register #13 or #11 (0Dh) then we really wanted a SYS not an INT.
3139
// The difference is that and INT returns to the interrupted instruction, and a SYS returns to the 
3140
// next instruction. In the case of hardware determined software exceptions we want to be able to
3141
// return to the interrupted instruction, hence an INT is forced targeting code address reg #13.
3142
assign int_commit = (iqentry_op[head0]==`INT && commit0_v && iqentry_tgt[head0][3:0]==4'hE) ||
3143
                    (commit0_v && iqentry_op[head1]==`INT && commit1_v && iqentry_tgt[head1][3:0]==4'hE);
3144
assign sys_commit = ((iqentry_op[head0]==`SYS || (iqentry_op[head0]==`INT &&
3145
                        (iqentry_tgt[head0][3:0]==4'hD || iqentry_tgt[head0][3:0]==4'hB))) && commit0_v) ||
3146
                     (commit0_v && (iqentry_op[head1]==`SYS || (iqentry_op[head1]==`INT &&
3147
                        (iqentry_tgt[head1][3:0]==4'hD || iqentry_tgt[head1][3:0]==4'hB))) && commit1_v);
3148
 
3149
always @(posedge clk)
3150
        if (rst_i)
3151
                tick <= 64'd0;
3152
        else
3153
                tick <= tick + 64'd1;
3154
 
3155
always @(posedge clk)
3156
        if (rst_i)
3157
                nmi1 <= 1'b0;
3158
        else
3159
                nmi1 <= nmi_i;
3160
 
3161
//-----------------------------------------------------------------------------
3162
// Clock control
3163
// - reset or NMI reenables the clock
3164
// - this circuit must be under the clk_i domain
3165
//-----------------------------------------------------------------------------
3166
//
3167
reg cpu_clk_en;
3168
reg [15:0] clk_throttle;
3169
reg [15:0] clk_throttle_new;
3170
reg ld_clk_throttle;
3171
 
3172
//BUFGCE u20 (.CE(cpu_clk_en), .I(clk_i), .O(clk) );
3173
 
3174
reg lct1;
3175
always @(posedge clk_i)
3176
if (rst_i) begin
3177
        cpu_clk_en <= 1'b1;
3178
        lct1 <= 1'b0;
3179
        clk_throttle <= 16'hAAAA;       // 50% power
3180
end
3181
else begin
3182
        lct1 <= ld_clk_throttle;
3183
        clk_throttle <= {clk_throttle[14:0],clk_throttle[15]};
3184
        if (ld_clk_throttle && !lct1) begin
3185
                clk_throttle <= clk_throttle_new;
3186
    end
3187
        if (nmi_i)
3188
                clk_throttle <= 16'hAAAA;
3189
        cpu_clk_en <= clk_throttle[15];
3190
end
3191
 
3192
// Clock throttling bypassed for now
3193
assign clk_o = clk;
3194
assign clk = clk_i;
3195
 
3196
//-----------------------------------------------------------------------------
3197
// Note that everything clocked has to be in the same always block. This is a
3198
// limitation of some toolsets. Simulation / synthesis may get confused if the
3199
// logic isn't placed in the same always block.
3200
//-----------------------------------------------------------------------------
3201
 
3202
always @(posedge clk) begin
3203
 
3204
        if (nmi_i & !nmi1)
3205
                nmi_edge <= 1'b1;
3206
 
3207
        ld_clk_throttle <= `FALSE;
3208
        dram_v <= `INV;
3209
        alu0_ld <= 1'b0;
3210
        alu1_ld <= 1'b0;
3211
`ifdef FLOATING_POINT
3212
        fp0_ld <= 1'b0;
3213
`endif
3214
 
3215
        ic_invalidate <= `FALSE;
3216
        dc_invalidate <= `FALSE;
3217
        ic_invalidate_line <= `FALSE;
3218
    dc_invalidate_line <= `FALSE;
3219
    alu0_dataready <= `FALSE;
3220
    alu1_dataready <= `FALSE;
3221
 
3222
    // Reset segmentation flag once operating in non-segmented area.
3223
    if (pc[ABW-1:ABW-4]==4'hF)
3224
        pc[ABW+3:ABW] <= 4'h0;
3225
 
3226
    if (rst_i)
3227
        cstate <= RESET1;
3228
        if (rst_i||cstate==RESET1||cstate==RESET2) begin
3229
            wb_nack();
3230
            ierr <= 1'b0;
3231
                GM <= 8'hFF;
3232
                nmi_edge <= 1'b0;
3233
                pc <= RSTADDR[ABW-1:0];
3234
                StatusHWI <= `TRUE;             // disables interrupts at startup until an RTI instruction is executed.
3235
                im <= 1'b1;
3236
                imb <= 1'b1;
3237
                ic_invalidate <= `TRUE;
3238
                dc_invalidate <= `TRUE;
3239
                fetchbuf <= 1'b0;
3240
                fetchbufA_v <= `INV;
3241
                fetchbufB_v <= `INV;
3242
                fetchbufC_v <= `INV;
3243
                fetchbufD_v <= `INV;
3244
                fetchbufA_instr <= {8{8'h10}};
3245
                fetchbufB_instr <= {8{8'h10}};
3246
                fetchbufC_instr <= {8{8'h10}};
3247
                fetchbufD_instr <= {8{8'h10}};
3248
                fetchbufA_pc <= {{DBW-4{1'b1}},4'h0};
3249
                fetchbufB_pc <= {{DBW-4{1'b1}},4'h0};
3250
                fetchbufC_pc <= {{DBW-4{1'b1}},4'h0};
3251
                fetchbufD_pc <= {{DBW-4{1'b1}},4'h0};
3252
                for (i=0; i< QENTRIES; i=i+1) begin
3253
                        iqentry_v[i] <= `INV;
3254
                        iqentry_agen[i] <= `FALSE;
3255
                        iqentry_op[i] <= `NOP;
3256
                        iqentry_memissue[i] <= `FALSE;
3257
                        iqentry_a1[i] <= 64'd0;
3258
                        iqentry_a2[i] <= 64'd0;
3259
                        iqentry_a3[i] <= 64'd0;
3260
                        iqentry_T[i] <= 64'd0;
3261
                        iqentry_a1_v[i] <= `INV;
3262
                        iqentry_a2_v[i] <= `INV;
3263
                        iqentry_a3_v[i] <= `INV;
3264
                        iqentry_T_v[i] <= `INV;
3265
                        iqentry_a1_s[i] <= 4'd0;
3266
                        iqentry_a2_s[i] <= 4'd0;
3267
                        iqentry_a3_s[i] <= 4'd0;
3268
                        iqentry_T_s[i] <= 4'd0;
3269
                end
3270
                // All the register are flagged as valid on startup even though they
3271
                // may not contain valid data. Otherwise the processor will stall
3272
                // waiting for the registers to become valid. Ideally the registers
3273
                // should be initialized with valid values before use. But who knows
3274
                // what someone will do in boot code and we don't want the processor
3275
                // to stall.
3276
                for (n = 1; n < NREGS; n = n + 1) begin
3277
                        rf_v[n] = `VAL;
3278
`ifdef SIMULATION
3279
                        rf_source[n] <= 4'd0;
3280
`endif
3281
        dbg_ctrl <= {DBW{1'b0}};
3282
`ifdef SIMULATION
3283
        dbg_adr0 <= 0;
3284
        dbg_adr1 <= 0;
3285
        dbg_adr2 <= 0;
3286
        dbg_adr3 <= 0;
3287
`endif
3288
                end
3289
                if (ABW==32)
3290
                  sregs_lmt[7] = 20'hFFFFF;
3291
                else
3292
                  sregs_lmt[7] = 52'hFFFFFFFFFFFFF;
3293
                rf_source[0] <= 4'd0;
3294
//              rf_v[0] = `VAL;
3295
//              rf_v[7'h50] = `VAL;
3296
//              rf_v[7'h5F] = `VAL;
3297
                alu0_available <= `TRUE;
3298
                alu1_available <= `TRUE;
3299
        reset_tail_pointers(1);
3300
                head0 <= 3'd0;
3301
                head1 <= 3'd1;
3302
                head2 <= 3'd2;
3303
                head3 <= 3'd3;
3304
                head4 <= 3'd4;
3305
                head5 <= 3'd5;
3306
                head6 <= 3'd6;
3307
                head7 <= 3'd7;
3308
                dram0 <= 3'b00;
3309
                dram1 <= 3'b00;
3310
                dram2 <= 3'b00;
3311
                tlb_state <= 3'd0;
3312
                panic <= `PANIC_NONE;
3313
                string_pc <= 64'd0;
3314
                // The pc wraps around to address zero while fetching the reset vector.
3315
                // This causes the processor to use the code segement register so the
3316
                // CS has to be defined for reset.
3317
                sregs[7] <= 52'd0;
3318
                for (i=0; i < 16; i=i+1)
3319
                        pregs[i] <= 4'd0;
3320
                asid <= 8'h00;
3321
                rrmapno <= 3'd0;
3322
                dram0_id <= 0;
3323
                alu1_sourceid <= 0;
3324
        end
3325
 
3326
        // The following registers are always valid
3327
        rf_v[7'h00] = `VAL;
3328
        rf_v[7'h50] = `VAL;     // C0
3329
        rf_v[7'h5F] = `VAL;     // C15 (PC)
3330
        rf_v[7'h72] = `VAL; // tick
3331
    queued1 = `FALSE;
3332
    queued2 = `FALSE;
3333
    allowq = `TRUE;
3334
 
3335
        did_branchback <= take_branch;
3336
        did_branchback0 <= take_branch0;
3337
        did_branchback1 <= take_branch1;
3338
 
3339
        if (branchmiss) begin
3340
                for (n = 1; n < NREGS; n = n + 1)
3341
                        if (rf_v[n] == `INV && ~livetarget[n]) begin
3342
                          $display("brmiss: rf_v[%d] <= VAL",n);
3343
                          rf_v[n] = `VAL;
3344
                        end
3345
 
3346
            if (|iqentry_0_latestID[NREGS:1])   rf_source[ iqentry_tgt[0] ] <= { iqentry_mem[0], 3'd0 };
3347
            if (|iqentry_1_latestID[NREGS:1])   rf_source[ iqentry_tgt[1] ] <= { iqentry_mem[1], 3'd1 };
3348
            if (|iqentry_2_latestID[NREGS:1])   rf_source[ iqentry_tgt[2] ] <= { iqentry_mem[2], 3'd2 };
3349
            if (|iqentry_3_latestID[NREGS:1])   rf_source[ iqentry_tgt[3] ] <= { iqentry_mem[3], 3'd3 };
3350
            if (|iqentry_4_latestID[NREGS:1])   rf_source[ iqentry_tgt[4] ] <= { iqentry_mem[4], 3'd4 };
3351
            if (|iqentry_5_latestID[NREGS:1])   rf_source[ iqentry_tgt[5] ] <= { iqentry_mem[5], 3'd5 };
3352
            if (|iqentry_6_latestID[NREGS:1])   rf_source[ iqentry_tgt[6] ] <= { iqentry_mem[6], 3'd6 };
3353
            if (|iqentry_7_latestID[NREGS:1])   rf_source[ iqentry_tgt[7] ] <= { iqentry_mem[7], 3'd7 };
3354
 
3355
        end
3356
 
3357
        if (ihit) begin
3358
                $display("\r\n");
3359
                $display("TIME %0d", $time);
3360
        end
3361
 
3362
// COMMIT PHASE (register-file update only ... dequeue is elsewhere)
3363
//
3364
// look at head0 and head1 and let 'em write the register file if they are ready
3365
//
3366
// why is it happening here and not in another phase?
3367
// want to emulate a pass-through register file ... i.e. if we are reading
3368
// out of r3 while writing to r3, the value read is the value written.
3369
// requires BLOCKING assignments, so that we can read from rf[i] later.
3370
//
3371
if (commit0_v) begin
3372
        if (!rf_v[ commit0_tgt ]) begin
3373
            rf_v[ commit0_tgt ] = (rf_source[ commit0_tgt ] == commit0_id) || (branchmiss && iqentry_source[ commit0_id[2:0] ]);
3374
        end
3375
        if (commit0_tgt != 7'd0) $display("r%d <- %h", commit0_tgt, commit0_bus);
3376
end
3377
if (commit1_v) begin
3378
        if (!rf_v[ commit1_tgt ]) begin
3379
            rf_v[ commit1_tgt ] = (rf_source[ commit1_tgt ] == commit1_id)|| (branchmiss && iqentry_source[ commit1_id[2:0] ]);
3380
        end
3381
        if (commit1_tgt != 7'd0) $display("r%d <- %h", commit1_tgt, commit1_bus);
3382
end
3383
 
3384
// This chunk of code has to be before the enqueue stage so that the agen bit
3385
// can be reset to zero by enqueue.
3386
// put results into the appropriate instruction entries
3387
//
3388
if ((alu0_op==`RR && (alu0_fn==`MUL || alu0_fn==`MULU)) || alu0_op==`MULI || alu0_op==`MULUI) begin
3389
    if (alu0_done) begin
3390
        alu0_dataready <= `TRUE;
3391
        alu0_op <= `NOP;
3392
    end
3393
end
3394
else if ((alu0_op==`RR && (alu0_fn==`DIV || alu0_fn==`DIVU)) || alu0_op==`DIVI || alu0_op==`DIVUI) begin
3395
    if (alu0_done) begin
3396
        alu0_dataready <= `TRUE;
3397
        alu0_op <= `NOP;
3398
    end
3399
end
3400
 
3401
if (alu0_v) begin
3402
        if (|alu0_exc)
3403
            set_exception(alu0_id, alu0_exc==`EXC_DBZ ? 8'd241 : 8'h00);
3404
        else begin
3405
        if (iqentry_op[alu0_id[2:0]]!=`IMM)
3406
            iqentry_done[ alu0_id[2:0] ] <= (!iqentry_mem[ alu0_id[2:0] ] || !alu0_cmt);
3407
        iqentry_res     [ alu0_id[2:0] ] <= alu0_bus;
3408
        iqentry_out     [ alu0_id[2:0] ] <= `FALSE;
3409
                iqentry_cmt [ alu0_id[2:0] ] <= alu0_cmt;
3410
        iqentry_agen[ alu0_id[2:0] ] <= `TRUE;
3411
                iqentry_out [ alu0_id[2:0] ] <= `FALSE;
3412
        end
3413
end
3414
 
3415
 
3416
if (((alu1_op==`RR && (alu1_fn==`MUL || alu1_fn==`MULU)) || alu1_op==`MULI || alu1_op==`MULUI) && ALU1BIG) begin
3417
    if (alu1_done) begin
3418
        alu1_dataready <= `TRUE;
3419
        alu1_op <= `NOP;
3420
    end
3421
end
3422
else if (((alu1_op==`RR && (alu1_fn==`DIV || alu1_fn==`DIVU)) || alu1_op==`DIVI || alu1_op==`DIVUI) && ALU1BIG) begin
3423
    if (alu1_done) begin
3424
        alu1_dataready <= `TRUE;
3425
        alu1_op <= `NOP;
3426
    end
3427
end
3428
 
3429
if (alu1_v) begin
3430
        if (|alu1_exc)
3431
            set_exception(alu1_id, alu1_exc==`EXC_DBZ ? 8'd241 : 8'h00);
3432
        else begin
3433
        if (iqentry_op[alu1_id[2:0]]!=`IMM)
3434
             iqentry_done[ alu1_id[2:0] ] <= (!iqentry_mem[ alu1_id[2:0] ] || !alu1_cmt);
3435
        iqentry_res     [ alu1_id[2:0] ] <= alu1_bus;
3436
        iqentry_out     [ alu1_id[2:0] ] <= `FALSE;
3437
                iqentry_cmt [ alu1_id[2:0] ] <= alu1_cmt;
3438
        iqentry_agen[ alu1_id[2:0] ] <= `TRUE;
3439
                iqentry_out [ alu1_id[2:0] ] <= `FALSE;
3440
        end
3441
end
3442
 
3443
`ifdef FLOATING_POINT
3444
if (fp0_v) begin
3445
        $display("0results to iq[%d]=%h", fp0_id[2:0],fp0_bus);
3446
        if (|fp0_exc)
3447
            set_exception(fp0_id, fp0_exc);
3448
        else begin
3449
                iqentry_res     [ fp0_id[2:0] ] <= fp0_bus;
3450
                iqentry_done[ fp0_id[2:0] ] <= fp0_done || !fp0_cmt;
3451
                iqentry_out     [ fp0_id[2:0] ] <= `FALSE;
3452
                iqentry_cmt [ fp0_id[2:0] ] <= fp0_cmt;
3453
                iqentry_agen[ fp0_id[2:0] ] <= `TRUE;
3454
        end
3455
end
3456
`endif
3457
 
3458
//-------------------------------------------------------------------------------
3459
// ENQUEUE
3460
//
3461
// place up to three instructions from the fetch buffer into slots in the IQ.
3462
//   note: they are placed in-order, and they are expected to be executed
3463
// 0, 1, or 2 of the fetch buffers may have valid data
3464
// 0, 1, or 2 slots in the instruction queue may be available.
3465
// if we notice that one of the instructions in the fetch buffer is a predicted
3466
// branch, (set branchback/backpc and delete any instructions after it in
3467
// fetchbuf)
3468
//
3469
// We place the queue logic before the fetch to allow the tools to do the work
3470
// for us. The fetch logic needs to know how many entries were queued, this is
3471
// tracked in the queue stage by variables queued1,queued2,queued3. Blocking
3472
// assignments are used for these vars.
3473
//-------------------------------------------------------------------------------
3474
//
3475
    queued1 = `FALSE;
3476
    queued2 = `FALSE;
3477
    allowq = `TRUE;
3478
    qstomp = `FALSE;
3479
    if (branchmiss) // don't bother doing anything if there's been a branch miss
3480
        reset_tail_pointers(0);
3481
    else begin
3482
        case ({fetchbuf0_v, fetchbuf1_v && fnNumReadPorts(fetchbuf1_instr) <=  ports_avail})
3483
        2'b00: ; // do nothing
3484
        2'b01:  enque1(tail0,1,0,1);
3485
        2'b10:  enque0(tail0,1,0,1);
3486
        2'b11:  begin
3487
                enque0(tail0,1,1,1);
3488
                if (allowq)
3489
                    enque1(tail1,2,0,0);
3490
                validate_args();
3491
                end
3492
        endcase
3493
    end
3494
 
3495
//------------------------------------------------------------------------------
3496
// FETCH
3497
//
3498
// fetch at least two instructions from memory into the fetch buffer unless
3499
// either one of the buffers is still full, in which case we do nothing (kinda
3500
// like alpha approach)
3501
//------------------------------------------------------------------------------
3502
//
3503
if (branchmiss) begin
3504
    $display("pc <= %h", misspc);
3505
    pc <= misspc;
3506
    fetchbuf <= 1'b0;
3507
    fetchbufA_v <= 1'b0;
3508
    fetchbufB_v <= 1'b0;
3509
    fetchbufC_v <= 1'b0;
3510
    fetchbufD_v <= 1'b0;
3511
end
3512
else if (take_branch) begin
3513
        if (fetchbuf == 1'b0) begin
3514
                case ({fetchbufA_v,fetchbufB_v,fetchbufC_v,fetchbufD_v})
3515
                4'b0000:
3516
                        begin
3517
                            fetchCD();
3518
                                if (do_pcinc) pc[31:0] <= pc[31:0] + fnInsnLength(insn) + fnInsnLength1(insn);
3519
                                fetchbuf <= 1'b1;
3520
                        end
3521
                4'b0100:
3522
                        begin
3523
                            fetchCD();
3524
                                if (do_pcinc) pc[31:0] <= pc[31:0] + fnInsnLength(insn) + fnInsnLength1(insn);
3525
                                fetchbufB_v <= !queued1;
3526
                                if (queued1) begin
3527
                                    fetchbufB_instr <= 64'd0;
3528
                                        fetchbuf <= 1'b1;
3529
                                end
3530
                                if (queued2|queued3)
3531
                                    panic <= `PANIC_INVALIDIQSTATE;
3532
                        end
3533
                4'b0111:
3534
                        begin
3535
                                fetchbufB_v <= !queued1;
3536
                                if (queued1) begin
3537
                                        fetchbuf <= 1'b1;
3538
                                    fetchbufB_instr <= 64'd0;
3539
                                end
3540
                                if (queued2|queued3)
3541
                    panic <= `PANIC_INVALIDIQSTATE;
3542
                        end
3543
                4'b1000:
3544
                        begin
3545
                            fetchCD();
3546
                                if (do_pcinc) pc[31:0] <= pc[31:0] + fnInsnLength(insn) + fnInsnLength1(insn);
3547
                                fetchbufA_v <= !queued1;
3548
                                if (queued1) begin
3549
                                        fetchbuf <= 1'b1;
3550
                                    fetchbufA_instr <= 64'd0;
3551
                                end
3552
                                if (queued2|queued3)
3553
                    panic <= `PANIC_INVALIDIQSTATE;
3554
                        end
3555
                4'b1011:
3556
                        begin
3557
                                fetchbufA_v <= !queued1;
3558
                                if (queued1) begin
3559
                                        fetchbuf <= 1'b1;
3560
                                    fetchbufB_instr <= 64'd0;
3561
                            end
3562
                                if (queued2|queued3)
3563
                    panic <= `PANIC_INVALIDIQSTATE;
3564
                        end
3565
                4'b1100:
3566
                        // Note that there is no point to loading C,D here because
3567
                        // there is a predicted taken branch that would stomp on the
3568
                        // instructions anyways.
3569
                        if ((fnIsBranch(opcodeA) && predict_takenA)||opcodeA==`LOOP) begin
3570
                                pc <= branch_pc;
3571
                                fetchbufA_v <= !(queued1|queued2);
3572
                                fetchbufB_v <= `INV;            // stomp on it
3573
                                // may as well stick with same fetchbuf
3574
                        end
3575
                        else begin
3576
                                if (did_branchback0) begin
3577
                                    fetchCD();
3578
                                        if (do_pcinc) pc[31:0] <= pc[31:0] + fnInsnLength(insn) + fnInsnLength1(insn);
3579
                                        fetchbufA_v <= !(queued1|queued2);
3580
                                        fetchbufB_v <= !queued2;
3581
                                        if (queued2)
3582
                                                fetchbuf <= 1'b1;
3583
                                end
3584
                                else begin
3585
                                        pc[ABW-1:0] <= branch_pc;
3586
                                        fetchbufA_v <= !(queued1|queued2);
3587
                                        fetchbufB_v <= !queued2;
3588
                                        // may as well keep the same fetchbuffer
3589
                                end
3590
                        end
3591
                4'b1111:
3592
                        begin
3593
                                fetchbufA_v <= !(queued1|queued2);
3594
                                fetchbufB_v <= !queued2;
3595
                                if (queued2) begin
3596
                                        fetchbuf <= 1'b1;
3597
                                    fetchbufA_instr <= 64'd0;
3598
                                    fetchbufB_instr <= 64'd0;
3599
                            end
3600
                        end
3601
                default: panic <= `PANIC_INVALIDFBSTATE;
3602
                endcase
3603
        end
3604
        else begin      // fetchbuf==1'b1
3605
                case ({fetchbufC_v,fetchbufD_v,fetchbufA_v,fetchbufB_v})
3606
                4'b0000:
3607
                        begin
3608
                            fetchAB();
3609
                                if (do_pcinc) pc[31:0] <= pc[31:0] + fnInsnLength(insn) + fnInsnLength1(insn);
3610
                                fetchbuf <= 1'b0;
3611
                        end
3612
                4'b0100:
3613
                        begin
3614
                            fetchAB();
3615
                                if (do_pcinc) pc[31:0] <= pc[31:0] + fnInsnLength(insn) + fnInsnLength1(insn);
3616
                                fetchbufD_v <= !queued1;
3617
                                if (queued1)
3618
                                        fetchbuf <= 1'b0;
3619
                                if (queued2|queued3)
3620
                    panic <= `PANIC_INVALIDIQSTATE;
3621
                        end
3622
                4'b0111:
3623
                        begin
3624
                                fetchbufD_v <= !queued1;
3625
                                if (queued1)
3626
                                        fetchbuf <= 1'b0;
3627
                                if (queued2|queued3)
3628
                    panic <= `PANIC_INVALIDIQSTATE;
3629
                        end
3630
                4'b1000:
3631
                        begin
3632
                            fetchAB();
3633
                                if (do_pcinc) pc[31:0] <= pc[31:0] + fnInsnLength(insn) + fnInsnLength1(insn);
3634
                                fetchbufC_v <= !queued1;
3635
                                if (queued1)
3636
                                        fetchbuf <= 1'b0;
3637
                                if (queued2|queued3)
3638
                    panic <= `PANIC_INVALIDIQSTATE;
3639
                        end
3640
                4'b1011:
3641
                        begin
3642
                                fetchbufC_v <= !queued1;
3643
                                if (queued1)
3644
                                        fetchbuf <= 1'b0;
3645
                                if (queued2|queued3)
3646
                    panic <= `PANIC_INVALIDIQSTATE;
3647
                        end
3648
                4'b1100:
3649
                        if ((fnIsBranch(opcodeC) && predict_takenC)||opcodeC==`LOOP) begin
3650
                                pc <= branch_pc;
3651
                                fetchbufC_v <= !(queued1|queued2);
3652
                                fetchbufD_v <= `INV;            // stomp on it
3653
                                // may as well stick with same fetchbuf
3654
                        end
3655
                        else begin
3656
                                if (did_branchback1) begin
3657
                                    fetchAB();
3658
                                        if (do_pcinc) pc[31:0] <= pc[31:0] + fnInsnLength(insn) + fnInsnLength1(insn);
3659
                                        fetchbufC_v <= !(queued1|queued2);
3660
                                        fetchbufD_v <= !queued2;
3661
                                        if (queued2)
3662
                                                fetchbuf <= 1'b0;
3663
                                end
3664
                                else begin
3665
                                        pc[ABW-1:0] <= branch_pc;
3666
                                        fetchbufC_v <= !(queued1|queued2);
3667
                                        fetchbufD_v <= !queued2;
3668
                                        // may as well keep the same fetchbuffer
3669
                                end
3670
                        end
3671
                4'b1111:
3672
                        begin
3673
                                fetchbufC_v <= !(queued1|queued2);
3674
                                fetchbufD_v <= !queued2;
3675
                                if (queued2)
3676
                                        fetchbuf <= 1'b0;
3677
                        end
3678
                default: panic <= `PANIC_INVALIDFBSTATE;
3679
                endcase
3680
        end
3681
end
3682
else begin
3683
        if (fetchbuf == 1'b0)
3684
                case ({fetchbufA_v, fetchbufB_v})
3685
                2'b00: ;
3686
                2'b01: begin
3687
                        fetchbufB_v <= !(queued2|queued1);
3688
                        fetchbuf <= queued2|queued1;
3689
                        end
3690
                2'b10: begin
3691
                        fetchbufA_v <= !(queued2|queued1);
3692
                        fetchbuf <= queued2|queued1;
3693
                        end
3694
                2'b11: begin
3695
                        fetchbufA_v <= !(queued1|queued2);
3696
                        fetchbufB_v <= !queued2;
3697
                        fetchbuf <= queued2;
3698
                        end
3699
                endcase
3700
        else
3701
                case ({fetchbufC_v, fetchbufD_v})
3702
                2'b00:    ;
3703
                2'b01: begin
3704
                        fetchbufD_v <= !(queued2|queued1);
3705
                        fetchbuf <= !(queued2|queued1);
3706
                        end
3707
                2'b10: begin
3708
                        fetchbufC_v <= !(queued2|queued1);
3709
                        fetchbuf <= !(queued2|queued1);
3710
                        end
3711
                2'b11: begin
3712
                        fetchbufC_v <= !(queued2|queued1);
3713
                        fetchbufD_v <= !queued2;
3714
                        fetchbuf <= !queued2;
3715
                        end
3716
                endcase
3717
        if (fetchbufA_v == `INV && fetchbufB_v == `INV) begin
3718
            fetchAB();
3719
                if (do_pcinc) pc[31:0] <= pc[31:0] + fnInsnLength(insn) + fnInsnLength1(insn);
3720
                // fetchbuf steering logic correction
3721
                if (fetchbufC_v==`INV && fetchbufD_v==`INV && do_pcinc)
3722
                        fetchbuf <= 1'b0;
3723
                $display("hit %b 1pc <= %h", do_pcinc, pc[31:0] + fnInsnLength(insn) + fnInsnLength1(insn));
3724
        end
3725
        else if (fetchbufC_v == `INV && fetchbufD_v == `INV) begin
3726
            fetchCD();
3727
                if (do_pcinc) pc[31:0] <= pc[31:0] + fnInsnLength(insn) + fnInsnLength1(insn);
3728
                $display("2pc <= %h", pc[31:0] + fnInsnLength(insn) + fnInsnLength1(insn));
3729
        end
3730
end
3731
 
3732
        if (ihit) begin
3733
        $display("%h %h hit0=%b hit1=%b#", spc, pc, hit0, hit1);
3734
        $display("insn=%h", insn);
3735
        $display("%c insn0=%h insn1=%h", nmi_edge ? "*" : " ",insn0, insn1);
3736
        $display("takb=%d br_pc=%h #", take_branch, branch_pc);
3737
        $display("%c%c A: %d %h %h #",
3738
            45, fetchbuf?45:62, fetchbufA_v, fetchbufA_instr, fetchbufA_pc);
3739
        $display("%c%c B: %d %h %h #",
3740
            45, fetchbuf?45:62, fetchbufB_v, fetchbufB_instr, fetchbufB_pc);
3741
        $display("%c%c C: %d %h %h #",
3742
            45, fetchbuf?62:45, fetchbufC_v, fetchbufC_instr, fetchbufC_pc);
3743
        $display("%c%c D: %d %h %h #",
3744
            45, fetchbuf?62:45, fetchbufD_v, fetchbufD_instr, fetchbufD_pc);
3745
        $display("fetchbuf=%d",fetchbuf);
3746
        end
3747
 
3748
//      if (ihit) begin
3749
        for (i=0; i<QENTRIES; i=i+1)
3750
            $display("%c%c %d: %c%c%c%c%c%c%c%c%c %d %c %c%h %d%s %h %h %h %c %o %h %c %o %h %c %o %h %c %o %h #",
3751
                (i[2:0]==head0)?72:46, (i[2:0]==tail0)?84:46, i,
3752
                iqentry_v[i]?"v":"-", iqentry_done[i]?"d":"-",
3753
                iqentry_cmt[i]?"c":"-", iq_cmt[i]?"C":"-",iqentry_out[i]?"o":"-", iqentry_bt[i]?"b":"-", iqentry_memissue[i]?"m":"-",
3754
                iqentry_agen[i]?"a":"-", iqentry_issue[i]?"i":"-",
3755
                iqentry_islot[i],
3756
//              ((i==0) ? iqentry_0_islot : (i==1) ? iqentry_1_islot : (i==2) ? iqentry_2_islot : (i==3) ? iqentry_3_islot :
3757
//               (i==4) ? iqentry_4_islot : (i==5) ? iqentry_5_islot : (i==6) ? iqentry_6_islot : iqentry_7_islot),
3758
                 iqentry_stomp[i] ? "s" : "-",
3759
                (fnIsFlowCtrl(iqentry_op[i]) ? 98 : fnIsMem(iqentry_op[i]) ? 109 : 97),
3760
                iqentry_op[i],
3761
                fnRegstr(iqentry_tgt[i]),fnRegstrGrp(iqentry_tgt[i]),
3762
                iqentry_res[i], iqentry_a0[i],
3763
                iqentry_a1[i], iqentry_a1_v[i]?"v":"-", iqentry_a1_s[i],
3764
                iqentry_a2[i], iqentry_a2_v[i]?"v":"-", iqentry_a2_s[i],
3765
                iqentry_a3[i], iqentry_a3_v[i]?"v":"-", iqentry_a3_s[i],
3766
                iqentry_pred[i], iqentry_p_v[i]?"v":"-", iqentry_p_s[i],
3767
                iqentry_pc[i]);
3768
        $display("com0:%c%c %d r%d %h", commit0_v?"v":"-", iqentry_cmt[head0]?"c":"-", commit0_id, commit0_tgt, commit0_bus);
3769
        $display("com1:%c%c %d r%d %h", commit1_v?"v":"-", iqentry_cmt[head1]?"c":"-", commit1_id, commit1_tgt, commit1_bus);
3770
 
3771
//      end
3772
//`include "Thor_dataincoming.v"
3773
// DATAINCOMING
3774
//
3775
// wait for operand/s to appear on alu busses and puts them into 
3776
// the iqentry_a1 and iqentry_a2 slots (if appropriate)
3777
// as well as the appropriate iqentry_res slots (and setting valid bits)
3778
//
3779
//
3780
if (dram_v && iqentry_v[ dram_id[2:0] ] && iqentry_mem[ dram_id[2:0] ] ) begin    // if data for stomped instruction, ignore
3781
        $display("dram results to iq[%d]=%h", dram_id[2:0],dram_bus);
3782
        iqentry_res     [ dram_id[2:0] ] <= dram_bus;
3783
        // If an exception occurred, stuff an interrupt instruction into the queue
3784
        // slot. The instruction will re-issue as an ALU operation. We can change
3785
        // the queued instruction because it isn't finished yet.
3786
        if (|dram_exc)
3787
            set_exception(dram_id,
3788
               dram_exc==`EXC_DBE ? 8'hFB :
3789
               dram_exc==`EXC_DBG ? 8'd243 :
3790
               dram_exc==`EXC_SEGV ? 8'd244 :
3791
               8'hF8);    // F8 = TLBMiss exception 243 = debug
3792
        else begin
3793
            // Note that the predicate was already evaluated to TRUE before the
3794
            // dram operation started.
3795
            iqentry_cmt[dram_id[2:0]] <= `TRUE;
3796
                iqentry_done[ dram_id[2:0] ] <= `TRUE;
3797
                if (iqentry_op[dram_id[2:0]]==`STS && lc==64'd0) begin
3798
                        string_pc <= 64'd0;
3799
                end
3800
        end
3801
end
3802
 
3803
// What if there's a databus error during the store ?
3804
// set the IQ entry == DONE as soon as the SW is let loose to the memory system
3805
//
3806
if (dram0 == 2'd2 && fnIsStore(dram0_op) && dram0_op != `STS) begin
3807
        if ((alu0_v && dram0_id[2:0] == alu0_id[2:0]) || (alu1_v && dram0_id[2:0] == alu1_id[2:0])) panic <= `PANIC_MEMORYRACE;
3808
        iqentry_done[ dram0_id[2:0] ] <= `TRUE;
3809
        iqentry_cmt [ dram0_id[2:0]] <= `TRUE;
3810
        iqentry_out[ dram0_id[2:0] ] <= `FALSE;
3811
end
3812
if (dram1 == 2'd2 && fnIsStore(dram1_op) && dram1_op != `STS) begin
3813
        if ((alu0_v && dram1_id[2:0] == alu0_id[2:0]) || (alu1_v && dram1_id[2:0] == alu1_id[2:0])) panic <= `PANIC_MEMORYRACE;
3814
        iqentry_done[ dram1_id[2:0] ] <= `TRUE;
3815
        iqentry_cmt [ dram1_id[2:0]] <= `TRUE;
3816
        iqentry_out[ dram1_id[2:0] ] <= `FALSE;
3817
end
3818
if (dram2 == 2'd2 && fnIsStore(dram2_op) && dram2_op != `STS) begin
3819
        if ((alu0_v && dram2_id[2:0] == alu0_id[2:0]) || (alu1_v && dram2_id[2:0] == alu1_id[2:0])) panic <= `PANIC_MEMORYRACE;
3820
        iqentry_done[ dram2_id[2:0] ] <= `TRUE;
3821
        iqentry_cmt [ dram2_id[2:0]] <= `TRUE;
3822
        iqentry_out[ dram2_id[2:0] ] <= `FALSE;
3823
end
3824
 
3825
//
3826
// see if anybody else wants the results ... look at lots of buses:
3827
//  - alu0_bus
3828
//  - alu1_bus
3829
//  - fp0_bus
3830
//  - dram_bus
3831
//  - commit0_bus
3832
//  - commit1_bus
3833
//
3834
 
3835
for (n = 0; n < QENTRIES; n = n + 1)
3836
begin
3837
        if (iqentry_p_v[n] == `INV && iqentry_p_s[n]==alu0_id && iqentry_v[n] == `VAL && alu0_v == `VAL) begin
3838
                iqentry_pred[n] <= alu0_bus[3:0];
3839
                iqentry_p_v[n] <= `VAL;
3840
        end
3841
        if (iqentry_a1_v[n] == `INV && iqentry_a1_s[n] == alu0_id && iqentry_v[n] == `VAL && alu0_v == `VAL) begin
3842
                iqentry_a1[n] <= alu0_bus;
3843
                iqentry_a1_v[n] <= `VAL;
3844
        end
3845
        if (iqentry_a2_v[n] == `INV && iqentry_a2_s[n] == alu0_id && iqentry_v[n] == `VAL && alu0_v == `VAL) begin
3846
                iqentry_a2[n] <= alu0_bus;
3847
                iqentry_a2_v[n] <= `VAL;
3848
        end
3849
        if (iqentry_a3_v[n] == `INV && iqentry_a3_s[n] == alu0_id && iqentry_v[n] == `VAL && alu0_v == `VAL) begin
3850
                iqentry_a3[n] <= alu0_bus;
3851
                iqentry_a3_v[n] <= `VAL;
3852
        end
3853
        if (iqentry_T_v[n] == `INV && iqentry_T_s[n] == alu0_id && iqentry_v[n] == `VAL && alu0_v == `VAL) begin
3854
        iqentry_T[n] <= alu0_bus;
3855
        iqentry_T_v[n] <= `VAL;
3856
    end
3857
        if (iqentry_p_v[n] == `INV && iqentry_p_s[n] == alu1_id && iqentry_v[n] == `VAL && alu1_v == `VAL) begin
3858
                iqentry_pred[n] <= alu1_bus[3:0];
3859
                iqentry_p_v[n] <= `VAL;
3860
        end
3861
        if (iqentry_a1_v[n] == `INV && iqentry_a1_s[n] == alu1_id && iqentry_v[n] == `VAL && alu1_v == `VAL) begin
3862
                iqentry_a1[n] <= alu1_bus;
3863
                iqentry_a1_v[n] <= `VAL;
3864
        end
3865
        if (iqentry_a2_v[n] == `INV && iqentry_a2_s[n] == alu1_id && iqentry_v[n] == `VAL && alu1_v == `VAL) begin
3866
                iqentry_a2[n] <= alu1_bus;
3867
                iqentry_a2_v[n] <= `VAL;
3868
        end
3869
        if (iqentry_a3_v[n] == `INV && iqentry_a3_s[n] == alu1_id && iqentry_v[n] == `VAL && alu1_v == `VAL) begin
3870
                iqentry_a3[n] <= alu1_bus;
3871
                iqentry_a3_v[n] <= `VAL;
3872
        end
3873
        if (iqentry_T_v[n] == `INV && iqentry_T_s[n] == alu1_id && iqentry_v[n] == `VAL && alu1_v == `VAL) begin
3874
        iqentry_T[n] <= alu1_bus;
3875
        iqentry_T_v[n] <= `VAL;
3876
    end
3877
`ifdef FLOATING_POINT
3878
/*
3879
        if (iqentry_p_v[n] == `INV && iqentry_p_s[n] == fp0_id && iqentry_v[n] == `VAL && fp0_v == `VAL) begin
3880
                iqentry_pred[n] <= fp0_bus[3:0];
3881
                iqentry_p_v[n] <= `VAL;
3882
        end
3883
*/
3884
        if (iqentry_a1_v[n] == `INV && iqentry_a1_s[n] == fp0_id && iqentry_v[n] == `VAL && fp0_v == `VAL) begin
3885
                iqentry_a1[n] <= fp0_bus;
3886
                iqentry_a1_v[n] <= `VAL;
3887
        end
3888
        if (iqentry_a2_v[n] == `INV && iqentry_a2_s[n] == fp0_id && iqentry_v[n] == `VAL && fp0_v == `VAL) begin
3889
                iqentry_a2[n] <= fp0_bus;
3890
                iqentry_a2_v[n] <= `VAL;
3891
        end
3892
        if (iqentry_a3_v[n] == `INV && iqentry_a3_s[n] == fp0_id && iqentry_v[n] == `VAL && fp0_v == `VAL) begin
3893
                iqentry_a3[n] <= fp0_bus;
3894
                iqentry_a3_v[n] <= `VAL;
3895
        end
3896
        if (iqentry_T_v[n] == `INV && iqentry_T_s[n] == fp0_id && iqentry_v[n] == `VAL && fp0_v == `VAL) begin
3897
        iqentry_T[n] <= fp0_bus;
3898
        iqentry_T_v[n] <= `VAL;
3899
    end
3900
`endif
3901
    // For SWCR
3902
        if (iqentry_p_v[n] == `INV && iqentry_p_s[n]==dram_id && iqentry_v[n] == `VAL && dram_v == `VAL) begin
3903
                iqentry_pred[n] <= dram_bus[3:0];
3904
                iqentry_p_v[n] <= `VAL;
3905
        end
3906
        if (iqentry_a1_v[n] == `INV && iqentry_a1_s[n] == dram_id && iqentry_v[n] == `VAL && dram_v == `VAL) begin
3907
                iqentry_a1[n] <= dram_bus;
3908
                iqentry_a1_v[n] <= `VAL;
3909
        end
3910
        if (iqentry_a2_v[n] == `INV && iqentry_a2_s[n] == dram_id && iqentry_v[n] == `VAL && dram_v == `VAL) begin
3911
                iqentry_a2[n] <= dram_bus;
3912
                iqentry_a2_v[n] <= `VAL;
3913
        end
3914
        if (iqentry_a3_v[n] == `INV && iqentry_a3_s[n] == dram_id && iqentry_v[n] == `VAL && dram_v == `VAL) begin
3915
                iqentry_a3[n] <= dram_bus;
3916
                iqentry_a3_v[n] <= `VAL;
3917
        end
3918
        if (iqentry_T_v[n] == `INV && iqentry_T_s[n] == dram_id && iqentry_v[n] == `VAL && dram_v == `VAL) begin
3919
        iqentry_T[n] <= dram_bus;
3920
        iqentry_T_v[n] <= `VAL;
3921
    end
3922
        if (iqentry_p_v[n] == `INV && iqentry_p_s[n]==commit0_id && iqentry_v[n] == `VAL && commit0_v == `VAL) begin
3923
                iqentry_pred[n] <= commit0_bus[3:0];
3924
                iqentry_p_v[n] <= `VAL;
3925
        end
3926
        if (iqentry_a1_v[n] == `INV && iqentry_a1_s[n] == commit0_id && iqentry_v[n] == `VAL && commit0_v == `VAL) begin
3927
                iqentry_a1[n] <= commit0_bus;
3928
                iqentry_a1_v[n] <= `VAL;
3929
        end
3930
        if (iqentry_a2_v[n] == `INV && iqentry_a2_s[n] == commit0_id && iqentry_v[n] == `VAL && commit0_v == `VAL) begin
3931
                iqentry_a2[n] <= commit0_bus;
3932
                iqentry_a2_v[n] <= `VAL;
3933
        end
3934
        if (iqentry_a3_v[n] == `INV && iqentry_a3_s[n] == commit0_id && iqentry_v[n] == `VAL && commit0_v == `VAL) begin
3935
                iqentry_a3[n] <= commit0_bus;
3936
                iqentry_a3_v[n] <= `VAL;
3937
        end
3938
        if (iqentry_T_v[n] == `INV && iqentry_T_s[n] == commit0_id && iqentry_v[n] == `VAL && commit0_v == `VAL) begin
3939
        iqentry_T[n] <= commit0_bus;
3940
        iqentry_T_v[n] <= `VAL;
3941
    end
3942
        if (iqentry_p_v[n] == `INV && iqentry_p_s[n] == commit1_id && iqentry_v[n] == `VAL && commit1_v == `VAL) begin
3943
                iqentry_pred[n] <= commit1_bus[3:0];
3944
                iqentry_p_v[n] <= `VAL;
3945
        end
3946
        if (iqentry_a1_v[n] == `INV && iqentry_a1_s[n] == commit1_id && iqentry_v[n] == `VAL && commit1_v == `VAL) begin
3947
                iqentry_a1[n] <= commit1_bus;
3948
                iqentry_a1_v[n] <= `VAL;
3949
        end
3950
        if (iqentry_a2_v[n] == `INV && iqentry_a2_s[n] == commit1_id && iqentry_v[n] == `VAL && commit1_v == `VAL) begin
3951
                iqentry_a2[n] <= commit1_bus;
3952
                iqentry_a2_v[n] <= `VAL;
3953
        end
3954
        if (iqentry_a3_v[n] == `INV && iqentry_a3_s[n] == commit1_id && iqentry_v[n] == `VAL && commit1_v == `VAL) begin
3955
                iqentry_a3[n] <= commit1_bus;
3956
                iqentry_a3_v[n] <= `VAL;
3957
        end
3958
        if (iqentry_T_v[n] == `INV && iqentry_T_s[n] == commit1_id && iqentry_v[n] == `VAL && commit1_v == `VAL) begin
3959
        iqentry_T[n] <= commit1_bus;
3960
        iqentry_T_v[n] <= `VAL;
3961
    end
3962
end
3963
 
3964
//`include "Thor_issue.v"
3965
// ISSUE 
3966
//
3967
// determines what instructions are ready to go, then places them
3968
// in the various ALU queues.  
3969
// also invalidates instructions following a branch-miss BEQ or any JALR (STOMP logic)
3970
//
3971
//alu0_dataready <= alu0_available && alu0_issue;
3972
/*
3973
                        && ((iqentry_issue[0] && iqentry_islot[0] == 4'd0 && !iqentry_stomp[0])
3974
                         || (iqentry_issue[1] && iqentry_islot[1] == 4'd0 && !iqentry_stomp[1])
3975
                         || (iqentry_issue[2] && iqentry_islot[2] == 4'd0 && !iqentry_stomp[2])
3976
                         || (iqentry_issue[3] && iqentry_islot[3] == 4'd0 && !iqentry_stomp[3])
3977
                         || (iqentry_issue[4] && iqentry_islot[4] == 4'd0 && !iqentry_stomp[4])
3978
                         || (iqentry_issue[5] && iqentry_islot[5] == 4'd0 && !iqentry_stomp[5])
3979
                         || (iqentry_issue[6] && iqentry_islot[6] == 4'd0 && !iqentry_stomp[6])
3980
                         || (iqentry_issue[7] && iqentry_islot[7] == 4'd0 && !iqentry_stomp[7]));
3981
*/
3982
//alu1_dataready <= alu1_available && alu1_issue;
3983
/*
3984
                        && ((iqentry_issue[0] && iqentry_islot[0] == 4'd1 && !iqentry_stomp[0])
3985
                         || (iqentry_issue[1] && iqentry_islot[1] == 4'd1 && !iqentry_stomp[1])
3986
                         || (iqentry_issue[2] && iqentry_islot[2] == 4'd1 && !iqentry_stomp[2])
3987
                         || (iqentry_issue[3] && iqentry_islot[3] == 4'd1 && !iqentry_stomp[3])
3988
                         || (iqentry_issue[4] && iqentry_islot[4] == 4'd1 && !iqentry_stomp[4])
3989
                         || (iqentry_issue[5] && iqentry_islot[5] == 4'd1 && !iqentry_stomp[5])
3990
                         || (iqentry_issue[6] && iqentry_islot[6] == 4'd1 && !iqentry_stomp[6])
3991
                         || (iqentry_issue[7] && iqentry_islot[7] == 4'd1 && !iqentry_stomp[7]));
3992
*/
3993
`ifdef FLOATING_POINT
3994
fp0_dataready <= 1'b1
3995
                        && ((iqentry_fpissue[0] && iqentry_islot[0] == 4'd0 && !iqentry_stomp[0])
3996
                         || (iqentry_fpissue[1] && iqentry_islot[1] == 4'd0 && !iqentry_stomp[1])
3997
                         || (iqentry_fpissue[2] && iqentry_islot[2] == 4'd0 && !iqentry_stomp[2])
3998
                         || (iqentry_fpissue[3] && iqentry_islot[3] == 4'd0 && !iqentry_stomp[3])
3999
                         || (iqentry_fpissue[4] && iqentry_islot[4] == 4'd0 && !iqentry_stomp[4])
4000
                         || (iqentry_fpissue[5] && iqentry_islot[5] == 4'd0 && !iqentry_stomp[5])
4001
                         || (iqentry_fpissue[6] && iqentry_islot[6] == 4'd0 && !iqentry_stomp[6])
4002
                         || (iqentry_fpissue[7] && iqentry_islot[7] == 4'd0 && !iqentry_stomp[7]));
4003
`endif
4004
 
4005
for (n = 0; n < QENTRIES; n = n + 1)
4006
begin
4007
        if (iqentry_v[n] && iqentry_stomp[n]) begin
4008
                iqentry_v[n] <= `INV;
4009
                if (dram0_id[2:0] == n[2:0])      dram0 <= `DRAMSLOT_AVAIL;
4010
                if (dram1_id[2:0] == n[2:0])      dram1 <= `DRAMSLOT_AVAIL;
4011
                if (dram2_id[2:0] == n[2:0])      dram2 <= `DRAMSLOT_AVAIL;
4012
        end
4013
        else if (iqentry_issue[n]) begin
4014
                case (iqentry_islot[n])
4015
                2'd0: if (alu0_available) begin
4016
                        alu0_ld <= 1'b1;
4017
                        alu0_sourceid   <= n[3:0];
4018
                        alu0_insnsz <= iqentry_insnsz[n];
4019
                        alu0_op         <= iqentry_op[n];
4020
                        alu0_fn     <= iqentry_fn[n];
4021
                        alu0_cond   <= iqentry_cond[n];
4022
                        alu0_bt         <= iqentry_bt[n];
4023
                        alu0_pc         <= iqentry_pc[n];
4024
                        alu0_pred   <= iqentry_p_v[n] ? iqentry_pred[n] :
4025
                                                        (iqentry_p_s[n] == alu0_id) ? alu0_bus[3:0] :
4026
                                                        (iqentry_p_s[n] == alu1_id) ? alu1_bus[3:0] : 4'h0;
4027
                        alu0_argA       <= iqentry_a1_v[n] ? iqentry_a1[n]
4028
                                                : (iqentry_a1_s[n] == alu0_id) ? alu0_bus
4029
                                                : (iqentry_a1_s[n] == alu1_id) ? alu1_bus
4030
                                                : 64'hDEADDEADDEADDEAD;
4031
                        alu0_argB       <= iqentry_a2_v[n] ? iqentry_a2[n]
4032
                                                : (iqentry_a2_s[n] == alu0_id) ? alu0_bus
4033
                                                : (iqentry_a2_s[n] == alu1_id) ? alu1_bus
4034
                                                : 64'hDEADDEADDEADDEAD;
4035
                        alu0_argC       <= (iqentry_op[n]==`POP || iqentry_op[n]==`PUSH || iqentry_op[n]==`PEA) ? {sregs[3'd6],12'h000} :
4036
                                       iqentry_mem[n] ? {sregs[iqentry_fn[n][5:3]],12'h000} :
4037
                                       iqentry_a3_v[n] ? iqentry_a3[n]
4038
                                                : (iqentry_a3_s[n] == alu0_id) ? alu0_bus
4039
                                                : (iqentry_a3_s[n] == alu1_id) ? alu1_bus
4040
                                                : 64'hDEADDEADDEADDEAD;
4041
                        alu0_argT       <= iqentry_T_v[n] ? iqentry_T[n]
4042
                        : (iqentry_T_s[n] == alu0_id) ? alu0_bus
4043
                        : (iqentry_T_s[n] == alu1_id) ? alu1_bus
4044
                        : 64'hDEADDEADDEADDEAD;
4045
            alu0_argI   <= iqentry_a0[n];
4046
            alu0_dataready <= fnAluValid(iqentry_op[n],iqentry_fn[n]);
4047
                        end
4048
                2'd1: if (alu1_available) begin
4049
                        alu1_ld <= 1'b1;
4050
                        alu1_sourceid   <= n[3:0];
4051
                        alu1_insnsz <= iqentry_insnsz[n];
4052
                        alu1_op         <= iqentry_op[n];
4053
                        alu1_fn     <= iqentry_fn[n];
4054
                        alu1_cond   <= iqentry_cond[n];
4055
                        alu1_bt         <= iqentry_bt[n];
4056
                        alu1_pc         <= iqentry_pc[n];
4057
                        alu1_pred   <= iqentry_p_v[n] ? iqentry_pred[n] :
4058
                                                        (iqentry_p_s[n] == alu0_id) ? alu0_bus[3:0] :
4059
                                                        (iqentry_p_s[n] == alu1_id) ? alu1_bus[3:0] : 4'h0;
4060
                        alu1_argA       <= iqentry_a1_v[n] ? iqentry_a1[n]
4061
                            : (iqentry_a1_s[n] == alu0_id) ? alu0_bus
4062
                            : (iqentry_a1_s[n] == alu1_id) ? alu1_bus
4063
                            : 64'hDEADDEADDEADDEAD;
4064
                        alu1_argB       <= iqentry_a2_v[n] ? iqentry_a2[n]
4065
                                                : (iqentry_a2_s[n] == alu0_id) ? alu0_bus
4066
                                                : (iqentry_a2_s[n] == alu1_id) ? alu1_bus
4067
                                                : 64'hDEADDEADDEADDEAD;
4068
                        alu1_argC       <= (iqentry_op[n]==`POP || iqentry_op[n]==`PUSH || iqentry_op[n]==`PEA) ? {sregs[3'd6],12'h000} :
4069
                                       iqentry_mem[n] ? {sregs[iqentry_fn[n][5:3]],12'h000} :
4070
                                       iqentry_a3_v[n] ? iqentry_a3[n]
4071
                                                : (iqentry_a3_s[n] == alu0_id) ? alu0_bus
4072
                                                : (iqentry_a3_s[n] == alu1_id) ? alu1_bus
4073
                                                : 64'hDEADDEADDEADDEAD;
4074
                        alu1_argT       <= iqentry_T_v[n] ? iqentry_T[n]
4075
                        : (iqentry_T_s[n] == alu0_id) ? alu0_bus
4076
                        : (iqentry_T_s[n] == alu1_id) ? alu1_bus
4077
                        : 64'hDEADDEADDEADDEAD;
4078
            alu1_argI   <= iqentry_a0[n];
4079
            alu1_dataready <= fnAluValid(iqentry_op[n],iqentry_fn[n]);
4080
                        end
4081
                default: panic <= `PANIC_INVALIDISLOT;
4082
                endcase
4083
                iqentry_out[n] <= `TRUE;
4084
                // if it is a memory operation, this is the address-generation step ... collect result into arg1
4085
                if (iqentry_mem[n] && iqentry_op[n]!=`TLB) begin
4086
                        iqentry_a1_v[n] <= `INV;
4087
                        iqentry_a1_s[n] <= n[3:0];
4088
                end
4089
        end
4090
end
4091
 
4092
 
4093
`ifdef FLOATING_POINT
4094
for (n = 0; n < QENTRIES; n = n + 1)
4095
begin
4096
        if (iqentry_v[n] && iqentry_stomp[n])
4097
                ;
4098
        else if (iqentry_fpissue[n]) begin
4099
                case (iqentry_fpislot[n])
4100
                2'd0: if (1'b1) begin
4101
                        fp0_ld <= 1'b1;
4102
                        fp0_sourceid    <= n[3:0];
4103
                        fp0_op          <= iqentry_op[n];
4104
                        fp0_fn     <= iqentry_fn[n];
4105
                        fp0_cond   <= iqentry_cond[n];
4106
                        fp0_pred   <= iqentry_p_v[n] ? iqentry_pred[n] :
4107
                                                        (iqentry_p_s[n] == alu0_id) ? alu0_bus[3:0] :
4108
                                                        (iqentry_p_s[n] == alu1_id) ? alu1_bus[3:0] : 4'h0;
4109
                        fp0_argA        <= iqentry_a1_v[n] ? iqentry_a1[n]
4110
                            : (iqentry_a1_s[n] == alu0_id) ? alu0_bus
4111
                            : (iqentry_a1_s[n] == alu1_id) ? alu1_bus
4112
                            : 64'hDEADDEADDEADDEAD;
4113
            fp0_argB    <= iqentry_a2_v[n] ? iqentry_a2[n]
4114
                                                : (iqentry_a2_s[n] == alu0_id) ? alu0_bus
4115
                                                : (iqentry_a2_s[n] == alu1_id) ? alu1_bus
4116
                                                : 64'hDEADDEADDEADDEAD;
4117
                        fp0_argC        <= iqentry_a3_v[n] ? iqentry_a3[n]
4118
                                                : (iqentry_a3_s[n] == alu0_id) ? alu0_bus
4119
                                                : (iqentry_a3_s[n] == alu1_id) ? alu1_bus
4120
                                                : 64'hDEADDEADDEADDEAD;
4121
                        fp0_argT        <= iqentry_T_v[n] ? iqentry_T[n]
4122
                        : (iqentry_T_s[n] == alu0_id) ? alu0_bus
4123
                        : (iqentry_T_s[n] == alu1_id) ? alu1_bus
4124
                        : 64'hDEADDEADDEADDEAD;
4125
                        fp0_argI        <= iqentry_a0[n];
4126
                        end
4127
                default: panic <= `PANIC_INVALIDISLOT;
4128
                endcase
4129
                iqentry_out[n] <= `TRUE;
4130
        end
4131
end
4132
`endif
4133
 
4134
// MEMORY
4135
//
4136
// update the memory queues and put data out on bus if appropriate
4137
// Always puts data on the bus even for stores. In the case of
4138
// stores, the data is ignored.
4139
//
4140
//
4141
// dram0, dram1, dram2 are the "state machines" that keep track
4142
// of three pipelined DRAM requests.  if any has the value "00", 
4143
// then it can accept a request (which bumps it up to the value "01"
4144
// at the end of the cycle).  once it hits the value "10" the request
4145
// and the bus is acknowledged the dram request
4146
// is finished and the dram_bus takes the value.  if it is a store, the 
4147
// dram_bus value is not used, but the dram_v value along with the
4148
// dram_id value signals the waiting memq entry that the store is
4149
// completed and the instruction can commit.
4150
//
4151
if (tlb_state != 3'd0 && tlb_state < 3'd3)
4152
        tlb_state <= tlb_state + 3'd1;
4153
if (tlb_state==3'd3) begin
4154
        dram_v <= `TRUE;
4155
        dram_id <= tlb_id;
4156
        dram_tgt <= tlb_tgt;
4157
        dram_exc <= `EXC_NONE;
4158
        dram_bus <= tlb_dato;
4159
        tlb_op <= 4'h0;
4160
        tlb_state <= 3'd0;
4161
end
4162
 
4163
case(dram0)
4164
// The first state is to translate the virtual to physical address.
4165
3'd1:
4166
        begin
4167
                $display("0MEM %c:%h %h cycle started",fnIsLoad(dram0_op)?"L" : "S", dram0_addr, dram0_data);
4168
                if (dbg_lmatch|dbg_smatch) begin
4169
                    dram_v <= `TRUE;
4170
                    dram_id <= dram0_id;
4171
                    dram_tgt <= dram0_tgt;
4172
            dram_exc <= `EXC_DBG;
4173
            dram_bus <= 64'h0;
4174
            dram0 <= 3'd0;
4175
        end
4176
`ifdef SEGMENTATION
4177
        else if (dram0_addr[ABW-1:12] >= dram0_lmt) begin
4178
            dram_v <= `TRUE;            // we are finished the memory cycle
4179
            dram_id <= dram0_id;
4180
            dram_tgt <= dram0_tgt;
4181
            dram_exc <= `EXC_SEGV;    //dram0_exc;
4182
            dram_bus <= 64'h0;
4183
            dram0 <= 3'd0;
4184
        end
4185
`endif
4186
        else if (!cyc_o) dram0 <= dram0 + 3'd1;
4187
        end
4188
 
4189
// State 2:
4190
// Check for a TLB miss on the translated address, and
4191
// Initiate a bus transfer
4192
3'd2:
4193
        if (DTLBMiss) begin
4194
                dram_v <= `TRUE;                        // we are finished the memory cycle
4195
                dram_id <= dram0_id;
4196
                dram_tgt <= dram0_tgt;
4197
                dram_exc <= `EXC_TLBMISS;       //dram0_exc;
4198
                dram_bus <= 64'h0;
4199
                dram0 <= 3'd0;
4200
        end
4201
        else if (dram0_exc!=`EXC_NONE) begin
4202
                dram_v <= `TRUE;                        // we are finished the memory cycle
4203
        dram_id <= dram0_id;
4204
        dram_tgt <= dram0_tgt;
4205
        dram_exc <= dram0_exc;
4206
                dram_bus <= 64'h0;
4207
        dram0 <= 3'd0;
4208
        end
4209
        else begin
4210
            if (dram0_op==`LCL) begin
4211
               if (dram0_tgt==7'd0) begin
4212
                   ic_invalidate_line <= `TRUE;
4213
                   ic_lineno <= dram0_addr;
4214
               end
4215
           dram0 <= 3'd6;
4216
            end
4217
                else if (uncached || fnIsStore(dram0_op) || fnIsLoadV(dram0_op) || dram0_op==`CAS ||
4218
                  ((dram0_op==`STMV || dram0_op==`INC) && stmv_flag)) begin
4219
                if (cstate==IDLE) begin // make sure an instruction load isn't taking place
4220
                dram0_owns_bus <= `TRUE;
4221
                resv_o <= dram0_op==`LVWAR;
4222
                cres_o <= dram0_op==`SWCR;
4223
                lock_o <= dram0_op==`CAS;
4224
                cyc_o <= 1'b1;
4225
                stb_o <= 1'b1;
4226
                we_o <= fnIsStore(dram0_op) || ((dram0_op==`STMV || dram0_op==`INC) && stmv_flag);
4227
                sel_o <= fnSelect(dram0_op,dram0_fn,pea);
4228
                rsel <= fnSelect(dram0_op,dram0_fn,pea);
4229
                adr_o <= pea;
4230
                if (dram0_op==`INC)
4231
                    dat_o <= fnDatao(dram0_op,dram0_fn,dram0_data) + index;
4232
                else
4233
                    dat_o <= fnDatao(dram0_op,dram0_fn,dram0_data);
4234
                dram0 <= dram0 + 3'd1;
4235
                        end
4236
                end
4237
                else begin      // cached read
4238
                        dram0 <= 3'd6;
4239
            rsel <= fnSelect(dram0_op,dram0_fn,pea);
4240
           end
4241
        end
4242
 
4243
// State 3:
4244
// Wait for a memory ack
4245
3'd3:
4246
        if (ack_i|err_i) begin
4247
                $display("MEM ack");
4248
                dram_v <= dram0_op != `CAS && dram0_op != `INC && dram0_op != `STS && dram0_op != `STMV && dram0_op != `STCMP && dram0_op != `STFND;
4249
                dram_id <= dram0_id;
4250
                dram_tgt <= dram0_tgt;
4251
                dram_exc <= (err_i & dram0_tgt!=7'd0) ? `EXC_DBE : `EXC_NONE;//dram0_exc;
4252
                if (dram0_op==`SWCR)
4253
                     dram_bus <= {63'd0,resv_i};
4254
                else
4255
                     dram_bus <= fnDatai(dram0_op,dram0_fn,dat_i,rsel);
4256
                dram0_owns_bus <= `FALSE;
4257
                wb_nack();
4258
                dram0 <= 3'd7;
4259
                case(dram0_op)
4260
`ifdef STRINGOPS
4261
                `STS:
4262
                        if (lc != 0 && !int_pending) begin
4263
                            dram0_owns_bus <= `TRUE;
4264
                                dram0_addr <= dram0_addr +
4265
                                    (dram0_fn[2:0]==3'd0 ? 64'd1 :
4266
                                    dram0_fn[2:0]==3'd1 ? 64'd2 :
4267
                                    dram0_fn[2:0]==3'd2 ? 64'd4 :
4268
                                    64'd8);
4269
                                lc <= lc - 64'd1;
4270
                                dram0 <= 3'd1;
4271
                                dram_bus <= dram0_addr +
4272
                    (dram0_fn[2:0]==3'd0 ? 64'd1 :
4273
                    dram0_fn[2:0]==3'd1 ? 64'd2 :
4274
                    dram0_fn[2:0]==3'd2 ? 64'd4 :
4275
                    64'd8);
4276
            end
4277
            else begin
4278
                dram_bus <= dram0_addr +
4279
                                (dram0_fn[2:0]==3'd0 ? 64'd1 :
4280
                                dram0_fn[2:0]==3'd1 ? 64'd2 :
4281
                                dram0_fn[2:0]==3'd2 ? 64'd4 :
4282
                                64'd8) - dram0_seg;
4283
                dram_v <= `VAL;
4284
            end
4285
        `STMV,`STCMP:
4286
            if (lc != 0 && !(int_pending && stmv_flag)) begin
4287
                dram0 <= 3'd1;
4288
                            dram0_owns_bus <= `TRUE;
4289
                if (stmv_flag) begin
4290
                    dram0_addr <= src_addr + index;
4291
                    if (dram0_op==`STCMP) begin
4292
                        if (dram0_data != fnDatai(dram0_op,dram0_fn,dat_i,rsel)) begin
4293
                            lc <= 64'd0;
4294
                            dram0 <= 3'd7;
4295
                            dram_v <= `VAL;
4296
                            dram_bus <= index;
4297
                        end
4298
                    end
4299
                end
4300
                else begin
4301
                    dram0_addr <= dst_addr + index;
4302
                    dram0_data <= fnDatai(dram0_op,dram0_fn,dat_i,rsel);
4303
                end
4304
                if (!stmv_flag)
4305
                    inc_index(dram0_fn);
4306
                stmv_flag <= ~stmv_flag;
4307
            end
4308
            else begin
4309
                dram_bus <= index;
4310
                dram_v <= `VAL;
4311
            end
4312
        `STFND:
4313
            if (lc != 0 && !int_pending) begin
4314
                dram0_addr <= src_addr + index;
4315
                inc_index(dram0_fn);
4316
                if (dram0_data == dram_bus) begin
4317
                    lc <= 64'd0;
4318
                    dram0 <= 3'd7;
4319
                    dram_v <= `VAL;
4320
                    dram_bus <= index;
4321
                end
4322
                else
4323
                    dram0 <= 3'd1;
4324
            end
4325
            else begin
4326
                dram_bus <= index;
4327
                dram_v <= `VAL;
4328
            end
4329
`endif
4330
        `CAS:
4331
                        if (dram0_datacmp == dat_i) begin
4332
                                $display("CAS match");
4333
                                dram0_owns_bus <= `TRUE;
4334
                                cyc_o <= 1'b1;  // hold onto cyc_o
4335
                                dram0 <= dram0 + 3'd1;
4336
                        end
4337
                        else
4338
                                dram_v <= `VAL;
4339
                `INC:
4340
                     begin
4341
                         if (stmv_flag) begin
4342
                             dram_v <= `VAL;
4343
                         end
4344
                         else begin
4345
                             dram0_data <= fnDatai(dram0_op,dram0_fn,dat_i,rsel);
4346
                     stmv_flag <= ~stmv_flag;
4347
                     dram0 <= 3'd2;
4348
                         end
4349
                     end
4350
                default:  ;
4351
                endcase
4352
        end
4353
 
4354
// State 4:
4355
// Start a second bus transaction for the CAS instruction
4356
3'd4:
4357
        begin
4358
                stb_o <= 1'b1;
4359
                we_o <= 1'b1;
4360
                sel_o <= fnSelect(dram0_op,dram0_fn,pea);
4361
                adr_o <= pea;
4362
                dat_o <= fnDatao(dram0_op,dram0_fn,dram0_data);
4363
                dram0 <= dram0 + 3'd1;
4364
        end
4365
 
4366
// State 5:
4367
// Wait for a memory ack for the second bus transaction of a CAS
4368
//
4369
3'd5:
4370
        if (ack_i|err_i) begin
4371
        $display("MEM ack2");
4372
        dram_v <= `VAL;
4373
        dram_id <= dram0_id;
4374
        dram_tgt <= dram0_tgt;
4375
        dram_exc <= (err_i & dram0_tgt!=7'd0) ? `EXC_DBE : `EXC_NONE;
4376
        dram0_owns_bus <= `FALSE;
4377
        wb_nack();
4378
        lock_o <= 1'b0;
4379
        dram0 <= 3'd7;
4380
    end
4381
 
4382
// State 6:
4383
// Wait for a data cache read hit
4384
3'd6:
4385
        if (rhit && dram0_op!=`LCL) begin
4386
            case(dram0_op)
4387
`ifdef STRINGOPS
4388
            // The read portion of the STMV was just done, go back and do
4389
            // the write portion.
4390
        `STMV:
4391
           begin
4392
               stmv_flag <= `TRUE;
4393
               dram0_addr <= dst_addr + index;
4394
               dram0_data <= fnDatai(dram0_op,dram0_fn,cdat,rsel);
4395
               dram0 <= 3'd2;
4396
           end
4397
        `STCMP:
4398
            if (lc != 0 && !int_pending && stmv_flag) begin
4399
                dram0_addr <= src_addr + index;
4400
                stmv_flag <= ~stmv_flag;
4401
                if (dram0_data != dram_bus) begin
4402
                    lc <= 64'd0;
4403
                    dram0 <= 3'd7;
4404
                    dram_v <= `VAL;
4405
                    dram_bus <= index;
4406
                    dram_id <= dram0_id;
4407
                    dram_tgt <= dram0_tgt;
4408
                end
4409
            end
4410
            else if (!stmv_flag) begin
4411
                stmv_flag <= ~stmv_flag;
4412
                dram0_addr <= dst_addr + index;
4413
                dram0_data <= fnDatai(dram0_op,dram0_fn,cdat,rsel);
4414
                dram0 <= 3'd2;
4415
                inc_index(dram0_fn);
4416
            end
4417
            else begin
4418
                dram_id <= dram0_id;
4419
                dram_tgt <= dram0_tgt;
4420
                dram_bus <= index;
4421
                dram_v <= `VAL;
4422
                dram0 <= 3'd7;
4423
            end
4424
        `STFND:
4425
            if (lc != 0 && !int_pending) begin
4426
                dram0_addr <= src_addr + index;
4427
                inc_index(dram0_fn);
4428
                if (dram0_data == dram_bus) begin
4429
                    lc <= 64'd0;
4430
                    dram_id <= dram0_id;
4431
                    dram_tgt <= dram0_tgt;
4432
                    dram0 <= 3'd7;
4433
                    dram_v <= `VAL;
4434
                    dram_bus <= index;
4435
                end
4436
            end
4437
            else begin
4438
                dram_id <= dram0_id;
4439
                dram_tgt <= dram0_tgt;
4440
                dram_bus <= index;
4441
                dram_v <= `VAL;
4442
                dram0 <= 3'd7;
4443
            end
4444
`endif
4445
                `INC:
4446
             begin
4447
                 dram0_data <= fnDatai(dram0_op,dram0_fn,cdat,rsel);
4448
                 stmv_flag <= `TRUE;
4449
                 dram0 <= 3'd2;
4450
            end
4451
    default: begin
4452
            $display("Read hit [%h]",dram0_addr);
4453
            dram_v <= `TRUE;
4454
            dram_id <= dram0_id;
4455
            dram_tgt <= dram0_tgt;
4456
            dram_exc <= `EXC_NONE;
4457
            dram_bus <= fnDatai(dram0_op,dram0_fn,cdat,rsel);
4458
            dram0 <= 3'd0;
4459
            end
4460
        endcase
4461
        end
4462
3'd7:
4463
    dram0 <= 3'd0;
4464
endcase
4465
 
4466
//
4467
// determine if the instructions ready to issue can, in fact, issue.
4468
// "ready" means that the instruction has valid operands but has not gone yet
4469
//
4470
// Stores can only issue if there is no possibility of a change of program flow.
4471
// That means no flow control operations or instructions that can cause an
4472
// exception can be before the store.
4473
iqentry_memissue[ head0 ] <= iqentry_memissue_head0;
4474
iqentry_memissue[ head1 ] <= iqentry_memissue_head1;
4475
iqentry_memissue[ head2 ] <= iqentry_memissue_head2;
4476
iqentry_memissue[ head3 ] <= iqentry_memissue_head3;
4477
iqentry_memissue[ head4 ] <= iqentry_memissue_head4;
4478
iqentry_memissue[ head5 ] <= iqentry_memissue_head5;
4479
iqentry_memissue[ head6 ] <= iqentry_memissue_head6;
4480
iqentry_memissue[ head7 ] <= iqentry_memissue_head7;
4481
 
4482
                                /* ||
4483
                                        (   !fnIsFlowCtrl(iqentry_op[head0])
4484
                                         && !fnIsFlowCtrl(iqentry_op[head1])
4485
                                         && !fnIsFlowCtrl(iqentry_op[head2])
4486
                                         && !fnIsFlowCtrl(iqentry_op[head3])
4487
                                         && !fnIsFlowCtrl(iqentry_op[head4])
4488
                                         && !fnIsFlowCtrl(iqentry_op[head5])
4489
                                         && !fnIsFlowCtrl(iqentry_op[head6])));
4490
*/
4491
//
4492
// take requests that are ready and put them into DRAM slots
4493
 
4494
if (dram0 == `DRAMSLOT_AVAIL)   dram0_exc <= `EXC_NONE;
4495
 
4496
// Memory should also wait until segment registers are valid. The segment
4497
// registers are essentially static registers while a program runs. They are
4498
// setup by only the operating system. The system software must ensure the
4499
// segment registers are stable before they get used. We don't bother checking
4500
// for rf_v[].
4501
//
4502
for (n = 0; n < QENTRIES; n = n + 1)
4503
        if (!iqentry_stomp[n] && iqentry_memissue[n] && iqentry_agen[n] && iqentry_op[n]==`TLB && !iqentry_out[n]) begin
4504
            $display("TLB issue");
4505
            if (!iq_cmt[n]) begin
4506
                iqentry_cmt[n] <= `FALSE;
4507
                iqentry_done[n] <= `TRUE;
4508
                iqentry_out[n] <= `FALSE;
4509
                iqentry_agen[n] <= `FALSE;
4510
                iqentry_res[n] <= iqentry_T_v[n] ? iqentry_T[n]
4511
                        : (iqentry_T_s[n] == alu0_id) ? alu0_bus
4512
                        : (iqentry_T_s[n] == alu1_id) ? alu1_bus
4513
                        : 64'hDEADDEADDEADDEAD;
4514
            end
4515
                else if (tlb_state==3'd0) begin
4516
                        tlb_state <= 3'd1;
4517
                        tlb_id <= {1'b1, n[2:0]};
4518
                        tlb_op <= iqentry_a0[n][3:0];
4519
                        tlb_regno <= iqentry_a0[n][7:4];
4520
                        tlb_tgt <= iqentry_tgt[n];
4521
                        tlb_data <= iqentry_a1[n];
4522
                        iqentry_out[n] <= `TRUE;
4523
                end
4524
        end
4525
        else if (!iqentry_stomp[n] && iqentry_memissue[n] && iqentry_agen[n] && !iqentry_out[n]) begin
4526
            if (!iq_cmt[n]) begin
4527
            iqentry_cmt[n] <= `FALSE;
4528
            iqentry_done[n] <= `TRUE;
4529
            iqentry_out[n] <= `FALSE;
4530
            iqentry_agen[n] <= `FALSE;
4531
                iqentry_res[n] <= iqentry_T_v[n] ? iqentry_T[n]
4532
                        : (iqentry_T_s[n] == alu0_id) ? alu0_bus
4533
                        : (iqentry_T_s[n] == alu1_id) ? alu1_bus
4534
                        : 64'hDEADDEADDEADDEAD;
4535
        end
4536
        else begin
4537
            if (fnIsStoreString(iqentry_op[n]))
4538
                string_pc <= iqentry_pc[n];
4539
            $display("issued memory cycle");
4540
            if (dram0 == `DRAMSLOT_AVAIL) begin
4541
                dram0           <= 3'd1;
4542
                dram0_id        <= { 1'b1, n[2:0] };
4543
                dram0_op        <= iqentry_op[n];
4544
                dram0_fn    <= iqentry_fn[n];
4545
                dram0_tgt       <= iqentry_tgt[n];
4546
                dram0_data      <= (fnIsIndexed(iqentry_op[n]) || iqentry_op[n]==`CAS) ? iqentry_a3[n] :
4547
`ifdef STACKOPS
4548
                                iqentry_op[n]==`PEA ? iqentry_a2[n] + iqentry_a0[n] :
4549
`endif
4550
                                iqentry_a2[n];
4551
                dram0_datacmp <= iqentry_a2[n];
4552
`ifdef SEGMENTATION
4553
                dram0_addr <= iqentry_a1[n];
4554
                dram0_seg <= {sregs[iqentry_fn[n][5:3]],12'h000};
4555
                dram0_lmt <= sregs[iqentry_fn[n][5:3]] + sregs_lmt[iqentry_fn[n][5:3]];
4556
//                dram0_exc <= (iqentry_a1[n][ABW-1:12] >= sregs_lmt[iqentry_fn[n][5:3]]) ? `EXC_SEGV : `EXC_NONE;
4557
`ifdef STRINGOPS
4558
                src_addr <= iqentry_a1[n] + {sregs[iqentry_fn[n][5:3]],12'h000};
4559
                dst_addr <= iqentry_a2[n] + {sregs[iqentry_fn[n][5:3]],12'h000};
4560
`endif
4561
`else
4562
                dram0_addr <= iqentry_a1[n];
4563
`ifdef STRINGOPS
4564
                src_addr <= iqentry_a1[n];
4565
                dst_addr <= iqentry_a2[n];
4566
`endif
4567
`endif
4568
                stmv_flag <= `FALSE;
4569
                index <= iqentry_op[n]==`INC ? iqentry_a2[n] : iqentry_a3[n];
4570
                iqentry_out[n]  <= `TRUE;
4571
            end
4572
                end
4573
        end
4574
 
4575
for (n = 0; n < QENTRIES; n = n + 1)
4576
begin
4577
    if (iqentry_op[n]==`IMM && iqentry_v[(n+1)&7] &&
4578
        ((iqentry_pc[(n+1)&7]==iqentry_pc[n]+iqentry_insnsz[n]) ||
4579
         (iqentry_pc[(n+1)&7]==iqentry_pc[n]))) // address inherited due to interrupt
4580
        iqentry_done[n] <= `TRUE;
4581
/*
4582
    if (iqentry_v[n] && args_valid[n] && !iqentry_out[n] && !iq_cmt[n] && iqentry_op[n]!=`IMM) begin
4583
        iqentry_done[n] <= `TRUE;
4584
        iqentry_res[n] <= iqentry_T[n];
4585
    end
4586
*/
4587
    if (!iqentry_v[n])
4588
        iqentry_done[n] <= `FALSE;
4589
/*
4590
    if (iqentry_v[n] && !iqentry_done[n]) begin
4591
        if (!iqentry_a1_v[n] && iqentry_v[iqentry_a1_s[n][2:0]] && iqentry_done[iqentry_a1_s[n][2:0]]) begin
4592
            iqentry_a1_v[n] <= `VAL;
4593
            iqentry_a1[n] <= iqentry_res[iqentry_a1_s[n][2:0]];
4594
        end
4595
        if (!iqentry_a2_v[n] && iqentry_v[iqentry_a2_s[n][2:0]] && iqentry_done[iqentry_a2_s[n][2:0]]) begin
4596
            iqentry_a2_v[n] <= `VAL;
4597
            iqentry_a2[n] <= iqentry_res[iqentry_a2_s[n][2:0]];
4598
        end
4599
        if (!iqentry_a3_v[n] && iqentry_v[iqentry_a3_s[n][2:0]] && iqentry_done[iqentry_a3_s[n][2:0]]) begin
4600
            iqentry_a3_v[n] <= `VAL;
4601
            iqentry_a3[n] <= iqentry_res[iqentry_a3_s[n][2:0]];
4602
        end
4603
    end
4604
*/
4605
end
4606
 
4607
 
4608
//      $display("TLB: en=%b imatch=%b pgsz=%d pcs=%h phys=%h", utlb1.TLBenabled,utlb1.IMatch,utlb1.PageSize,utlb1.pcs,utlb1.IPFN);
4609
//      for (i = 0; i < 64; i = i + 1)
4610
//              $display("vp=%h G=%b",utlb1.TLBVirtPage[i],utlb1.TLBG[i]);
4611
//`include "Thor_commit.v"
4612
// It didn't work in simulation when the following was declared under an
4613
// independant always clk block
4614
//
4615
commit_spr(commit0_v,commit0_tgt,commit0_bus);
4616
commit_spr(commit1_v,commit1_tgt,commit1_bus);
4617
 
4618
// When the INT instruction commits set the hardware interrupt status to disable further interrupts.
4619
if (int_commit)
4620
begin
4621
        $display("*********************");
4622
        $display("*********************");
4623
        $display("Interrupt committing");
4624
        $display("*********************");
4625
        $display("*********************");
4626
        StatusHWI <= `TRUE;
4627
        imb <= im;
4628
        im <= 1'b0;
4629
        // Reset the nmi edge sense circuit but only for an NMI
4630
        if ((iqentry_a0[head0][7:0]==8'hFE && commit0_v && iqentry_op[head0]==`INT) ||
4631
            (iqentry_a0[head1][7:0]==8'hFE && commit1_v && iqentry_op[head1]==`INT))
4632
                nmi_edge <= 1'b0;
4633
        string_pc <= 64'd0;
4634
end
4635
 
4636
if (sys_commit)
4637
begin
4638
        if (StatusEXL!=8'hFF)
4639
                StatusEXL <= StatusEXL + 8'd1;
4640
end
4641
 
4642
oddball_commit(commit0_v,head0);
4643
oddball_commit(commit1_v,head1);
4644
 
4645
//
4646
// COMMIT PHASE (dequeue only ... not register-file update)
4647
//
4648
// If the third instruction is invalidated or if it doesn't update the register
4649
// file then it is allowed to commit too.
4650
// The head pointer might advance by three.
4651
//
4652
if (~|panic)
4653
casex ({ iqentry_v[head0],
4654
        iqentry_done[head0],
4655
        iqentry_v[head1],
4656
        iqentry_done[head1],
4657
        iqentry_v[head2],
4658
        iqentry_done[head2]})
4659
 
4660
        // retire 3
4661
        6'b0x_0x_0x:
4662
                if (head0 != tail0 && head1 != tail0 && head2 != tail0) begin
4663
                    head_inc(3);
4664
                end
4665
                else if (head0 != tail0 && head1 != tail0) begin
4666
                    head_inc(2);
4667
                end
4668
                else if (head0 != tail0) begin
4669
                    head_inc(1);
4670
                end
4671
 
4672
        // retire 2 (wait for regfile for head2)
4673
        6'b0x_0x_10:
4674
                begin
4675
                    head_inc(2);
4676
                end
4677
 
4678
        // retire 2 or 3 (wait for regfile for head2)
4679
        6'b0x_0x_11:
4680
           begin
4681
                if (iqentry_tgt[head2]==7'd0) begin
4682
                    iqentry_v[head2] <= `INV;
4683
                    head_inc(3);
4684
                end
4685
                else begin
4686
                    head_inc(2);
4687
                        end
4688
                end
4689
 
4690
        // retire 3
4691
        6'b0x_11_0x:
4692
                if (head1 != tail0 && head2 != tail0) begin
4693
                        iqentry_v[head1] <= `INV;
4694
                        head_inc(3);
4695
                end
4696
                else begin
4697
                        iqentry_v[head1] <= `INV;
4698
                        head_inc(2);
4699
                end
4700
 
4701
        // retire 2     (wait on head2 or wait on register file for head2)
4702
        6'b0x_11_10:
4703
                begin
4704
                        iqentry_v[head1] <= `INV;
4705
                        head_inc(2);
4706
                end
4707
        6'b0x_11_11:
4708
        begin
4709
            if (iqentry_tgt[head2]==7'd0) begin
4710
                iqentry_v[head1] <= `INV;
4711
                iqentry_v[head2] <= `INV;
4712
                head_inc(3);
4713
            end
4714
            else begin
4715
                iqentry_v[head1] <= `INV;
4716
                head_inc(2);
4717
            end
4718
        end
4719
 
4720
        // 4'b00_00     - neither valid; skip both
4721
        // 4'b00_01     - neither valid; skip both
4722
        // 4'b00_10     - skip head0, wait on head1
4723
        // 4'b00_11     - skip head0, commit head1
4724
        // 4'b01_00     - neither valid; skip both
4725
        // 4'b01_01     - neither valid; skip both
4726
        // 4'b01_10     - skip head0, wait on head1
4727
        // 4'b01_11     - skip head0, commit head1
4728
        // 4'b10_00     - wait on head0
4729
        // 4'b10_01     - wait on head0
4730
        // 4'b10_10     - wait on head0
4731
        // 4'b10_11     - wait on head0
4732
        // 4'b11_00     - commit head0, skip head1
4733
        // 4'b11_01     - commit head0, skip head1
4734
        // 4'b11_10     - commit head0, wait on head1
4735
        // 4'b11_11     - commit head0, commit head1
4736
 
4737
        //
4738
        // retire 0 (stuck on head0)
4739
        6'b10_xx_xx:    ;
4740
 
4741
        // retire 3
4742
        6'b11_0x_0x:
4743
                if (head1 != tail0 && head2 != tail0) begin
4744
                        iqentry_v[head0] <= `INV;
4745
                        head_inc(3);
4746
                end
4747
                else if (head1 != tail0) begin
4748
                        iqentry_v[head0] <= `INV;
4749
                        head_inc(2);
4750
                end
4751
                else begin
4752
                        iqentry_v[head0] <= `INV;
4753
                        head_inc(1);
4754
                end
4755
 
4756
        // retire 2 (wait for regfile for head2)
4757
        6'b11_0x_10:
4758
                begin
4759
                        iqentry_v[head0] <= `INV;
4760
                        head_inc(2);
4761
                end
4762
 
4763
        // retire 2 or 3 (wait for regfile for head2)
4764
        6'b11_0x_11:
4765
            if (iqentry_tgt[head2]==7'd0) begin
4766
                        iqentry_v[head0] <= `INV;
4767
                        iqentry_v[head2] <= `INV;
4768
                        head_inc(3);
4769
            end
4770
            else begin
4771
                        iqentry_v[head0] <= `INV;
4772
                        head_inc(2);
4773
                end
4774
 
4775
        //
4776
        // retire 1 (stuck on head1)
4777
        6'b00_10_xx,
4778
        6'b01_10_xx,
4779
        6'b11_10_xx:
4780
                if (iqentry_v[head0] || head0 != tail0) begin
4781
            iqentry_v[head0] <= `INV;
4782
            head_inc(1);
4783
                end
4784
 
4785
        // retire 2 or 3
4786
        6'b11_11_0x:
4787
                if (head2 != tail0) begin
4788
                        iqentry_v[head0] <= `INV;       // may conflict with STOMP, but since both are setting to 0, it is okay
4789
                        iqentry_v[head1] <= `INV;
4790
                        head_inc(3);
4791
                end
4792
                else begin
4793
                        iqentry_v[head0] <= `INV;
4794
                        iqentry_v[head1] <= `INV;
4795
                        head_inc(2);
4796
                end
4797
 
4798
        // retire 2 (wait on regfile for head2)
4799
        6'b11_11_10:
4800
                begin
4801
                        iqentry_v[head0] <= `INV;       // may conflict with STOMP, but since both are setting to 0, it is okay
4802
                        iqentry_v[head1] <= `INV;       // may conflict with STOMP, but since both are setting to 0, it is okay
4803
                        head_inc(2);
4804
                end
4805
        6'b11_11_11:
4806
            if (iqentry_tgt[head2]==7'd0) begin
4807
            iqentry_v[head0] <= `INV;    // may conflict with STOMP, but since both are setting to 0, it is okay
4808
            iqentry_v[head1] <= `INV;    // may conflict with STOMP, but since both are setting to 0, it is okay
4809
            iqentry_v[head2] <= `INV;    // may conflict with STOMP, but since both are setting to 0, it is okay
4810
            head_inc(3);
4811
            end
4812
        else begin
4813
            iqentry_v[head0] <= `INV;    // may conflict with STOMP, but since both are setting to 0, it is okay
4814
            iqentry_v[head1] <= `INV;    // may conflict with STOMP, but since both are setting to 0, it is okay
4815
            head_inc(2);
4816
        end
4817
endcase
4818
 
4819
        if (branchmiss)
4820
                rrmapno <= iqentry_renmapno[missid];
4821
 
4822
        case(cstate)
4823
        RESET1:
4824
           begin
4825
               ic_ld <= `TRUE;
4826
               ic_ld_cntr <= 32'd0;
4827
               cstate <= RESET2;
4828
           end
4829
        RESET2:
4830
           begin
4831
               ic_ld_cntr <= ic_ld_cntr + 32'd32;
4832
               if (ic_ld_cntr >= 32'd32768) begin
4833
                   ic_ld <= `FALSE;
4834
                   ic_ld_cntr <= 32'd0;
4835
                   cstate <= IDLE;
4836
               end;
4837
           end
4838
        IDLE:
4839
                if (dcache_access_pending) begin
4840
                                $display("********************");
4841
                                $display("DCache access to: %h",{pea[DBW-1:5],5'b00000});
4842
                                $display("********************");
4843
                                derr <= 1'b0;
4844
                                bte_o <= 2'b00;
4845
                                cti_o <= 3'b001;
4846
                                bl_o <= DBW==32 ? 5'd7 : 5'd3;
4847
                                cyc_o <= 1'b1;
4848
                                stb_o <= 1'b1;
4849
                                we_o <= 1'b0;
4850
                                sel_o <= {DBW/8{1'b1}};
4851
                                adr_o <= {pea[DBW-1:5],5'b00000};
4852
                                dat_o <= {DBW{1'b0}};
4853
                                cstate <= DCACHE1;
4854
                end
4855
                else if ((!ihit && !mem_issue && dram0==3'd0)||(dram0==3'd6 && (dram0_op==`LCL && dram0_tgt==7'd0))) begin
4856
                        if ((dram0!=2'd0 || dram1!=2'd0 || dram2!=2'd0) && !(dram0==3'd6 && (dram0_op==`LCL && dram0_tgt==7'd0)))
4857
                                $display("drams non-zero");
4858
                        else begin
4859
                                $display("********************");
4860
                                $display("ICache access to: %h",
4861
                                    (dram0==3'd6 && (dram0_op==`LCL && dram0_tgt==7'd0)) ? {dram0_addr[ABW-1:5],5'h00} :
4862
                                    !hit0 ? {ppc[DBW-1:5],5'b00000} : {ppcp16[DBW-1:5],5'b00000});
4863
                                $display("********************");
4864
                                ierr <= 1'b0;
4865
                                bte_o <= 2'b00;
4866
                                cti_o <= 3'b001;
4867
                                bl_o <= DBW==32 ? 5'd7 : 5'd3;
4868
                                cyc_o <= 1'b1;
4869
                                stb_o <= 1'b1;
4870
                                we_o <= 1'b0;
4871
                                sel_o <= {DBW/8{1'b1}};
4872
                                adr_o <= (dram0==3'd6 && (dram0_op==`LCL && dram0_tgt==7'd0)) ? {dram0_addr[ABW-1:5],5'h00} : !hit0 ? {ppc[DBW-1:5],5'b00000} : {ppcp16[DBW-1:5],5'b00000};
4873
                                dat_o <= {DBW{1'b0}};
4874
                                cstate <= ICACHE1;
4875
                        end
4876
                end
4877
        ICACHE1:
4878
                begin
4879
                        if (ack_i|err_i) begin
4880
                                ierr <= ierr | err_i;   // cumulate an error status
4881
                                if (DBW==32) begin
4882
                                        adr_o[4:2] <= adr_o[4:2] + 3'd1;
4883
                                        if (adr_o[4:2]==3'b110)
4884
                                                cti_o <= 3'b111;
4885
                                        if (adr_o[4:2]==3'b111) begin
4886
                                                wb_nack();
4887
                                                cstate <= IDLE;
4888
                                                if (dram0==3'd6 && dram0_op==`LCL) begin
4889
                                                     dram0_op<=`NOP;
4890
                                                end
4891
                                        end
4892
                                end
4893
                                else begin
4894
                                        adr_o[4:3] <= adr_o[4:3] + 2'd1;
4895
                                        if (adr_o[4:3]==2'b10)
4896
                                                cti_o <= 3'b111;
4897
                                        if (adr_o[4:3]==2'b11) begin
4898
                                                wb_nack();
4899
                                                cstate <= IDLE;
4900
                                                if (dram0==3'd6 && dram0_op==`LCL) begin
4901
                             dram0_op<=`NOP;
4902
                        end
4903
                                        end
4904
                                end
4905
                        end
4906
                end
4907
        DCACHE1:
4908
                begin
4909
                        if (ack_i|err_i) begin
4910
                                derr <= derr | err_i;   // cumulate an error status
4911
                                if (DBW==32) begin
4912
                                        adr_o[4:2] <= adr_o[4:2] + 3'd1;
4913
                                        if (adr_o[4:2]==3'b110)
4914
                                                cti_o <= 3'b111;
4915
                                        if (adr_o[4:2]==3'b111) begin
4916
                                                wb_nack();
4917
                                                cstate <= IDLE;
4918
                                                if (dram0_op==`LCL) begin
4919
                                                    dram0_op <= `NOP;
4920
                                                    dram0_tgt <= 7'd0;
4921
                                                end
4922
                                        end
4923
                                end
4924
                                else begin
4925
                                        adr_o[4:3] <= adr_o[4:3] + 2'd1;
4926
                                        if (adr_o[4:3]==2'b10)
4927
                                                cti_o <= 3'b111;
4928
                                        if (adr_o[4:3]==2'b11) begin
4929
                                                wb_nack();
4930
                                                cstate <= IDLE;
4931
                                                if (dram0_op==`LCL) begin
4932
                                                    dram0_op <= `NOP;
4933
                                                    dram0_tgt <= 7'd0;
4934
                                            end
4935
                                        end
4936
                                end
4937
                        end
4938
                end
4939
    default:    cstate <= IDLE;
4940
        endcase
4941
 
4942
//      for (i=0; i<8; i=i+1)
4943
//          $display("%d: %h %d %o #", i, urf1.regs0[i], rf_v[i], rf_source[i]);
4944
 
4945
        if (ihit) begin
4946
        $display("dr=%d I=%h A=%h B=%h op=%c%d bt=%d src=%o pc=%h #",
4947
                alu0_dataready, alu0_argI, alu0_argA, alu0_argB,
4948
                 (fnIsFlowCtrl(alu0_op) ? 98 : (fnIsMem(alu0_op)) ? 109 : 97),
4949
                alu0_op, alu0_bt, alu0_sourceid, alu0_pc);
4950
        $display("dr=%d I=%h A=%h B=%h op=%c%d bt=%d src=%o pc=%h #",
4951
                alu1_dataready, alu1_argI, alu1_argA, alu1_argB,
4952
                 (fnIsFlowCtrl(alu1_op) ? 98 : (fnIsMem(alu1_op)) ? 109 : 97),
4953
                alu1_op, alu1_bt, alu1_sourceid, alu1_pc);
4954
        $display("v=%d bus=%h id=%o 0 #", alu0_v, alu0_bus, alu0_id);
4955
        $display("bmiss0=%b src=%o mpc=%h #", alu0_branchmiss, alu0_sourceid, alu0_misspc);
4956
        $display("cmt=%b cnd=%d prd=%d", alu0_cmt, alu0_cond, alu0_pred);
4957
        $display("bmiss1=%b src=%o mpc=%h #", alu1_branchmiss, alu1_sourceid, alu1_misspc);
4958
        $display("cmt=%b cnd=%d prd=%d", alu1_cmt, alu1_cond, alu1_pred);
4959
        $display("bmiss=%b mpc=%h", branchmiss, misspc);
4960
 
4961
        $display("0: %d %h %o 0%d #", commit0_v, commit0_bus, commit0_id, commit0_tgt);
4962
        $display("1: %d %h %o 0%d #", commit1_v, commit1_bus, commit1_id, commit1_tgt);
4963
        end
4964
        if (|panic) begin
4965
            $display("");
4966
            $display("-----------------------------------------------------------------");
4967
            $display("-----------------------------------------------------------------");
4968
            $display("---------------     PANIC:%s     -----------------", message[panic]);
4969
            $display("-----------------------------------------------------------------");
4970
            $display("-----------------------------------------------------------------");
4971
            $display("");
4972
            $display("instructions committed: %d", I);
4973
            $display("total execution cycles: %d", $time / 10);
4974
            $display("");
4975
        end
4976
        if (|panic && ~outstanding_stores) begin
4977
            $finish;
4978
        end
4979
end
4980
 
4981
task wb_nack;
4982
begin
4983
    resv_o <= 1'b0;
4984
    cres_o <= 1'b0;
4985
        bte_o <= 2'b00;
4986
        cti_o <= 3'b000;
4987
        bl_o <= 5'd0;
4988
        cyc_o <= 1'b0;
4989
        stb_o <= 1'b0;
4990
        we_o <= 1'b0;
4991
        sel_o <= 8'h00;
4992
        adr_o <= {DBW{1'b0}};
4993
        dat_o <= {DBW{1'b0}};
4994
end
4995
endtask
4996
 
4997
task commit_spr;
4998
input commit_v;
4999
input [6:0] commit_tgt;
5000
input [DBW-1:0] commit_bus;
5001
begin
5002
if (commit_v && commit_tgt[6]) begin
5003
    casex(commit_tgt[5:0])
5004
    6'b00xxxx:  begin
5005
                pregs[commit_tgt[3:0]] <= commit_bus[3:0];
5006
                    $display("pregs[%d]<=%h", commit_tgt[3:0], commit_bus[3:0]);
5007
//                  $stop;
5008
                end
5009
    6'b01xxxx:  begin
5010
                cregs[commit_tgt[3:0]] <= commit_bus;
5011
                    $display("cregs[%d]<=%h", commit_tgt[3:0], commit_bus);
5012
                   end
5013
`ifdef SEGMENTATION
5014
    6'b100xxx:  begin
5015
                sregs[commit_tgt[2:0]] <= commit_bus[DBW-1:12];
5016
                    $display("sregs[%d]<=%h", commit_tgt[2:0], commit_bus);
5017
                    end
5018
        6'b101xxx:  sregs_lmt[commit_tgt[2:0]] <= commit_bus[DBW-1:12];
5019
`endif
5020
    6'b110000:
5021
        begin
5022
        pregs[0] <= commit_bus[3:0];
5023
        pregs[1] <= commit_bus[7:4];
5024
        pregs[2] <= commit_bus[11:8];
5025
        pregs[3] <= commit_bus[15:12];
5026
        pregs[4] <= commit_bus[19:16];
5027
        pregs[5] <= commit_bus[23:20];
5028
        pregs[6] <= commit_bus[27:24];
5029
        pregs[7] <= commit_bus[31:28];
5030
        if (DBW==64) begin
5031
            pregs[8] <= commit_bus[35:32];
5032
            pregs[9] <= commit_bus[39:36];
5033
            pregs[10] <= commit_bus[43:40];
5034
            pregs[11] <= commit_bus[47:44];
5035
            pregs[12] <= commit_bus[51:48];
5036
            pregs[13] <= commit_bus[55:52];
5037
            pregs[14] <= commit_bus[59:56];
5038
            pregs[15] <= commit_bus[63:60];
5039
        end
5040
        end
5041
    `LCTR:  begin    lc <= commit_bus; $display("LC <= %h", commit_bus); end
5042
        `ASID:      asid <= commit_bus;
5043
    `SR:    begin
5044
            GM <= commit_bus[7:0];
5045
            GMB <= commit_bus[23:16];
5046
            imb <= commit_bus[31];
5047
            im <= commit_bus[15];
5048
            fxe <= commit_bus[12];
5049
            end
5050
    6'd60:  spr_bir <= commit_bus[11:0];
5051
    6'd61:
5052
            case(spr_bir[5:0])
5053
            6'd0:   dbg_adr0 <= commit_bus;
5054
            6'd1:   dbg_adr1 <= commit_bus;
5055
            6'd2:   dbg_adr2 <= commit_bus;
5056
            6'd3:   dbg_adr3 <= commit_bus;
5057
            6'd4:   dbg_ctrl <= commit_bus;
5058
            endcase
5059
    6'b111111:
5060
            begin
5061
                ld_clk_throttle <= `TRUE;
5062
                clk_throttle_new <= commit_bus[15:0];
5063
            end
5064
    endcase
5065
end
5066
end
5067
endtask
5068
 
5069
// For string memory operations.
5070
//
5071
task inc_index;
5072
input [5:0] fn;
5073
begin
5074
    case(fn[2:0])
5075
    3'd0:   index <= index + 64'd1;
5076
    3'd1:   index <= index + 64'd2;
5077
    3'd2:   index <= index + 64'd4;
5078
    3'd3:   index <= index + 64'd8;
5079
    3'd4:   index <= index - 64'd1;
5080
    3'd5:   index <= index - 64'd2;
5081
    3'd6:   index <= index - 64'd4;
5082
    3'd7:   index <= index - 64'd8;
5083
    endcase
5084
    lc <= lc - 64'd1;
5085
end
5086
endtask
5087
 
5088
function [DBW-1:0] fnSpr;
5089
input [5:0] regno;
5090
input [63:0] epc;
5091
begin
5092
    // Read from the special registers unless overridden by the
5093
    // value on the commit bus.
5094
    casex(regno)
5095
    6'b00xxxx:  fnSpr = pregs[regno[3:0]];
5096
    6'b01xxxx:  fnSpr = cregs[regno[3:0]];
5097
    6'b100xxx:  fnSpr = {sregs[regno[2:0]],12'h000};
5098
    6'b101xxx:  fnSpr = {sregs_lmt[regno[2:0]],12'h000};
5099
    6'b110000:  if (DBW==64)
5100
                fnSpr = {pregs[15],pregs[14],pregs[13],pregs[12],
5101
                         pregs[11],pregs[10],pregs[9],pregs[8],
5102
                         pregs[7],pregs[6],pregs[5],pregs[4],
5103
                         pregs[3],pregs[2],pregs[1],pregs[0]};
5104
                else
5105
                fnSpr = {pregs[7],pregs[6],pregs[5],pregs[4],
5106
                         pregs[3],pregs[2],pregs[1],pregs[0]};
5107
    `TICK:      fnSpr = tick;
5108
    `LCTR:      fnSpr = lc;
5109
    `ASID:      fnSpr = asid;
5110
    `SR:    begin
5111
            fnSpr[7:0] = GM;
5112
            fnSpr[23:16] = GMB;
5113
            fnSpr[31] = imb;
5114
            fnSpr[15] = im;
5115
            fnSpr[12] = fxe;
5116
            end
5117
    6'd60:  fnSpr = spr_bir;
5118
    6'd61:
5119
            case(spr_bir[5:0])
5120
            6'd0:   fnSpr = dbg_adr0;
5121
            6'd1:   fnSpr = dbg_adr1;
5122
            6'd2:   fnSpr = dbg_adr2;
5123
            6'd3:   fnSpr = dbg_adr3;
5124
            6'd4:   fnSpr = dbg_ctrl;
5125
            6'd5:   fnSpr = dbg_stat;
5126
            default:    fnSpr = 64'd0;
5127
            endcase
5128
    default:    fnSpr = 64'd0;
5129
    endcase
5130
 
5131
    // If an spr is committing...
5132
    if (commit0_v && commit0_tgt=={1'b1,regno})
5133
        fnSpr = commit0_bus;
5134
    if (commit1_v && commit1_tgt=={1'b1,regno})
5135
            fnSpr = commit1_bus;
5136
 
5137
    // Special cases where the register would not be read from the commit bus
5138
    case(regno)
5139
    `TICK:      fnSpr = tick;
5140
    6'b010000:  fnSpr = 64'd0;  // code address zero
5141
    6'b011111:  fnSpr = epc;    // current program counter from fetchbufx_pc
5142
    default:    ;
5143
    endcase
5144
end
5145
endfunction
5146
 
5147
// "oddball" instruction commit cases.
5148
//
5149
task oddball_commit;
5150
input commit_v;
5151
input [2:0] head;
5152
begin
5153
    if (commit_v)
5154
        case(iqentry_op[head])
5155
        `CLI:   begin im <= 1'b0; imb <= 1'b0; end
5156
        `SEI:   begin im <= 1'b1; imb <= 1'b1; end
5157
        // When the RTI instruction commits clear the hardware interrupt status to enable interrupts.
5158
        `RTI:   begin
5159
                StatusHWI <= `FALSE;
5160
                im <= imb;
5161
                end
5162
        `RTE,`RTD:
5163
                begin
5164
                    if (StatusEXL!=8'h00)
5165
                        StatusEXL <= StatusEXL - 8'd1;
5166
                end
5167
        `CACHE:
5168
               begin
5169
                   case(iqentry_fn[head])
5170
                   6'd0:   ic_invalidate <= `TRUE;
5171
                   6'd1:   begin
5172
                           ic_invalidate_line <= `TRUE;
5173
                           ic_lineno <= iqentry_a1[head]  + {sregs[3'd7],12'h000};
5174
                           end
5175
                   6'd32:  dc_invalidate <= `TRUE;
5176
                   6'd33:  begin
5177
                           dc_invalidate_line <= `TRUE;
5178
                           dc_lineno <= iqentry_a1[head] + {sregs[iqentry_fn[head][5:3]],12'h000};
5179
                           end
5180
                   default: ;   // do nothing
5181
                   endcase
5182
               end
5183
        default:        ;
5184
        endcase
5185
end
5186
endtask
5187
 
5188
task enque0a;
5189
input [2:0] tail;
5190
input [2:0] inc;
5191
input unlink;
5192
begin
5193
    // If segment limit exceeded and not in the non-segmented area.
5194
    if (fetchbuf0_pc >= {sregs_lmt[7],12'h000} && fetchbuf0_pc[ABW-1:ABW-4]!=4'hF)
5195
        set_exception(tail,8'd244);
5196
    else begin
5197
`ifdef DEBUG_LOGIC
5198
    if (dbg_ctrl[0] && dbg_ctrl[17:16]==2'b00 && fetchbuf0_pc==dbg_adr0)
5199
        dbg_imatchA0 = `TRUE;
5200
    if (dbg_ctrl[1] && dbg_ctrl[21:20]==2'b00 && fetchbuf0_pc==dbg_adr1)
5201
        dbg_imatchA1 = `TRUE;
5202
    if (dbg_ctrl[2] && dbg_ctrl[25:24]==2'b00 && fetchbuf0_pc==dbg_adr2)
5203
        dbg_imatchA2 = `TRUE;
5204
    if (dbg_ctrl[3] && dbg_ctrl[29:28]==2'b00 && fetchbuf0_pc==dbg_adr3)
5205
        dbg_imatchA3 = `TRUE;
5206
    if (dbg_imatchA0|dbg_imatchA1|dbg_imatchA2|dbg_imatchA3)
5207
        dbg_imatchA = `TRUE;
5208
    if (dbg_imatchA)
5209
        set_exception(tail,8'd243); // Debug exception
5210
    else begin
5211
`endif
5212
    interrupt_pc =
5213
            // If the previous instruction was an interrupt, then inherit the address 
5214
            (iqentry_op[(tail-3'd1)&7]==`INT && iqentry_v[(tail-3'd1)&7]==`VAL && iqentry_tgt[(tail-3'd1)&7][3:0]==4'hE) ?
5215
            (string_pc != 0 ? string_pc : iqentry_pc[(tail-3'd1)&7]) :
5216
            // Otherwise inherit the address of any preceding immediate prefix.
5217
            (iqentry_op[(tail-3'd1)&7]==`IMM && iqentry_v[(tail-3'd1)&7]==`VAL) ?
5218
                (string_pc != 0 ? string_pc : iqentry_pc[(tail-3'd1)&7]) :
5219
            // Otherwise use the address of the interrupted instruction
5220
            (string_pc != 0 ? string_pc : fetchbuf0_pc);
5221
    iqentry_v    [tail]    <=   `VAL;
5222
    iqentry_done [tail]    <=   `INV;
5223
    iqentry_cmt  [tail]    <=   `TRUE;
5224
    iqentry_out  [tail]    <=   `INV;
5225
    iqentry_res  [tail]    <=   `ZERO;
5226
    iqentry_insnsz[tail]   <=  fnInsnLength(fetchbuf0_instr);
5227
    iqentry_op   [tail]    <=   opcode0;
5228
    iqentry_fn   [tail]    <=   opcode0==`MLO ? rfoc0[5:0] : fnFunc(fetchbuf0_instr);
5229
    iqentry_cond [tail]    <=   cond0;
5230
    iqentry_bt   [tail]    <=   fnIsFlowCtrl(opcode0) && predict_taken0;
5231
    iqentry_agen [tail]    <=   `INV;
5232
    iqentry_pc   [tail]    <=   (opcode0==`INT && Rt0[3:0]==4'hE) ? interrupt_pc : fetchbuf0_pc;
5233
    iqentry_mem  [tail]    <=   fetchbuf0_mem;
5234
    iqentry_jmp  [tail]    <=   fetchbuf0_jmp;
5235
    iqentry_fp   [tail]    <=   fetchbuf0_fp;
5236
    iqentry_rfw  [tail]    <=   fetchbuf0_rfw;
5237
    iqentry_tgt  [tail]    <=   Rt0;
5238
    iqentry_pred [tail]    <=   pregs[Pn0];
5239
    // Look at the previous queue slot to see if an immediate prefix is enqueued
5240
    iqentry_a0[tail]   <=      opcode0==`INT ? fnImm(fetchbuf0_instr) :
5241
                                fnIsBranch(opcode0) ? {{DBW-12{fetchbuf0_instr[11]}},fetchbuf0_instr[11:8],fetchbuf0_instr[23:16]} :
5242
                                iqentry_op[(tail-3'd1)&7]==`IMM && iqentry_v[tail-3'd1] ? {iqentry_a0[(tail-3'd1)&7][DBW-1:8],fnImm8(fetchbuf0_instr)}:
5243
                                opcode0==`IMM ? fnImmImm(fetchbuf0_instr) :
5244
                                fnImm(fetchbuf0_instr);
5245
    iqentry_a1   [tail]    <=   fnOpa(opcode0,fetchbuf0_instr,rfoa0,fetchbuf0_pc);
5246
    iqentry_a2   [tail]    <=   fnIsShiftiop(fetchbuf0_instr) ? {{DBW-6{1'b0}},fetchbuf0_instr[`INSTRUCTION_RB]} :
5247
                                fnIsFPCtrl(fetchbuf0_instr) ? {{DBW-6{1'b0}},fetchbuf0_instr[`INSTRUCTION_RB]} :
5248
                                 opcode0==`INC ? {{56{fetchbuf0_instr[47]}},fetchbuf0_instr[47:40]} :
5249
                                 opcode0==`STI ? fetchbuf0_instr[27:22] :
5250
                                 Rb0[6] ? fnSpr(Rb0[5:0],fetchbuf0_pc) :
5251
                                 rfob0;
5252
    iqentry_a3   [tail]    <=   rfoc0;
5253
    iqentry_T    [tail]    <=   rfot0;
5254
    // The source is set even though the arg might be automatically valid (less logic).
5255
    // This is harmless to do. Note there is no source for the 'I' argument.
5256
    iqentry_p_s  [tail]    <=   rf_source[{1'b1,2'h0,Pn0}];
5257
    iqentry_a1_s [tail]    <=   //unlink ? {1'b0, (tail-1)&7} :
5258
                                 rf_source[Ra0];
5259
    iqentry_a2_s [tail]    <=   rf_source[Rb0];
5260
    iqentry_a3_s [tail]    <=   rf_source[Rc0];
5261
    iqentry_T_s  [tail]    <=   rf_source[Rt0];
5262
    // Always do this because it's the first queue slot.
5263
    validate_args10(tail);
5264
`ifdef DEBUG_LOGIC
5265
    end
5266
`endif
5267
    end
5268
    tail0 <= tail0 + inc;
5269
    tail1 <= tail1 + inc;
5270
    tail2 <= tail2 + inc;
5271
    queued1 = `TRUE;
5272
    rrmapno <= rrmapno + 3'd1;
5273
end
5274
endtask
5275
 
5276
task enquePushpopAdd;
5277
input [2:0] tail;
5278
input pushpop;
5279
input link;
5280
input unlink;
5281
input which;
5282
begin
5283
    $display("Pushpop add");
5284
    iqentry_v    [tail]    <=   `VAL;
5285
    iqentry_done [tail]    <=   `INV;
5286
    iqentry_cmt  [tail]    <=   `TRUE;
5287
    iqentry_out  [tail]    <=   `INV;
5288
    iqentry_res  [tail]    <=   64'd0;
5289
    iqentry_insnsz[tail]   <=   4'd0;
5290
    iqentry_op   [tail]    <=   `ADDUI;
5291
    iqentry_fn   [tail]    <=   6'b0;
5292
    iqentry_cond [tail]    <=   which ? cond1 :cond0;
5293
    iqentry_bt   [tail]    <=   1'b0;
5294
    iqentry_agen [tail]    <=   `INV;
5295
    iqentry_pc   [tail]    <=   which ? fetchbuf1_pc : fetchbuf0_pc;
5296
    iqentry_mem  [tail]    <=   1'b0;
5297
    iqentry_jmp  [tail]    <=   1'b0;
5298
    iqentry_fp   [tail]    <=   1'b0;
5299
    iqentry_rfw  [tail]    <=   1'b1;
5300
    iqentry_tgt  [tail]    <=   7'd27;
5301
    iqentry_pred [tail]    <=   pregs[which ? Pn1 : Pn0];
5302
    // Look at the previous queue slot to see if an immediate prefix is enqueued
5303
    iqentry_a0   [tail]    <=   link ? (which ? {{46{fetchbuf1_instr[39]}},fetchbuf1_instr[21:16],fetchbuf1_instr[39:28],3'b000} :
5304
                                                {{46{fetchbuf0_instr[39]}},fetchbuf0_instr[21:16],fetchbuf0_instr[39:28],3'b000}) :
5305
                                (pushpop|unlink) ? 64'd8 : -64'd8;
5306
    iqentry_a1   [tail]    <=   which ? rfoa1 : rfoa0;
5307
    iqentry_a2   [tail]    <=   64'd0;
5308
    iqentry_a3   [tail]    <=   64'd0;
5309
    iqentry_T    [tail]    <=   //unlink ? (which ? rfot1 : rfot0) :
5310
                                 (which ? rfoa1 : rfoa0);
5311
    // The source is set even though the arg might be automatically valid (less logic).
5312
    // This is harmless to do. Note there is no source for the 'I' argument.
5313
    iqentry_p_s  [tail]    <=   rf_source[{1'b1,2'h0,which ? Pn1 : Pn0}];
5314
    iqentry_a1_s [tail]    <=   rf_source[Ra0];
5315
    iqentry_a2_s [tail]    <=   rf_source[Rb0];
5316
    iqentry_a3_s [tail]    <=   rf_source[Rc0];
5317
    iqentry_T_s  [tail]    <=   rf_source[Ra0];
5318
    // Always do this because it's the first queue slot.
5319
    iqentry_p_v  [tail]    <=   rf_v [{1'b1,2'h0,which ? Pn1:Pn0}] || ((which ? cond1 : cond0) < 4'h2);
5320
    iqentry_a1_v [tail]    <=   rf_v[ which ? Ra1 :  Ra0 ];
5321
    iqentry_a2_v [tail]    <=   1'b1;
5322
    iqentry_a3_v [tail]    <=   1'b1;
5323
    iqentry_T_v  [tail]    <=   //unlink ? rf_v[which ? Rt1 : Rt0] :
5324
                                rf_v[ which ? Ra1 :  Ra0 ];
5325
    rf_v[ 7'd27 ] = `INV;
5326
    rf_source[ 7'd27 ] <= { 1'b0, tail };    // top bit indicates ALU/MEM bus
5327
end
5328
endtask
5329
 
5330
// enque 0 on tail0 or tail1
5331
task enque0;
5332
input [2:0] tail;
5333
input [2:0] inc;
5334
input test_stomp;
5335
input validate_args;
5336
begin
5337
    if (opcode0==`NOP)
5338
        queued1 = `TRUE;    // to update fetch buffers
5339
`ifdef STACKOPS
5340
    // A pop instruction takes 2 queue entries.
5341
    else if (fnIsPop(fetchbuf0_instr)|fnIsPush(fetchbuf0_instr)|opcode0==`LINK) begin
5342
        $display("0 found push/pop");
5343
        if (iqentry_v[tail]==`INV && iqentry_v[tail+1]==`INV) begin
5344
            $display("enqueing2");
5345
            enque0a(tail,3'd2,1'b0);
5346
            enquePushpopAdd((tail+1)&7,fnIsPop(fetchbuf0_instr),opcode0==`LINK,0,0);
5347
            allowq = `FALSE;
5348
        end
5349
    end
5350
    else if (opcode0==`UNLINK) begin
5351
        if (iqentry_v[tail]==`INV && iqentry_v[(tail+1)&7]==`INV) begin
5352
            enquePushpopAdd(tail,1'b0,1'b0,1'b1,0);
5353
            enque0a((tail+1)&7,3'd2,1'b1);
5354
            allowq = `FALSE;
5355
        end
5356
    end
5357
`endif
5358
    else if (iqentry_v[tail] == `INV) begin
5359
        if ((({fnIsBranch(opcode0), predict_taken0} == {`TRUE, `TRUE})||(opcode0==`LOOP)) && test_stomp)
5360
            qstomp = `TRUE;
5361
        enque0a(tail,inc,0);
5362
    end
5363
end
5364
endtask
5365
 
5366
task enque1a;
5367
input [2:0] tail;
5368
input [2:0] inc;
5369
input validate_args;
5370
input unlink;
5371
begin
5372
    if (fetchbuf1_pc >= {sregs_lmt[7],12'h000} && fetchbuf1_pc[ABW-1:ABW-4]!=4'hF)
5373
        set_exception(tail,8'd244);
5374
    else begin
5375
`ifdef DEBUG_LOGIC
5376
    if (dbg_ctrl[0] && dbg_ctrl[17:16]==2'b00 && fetchbuf1_pc==dbg_adr0)
5377
        dbg_imatchB0 = `TRUE;
5378
    if (dbg_ctrl[1] && dbg_ctrl[21:20]==2'b00 && fetchbuf1_pc==dbg_adr1)
5379
        dbg_imatchB1 = `TRUE;
5380
    if (dbg_ctrl[2] && dbg_ctrl[25:24]==2'b00 && fetchbuf1_pc==dbg_adr2)
5381
        dbg_imatchB2 = `TRUE;
5382
    if (dbg_ctrl[3] && dbg_ctrl[29:28]==2'b00 && fetchbuf1_pc==dbg_adr3)
5383
        dbg_imatchB3 = `TRUE;
5384
    if (dbg_imatchB0|dbg_imatchB1|dbg_imatchB2|dbg_imatchB3)
5385
        dbg_imatchB = `TRUE;
5386
    if (dbg_imatchB)
5387
        set_exception(tail,8'd243);     // debug excpetion
5388
    else begin
5389
`endif
5390
    // If an instruction wasn't enqueued or it wasn't an interrupt instruction then
5391
    // the interrupt pc will need to be set. Othersise this enqueue will inherit
5392
    // from the previous one.
5393
    if (!queued1 || !(opcode0==`INT && Rt0[3:0]==4'hE))
5394
        interrupt_pc = (iqentry_op[(tail-3'd1)&7]==`INT && iqentry_v[(tail-3'd1)&7]==`VAL && iqentry_tgt[(tail-3'd1)&7][3:0]==4'hE) ?
5395
            (string_pc != 0 ? string_pc : iqentry_pc[(tail-3'd1)&7]) :
5396
            (iqentry_op[(tail-3'd1)&7]==`IMM && iqentry_v[(tail-3'd1)&7]==`VAL) ? (string_pc != 0 ? string_pc :
5397
            iqentry_pc[(tail-3'd1)&7]) : (string_pc != 0 ? string_pc : fetchbuf1_pc);
5398
    iqentry_v    [tail]    <=   `VAL;
5399
    iqentry_done [tail]    <=   `INV;
5400
    iqentry_cmt  [tail]    <=   `TRUE;
5401
    iqentry_out  [tail]    <=   `INV;
5402
    iqentry_res  [tail]    <=   `ZERO;
5403
    iqentry_insnsz[tail]   <=  fnInsnLength(fetchbuf1_instr);
5404
    iqentry_op   [tail]    <=   opcode1;
5405
    iqentry_fn   [tail]    <=   opcode1==`MLO ? rfoc1[5:0] : fnFunc(fetchbuf1_instr);
5406
    iqentry_cond [tail]    <=   cond1;
5407
    iqentry_bt   [tail]    <=   fnIsFlowCtrl(opcode1) && predict_taken1;
5408
    iqentry_agen [tail]    <=   `INV;
5409
    // If an interrupt is being enqueued and the previous instruction was an immediate prefix, then
5410
    // inherit the address of the previous instruction, so that the prefix will be executed on return
5411
    // from interrupt.
5412
    // If a string operation was in progress then inherit the address of the string operation so that
5413
    // it can be continued.
5414
 
5415
    iqentry_pc   [tail]    <= (opcode1==`INT && Rt1[3:0]==4'hE) ? interrupt_pc : fetchbuf1_pc;
5416
    iqentry_mem  [tail]    <=   fetchbuf1_mem;
5417
    iqentry_jmp  [tail]    <=   fetchbuf1_jmp;
5418
    iqentry_fp   [tail]    <=   fetchbuf1_fp;
5419
    iqentry_rfw  [tail]    <=   fetchbuf1_rfw;
5420
    iqentry_tgt  [tail]    <=   Rt1;
5421
    iqentry_pred [tail]    <=   pregs[Pn1];
5422
    // Look at the previous queue slot to see if an immediate prefix is enqueued
5423
    // But don't allow it for a branch
5424
    iqentry_a0[tail]   <=       opcode1==`INT ? fnImm(fetchbuf1_instr) :
5425
                                fnIsBranch(opcode1) ? {{DBW-12{fetchbuf1_instr[11]}},fetchbuf1_instr[11:8],fetchbuf1_instr[23:16]} :
5426
                                (queued1 && opcode0==`IMM) ? {fnImmImm(fetchbuf0_instr)|fnImm8(fetchbuf1_instr)} :
5427
                                (!queued1 && iqentry_op[(tail-3'd1)&7]==`IMM) && iqentry_v[(tail-3'd1)&7] ? {iqentry_a0[(tail-3'd1)&7][DBW-1:8],fnImm8(fetchbuf1_instr)} :
5428
                                opcode1==`IMM ? fnImmImm(fetchbuf1_instr) :
5429
                                fnImm(fetchbuf1_instr);
5430
    iqentry_a1   [tail]    <=   fnOpa(opcode1,fetchbuf1_instr,rfoa1,fetchbuf1_pc);
5431
    iqentry_a2   [tail]    <=   fnIsShiftiop(fetchbuf1_instr) ? {{DBW-6{1'b0}},fetchbuf1_instr[`INSTRUCTION_RB]} :
5432
                                fnIsFPCtrl(fetchbuf1_instr) ? {{DBW-6{1'b0}},fetchbuf1_instr[`INSTRUCTION_RB]} :
5433
                                opcode1==`INC ? {{56{fetchbuf1_instr[47]}},fetchbuf1_instr[47:40]} :
5434
                                opcode1==`STI ? fetchbuf1_instr[27:22] :
5435
                                Rb1[6] ? fnSpr(Rb1[5:0],fetchbuf1_pc) :
5436
                                rfob1;
5437
    iqentry_a3   [tail]    <=   rfoc1;
5438
    iqentry_T    [tail]    <=   rfot1;
5439
    // The source is set even though the arg might be automatically valid (less logic). If 
5440
    // queueing two entries the source settings may be overridden in the argument valudation.
5441
    iqentry_p_s  [tail]    <=   rf_source[{1'b1,2'h0,Pn1}];
5442
    iqentry_a1_s [tail]    <=   //unlink ? {1'b0, (tail-3'd1)&7} :
5443
                                rf_source[Ra1];
5444
    iqentry_a2_s [tail]    <=   rf_source[Rb1];
5445
    iqentry_a3_s [tail]    <=   rf_source[Rc1];
5446
    iqentry_T_s  [tail]    <=   rf_source[Rt1];
5447
    if (validate_args)
5448
        validate_args11(tail);
5449
`ifdef DEBUG_LOGIC
5450
    end
5451
`endif
5452
    end
5453
    tail0 <= tail0 + inc;
5454
    tail1 <= tail1 + inc;
5455
    tail2 <= tail2 + inc;
5456
end
5457
endtask
5458
 
5459
// enque 1 on tail0 or tail1
5460
task enque1;
5461
input [2:0] tail;
5462
input [2:0] inc;
5463
input test_stomp;
5464
input validate_args;
5465
begin
5466
    if (opcode1==`NOP) begin
5467
        if (queued1==`TRUE) queued2 = `TRUE;
5468
        queued1 = `TRUE;
5469
    end
5470
`ifdef STACKOPS
5471
    else if (fnIsPop(fetchbuf1_instr)|fnIsPush(fetchbuf1_instr)|opcode1==`LINK) begin
5472
        $display("1 found push/pop");
5473
        $display("iqv[%d]:%d", tail,iqentry_v[tail]);
5474
        $display("iqv[%d+1]:%d", tail, iqentry_v[tail+1]);
5475
        $display("valargs:%d", validate_args);
5476
        $display("qd1:%d", queued1);
5477
        if (iqentry_v[tail]==`INV && iqentry_v[(tail+1)&7]==`INV && validate_args && !queued1) begin
5478
            $display("1 enq 2 ");
5479
            enque1a(tail,3'd2,1,0);
5480
            enquePushpopAdd((tail+1)&7,fnIsPop(fetchbuf1_instr),opcode1==`LINK,0,1);
5481
            allowq = `FALSE;
5482
        end
5483
    end
5484
    else if (opcode1==`UNLINK) begin
5485
        if (iqentry_v[tail]==`INV && iqentry_v[(tail+1)&7]==`INV) begin
5486
            enquePushpopAdd(tail,1'b0,1'b0,1'b1,1);
5487
            enque1a((tail+1)&7,3'd2,1,1);
5488
            allowq = `FALSE;
5489
        end
5490
    end
5491
`endif
5492
    else if (iqentry_v[tail] == `INV && !qstomp) begin
5493
        if ((({fnIsBranch(opcode1), predict_taken1} == {`TRUE, `TRUE})||(opcode1==`LOOP)) && test_stomp)
5494
            qstomp = `TRUE;
5495
        enque1a(tail,inc,validate_args,0);
5496
        if (queued1==`TRUE) queued2 = `TRUE;
5497
        else queued1 = `TRUE;
5498
    end
5499
end
5500
endtask
5501
 
5502
task validate_args10;
5503
input [2:0] tail;
5504
begin
5505
    iqentry_p_v  [tail]    <=   rf_v [{1'b1,2'h0,Pn0}] || cond0 < 4'h2;
5506
    iqentry_a1_v [tail]    <=   fnSource1_v( opcode0 ) | rf_v[ Ra0 ];
5507
    iqentry_a2_v [tail]    <=   fnSource2_v( opcode0, fnFunc(fetchbuf0_instr)) | rf_v[Rb0];
5508
    iqentry_a3_v [tail]    <=   fnSource3_v( opcode0 ) | rf_v[ Rc0 ];
5509
    iqentry_T_v  [tail]    <=   fnSourceT_v( opcode0 ) | rf_v[ Rt0 ];
5510
    if (fetchbuf0_rfw|fetchbuf0_pfw) begin
5511
        $display("regv[%d] = %d", Rt0,rf_v[ Rt0 ]);
5512
        rf_v[ Rt0 ] = Rt0==7'd0;
5513
        $display("reg[%d] <= INV",Rt0);
5514
        rf_source[ Rt0 ] <= { fetchbuf0_mem, tail };    // top bit indicates ALU/MEM bus
5515
        $display("10:rf_src[%d] <= %d, insn=%h", Rt0, tail,fetchbuf0_instr);
5516
    end
5517
end
5518
endtask
5519
 
5520
task validate_args11;
5521
input [2:0] tail;
5522
begin
5523
    // The predicate is automatically valid for condiitions 0 and 1 (always false or always true).
5524
    iqentry_p_v  [tail]    <=   rf_v [{1'b1,2'h0,Pn1}] || cond1 < 4'h2;
5525
    iqentry_a1_v [tail]    <=   fnSource1_v( opcode1 ) | rf_v[ Ra1 ];
5526
    iqentry_a2_v [tail]    <=   fnSource2_v( opcode1, fnFunc(fetchbuf1_instr) ) | rf_v[ Rb1 ];
5527
    iqentry_a3_v [tail]    <=   fnSource3_v( opcode1 ) | rf_v[ Rc1 ];
5528
    iqentry_T_v  [tail]    <=   fnSourceT_v( opcode1 ) | rf_v[ Rt1 ];
5529
    if (fetchbuf1_rfw|fetchbuf1_pfw) begin
5530
        $display("1:regv[%d] = %d", Rt1,rf_v[ Rt1 ]);
5531
        rf_v[ Rt1 ] = Rt1==7'd0;
5532
        $display("reg[%d] <= INV",Rt1);
5533
        rf_source[ Rt1 ] <= { fetchbuf1_mem, tail };    // top bit indicates ALU/MEM bus
5534
        $display("11:rf_src[%d] <= %d, insn=%h", Rt1, tail,fetchbuf0_instr);
5535
    end
5536
end
5537
endtask
5538
 
5539
// If two entries were queued then validate the arguments for the second entry.
5540
//
5541
task validate_args;
5542
begin
5543
    if (queued2) begin
5544
    // SOURCE 1 ... this is relatively straightforward, because all instructions
5545
       // that have a source (i.e. every instruction but LUI) read from RB
5546
       //
5547
       // if the argument is an immediate or not needed, we're done
5548
       if (fnSource1_v( opcode1 ) == `VAL) begin
5549
           $display("fnSource1_v=1 iq[%d]", tail1);
5550
           iqentry_a1_v [tail1] <= `VAL;
5551
           iqentry_a1_s [tail1] <= 4'hF;
5552
//                    iqentry_a1_s [tail1] <= 4'd0;
5553
       end
5554
       // if previous instruction writes nothing to RF, then get info from rf_v and rf_source
5555
       else if (!fetchbuf0_rfw) begin
5556
           iqentry_a1_v [tail1]    <=   rf_v [Ra1];
5557
           iqentry_a1_s [tail1]    <=   rf_source [Ra1];
5558
       end
5559
       // otherwise, previous instruction does write to RF ... see if overlap
5560
       else if (Rt0 != 7'd0 && Ra1 == Rt0) begin
5561
           // if the previous instruction is a LW, then grab result from memq, not the iq
5562
           $display("invalidating iqentry_a1_v[%d]", tail1);
5563
           iqentry_a1_v [tail1]    <=   `INV;
5564
           iqentry_a1_s [tail1]    <=   {fetchbuf0_mem, tail0};
5565
       end
5566
       // if no overlap, get info from rf_v and rf_source
5567
       else begin
5568
           iqentry_a1_v [tail1]    <=   rf_v [Ra1];
5569
           iqentry_a1_s [tail1]    <=   rf_source [Ra1];
5570
           $display("2:iqentry_a1_s[%d] <= %d", tail1, rf_source [Ra1]);
5571
       end
5572
 
5573
       if (!fetchbuf0_pfw) begin
5574
           iqentry_p_v  [tail1]    <=   rf_v [{1'b1,2'h0,Pn1}] || cond1 < 4'h2;
5575
           iqentry_p_s  [tail1]    <=   rf_source [{1'b1,2'h0,Pn1}];
5576
       end
5577
       else if ((Rt0 != 7'd0 && Pn1==Rt0[3:0]) && (Rt0 & 7'h70)==7'h40) begin
5578
           iqentry_p_v [tail1] <= cond1 < 4'h2;
5579
           iqentry_p_s [tail1] <= {fetchbuf0_mem, tail0};
5580
       end
5581
       else begin
5582
           iqentry_p_v [tail1] <= rf_v[{1'b1,2'h0,Pn1}] || cond1 < 4'h2;
5583
           iqentry_p_s [tail1] <= rf_source[{1'b1,2'h0,Pn1}];
5584
       end
5585
 
5586
       //
5587
       // SOURCE 2 ... this is more contorted than the logic for SOURCE 1 because
5588
       // some instructions (NAND and ADD) read from RC and others (SW, BEQ) read from RA
5589
       //
5590
       // if the argument is an immediate or not needed, we're done
5591
       if (fnSource2_v( opcode1,fnFunc(fetchbuf1_instr) ) == `VAL) begin
5592
           iqentry_a2_v [tail1] <= `VAL;
5593
           iqentry_a2_s [tail1] <= 4'hF;
5594
       end
5595
       // if previous instruction writes nothing to RF, then get info from rf_v and rf_source
5596
       else if (!fetchbuf0_rfw) begin
5597
           iqentry_a2_v [tail1] <= rf_v[ Rb1 ];
5598
           iqentry_a2_s [tail1] <= rf_source[Rb1];
5599
       end
5600
       // otherwise, previous instruction does write to RF ... see if overlap
5601
       else if (Rt0 != 7'd0 && Rb1 == Rt0) begin
5602
           // if the previous instruction is a LW, then grab result from memq, not the iq
5603
           iqentry_a2_v [tail1]    <=   `INV;
5604
           iqentry_a2_s [tail1]    <=   {fetchbuf0_mem,tail0};
5605
       end
5606
       // if no overlap, get info from rf_v and rf_source
5607
       else begin
5608
           iqentry_a2_v [tail1] <= rf_v[ Rb1 ];
5609
           iqentry_a2_s [tail1] <= rf_source[Rb1];
5610
       end
5611
 
5612
       //
5613
       // SOURCE 3 ... this is relatively straightforward, because all instructions
5614
       // that have a source (i.e. every instruction but LUI) read from RC
5615
       //
5616
       // if the argument is an immediate or not needed, we're done
5617
       if (fnSource3_v( opcode1 ) == `VAL) begin
5618
           iqentry_a3_v [tail1] <= `VAL;
5619
           iqentry_a3_v [tail1] <= 4'hF;
5620
//                    iqentry_a1_s [tail1] <= 4'd0;
5621
       end
5622
       // if previous instruction writes nothing to RF, then get info from rf_v and rf_source
5623
       else if (!fetchbuf0_rfw) begin
5624
           iqentry_a3_v [tail1]    <=   rf_v [Rc1];
5625
           iqentry_a3_s [tail1]    <=   rf_source [Rc1];
5626
       end
5627
       // otherwise, previous instruction does write to RF ... see if overlap
5628
       else if (Rt0 != 7'd0 && Rc1 == Rt0) begin
5629
           // if the previous instruction is a LW, then grab result from memq, not the iq
5630
           iqentry_a3_v [tail1]    <=   `INV;
5631
           iqentry_a3_s [tail1]    <=   {fetchbuf0_mem,tail0};
5632
       end
5633
       // if no overlap, get info from rf_v and rf_source
5634
       else begin
5635
           iqentry_a3_v [tail1]    <=   rf_v [Rc1];
5636
           iqentry_a3_s [tail1]    <=   rf_source [Rc1];
5637
       end
5638
 
5639
 
5640
       //
5641
       // Target 3 ... this is relatively straightforward, because all instructions
5642
       // that have a source (i.e. every instruction but LUI) read from RC
5643
       //
5644
       // if the argument is an immediate or not needed, we're done
5645
       if (fnSourceT_v( opcode1 ) == `VAL) begin
5646
           iqentry_T_v [tail1] <= `VAL;
5647
           iqentry_T_v [tail1] <= 4'hF;
5648
       end
5649
       // if previous instruction writes nothing to RF, then get info from rf_v and rf_source
5650
       else if (!fetchbuf0_rfw) begin
5651
           iqentry_T_v [tail1]    <=   rf_v [Rt1];
5652
           iqentry_T_s [tail1]    <=   rf_source [Rt1];
5653
       end
5654
       // otherwise, previous instruction does write to RF ... see if overlap
5655
       else if (Rt0 != 7'd0 && Rt1 == Rt0) begin
5656
           // if the previous instruction is a LW, then grab result from memq, not the iq
5657
           iqentry_T_v [tail1]    <=   `INV;
5658
           iqentry_T_s [tail1]    <=   {fetchbuf0_mem,tail0};
5659
       end
5660
       // if no overlap, get info from rf_v and rf_source
5661
       else begin
5662
           iqentry_T_v [tail1]    <=   rf_v [Rt1];
5663
           iqentry_T_s [tail1]    <=   rf_source [Rt1];
5664
       end
5665
    end
5666
    if (queued1|queued2) begin
5667
        if (fetchbuf0_rfw|fetchbuf0_pfw) begin
5668
            $display("regv[%d] = %d", Rt0,rf_v[ Rt0 ]);
5669
            rf_v[ Rt0 ] = Rt0==7'd0;
5670
            $display("reg[%d] <= INV",Rt0);
5671
            rf_source[ Rt0 ] <= { fetchbuf0_mem, tail0 };    // top bit indicates ALU/MEM bus
5672
            $display("12:rf_src[%d] <= %d, insn=%h", Rt0, tail0,fetchbuf0_instr);
5673
        end
5674
    end
5675
    if (queued2) begin
5676
        if (fetchbuf1_rfw|fetchbuf1_pfw) begin
5677
            $display("1:regv[%d] = %d", Rt1,rf_v[ Rt1 ]);
5678
            rf_v[ Rt1 ] = Rt1==7'd0;
5679
            $display("reg[%d] <= INV",Rt1);
5680
            rf_source[ Rt1 ] <= { fetchbuf1_mem, tail1 };    // top bit indicates ALU/MEM bus
5681
        end
5682
    end
5683
end
5684
endtask
5685
 
5686
task fetchAB;
5687
begin
5688
    fetchbufA_instr <= insn0;
5689
    fetchbufA_pc <= pc;
5690
    fetchbufA_v <= ld_fetchbuf;
5691
    fetchbufB_instr <= insn1;
5692
    fetchbufB_pc <= pc + fnInsnLength(insn);
5693
    fetchbufB_v <= ld_fetchbuf;
5694
end
5695
endtask
5696
 
5697
task fetchCD;
5698
begin
5699
    fetchbufC_instr <= insn0;
5700
    fetchbufC_pc <= pc;
5701
    fetchbufC_v <= ld_fetchbuf;
5702
    fetchbufD_instr <= insn1;
5703
    fetchbufD_pc <= pc + fnInsnLength(insn);
5704
    fetchbufD_v <= ld_fetchbuf;
5705
end
5706
endtask
5707
 
5708
// Reset the tail pointers.
5709
// Used by the enqueue logic
5710
//
5711
task reset_tail_pointers;
5712
input first;
5713
begin
5714
    if ((iqentry_stomp[0] & ~iqentry_stomp[7]) | first) begin
5715
        tail0 <= 0;
5716
        tail1 <= 1;
5717
    end
5718
    else if (iqentry_stomp[1] & ~iqentry_stomp[0]) begin
5719
        tail0 <= 1;
5720
        tail1 <= 2;
5721
    end
5722
    else if (iqentry_stomp[2] & ~iqentry_stomp[1]) begin
5723
        tail0 <= 2;
5724
        tail1 <= 3;
5725
    end
5726
    else if (iqentry_stomp[3] & ~iqentry_stomp[2]) begin
5727
        tail0 <= 3;
5728
        tail1 <= 4;
5729
    end
5730
    else if (iqentry_stomp[4] & ~iqentry_stomp[3]) begin
5731
        tail0 <= 4;
5732
        tail1 <= 5;
5733
    end
5734
    else if (iqentry_stomp[5] & ~iqentry_stomp[4]) begin
5735
        tail0 <= 5;
5736
        tail1 <= 6;
5737
    end
5738
    else if (iqentry_stomp[6] & ~iqentry_stomp[5]) begin
5739
        tail0 <= 6;
5740
        tail1 <= 7;
5741
    end
5742
    else if (iqentry_stomp[7] & ~iqentry_stomp[6]) begin
5743
        tail0 <= 7;
5744
        tail1 <= 0;
5745
    end
5746
    // otherwise, it is the last instruction in the queue that has been mispredicted ... do nothing
5747
end
5748
endtask
5749
 
5750
// Increment the head pointers
5751
// Also increments the instruction counter
5752
// Used when instructions are committed.
5753
// Also clear any outstanding state bits that foul things up.
5754
//
5755
task head_inc;
5756
input [2:0] amt;
5757
begin
5758
    head0 <= head0 + amt;
5759
    head1 <= head1 + amt;
5760
    head2 <= head2 + amt;
5761
    head3 <= head3 + amt;
5762
    head4 <= head4 + amt;
5763
    head5 <= head5 + amt;
5764
    head6 <= head6 + amt;
5765
    head7 <= head7 + amt;
5766
    I <= I + amt;
5767
    if (amt==3'd3) begin
5768
    iqentry_agen[head0] <= `INV;
5769
    iqentry_agen[head1] <= `INV;
5770
    iqentry_agen[head2] <= `INV;
5771
    end else if (amt==3'd2) begin
5772
    iqentry_agen[head0] <= `INV;
5773
    iqentry_agen[head1] <= `INV;
5774
    end else if (amt==3'd1)
5775
            iqentry_agen[head0] <= `INV;
5776
end
5777
endtask
5778
 
5779
 
5780
// set_exception:
5781
// Used to requeue the instruction as an exception if an exception occurs.
5782
 
5783
task set_exception;
5784
input [2:0] id;     // instruction queue id
5785
input [7:0] exc;    // exception number
5786
begin
5787
    iqentry_op [id[2:0] ] <= `INT;
5788
    iqentry_cond [id[2:0]] <= 4'd1;        // always execute
5789
    iqentry_mem[id[2:0]] <= `FALSE;
5790
    iqentry_rfw[id[2:0]] <= `TRUE;            // writes to IPC
5791
    iqentry_a0 [id[2:0]] <= exc;
5792
    iqentry_p_v  [id[2:0]] <= `TRUE;
5793
    iqentry_a1 [id[2:0]] <= cregs[4'hC];    // *** assumes BR12 is static
5794
    iqentry_a1_v [id[2:0]] <= `TRUE;        // Flag arguments as valid
5795
    iqentry_a2_v [id[2:0]] <= `TRUE;
5796
    iqentry_a3_v [id[2:0]] <= `TRUE;
5797
    iqentry_T_v  [id[2:0]] <= `TRUE;
5798
    iqentry_out [id[2:0]] <= `FALSE;
5799
    iqentry_agen [id[2:0]] <= `FALSE;
5800
    iqentry_tgt[id[2:0]] <= {1'b1,2'h1,(exc==8'd243)?4'hB:4'hD};    // Target EPC
5801
end
5802
endtask
5803
 
5804
endmodule

powered by: WebSVN 2.1.0

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