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

Subversion Repositories thor

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

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

powered by: WebSVN 2.1.0

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