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

Subversion Repositories thor

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

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

powered by: WebSVN 2.1.0

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