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

Subversion Repositories thor

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

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

powered by: WebSVN 2.1.0

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