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

Subversion Repositories thor

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

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

powered by: WebSVN 2.1.0

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