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

Subversion Repositories thor

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

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

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

powered by: WebSVN 2.1.0

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