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

Subversion Repositories s1_core

[/] [s1_core/] [trunk/] [hdl/] [rtl/] [sparc_core/] [sparc_ifu_swl.v] - Blame information for rev 113

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 95 fafa1971
// ========== Copyright Header Begin ==========================================
2
// 
3
// OpenSPARC T1 Processor File: sparc_ifu_swl.v
4
// Copyright (c) 2006 Sun Microsystems, Inc.  All Rights Reserved.
5
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
6
// 
7
// The above named program is free software; you can redistribute it and/or
8
// modify it under the terms of the GNU General Public
9
// License version 2 as published by the Free Software Foundation.
10
// 
11
// The above named program is distributed in the hope that it will be 
12
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
// General Public License for more details.
15
// 
16
// You should have received a copy of the GNU General Public
17
// License along with this work; if not, write to the Free Software
18
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
19
// 
20
// ========== Copyright Header End ============================================
21 113 albert.wat
`ifdef SIMPLY_RISC_TWEAKS
22
`define SIMPLY_RISC_SCANIN .si(0)
23
`else
24
`define SIMPLY_RISC_SCANIN .si()
25
`endif
26 95 fafa1971
////////////////////////////////////////////////////////////////////////
27
/*
28
//  Module Name: sparc_ifu_swl
29
//  Description:
30
//  The switch logic manages the 4 threads.  It schedules the next
31
//  thread to be executed.
32
*/
33
////////////////////////////////////////////////////////////////////////
34
 
35 113 albert.wat
`include "ifu.h"
36 95 fafa1971
 
37
module sparc_ifu_swl(/*AUTOARG*/
38
   // Outputs
39
   swl_sscan_thrstate, so, dtu_reset, swl_dec_mulbusy_e,
40
   swl_dec_divbusy_e, swl_dec_fpbusy_e, swl_dec_fp_enable_d,
41
   swl_dec_ibe_e, dtu_fcl_ntr_s, dtu_fcl_running_s,
42
   dtu_fcl_rollback_g, dtu_fcl_retract_d, dtu_fcl_thr_active,
43
   dtu_fcl_nextthr_bf, swl_dcl_thr_d, swl_dcl_thr_w2,
44
   dtu_fdp_thrconf_e,
45
   // Inputs
46
   rclk, se, si, gdbginit_l, arst_l, grst_l, ctu_sscan_tid,
47
   ifq_dtu_thrrdy, ifq_dtu_pred_rdy, ifu_tlu_inst_vld_w,
48
   ifu_tlu_ttype_vld_m, fcl_dtu_hprivmode_d, fcl_dtu_hprivmode_w2,
49
   tlu_ifu_flush_pipe_w, fcl_swl_flush_w, fcl_dtu_sync_intr_d,
50
   fcl_dtu_nuke_thr_w, fcl_dtu_rst_thr_w, fcl_dtu_resum_thr_w,
51
   fcl_dtu_thr_f, tlu_hpstate_ibe, lsu_ifu_ldsta_internal_e,
52
   tlu_ifu_trappc_vld_w1, dec_swl_ll_done_d, dec_swl_br_done_d,
53
   dec_swl_rdsr_sel_thr_d, dec_swl_std_inst_d, dec_swl_sta_inst_e,
54
   wsr_fixed_inst_w, dec_swl_ld_inst_d, dec_swl_mul_inst_d,
55
   dec_swl_div_inst_d, dec_swl_fpop_d, dec_swl_allfp_d,
56
   dec_swl_frf_upper_d, dec_swl_frf_lower_d, dec_swl_wrtfprs_w,
57
   dcl_swl_tcc_done_m, exu_ifu_longop_done_g, exu_ifu_spill_e,
58
   lsu_ifu_ldst_cmplt, lsu_ifu_dc_parity_error_w2, lsu_ifu_stbcnt0,
59
   lsu_ifu_stbcnt1, lsu_ifu_stbcnt2, lsu_ifu_stbcnt3,
60
   lsu_ifu_quad_asi_e, ffu_ifu_fpop_done_w2, ffu_ifu_tid_w2,
61
   ffu_ifu_fst_ce_w, tlu_ifu_trap_tid_w1, tlu_ifu_pstate_pef,
62
   lsu_ifu_ldst_miss_g, fcl_swl_int_activate_i3,
63
   fcl_swl_flush_wake_w, ifq_swl_stallreq, fcl_dtu_stall_bf,
64
   fcl_swl_swout_f, fcl_swl_swcvld_s, fdp_fcl_swc_s2,
65
   fcl_ifq_icmiss_s1, fcl_dtu_inst_vld_e, fcl_dtu_intr_vld_e,
66
   fcl_dtu_inst_vld_d, erb_dtu_ifeterr_d1, dtu_inst_anull_e,
67 113 albert.wat
   const_cpuid, thr_config_in_m, dec_swl_wrt_tcr_w,
68 95 fafa1971
   dec_swl_st_inst_d, extra_longlat_compl
69
   );
70
 
71
   input       rclk,
72
               se,
73
               si,
74
               gdbginit_l,
75
               arst_l,
76
               grst_l;
77
 
78
   input [3:0] ctu_sscan_tid;   // guaranteed one-hot by ctu
79
 
80
   input [3:0] ifq_dtu_thrrdy;         // ifq completion signals
81
   input [3:0] ifq_dtu_pred_rdy;     // ifq almost done
82
 
83
   input       ifu_tlu_inst_vld_w,    //
84
                     ifu_tlu_ttype_vld_m;
85
   input       fcl_dtu_hprivmode_d;
86
   input       fcl_dtu_hprivmode_w2;
87
   input       tlu_ifu_flush_pipe_w;  // flush after a trap
88
   input       fcl_swl_flush_w;
89
   input       fcl_dtu_sync_intr_d;   // interrupt
90
   input       fcl_dtu_nuke_thr_w;    // sync suspend
91
   input       fcl_dtu_rst_thr_w;    // 
92
   input       fcl_dtu_resum_thr_w;    // 
93
   input [3:0] fcl_dtu_thr_f;
94
 
95
   input [3:0] tlu_hpstate_ibe;
96
 
97
   input       lsu_ifu_ldsta_internal_e,// sta to local reg
98
                     tlu_ifu_trappc_vld_w1, // trap completion
99
                     dec_swl_ll_done_d,   // rdsr completion
100
               dec_swl_br_done_d,
101
                     dec_swl_rdsr_sel_thr_d,
102
                     dec_swl_std_inst_d,    //
103
                     dec_swl_sta_inst_e,    // state change
104
                     wsr_fixed_inst_w,      // wrspr completion
105
                     dec_swl_ld_inst_d;     // load hit/compl. speculation
106
 
107
   input       dec_swl_mul_inst_d,
108
                     dec_swl_div_inst_d;
109
   input       dec_swl_fpop_d,
110
                     dec_swl_allfp_d;
111
 
112
   input       dec_swl_frf_upper_d,
113
                     dec_swl_frf_lower_d,
114
                     dec_swl_wrtfprs_w;
115
 
116
   input       dcl_swl_tcc_done_m;
117
 
118
   input [3:0] exu_ifu_longop_done_g; // save, restore, div, mul compl.
119
   input       exu_ifu_spill_e;
120
   input [3:0] lsu_ifu_ldst_cmplt;
121
   input       lsu_ifu_dc_parity_error_w2;
122
 
123
   input [3:0] lsu_ifu_stbcnt0,
124
                     lsu_ifu_stbcnt1,
125
                     lsu_ifu_stbcnt2,
126
                     lsu_ifu_stbcnt3;
127
 
128
//   input [3:0] lsu_ifu_stq_busy;
129
   input       lsu_ifu_quad_asi_e;
130
 
131
   input       ffu_ifu_fpop_done_w2;
132
   input [1:0] ffu_ifu_tid_w2;
133
   input       ffu_ifu_fst_ce_w;
134
 
135
   input [1:0] tlu_ifu_trap_tid_w1;
136
 
137
   input [3:0] tlu_ifu_pstate_pef;
138
 
139
   input       lsu_ifu_ldst_miss_g;   // dcache hit or miss
140
 
141
   input [3:0] fcl_swl_int_activate_i3; // wake up thread on interrupt
142
   input       fcl_swl_flush_wake_w;
143
 
144
   // TBD: with the latest changes fcl_dtu_switch_s = dtu_fcl_ntr_s, so 
145
   // this input can be removed.
146
//   input       fcl_dtu_switch_s; // switch out curr, sw in next
147
 
148
   input       ifq_swl_stallreq;
149
 
150
   input       fcl_dtu_stall_bf,
151
               fcl_swl_swout_f,       // curr thread is stalled
152
                     fcl_swl_swcvld_s,
153
               fdp_fcl_swc_s2,        // thread stall condition
154
                     fcl_ifq_icmiss_s1;     // icache miss
155
   input       fcl_dtu_inst_vld_e,
156
               fcl_dtu_intr_vld_e,
157
                     fcl_dtu_inst_vld_d;
158
 
159
   input       erb_dtu_ifeterr_d1;
160
 
161
   input       dtu_inst_anull_e;      // anull delay slot
162
 
163
   input [3:0] const_cpuid;           // use 4 bits to allow future
164
                                      // expansion to 16 cores
165
 
166 113 albert.wat
   input [2:0] thr_config_in_m;       // write data to thread status reg
167 95 fafa1971
   input       dec_swl_wrt_tcr_w;     // write signal for thr status reg
168
   input       dec_swl_st_inst_d;
169
 
170
   input [3:0] extra_longlat_compl;   // spare signal, not used
171
 
172
 
173
   output [10:0] swl_sscan_thrstate;
174
   output        so;
175
 
176
   output      dtu_reset;
177
 
178
   output      swl_dec_mulbusy_e,
179
                     swl_dec_divbusy_e,
180
                     swl_dec_fpbusy_e,
181
                     swl_dec_fp_enable_d;
182
 
183
   output      swl_dec_ibe_e;
184
 
185
   // to fcl
186
   output      dtu_fcl_ntr_s,         // next thread ready
187
               dtu_fcl_running_s,
188
                     dtu_fcl_rollback_g,    // rollback on spec
189
                     dtu_fcl_retract_d;     // rollback on hw hazard
190
 
191
   output [3:0] dtu_fcl_thr_active;   // currently active threads
192
 
193
   output [3:0] dtu_fcl_nextthr_bf,   // thread to switch to when ntr=1
194
                            swl_dcl_thr_d,
195
                            swl_dcl_thr_w2;
196
 
197
   // to fdp
198
   output [40:0] dtu_fdp_thrconf_e;   // thread conf for RDSR inst
199
 
200
//----------------------------------------------------------
201
// Declarations
202
//----------------------------------------------------------
203
   // local signals
204
//   wire [3:0]    count_nxt,
205
//                     count;
206
//   wire          proc0;
207
//   wire          start_on_rst;
208
 
209
   wire          ibe_d,
210
                 ibe_e;
211
 
212
   wire [3:0]    completion,
213
                             wm_imiss,
214
                             wm_other,
215
                             spec_ld_d,
216
                             issue_spec_ld,
217
                             ldmiss,
218
                             ldhit_thr,
219
                             spec_ld_g,
220
                             imiss,
221
                             trap,
222
                 ldmiss_non_crit,
223
                 ldmiss_crit,
224
                             trp_no_retr,
225
//                           rb_thr_w,
226
                 rt_st_thr_d,
227
                 rt_st_thr_e,
228
                             schedule,
229
                             int_activate,
230
                             start_thread,
231
                 thaw_thread,
232
                             resum_thread,
233
                             nuke_thread,
234
                             rst_thread;
235
 
236
   wire          rollback_g,
237
                 rb_en_g,
238
                 rollback_g_l,
239
                 rollback_w2;
240
 
241
 
242
   wire          sched_nt;
243
 
244
   wire [3:0]    fixedop_done,
245
                             wsr_done_w3;
246
 
247
   wire          wsr_inst_w2,
248
                 wsr_inst_w3;
249
 
250
   wire          wsr_fixed_qual_w,
251
                 wsr_fixed_w2;
252
 
253
   wire          llinst_done_e;
254
 
255
   wire [3:0]    ll_done_e,
256
                 branch_done_d,
257
                 std_tcc_done_m;
258
 
259
   wire          sta_done_e,
260
                             killed_inst_done_e;
261
   wire [3:0]    killed_uniop_done_e;
262
 
263
   wire          uniop_d,
264
                             uniop_e;
265
 
266
//   wire          no_iftrap_m,
267
//                 no_iftrap_w;
268
 
269
   wire [3:0]    thr_s1,
270
                 thr_s2,
271
                             thr_f,
272
                             thr_d,
273
                             thr_e,
274
                             thr_m,
275
                             thr_w,
276
                 st_thr_w2,
277
                             st_thr_w3;
278
 
279
   wire          flush_pipe_w_nxt,
280
                 flush_all_w,
281
                 flush_pipe_w2,
282
                 flush_done_w,
283
                 fp_flush_done_w2,
284
                 fp_flush_done_w3,
285
                             flush_done_w2;
286
 
287
   wire          rbfor_fst_ce_w;
288
 
289
   wire [3:0]    flush_wake_w2,
290
                 fp_flush_wake_w3,
291
                 halt_thread;
292
 
293
   wire          wrt_spec_w,
294
                 wrt_spec_w2,
295
                 halt_w,
296
                 halt_w2,
297
                             en_spec_d,
298
                             en_spec_m,
299
                             en_spec_g,
300
                             spec_next;
301
 
302
 
303
   wire          ld_inst_e,
304
                             ld_inst_next_e,
305
                 ld_inst_qual_d,
306
                             ld_inst_m,
307
                             ld_inst_unq_w,
308
                             ld_inst_w,
309
                 ld_inst_w2;
310
 
311
   wire          switch_out,
312
                       sw_cond_s,
313
                       swc_d,
314
                       swc_next_d,
315
                       swc_e;
316
 
317
   wire          trp_noretr_d;
318
 
319
   wire [3:0]    all_stall;
320
 
321
   wire [3:0]    rdy,
322
                       sprdy_or_urdy;
323
 
324
   wire          running_s2,
325
                 atr_s;
326
 
327
   wire [4:0]    thr0_state,
328
                             thr1_state,
329
                             thr2_state,
330
                             thr3_state;
331
 
332
   wire          use_spec;
333
 
334
   wire [3:0]    wrt_tcr_w2;
335
 
336
   wire [1:0]    enc_thr_d;
337
 
338
   wire          rd_thract_d,
339
                             rd_thract_e;
340
   wire [51:0]   fmt_thrconf_e,
341
                 thrconf_out_e,
342
                 fmt_thrconf_adj;
343
 
344
   wire          hprivmode_e,
345
                 rdsr_sel_thr_e;
346
 
347
   wire [2:0]    rd_tid_spec_e;
348
 
349
   wire [3:0]    mul_busy_d,
350
                             mul_busy_e,
351
                             div_busy_d,
352
                             div_busy_e,
353
                             fp_busy_d,
354
                             fp_busy_e;
355
 
356
   wire          true_fpbusy_e,
357
                 fpbusy_local_e,
358
                 true_mulbusy_e,
359
                 true_divbusy_e;
360
 
361
   wire          fbusy_nxt_d,
362
                 fbusy_crit_e,
363
                 fbusy_d3,
364
                 fbusy_d0,
365
                 fbusy_d1,
366
                 fbusy_d2,
367
                 dbusy_d3,
368
                 dbusy_d0,
369
                 dbusy_d1,
370
                 dbusy_d2,
371
                 mbusy_d3,
372
                 mbusy_d0,
373
                 mbusy_d1,
374
                 mbusy_d2;
375
 
376
   wire [3:0]    mul_wait,
377
                             mul_wait_nxt,
378
                             div_wait,
379
                             div_wait_nxt,
380
                             fp_wait,
381
                             fp_wait_nxt;
382
 
383
   wire          mul_wait_any,
384
                             div_wait_any,
385
                             fp_wait_any;
386
 
387
   wire [3:0]    mul_wake,
388
                             div_wake,
389
                             fp_wake;
390
 
391
   wire [3:0]    exu_lop_done,
392
                             mul_done,
393
                             div_done,
394
                             fp_done;
395
 
396
   wire [3:0]    retr_thr_wakeup;
397
   wire [3:0]    trap_thrrdy,
398
                             trap_thr;
399
 
400
   wire [3:0]    fp_thr,
401
                             fp_thrrdy;
402
 
403
   wire          same_thr_de,
404
                             same_thr_dg,
405
                 same_thr_fd,
406
                 same_thr_fe,
407
                             same_thr_fm,
408
                             same_thr_fg;
409
 
410
 
411
   wire          st_thisthr_e;
412
 
413
   wire          st_inst_e,
414
                             st_inst_qual_d,
415
                             st_inst_qual_e,
416
                             st_inst_m,
417
                             st_inst_g;
418
 
419
   wire          pipe_st_cnt_ge1,
420
                             pipe_st_cnt_ge2,
421
                             pipe_st_cnt_ge3;
422
 
423
   wire          pipe_st_d,
424
                 pipe_st_e,
425
                             pipe_st_m,
426
                             pipe_st_g;
427
 
428
   wire          all_dst_ge1,
429
                             all_dst_ge2,
430
                             all_dst_ge3,
431
                             all_dst_eq4;
432
 
433
   wire          dst_cnt_ge1,
434
                             dst_cnt_ge2,
435
                             dst_cnt_ge3;
436
 
437
 
438
   wire [3:0]    stbcnt_s,
439
                             stbcnt_d;
440
 
441
   wire [3:0]    stb_stall,
442
                             stb_blocked,
443
                             stb_blocked_d1,
444
                             st_in_pipe,
445
                             stb_retry,
446
                             wm_stbwait,
447
                             stb_wait_nxt;
448
 
449
   wire          switch_store_d,
450
//                           retract_stall_d,
451
                             retract_store_e,
452
                 retract_st_next_d,
453
                             retract_store_d;
454
 
455
   wire          retract_iferr_d,
456
                 iferr_s,
457
                 iferr_d;
458
 
459
   wire          clear_wmo_e;
460
 
461
   wire          sw_st_e,
462
                             sw_st_m,
463
                             sw_st_g,
464
                             sw_st_w2;
465
 
466
   wire          std_inst_e;
467
//                           stq_inst_e,
468
//                           stq_inst_m,
469
//                           stq_inst_w,
470
//                           stq_inst_w2;
471
   wire          std_done_e;
472
   wire          std_done_m;
473
//   wire [3:0]    stq_busy,
474
//                           stq_in_pipe,
475
//                           stq_wait,
476
//                           stq_wait_next,
477
//                           stq_done_thr;
478
 
479
   wire [2:0]    fprs0,
480
                             fprs1,
481
                             fprs2,
482
                             fprs3,
483
                             fprs_d,
484
                             fprs_e,
485
                             fprs_wrt_data,
486
                 thr_config_in_w,
487
                 thr_config_in_w2,
488
                             fprs0_nxt,
489
                             fprs1_nxt,
490
                             fprs2_nxt,
491
                             fprs3_nxt;
492
 
493
   wire [1:0]    new_fprs;
494
 
495
   wire [3:0]    fprs_en_s,
496
                             fpen_vec_s;
497
 
498
   wire          wrt_fprs_w,
499
                 wrt_fprs_w2;
500
 
501
   wire [3:0]    sel_wrt,
502
                             fprs_sel_set,
503
                             fprs_sel_wrt,
504
                             fprs_sel_old;
505
 
506
   wire          fpen_s;
507
 
508
   wire [1:0]    trap_tid_w2;
509
   wire          trappc_vld_w2;
510
 
511
   wire          dtu_reset_l;
512
   wire          sched_reset;
513
 
514
   wire          clk;
515
 
516
   //
517
   // Code Begins Here
518
   //
519
 
520
   assign        clk = rclk;
521
 
522
   // reset buffer
523
   dffrl_async rstff(.din (grst_l),
524
                        .q   (dtu_reset_l),
525 113 albert.wat
                        .clk (clk), .se(se), `SIMPLY_RISC_SCANIN, .so(),
526 95 fafa1971
                        .rst_l (arst_l));
527
 
528
   assign       dtu_reset = ~dtu_reset_l;
529
 
530
 
531
   //---------------------------------------------
532
   // Start off thread on reset using this counter
533
   //---------------------------------------------
534
//   dffr #(4) thrrdy_ctr(.din (count_nxt),
535
//                                  .clk (clk),
536
//                                  .q   (count),
537
//                                  .rst (dtu_reset),
538 113 albert.wat
//                                  .se (se), `SIMPLY_RISC_SCANIN, .so());
539 95 fafa1971
//
540
//   // count_nxt = count + 1, sticky at 8 = 1111
541
//   assign count_nxt[0] = ~count[0] | count[3];
542
//   assign count_nxt[1] = (count[1] ^ count[0]) | count[3];
543
//   assign count_nxt[2] = (count[2] ^ (count[1] & count[0])) | count[3]; 
544
//   assign count_nxt[3] = (count[3] ^ (count[2] & count[1] & count[0])) |
545
//                             count[3]; 
546
//
547
//   assign proc0 = (const_cpuid == 4'b0000) ? 1'b1 : 1'b0;
548
//   assign start_on_rst = (~count[3] & count[2] & count[1] & count[0])
549
//                          & proc0;
550
 
551
//`ifdef IFU_SAT   
552
//   // temporary hack to start threads
553
//   reg [3:0]  auto_start;
554
//   always @ (posedge clk)
555
//     auto_start = 4'b0000;
556
//`endif
557
 
558
   //-----------------
559
   // completion logic
560
   //-----------------
561 113 albert.wat
   sparc_ifu_thrcmpl compl(
562 95 fafa1971
                           .reset       (dtu_reset),
563
                                             /*AUTOINST*/
564
                           // Outputs
565
                           .completion  (completion[3:0]),
566
                           .wm_imiss    (wm_imiss[3:0]),
567
                           .wm_other    (wm_other[3:0]),
568
                           // Inputs
569
                           .clk         (clk),
570
                           .se          (se),
571
                           .si          (si),
572
                           .fcl_ifq_icmiss_s1(fcl_ifq_icmiss_s1),
573
                           .erb_dtu_ifeterr_d1(erb_dtu_ifeterr_d1),
574
                           .sw_cond_s   (sw_cond_s),
575
                           .en_spec_g   (en_spec_g),
576
                           .atr_s       (atr_s),
577
                           .dtu_fcl_thr_active(dtu_fcl_thr_active[3:0]),
578
                           .ifq_dtu_thrrdy(ifq_dtu_thrrdy[3:0]),
579
                           .ifq_dtu_pred_rdy(ifq_dtu_pred_rdy[3:0]),
580
                           .exu_lop_done(exu_lop_done[3:0]),
581
                           .branch_done_d(branch_done_d[3:0]),
582
                           .fixedop_done(fixedop_done[3:0]),
583
                           .ldmiss      (ldmiss[3:0]),
584
                           .spec_ld_d   (spec_ld_d[3:0]),
585
                           .trap        (trap[3:0]),
586
                           .retr_thr_wakeup(retr_thr_wakeup[3:0]),
587
                           .flush_wake_w2(flush_wake_w2[3:0]),
588
                           .ldhit_thr   (ldhit_thr[3:0]),
589
                           .spec_ld_g   (spec_ld_g[3:0]),
590
                           .clear_wmo_e (clear_wmo_e),
591
                           .wm_stbwait  (wm_stbwait[3:0]),
592
                           .stb_retry   (stb_retry[3:0]),
593
                           .rst_thread  (rst_thread[3:0]),
594
                           .trap_thrrdy (trap_thrrdy[3:0]),
595
                           .thr_s2      (thr_s2[3:0]),
596
                           .thr_e       (thr_e[3:0]),
597
                           .thr_s1      (thr_s1[3:0]),
598
                           .fp_thrrdy   (fp_thrrdy[3:0]),
599
                           .lsu_ifu_ldst_cmplt(lsu_ifu_ldst_cmplt[3:0]),
600
                           .sta_done_e  (sta_done_e),
601
                           .killed_inst_done_e(killed_inst_done_e));
602
 
603
   //------------
604
   // Thread Pipe
605
   //------------
606
   assign thr_f = fcl_dtu_thr_f;
607
 
608
//   assign thr_dec_f[0] = thr_f[0] | rst_tri_en;
609
//   assign thr_dec_f[3:1] = thr_f[3:1] & {3{~rst_tri_en}};
610
 
611
//   assign thr_dec_d[0] = thr_d[0] | rst_tri_en;
612
//   assign thr_dec_d[3:1] = thr_d[3:1] & {3{~rst_tri_en}};
613
 
614
 
615 113 albert.wat
   dff_s #(4) thrd_reg(.din  (thr_f[3:0]),
616 95 fafa1971
                   .clk  (clk),
617
                   .q    (thr_d[3:0]),
618 113 albert.wat
                   .se   (se), `SIMPLY_RISC_SCANIN, .so());
619 95 fafa1971
 
620
   assign     swl_dcl_thr_d = thr_d;
621
 
622 113 albert.wat
   dff_s #(4) thre_reg(.din  (thr_d),
623 95 fafa1971
                   .clk  (clk),
624
                   .q    (thr_e),
625 113 albert.wat
                   .se   (se), `SIMPLY_RISC_SCANIN, .so());
626 95 fafa1971
 
627 113 albert.wat
   dff_s #(4) thrm_reg(.din  (thr_e),
628 95 fafa1971
                   .clk  (clk),
629
                   .q    (thr_m),
630 113 albert.wat
                   .se   (se), `SIMPLY_RISC_SCANIN, .so());
631
   dff_s #(4) thrw_reg(.din  (thr_m),
632 95 fafa1971
                   .clk  (clk),
633
                   .q    (thr_w),
634 113 albert.wat
                   .se   (se), `SIMPLY_RISC_SCANIN, .so());
635 95 fafa1971
 
636 113 albert.wat
   dff_s #(4) thrw2_reg(.din  (thr_w),
637 95 fafa1971
                    .clk  (clk),
638
                    .q    (st_thr_w2),
639 113 albert.wat
                    .se   (se), `SIMPLY_RISC_SCANIN, .so());
640 95 fafa1971
 
641 113 albert.wat
   dff_s #(4) thrw3_reg(.din  (st_thr_w2),
642 95 fafa1971
                    .clk  (clk),
643
                    .q    (st_thr_w3),
644 113 albert.wat
                    .se   (se), `SIMPLY_RISC_SCANIN, .so());
645 95 fafa1971
 
646
   assign     swl_dcl_thr_w2 = st_thr_w2;
647
 
648
   // send ibe of curr thread to dec
649
   assign ibe_d = (thr_d[0] & tlu_hpstate_ibe[0] |
650
                   thr_d[1] & tlu_hpstate_ibe[1] |
651
                   thr_d[2] & tlu_hpstate_ibe[2] |
652
                   thr_d[3] & tlu_hpstate_ibe[3]);
653
 
654 113 albert.wat
   dff_s #(1) ibee_ff(.din (ibe_d),
655 95 fafa1971
                    .q   (ibe_e),
656 113 albert.wat
                    .clk (clk), .se(se), `SIMPLY_RISC_SCANIN, .so());
657 95 fafa1971
   assign swl_dec_ibe_e = ibe_e;
658
 
659
//----------------------------------------------------------------------
660
// Track Thread Execution
661
//----------------------------------------------------------------------
662
 
663
   // track instructions
664 113 albert.wat
   dff_s #(1) lle_ff(.din (dec_swl_ll_done_d),
665 95 fafa1971
                   .q   (llinst_done_e),
666 113 albert.wat
                   .clk (clk), .se (se), `SIMPLY_RISC_SCANIN, .so());
667 95 fafa1971
 
668
   assign ll_done_e = thr_e & {4{llinst_done_e & fcl_dtu_inst_vld_e &
669
                                 ~exu_ifu_spill_e}};
670
   assign std_tcc_done_m = thr_m & {4{dcl_swl_tcc_done_m | std_done_m}};
671
 
672
   assign wsr_fixed_qual_w  = wsr_fixed_inst_w & ifu_tlu_inst_vld_w &
673
                              ~fcl_swl_flush_w;
674 113 albert.wat
   dff_s #(1) wsrw2_ff(.din (wsr_fixed_qual_w),
675 95 fafa1971
                     .q   (wsr_fixed_w2),
676 113 albert.wat
                     .clk (clk), .se(se), `SIMPLY_RISC_SCANIN, .so());
677 95 fafa1971
 
678
   assign wsr_inst_w2  = wsr_fixed_w2 & ~flush_pipe_w2;
679
 
680
   // delay one cycle to allow tlu to finish
681 113 albert.wat
   dff_s #(1) wsw3_ff(.din (wsr_inst_w2),
682 95 fafa1971
                    .q   (wsr_inst_w3),
683 113 albert.wat
                    .clk (clk), .se(se), `SIMPLY_RISC_SCANIN, .so());
684 95 fafa1971
 
685
   assign wsr_done_w3 = {4{wsr_inst_w3}} & st_thr_w3;
686
 
687
   assign fixedop_done = (ll_done_e | wsr_done_w3 | std_tcc_done_m |
688
                                wrt_tcr_w2 | extra_longlat_compl);
689
 
690
   assign branch_done_d = thr_d & {4{dec_swl_br_done_d & fcl_dtu_inst_vld_d}};
691
 
692
   assign sta_done_e = dec_swl_sta_inst_e & fcl_dtu_inst_vld_e &
693
                       ~lsu_ifu_ldsta_internal_e;
694
   assign ld_inst_qual_d = dec_swl_ld_inst_d & fcl_dtu_inst_vld_d &
695
                           ~iferr_d;
696 113 albert.wat
   dff_s #(1) lde_ff(.din  (ld_inst_qual_d),
697 95 fafa1971
                               .clk  (clk),
698
                               .q    (ld_inst_e),
699 113 albert.wat
                               .se   (se), `SIMPLY_RISC_SCANIN, .so());
700 95 fafa1971
   assign ld_inst_next_e = ld_inst_e;
701
//                         & ~dtu_inst_anull_e &    
702
//                           ~(lsu_ifu_ldsta_internal_e & 
703
//                             ifu_lsu_alt_space_e &
704
//                             fcl_dtu_inst_vld_e);
705
 
706
//   assign ld_inst_internal_e = ~dtu_inst_anull_e & ld_inst_e &
707
//                               (fcl_dtu_inst_vld_e & 
708
//                                lsu_ifu_ldsta_internal_e & 
709
//                                ifu_lsu_alt_space_e);
710
 
711 113 albert.wat
   dff_s #(1) ldm_ff(.din  (ld_inst_next_e),
712 95 fafa1971
                               .clk  (clk),
713
                               .q    (ld_inst_m),
714 113 albert.wat
                               .se   (se), `SIMPLY_RISC_SCANIN, .so());
715
   dff_s #(1) ldw_ff(.din  (ld_inst_m),
716 95 fafa1971
                               .clk  (clk),
717
                               .q    (ld_inst_unq_w),
718 113 albert.wat
                               .se   (se), `SIMPLY_RISC_SCANIN, .so());
719 95 fafa1971
   assign ld_inst_w = ifu_tlu_inst_vld_w & ld_inst_unq_w;
720 113 albert.wat
   dff_s #(1) ldw2_ff(.din  (ld_inst_w),
721 95 fafa1971
                               .clk  (clk),
722
                               .q    (ld_inst_w2),
723 113 albert.wat
                               .se   (se), `SIMPLY_RISC_SCANIN, .so());
724 95 fafa1971
 
725
   // track instruction status
726 113 albert.wat
   dff_s #(1) swcd_ff(.din  (sw_cond_s),
727 95 fafa1971
                                .clk  (clk),
728
                                .q    (swc_d),
729 113 albert.wat
                                .se   (se), `SIMPLY_RISC_SCANIN, .so());
730 95 fafa1971
 
731
   assign swc_next_d = (swc_d & ~dec_swl_br_done_d);
732
//                                         | fcl_dtu_sync_intr_d;
733
 
734 113 albert.wat
   dff_s #(1) swce_ff(.din  (swc_next_d),
735 95 fafa1971
                                .clk  (clk),
736
                                .q    (swc_e),
737 113 albert.wat
                                .se   (se), `SIMPLY_RISC_SCANIN, .so());
738 95 fafa1971
 
739
//bug6838,bug6989 - interrupt issued in annulled delay slot resets wm_other mask in e-stage; this
740
//                  reset causes switch logic to lose a long latency op(div) which set the wm_other mask
741
//                  in s-stage. Note that the div is issued to FPU. the ifu re-issues the interrupt - 
742
//                  which results in flush. this kills the long latency op and div is lost
743
//
744
//                  fix is to detect interrupt in anulled delay slot followed by long latency op and
745
//                  not reset the wm_other mask.
746
//
747
//       10/07/04 - fix changed to delay setting of wm_other mask from d-cycle to e-cycle. hence
748
//                  removing the kill in killed_inst_done_e
749
//
750
//   assign killed_inst_done_e = (fcl_dtu_inst_vld_e  & swc_e | //sw inst
751
//                                fcl_dtu_intr_vld_e) &  // any intr
752
//                                 dtu_inst_anull_e;
753
 
754
   assign killed_inst_done_e = fcl_dtu_inst_vld_e  & swc_e & //sw inst
755
                                 dtu_inst_anull_e;
756
 
757
   // a uniop is something that stalls all threads (looks like a uni
758
   // threaded machine)
759
   assign uniop_d = (dec_swl_allfp_d | //& swl_dec_fp_enable_d  
760
                     dec_swl_mul_inst_d | dec_swl_div_inst_d) &
761
                      fcl_dtu_inst_vld_d;
762 113 albert.wat
   dff_s #(1) uniop_ff(.din  (uniop_d),
763 95 fafa1971
                                 .clk  (clk),
764
                                 .q    (uniop_e),
765 113 albert.wat
                                 .se   (se), `SIMPLY_RISC_SCANIN, .so());
766 95 fafa1971
   assign killed_uniop_done_e = thr_e & {4{dtu_inst_anull_e & uniop_e &
767
                                           fcl_dtu_inst_vld_e |
768
                                           clear_wmo_e}};
769
 
770
//   assign sched_nt = fcl_dtu_switch_s & ~fcl_dtu_stall_bf;
771
   assign sched_nt = dtu_fcl_ntr_s & ~(fcl_dtu_stall_bf | ifq_swl_stallreq);
772
   assign schedule = dtu_fcl_nextthr_bf & {4{sched_nt}};
773
 
774
   // speculate load hit if it is a load instruction
775
   // FP loads are not speculated on 
776
   assign spec_ld_d = thr_d & {4{ld_inst_qual_d & en_spec_d}};
777
   assign issue_spec_ld = thr_d & {4{ld_inst_qual_d & en_spec_d}} &
778
                          ~wm_imiss & ~wm_stbwait;
779
 
780
//   assign issue_spec_ld = thr_d & {4{dec_swl_ld_inst_d & en_spec_d & 
781
//                                     ~fcl_ifq_icmiss_s1}} & ~wm_imiss;
782
 
783
   assign spec_ld_g = (thr_w & {4{ld_inst_w & en_spec_g}});
784
 
785
   // actual load hit signal and load miss stall
786
//   assign rollback_g = en_spec_g & ld_inst_w & lsu_ifu_ldst_miss_g;
787
   // expand to gates:
788
   assign rb_en_g = en_spec_g & ld_inst_w;
789
   assign rollback_g_l = ~(lsu_ifu_ldst_miss_g & rb_en_g);
790
//   bw_u1_nand2_7x UZsize_rbgen(.a (lsu_ifu_ldst_miss_g),
791
//                               .b (rb_en_g),
792
//                               .z (rollback_g_l));
793
   assign rollback_g = ~rollback_g_l;
794
//   bw_u1_invh_25x UZsize_rbbuf(.a (rollback_g_l),
795
//                               .z (rollback_g));
796
   assign dtu_fcl_rollback_g = rollback_g;
797
 
798
   // delay restart of ldhit when en_spec=0 by 1 more cycle?
799
 
800
// assign rb_thr_w = thr_w & {4{en_spec_g & ld_inst_w & lsu_ifu_ldst_miss_g}};
801
// assign spec_ldmiss = rb_thr_w; // to thrcmpl
802
 
803
   assign ldhit_thr = (thr_w & {4{ld_inst_w & ~lsu_ifu_ldst_miss_g}} |
804
                       thr_e & {4{ld_inst_e & dtu_inst_anull_e}});
805
   assign ldmiss_crit = thr_w & {4{ld_inst_w & lsu_ifu_ldst_miss_g}};
806
   assign ldmiss_non_crit = st_thr_w2 & {4{lsu_ifu_dc_parity_error_w2}};
807
                            // | thr_e & {4{ld_inst_internal_e}} 
808
 
809
   assign ldmiss = ldmiss_crit | ldmiss_non_crit;
810
 
811
   assign rt_st_thr_d = thr_d & {4{retract_store_d}};
812
   assign rt_st_thr_e = thr_e & {4{retract_store_e}};
813
 
814 113 albert.wat
   dff_s #(1) rbw2_ff(.din (rollback_g),
815 95 fafa1971
                    .q   (rollback_w2),
816 113 albert.wat
                    .clk (clk), .se(se), `SIMPLY_RISC_SCANIN, .so());
817 95 fafa1971
 
818
   // traps and interrupts
819 113 albert.wat
   dff_s #(1) ld_trp_reg(.din (tlu_ifu_trappc_vld_w1),
820 95 fafa1971
                       .q   (trappc_vld_w2),
821 113 albert.wat
                       .clk (clk), .se(se), `SIMPLY_RISC_SCANIN, .so());
822 95 fafa1971
 
823 113 albert.wat
   dff_s #(2) trp_tid_reg(.din (tlu_ifu_trap_tid_w1[1:0]),
824 95 fafa1971
                        .q   (trap_tid_w2[1:0]),
825 113 albert.wat
                        .clk (clk), .se(se), `SIMPLY_RISC_SCANIN, .so());
826 95 fafa1971
 
827
   assign trap_thr[0] = ~trap_tid_w2[1] & ~trap_tid_w2[0];
828
   assign trap_thr[1] = ~trap_tid_w2[1] &  trap_tid_w2[0];
829
   assign trap_thr[2] =  trap_tid_w2[1] & ~trap_tid_w2[0];
830
   assign trap_thr[3] =  trap_tid_w2[1] &  trap_tid_w2[0];
831
 
832
   assign trap_thrrdy = trap_thr & {4{trappc_vld_w2}};
833
 
834
   // fst processed directly in swl
835
   assign rbfor_fst_ce_w = ifu_tlu_inst_vld_w & ~tlu_ifu_flush_pipe_w &
836
                           ffu_ifu_fst_ce_w & ~fcl_swl_flush_w;
837
 
838
//   dff #(1) fstce_ff(.din (rbfor_fst_ce_w),
839
//                     .q   (rbfor_fst_ce_w2),
840 113 albert.wat
//                     .clk (clk), .se(se), `SIMPLY_RISC_SCANIN, .so());
841 95 fafa1971
 
842
   assign flush_all_w = tlu_ifu_flush_pipe_w | fcl_swl_flush_w;
843
//   assign flush_pipe_w_nxt = tlu_ifu_flush_pipe_w & ~fcl_swl_flush_w;
844
   assign flush_pipe_w_nxt = tlu_ifu_flush_pipe_w &
845
                             ~fcl_swl_flush_wake_w;
846
 
847 113 albert.wat
   dff_s #(1) flpw2_ff(.din (flush_pipe_w_nxt),
848 95 fafa1971
                     .q   (flush_pipe_w2),
849 113 albert.wat
                     .clk (clk), .se(se), `SIMPLY_RISC_SCANIN, .so());
850 95 fafa1971
 
851
//   assign no_iftrap_m = ~ifu_tlu_ttype_vld_m;
852
//   dff #(1) trpw_ff(.din (no_iftrap_m),
853
//                    .q   (no_iftrap_w),
854 113 albert.wat
//                    .clk (clk), .se(se), `SIMPLY_RISC_SCANIN, .so());
855 95 fafa1971
 
856
//bug6838,bug6989 - change setting of trap for interrupt from d-cycle to e-cycle
857
//                  remove  thr_d & {4{fcl_dtu_sync_intr_d & ~iferr_d}} & ~rt_st_thr_e |
858
 
859
//   assign trap =  thr_w & {4{flush_all_w}} |
860
   assign trap =  st_thr_w2 & {4{flush_pipe_w2}} |
861
                  thr_w & {4{fcl_swl_flush_w}} |
862
                        thr_e & {4{fcl_dtu_intr_vld_e & ~dtu_inst_anull_e}} |
863
                        thr_m & {4{ifu_tlu_ttype_vld_m}};
864
 
865
   assign trp_no_retr = st_thr_w2 & {4{flush_pipe_w2 |
866
                                       lsu_ifu_dc_parity_error_w2 &
867
                                       ld_inst_w2    |
868
                                       rollback_w2}}  |
869
                              trap_thr & {4{trappc_vld_w2}} |
870
                        fp_flush_wake_w3 |
871
                        thr_w & {4{fcl_swl_flush_w}};
872
//                             thr_m    & {4{ifu_tlu_ttype_vld_m}};
873
 
874
   assign trp_noretr_d = (thr_d[0] & trp_no_retr[0] |
875
                          thr_d[1] & trp_no_retr[1] |
876
                          thr_d[2] & trp_no_retr[2] |
877
                          thr_d[3] & trp_no_retr[3]);
878
 
879
//   assign flush_done_w = fcl_swl_flush_w & ~fcl_swl_flush_wait_w;
880
   assign flush_done_w = fcl_swl_flush_wake_w;
881 113 albert.wat
   dff_s #(1) flsh_ff(.din (flush_done_w),
882 95 fafa1971
                                .q   (flush_done_w2),
883 113 albert.wat
                                .clk (clk), .se(se), `SIMPLY_RISC_SCANIN, .so());
884 95 fafa1971
   assign flush_wake_w2 = {4{flush_done_w2}} & st_thr_w2 | fp_flush_wake_w3;
885
 
886
   // delay FP wakeup by one extra cycle to allow time for IRF CE
887
   // to be corrected.
888 113 albert.wat
   dff_s #(1) fpflsh_ff(.din (rbfor_fst_ce_w),
889 95 fafa1971
                                  .q   (fp_flush_done_w2),
890 113 albert.wat
                                  .clk (clk), .se(se), `SIMPLY_RISC_SCANIN, .so());
891 95 fafa1971
 
892 113 albert.wat
   dff_s #(1) fpflw_ff(.din (fp_flush_done_w2),
893 95 fafa1971
                                 .q   (fp_flush_done_w3),
894 113 albert.wat
                                 .clk (clk), .se(se), `SIMPLY_RISC_SCANIN, .so());
895 95 fafa1971
   assign fp_flush_wake_w3 = st_thr_w3 & {4{fp_flush_done_w3}};
896
 
897
   // store buffer full
898
//   assign stbfull_on_curr_thr = stb_stall & thr_f;
899
//   assign stbfull_thisthr =  stbfull_on_curr_thr[0] |
900
//                                 stbfull_on_curr_thr[1] |
901
//                                 stbfull_on_curr_thr[2] |
902
//                                 stbfull_on_curr_thr[3];
903
 
904
//   assign stbfull_nextthr = ((stb_stall & dtu_fcl_nextthr_bf)
905
//                                             == 4'b0) ?
906
//                                              1'b0 : 1'b1;
907
 
908
   // imiss stall condition
909
   assign thr_s1 = thr_d;
910
   assign imiss = (thr_s1 & {4{fcl_ifq_icmiss_s1}}) |
911
                          (thr_e & {4{erb_dtu_ifeterr_d1}});  //
912
 
913
   // All Stall conditions
914
   assign all_stall = imiss | ldmiss_non_crit | trap | stb_stall |
915
                      ldmiss_crit;
916
 
917
   // TBD: move to ifu -- done
918
//   assign ext_stallreq = ifq_dtu_stallreq | lsu_ifu_stallreq | 
919
//                         ffu_ifu_stallreq;  
920
                         // | other stall reqs
921
//   assign cpu_fcl_stallreq = ext_stallreq;
922
 
923
   // thread start and stop
924
//   assign switch_out = fcl_dtu_switch_s | fcl_dtu_stall_bf | fcl_swl_swout_f;
925
   assign switch_out = dtu_fcl_ntr_s | fcl_dtu_stall_bf | fcl_swl_swout_f |
926
                       ifq_swl_stallreq;
927
 
928
   // general stall condition
929
//   assign cpu_fcl_stallreq = ~dtu_fcl_ntr_s & (stbfull_thisthr) |
930
//                             dtu_fcl_ntr_s & (stbfull_nextthr) |
931
//                                 ext_stallreq;
932
 
933
   // ldmiss (i.e rollback) and flush_pipe are taken care of in FCL
934
   assign sw_cond_s = fdp_fcl_swc_s2 & fcl_swl_swcvld_s & ~iferr_s;
935
 
936
   // thread reset and other interrupts
937
   // added flop for timing reasons
938
 
939
//   assign async_rst_i3 = rst_thread & ~dtu_fcl_thr_active;
940
//   assign rst_thread   = rstthr_i3 & {4{rstint_i3}};
941
  // assign nuke_thread  = (rstthr_i3 & {4{nukeint_i3}} & 
942
//                                          ~dtu_fcl_thr_active) |   // if not active nuke 
943
                                                                     // immediately
944
//                                           ({4{fcl_dtu_nuke_thr_ms}} & thr_m);
945
                                                   // else wait for signal
946
 
947
   assign resum_thread = ({4{fcl_dtu_resum_thr_w}} & thr_w);
948
   assign nuke_thread = ({4{fcl_dtu_nuke_thr_w}} & thr_w);
949
   assign rst_thread = ({4{fcl_dtu_rst_thr_w}} & thr_w);
950
 
951
   assign int_activate = fcl_swl_int_activate_i3 & ~wm_imiss;
952
 
953
//`ifdef IFU_SAT   
954
//   assign start_thread = {3'b0, start_on_rst} | auto_start | 
955
//                         resum_thread & (~wm_imiss | ifq_dtu_thrrdy);
956
//`else
957
   assign start_thread = resum_thread & (~wm_imiss | ifq_dtu_thrrdy) &
958 113 albert.wat
                                          (~wm_stbwait | stb_retry);
959 95 fafa1971
   assign thaw_thread = resum_thread & (wm_imiss & ~ifq_dtu_thrrdy |
960 113 albert.wat
                                        wm_stbwait & ~stb_retry);
961 95 fafa1971
 
962
//`endif
963
 
964
 
965
//----------------------------------------------------------------------
966
// Thread FSM
967
//----------------------------------------------------------------------   
968
   sparc_ifu_thrfsm  thrfsm0(
969
                             // Outputs
970 113 albert.wat
`ifdef FPGA_SYN
971 95 fafa1971
 
972
                             .so        (/*so*/),
973 113 albert.wat
`else
974
                             .so        (so),
975
`endif
976 95 fafa1971
                             .thr_state (thr0_state[4:0]),
977
                             // Inputs
978
                             .completion(completion[0]),
979
                             .schedule  (schedule[0]),
980
                             .spec_ld   (issue_spec_ld[0]),
981
                             .ldhit     (ldhit_thr[0]),
982
                             .switch_out(switch_out),
983
 
984
                             .stall     (all_stall[0]),
985
                             .sw_cond   (sw_cond_s),
986
 
987
                             .int_activate(int_activate[0]),
988
                             .start_thread(start_thread[0]),
989
                             .thaw_thread(thaw_thread[0]),
990
                             .nuke_thread (nuke_thread[0]),
991
                             .rst_thread(rst_thread[0]),
992
 
993
                             .halt_thread (halt_thread[0]),
994
 
995
                             .clk       (clk),
996
                             .se        (se),
997
                             .si        (si),
998
                             .reset     (dtu_reset));
999
 
1000
   sparc_ifu_thrfsm  thrfsm1(
1001
                             // Outputs
1002 113 albert.wat
`ifdef FPGA_SYN
1003 95 fafa1971
 
1004
                             .so        (/*so*/),
1005 113 albert.wat
`else
1006
                             .so        (so),
1007
`endif
1008 95 fafa1971
                             .thr_state (thr1_state[4:0]),
1009
                             // Inputs
1010
                             .completion(completion[1]),
1011
                             .schedule  (schedule[1]),
1012
                             .spec_ld   (issue_spec_ld[1]),
1013
                             .ldhit     (ldhit_thr[1]),
1014
                             .switch_out(switch_out),
1015
 
1016
                             .stall     (all_stall[1]),
1017
                             .sw_cond   (sw_cond_s),
1018
 
1019
                             .int_activate(int_activate[1]),
1020
                             .start_thread(start_thread[1]),
1021
                             .thaw_thread(thaw_thread[1]),
1022
                             .nuke_thread (nuke_thread[1]),
1023
                             .rst_thread(rst_thread[1]),
1024
 
1025
                             .halt_thread (halt_thread[1]),
1026
 
1027
                             .clk       (clk),
1028
                             .se        (se),
1029
                             .si        (si),
1030
                             .reset     (dtu_reset));
1031
 
1032
   sparc_ifu_thrfsm  thrfsm2(
1033
                             // Outputs
1034 113 albert.wat
`ifdef FPGA_SYN
1035 95 fafa1971
 
1036
                             .so        (/*so*/),
1037 113 albert.wat
`else
1038
                             .so        (so),
1039
`endif
1040 95 fafa1971
                             .thr_state (thr2_state[4:0]),
1041
                             // Inputs
1042
                             .completion(completion[2]),
1043
                             .schedule  (schedule[2]),
1044
                             .spec_ld   (issue_spec_ld[2]),
1045
                             .ldhit     (ldhit_thr[2]),
1046
                             .switch_out(switch_out),
1047
 
1048
                             .stall     (all_stall[2]),
1049
                             .sw_cond   (sw_cond_s),
1050
 
1051
                             .int_activate(int_activate[2]),
1052
                             .start_thread(start_thread[2]),
1053
                             .thaw_thread(thaw_thread[2]),
1054
                             .nuke_thread (nuke_thread[2]),
1055
                             .rst_thread(rst_thread[2]),
1056
 
1057
                             .halt_thread (halt_thread[2]),
1058
 
1059
                             .clk       (clk),
1060
                             .se        (se),
1061
                             .si        (si),
1062
                             .reset     (dtu_reset));
1063
 
1064
   sparc_ifu_thrfsm  thrfsm3(
1065
                             // Outputs
1066 113 albert.wat
`ifdef FPGA_SYN
1067 95 fafa1971
 
1068
                             .so        (/*so*/),
1069 113 albert.wat
`else
1070
                             .so        (so),
1071
`endif
1072 95 fafa1971
                             .thr_state (thr3_state[4:0]),
1073
                             // Inputs
1074
                             .completion(completion[3]),
1075
                             .schedule  (schedule[3]),
1076
                             .spec_ld   (issue_spec_ld[3]),
1077
                             .ldhit     (ldhit_thr[3]),
1078
                             .switch_out(switch_out),
1079
 
1080
                             .stall     (all_stall[3]),
1081
                             .sw_cond   (sw_cond_s),
1082
 
1083
                             .int_activate(int_activate[3]),
1084
                             .start_thread(start_thread[3]),
1085
                             .thaw_thread(thaw_thread[3]),
1086
                             .nuke_thread (nuke_thread[3]),
1087
                             .rst_thread(rst_thread[3]),
1088
 
1089
                             .halt_thread (halt_thread[3]),
1090
 
1091
                             .clk       (clk),
1092
                             .se        (se),
1093
                             .si        (si),
1094
                             .reset     (dtu_reset));
1095
 
1096
//----------------------------------------------------------------------
1097
// Schedule Next Thread
1098
//----------------------------------------------------------------------
1099
   // rdy bit from thrfsm
1100 113 albert.wat
   assign dtu_fcl_thr_active[0] = thr0_state[`TCR_ACTIVE];
1101
   assign dtu_fcl_thr_active[1] = thr1_state[`TCR_ACTIVE];
1102
   assign dtu_fcl_thr_active[2] = thr2_state[`TCR_ACTIVE];
1103
   assign dtu_fcl_thr_active[3] = thr3_state[`TCR_ACTIVE];
1104 95 fafa1971
 
1105 113 albert.wat
   assign rdy[0] = thr0_state[`TCR_URDY];
1106
   assign rdy[1] = thr1_state[`TCR_URDY];
1107
   assign rdy[2] = thr2_state[`TCR_URDY];
1108
   assign rdy[3] = thr3_state[`TCR_URDY];
1109 95 fafa1971
 
1110 113 albert.wat
   assign sprdy_or_urdy[0] = thr0_state[`TCR_READY];
1111
   assign sprdy_or_urdy[1] = thr1_state[`TCR_READY];
1112
   assign sprdy_or_urdy[2] = thr2_state[`TCR_READY];
1113
   assign sprdy_or_urdy[3] = thr3_state[`TCR_READY];
1114 95 fafa1971
 
1115 113 albert.wat
   assign running_s2 = (thr0_state[`TCR_RUNNING] |
1116
                                          thr1_state[`TCR_RUNNING] |
1117
                                          thr2_state[`TCR_RUNNING] |
1118
                                          thr3_state[`TCR_RUNNING]);
1119 95 fafa1971
 
1120
   assign dtu_fcl_running_s = running_s2;
1121
 
1122 113 albert.wat
   assign thr_s2 =  {thr3_state[`TCR_RUNNING],
1123
                                       thr2_state[`TCR_RUNNING],
1124
                                       thr1_state[`TCR_RUNNING],
1125
                                       thr0_state[`TCR_RUNNING]};
1126 95 fafa1971
 
1127
   // Next Thread Ready
1128
   assign dtu_fcl_ntr_s = (sprdy_or_urdy[0] | sprdy_or_urdy[1] |
1129
                                                   sprdy_or_urdy[2] | sprdy_or_urdy[3]);
1130
 
1131
   // Any thread ready
1132
   assign atr_s = dtu_fcl_ntr_s | running_s2;
1133
 
1134
   // decide which scheduler to use
1135
   // timing note: see if use_spec can be generated in previous cycle
1136
   assign use_spec = ~(rdy[3] | rdy[2] | rdy[1] | rdy[0]);
1137
 
1138
   assign sched_reset = dtu_reset | ~gdbginit_l;
1139
   // schedule ready threads
1140
   sparc_ifu_lru4 thr_sched(// Outputs
1141
                                              .grant_vec        (dtu_fcl_nextthr_bf[3:0]),
1142
                                              .so               (so),
1143
                                              // Inputs
1144
                                              .clk      (clk),
1145
                                              .reset    (sched_reset),
1146
                                              .se               (se),
1147
                                              .si               (si),
1148
                                              .recent_vec       (thr_e[3:0]),
1149
                                              .load_recent(fcl_dtu_inst_vld_e),
1150
                                              .req_vec  (rdy[3:0]),
1151
                            .spec_vec (sprdy_or_urdy[3:0]),
1152
                            .use_spec (use_spec));
1153
 
1154
//----------------------------------------------------------------------
1155
// Thread Status (Config) Register
1156
//----------------------------------------------------------------------
1157
   // Read thread config
1158
   assign enc_thr_d[1] = thr_d[3] | thr_d[2];
1159
   assign enc_thr_d[0] = thr_d[3] | thr_d[1];
1160
 
1161
   assign rd_thract_d = (thr0_state[0] & thr_d[0] |
1162
                         thr1_state[0] & thr_d[1] |
1163
                         thr2_state[0] & thr_d[2] |
1164
                         thr3_state[0] & thr_d[3]);
1165
 
1166 113 albert.wat
   dff_s #(1) rdthr_ff(.din (rd_thract_d),
1167 95 fafa1971
                                  .clk (clk),
1168
                                  .q   (rd_thract_e),
1169 113 albert.wat
                                  .se   (se), `SIMPLY_RISC_SCANIN, .so());
1170 95 fafa1971
 
1171 113 albert.wat
   dff_s #(3) rdcf_reg(.din ({enc_thr_d, en_spec_d}),
1172 95 fafa1971
                                 .clk (clk),
1173
                                 .q   (rd_tid_spec_e),
1174 113 albert.wat
                                 .se   (se), `SIMPLY_RISC_SCANIN, .so());
1175 95 fafa1971
 
1176 113 albert.wat
   dff_s #(1) hpe_ff(.din (fcl_dtu_hprivmode_d),
1177 95 fafa1971
                               .clk (clk),
1178
                               .q   (hprivmode_e),
1179 113 albert.wat
                               .se   (se), `SIMPLY_RISC_SCANIN, .so());
1180
   dff_s #(1) rdthre_ff(.din (dec_swl_rdsr_sel_thr_d),
1181 95 fafa1971
                                  .clk (clk),
1182
                                  .q   (rdsr_sel_thr_e),
1183 113 albert.wat
                                  .se   (se), `SIMPLY_RISC_SCANIN, .so());
1184 95 fafa1971
 
1185
   // TBD: read out all thread state, not just the current thread
1186
   //      Done 9/26/02
1187
   assign fmt_thrconf_e = {wm_stbwait,
1188
                           wm_other,
1189
                           wm_imiss,           // 51:40 - wait mask
1190
                           4'b0,               // 39:36 - rsvd
1191
                           thr0_state,
1192
                           thr1_state,
1193
                           thr2_state,
1194
                           thr3_state,         // 35:16 - thr state
1195
                                             {2'b0},             // 15:14 - rsvd
1196
                                             const_cpuid,        // 13:10 - 4b cpu id
1197
                                             rd_tid_spec_e[2:1], // 9:8 - 2b tid
1198
                                             {5'b0},             // 7:3 - rsvd
1199
                                             rd_tid_spec_e[0],   // 2 - en spec
1200
                                             {1'b0},             // 1 - QOS/rsvd
1201
                                             rd_thract_e};       // 0 - active
1202
 
1203
//`ifdef SPARC_HPV_EN
1204
   assign fmt_thrconf_adj[51:1] = fmt_thrconf_e[51:1] & {51{hprivmode_e}};
1205
   assign fmt_thrconf_adj[0] = fmt_thrconf_e[0];
1206
//`else
1207
//   assign fmt_thrconf_adj[51:0] = fmt_thrconf_e[51:0];
1208
//`endif
1209
 
1210
//   assign thrconf_out_e[51:16] = (fmt_thrconf_e[51:16] & 
1211
//                                      {36{hprivmode_e}});
1212
 
1213
//   mux2ds #(52) rdsr_mxe(.dout (thrconf_out_e[51:0]),
1214
//                                   .in0  ({49'b0, fprs_e}),
1215
//                                   .in1  (fmt_thrconf_adj[51:0]),
1216
//                                   .sel0 (~rdsr_sel_thr_e),
1217
//                                   .sel1 (rdsr_sel_thr_e));
1218
   assign thrconf_out_e[51:0] = rdsr_sel_thr_e ? fmt_thrconf_adj[51:0] :
1219
                                                 {49'b0, fprs_e};
1220
 
1221
   // leave out the zeros before sending to fdp
1222
   assign dtu_fdp_thrconf_e = {thrconf_out_e[51:40], // 40:29
1223
                               thrconf_out_e[35:16], // 28:9
1224
                               thrconf_out_e[13:8],  // 8:3
1225
                               thrconf_out_e[2:0]};
1226
 
1227
   // shadow scan outputs
1228
   mux4ds #(11) sscan_mx(.dout (swl_sscan_thrstate[10:0]),
1229
                         .in0  ({thr0_state[4:0],
1230
                                 wm_imiss[0],
1231
                                 wm_other[0],
1232
                                 wm_stbwait[0],
1233
                                 mul_busy_e[0],
1234
                                 div_busy_e[0],
1235
                                 fp_busy_e[0]}),
1236
                         .in1  ({thr1_state[4:0],
1237
                                 wm_imiss[1],
1238
                                 wm_other[1],
1239
                                 wm_stbwait[1],
1240
                                 mul_busy_e[1],
1241
                                 div_busy_e[1],
1242
                                 fp_busy_e[1]}),
1243
                         .in2  ({thr2_state[4:0],
1244
                                 wm_imiss[2],
1245
                                 wm_other[2],
1246
                                 wm_stbwait[2],
1247
                                 mul_busy_e[2],
1248
                                 div_busy_e[2],
1249
                                 fp_busy_e[2]}),
1250
                         .in3  ({thr3_state[4:0],
1251
                                 wm_imiss[3],
1252
                                 wm_other[3],
1253
                                 wm_stbwait[3],
1254
                                 mul_busy_e[3],
1255
                                 div_busy_e[3],
1256
                                 fp_busy_e[3]}),
1257
                         .sel0 (ctu_sscan_tid[0]),
1258
                         .sel1 (ctu_sscan_tid[1]),
1259
                         .sel2 (ctu_sscan_tid[2]),
1260
                         .sel3 (ctu_sscan_tid[3]));
1261
 
1262
   // write to TCR
1263
   assign wrt_spec_w = dec_swl_wrt_tcr_w & ifu_tlu_inst_vld_w &
1264
                       ~flush_all_w;
1265
 
1266
   assign spec_next = (wrt_spec_w2 & fcl_dtu_hprivmode_w2) ?
1267
                             thr_config_in_w2[2] :
1268
                             en_spec_d;
1269
 
1270
   assign halt_w = wrt_spec_w & ~thr_config_in_w[0];
1271
 
1272 113 albert.wat
   dff_s #(1) wrsw2_ff(.din (wrt_spec_w),
1273 95 fafa1971
                     .q   (wrt_spec_w2),
1274 113 albert.wat
                     .clk (clk), .se(se), `SIMPLY_RISC_SCANIN, .so());
1275 95 fafa1971
 
1276
   assign wrt_tcr_w2 = st_thr_w2 & {4{wrt_spec_w2}};
1277
 
1278 113 albert.wat
   dff_s #(1) hlt_ff(.din (halt_w),
1279 95 fafa1971
                   .q   (halt_w2),
1280 113 albert.wat
                   .clk (clk), .se(se), `SIMPLY_RISC_SCANIN, .so());
1281 95 fafa1971
   assign halt_thread = st_thr_w2 & {4{halt_w2}};
1282
 
1283 113 albert.wat
   dffr_s #(1) enspec_ff(.din (spec_next),
1284 95 fafa1971
                                   .clk (clk),
1285
                                   .q   (en_spec_d),
1286
                                   .rst (dtu_reset),
1287 113 albert.wat
                                   .se  (se), `SIMPLY_RISC_SCANIN, .so());
1288 95 fafa1971
 
1289 113 albert.wat
   dff_s #(1) enspecm_ff(.din (rd_tid_spec_e[0]),
1290 95 fafa1971
                                   .clk (clk),
1291
                                   .q   (en_spec_m),
1292 113 albert.wat
                                   .se  (se), `SIMPLY_RISC_SCANIN, .so());
1293 95 fafa1971
 
1294 113 albert.wat
   dff_s #(1) enspecw_ff(.din (en_spec_m),
1295 95 fafa1971
                                   .clk (clk),
1296
                                   .q   (en_spec_g),
1297 113 albert.wat
                                   .se  (se), `SIMPLY_RISC_SCANIN, .so());
1298 95 fafa1971
 
1299
 
1300
   //-----------------------------
1301
   // Instruction Flow Control
1302
   //-----------------------------
1303
 
1304
   // mul and div control (1 each per cpu)
1305
   assign mul_busy_d = ({4{dec_swl_mul_inst_d & ~swl_dec_mulbusy_e &
1306
                           fcl_dtu_inst_vld_d & ~iferr_d}} & thr_d &
1307
//                                        ~rb_thr_w & ~rt_st_thr_e |          // set
1308
                        ~rt_st_thr_e |
1309
                                          mul_busy_e & ~killed_uniop_done_e) &
1310
                                           ~exu_ifu_longop_done_g & (~trp_no_retr);  // reset wins
1311
 
1312
   assign div_busy_d = ({4{dec_swl_div_inst_d & ~swl_dec_divbusy_e &
1313
                           fcl_dtu_inst_vld_d & ~iferr_d}} &
1314
                                          thr_d  & ~rt_st_thr_e |        // set
1315
                                          div_busy_e & ~killed_uniop_done_e) &
1316
                                           ~exu_ifu_longop_done_g & (~trp_no_retr); // reset wins
1317
 
1318
   assign fp_busy_d = ({4{dec_swl_allfp_d & // swl_dec_fp_enable_d &
1319
                          fcl_dtu_inst_vld_d &
1320
                          ~fpbusy_local_e & ~iferr_d}} & thr_d &
1321
                                   ~rt_st_thr_d & ~rt_st_thr_e |
1322
                                  // FP could be a st
1323
                                   fp_busy_e & ~killed_uniop_done_e) &
1324
                                          {4{~ffu_ifu_fpop_done_w2}} & ~trp_no_retr; // reset wins
1325
 
1326 113 albert.wat
   dffr_s #(4) mulb_ff(.din (mul_busy_d),
1327 95 fafa1971
                                 .q   (mul_busy_e),
1328
                                 .clk (clk),
1329
                                 .rst (dtu_reset),
1330 113 albert.wat
                                 .se  (se), `SIMPLY_RISC_SCANIN, .so());
1331 95 fafa1971
   assign true_mulbusy_e = (|mul_busy_e[3:0]);
1332
   assign mbusy_d0 = true_mulbusy_e & mul_wait_any;
1333
 
1334
   // block shared resource for two extra cycles, to allow waiting
1335
   // threads a fair chance at getting it.  
1336
   assign swl_dec_mulbusy_e = true_mulbusy_e | mbusy_d3 | mbusy_d1 | mbusy_d2;
1337
 
1338 113 albert.wat
   dffr_s #(4) divb_ff(.din (div_busy_d),
1339 95 fafa1971
                                 .q   (div_busy_e),
1340
                                 .clk (clk),
1341
                                 .rst (dtu_reset),
1342 113 albert.wat
                                 .se  (se), `SIMPLY_RISC_SCANIN, .so());
1343 95 fafa1971
   assign true_divbusy_e = (|div_busy_e[3:0]);
1344
   assign dbusy_d0 = true_divbusy_e & div_wait_any;
1345
 
1346
   // block shared resource for two extra cycles, to allow waiting
1347
   // threads a fair chance at getting it.  
1348
   assign swl_dec_divbusy_e = true_divbusy_e | dbusy_d3 | dbusy_d1 | dbusy_d2;
1349
 
1350 113 albert.wat
   dffr_s #(4) fpb_ff(.din (fp_busy_d),
1351 95 fafa1971
                                .q   (fp_busy_e),
1352
                                .clk (clk),
1353
                                .rst (dtu_reset),
1354 113 albert.wat
                                .se  (se), `SIMPLY_RISC_SCANIN, .so());
1355 95 fafa1971
   assign true_fpbusy_e = (|fp_busy_e[3:0]);
1356
   assign fbusy_d0 = true_fpbusy_e & fp_wait_any;
1357
 
1358
   assign fbusy_nxt_d = (|fp_busy_d[3:0]) | fbusy_d0 | fbusy_d1 | fbusy_d2;
1359 113 albert.wat
   dffr_s #(1) tfbe_ff(.din (fbusy_nxt_d),
1360 95 fafa1971
                     .q   (fbusy_crit_e),
1361
                     .clk (clk),
1362 113 albert.wat
                     .rst (dtu_reset), .se(se), `SIMPLY_RISC_SCANIN, .so());
1363 95 fafa1971
 
1364
   // block shared resource for two extra cycles, to allow waiting
1365
   // threads a fair chance at getting it.  
1366
   assign swl_dec_fpbusy_e = fbusy_crit_e;
1367
   assign fpbusy_local_e = true_fpbusy_e | fbusy_d3 | fbusy_d1 | fbusy_d2;
1368
 
1369 113 albert.wat
   dff_s #(3) bd1_reg(.din ({mbusy_d0, dbusy_d0, fbusy_d0}),
1370 95 fafa1971
                    .q   ({mbusy_d1, dbusy_d1, fbusy_d1}),
1371 113 albert.wat
                    .clk (clk), .se(se), `SIMPLY_RISC_SCANIN, .so());
1372 95 fafa1971
 
1373 113 albert.wat
   dff_s #(3) bd2_reg(.din ({mbusy_d1, dbusy_d1, fbusy_d1}),
1374 95 fafa1971
                    .q   ({mbusy_d2, dbusy_d2, fbusy_d2}),
1375 113 albert.wat
                    .clk (clk), .se(se), `SIMPLY_RISC_SCANIN, .so());
1376 95 fafa1971
 
1377 113 albert.wat
   dff_s #(3) bd3_reg(.din ({mbusy_d2, dbusy_d2, fbusy_d2}),
1378 95 fafa1971
                    .q   ({mbusy_d3, dbusy_d3, fbusy_d3}),
1379 113 albert.wat
                    .clk (clk), .se(se), `SIMPLY_RISC_SCANIN, .so());
1380 95 fafa1971
 
1381
   // ifetch errors
1382
   // If there was an error in the ifetch call back this instruction
1383
   assign iferr_d = erb_dtu_ifeterr_d1 & same_thr_de;
1384
   assign iferr_s = erb_dtu_ifeterr_d1 & same_thr_fe;
1385
   assign retract_iferr_d =  erb_dtu_ifeterr_d1 & fcl_dtu_inst_vld_d &
1386
                             same_thr_de;
1387
 
1388
   // mul_inst is already already qualified with inst_vld
1389
   // so is fpop
1390
   // don't set retract if there is an iferr, since this will cancel
1391
   // the pending imisses!  
1392
   assign dtu_fcl_retract_d = ((dec_swl_mul_inst_d & swl_dec_mulbusy_e |
1393
                                                  dec_swl_div_inst_d & swl_dec_divbusy_e |
1394
                                                  dec_swl_allfp_d & fpbusy_local_e) &
1395
                                // & swl_dec_fp_enable_d 
1396
                               fcl_dtu_inst_vld_d |
1397
                               retract_store_d
1398
//                             |  retract_iferr_d
1399
                               );
1400
 
1401
   // what does this do???
1402
   // no need to stall after retract since thread is already switched out
1403
//   assign retract_stall_d = (dec_swl_mul_inst_d & swl_dec_mulbusy_e | 
1404
//                                             dec_swl_div_inst_d & swl_dec_divbusy_e |
1405
//                                             dec_swl_allfp_d & swl_dec_fp_enable_d & 
1406
//                             fpbusy_local_e);
1407
 
1408
   assign mul_wait_nxt = ({4{dec_swl_mul_inst_d & swl_dec_mulbusy_e &
1409
                             fcl_dtu_inst_vld_d & ~iferr_d}} &
1410
                                         thr_d  & ~rt_st_thr_e | mul_done |   // set
1411
                                         mul_wait & ~retr_thr_wakeup  & ~killed_uniop_done_e) &
1412
                                         (~trp_no_retr);
1413
 
1414 113 albert.wat
   dffr_s #(4) mw_ff(.din (mul_wait_nxt[3:0]),
1415 95 fafa1971
                               .q   (mul_wait[3:0]),
1416
                               .clk (clk),
1417
                               .rst (dtu_reset),
1418 113 albert.wat
                               .se(se), `SIMPLY_RISC_SCANIN, .so());
1419 95 fafa1971
   assign mul_wait_any = (|mul_wait[3:0]);
1420
 
1421
   assign div_wait_nxt =  ({4{dec_swl_div_inst_d & swl_dec_divbusy_e &
1422
                              fcl_dtu_inst_vld_d & ~iferr_d}} &
1423
                        thr_d  & ~rt_st_thr_e | div_done | // set 
1424
                                          div_wait & ~retr_thr_wakeup & ~killed_uniop_done_e) &
1425
                                          (~trp_no_retr);
1426
 
1427 113 albert.wat
   dffr_s #(4) dw_ff(.din (div_wait_nxt[3:0]),
1428 95 fafa1971
                               .q   (div_wait[3:0]),
1429
                               .clk (clk),
1430
                               .rst (dtu_reset),
1431 113 albert.wat
                               .se(se), `SIMPLY_RISC_SCANIN, .so());
1432 95 fafa1971
   assign div_wait_any = (|div_wait[3:0]);
1433
 
1434
   assign fp_wait_nxt =  ({4{dec_swl_allfp_d & // swl_dec_fp_enable_d & 
1435
                             fcl_dtu_inst_vld_d & fpbusy_local_e &
1436
                             ~iferr_d}} &
1437
                                            thr_d  & ~rt_st_thr_d & ~rt_st_thr_e |
1438
                          fp_done |    // set 
1439
                                            fp_wait & ~retr_thr_wakeup & ~killed_uniop_done_e) &
1440
                                             (~trp_no_retr);
1441
 
1442 113 albert.wat
   dffr_s #(4) fw_ff(.din (fp_wait_nxt[3:0]),
1443 95 fafa1971
                               .q   (fp_wait[3:0]),
1444
                               .clk (clk),
1445
                               .rst (dtu_reset),
1446 113 albert.wat
                               .se(se), `SIMPLY_RISC_SCANIN, .so());
1447 95 fafa1971
   assign fp_wait_any = (|fp_wait[3:0]);
1448
 
1449
   // wake up waiting threads when the unit is no longer busy
1450
   // need to qual with trp_no_retr since trp can occur at the same
1451
   // time as unit becoming unbusy.  
1452
   assign mul_wake = mul_wait & {4{~true_mulbusy_e}} & ~trp_no_retr;
1453
   assign div_wake = div_wait & {4{~true_divbusy_e}} & ~trp_no_retr;
1454
   assign fp_wake  = fp_wait & {4{~true_fpbusy_e}} & ~trp_no_retr;
1455
 
1456
//   assign retr_thr_wakeup = (mul_wait & {4{~swl_dec_mulbusy_e}} |
1457
//                           div_wait & {4{~swl_dec_divbusy_e}} | 
1458
//                           fp_wait & {4{~fpbusy_local_e}} | 
1459
//                           wm_stbwait & stb_retry);
1460
 
1461
   assign retr_thr_wakeup = mul_wake | div_wake | fp_wake;
1462
//                        |  (wm_stbwait & stb_retry & ~wm_other);
1463
 
1464
   assign fp_thr[0] = ~ffu_ifu_tid_w2[1] & ~ffu_ifu_tid_w2[0];
1465
   assign fp_thr[1] = ~ffu_ifu_tid_w2[1] &  ffu_ifu_tid_w2[0];
1466
   assign fp_thr[2] =  ffu_ifu_tid_w2[1] & ~ffu_ifu_tid_w2[0];
1467
   assign fp_thr[3] =  ffu_ifu_tid_w2[1] &  ffu_ifu_tid_w2[0];
1468
 
1469
   // Delay mul div completion to prevent one thread from hogging mul and div
1470
   assign mul_done = exu_ifu_longop_done_g & mul_busy_e & {4{mul_wait_any}};
1471
   assign div_done = exu_ifu_longop_done_g & div_busy_e & {4{div_wait_any}};
1472
   assign fp_done = fp_thr & {4{ffu_ifu_fpop_done_w2}} & {4{fp_wait_any}};
1473
 
1474
   assign fp_thrrdy = fp_thr & {4{ffu_ifu_fpop_done_w2}} & {4{~fp_wait_any}};
1475
 
1476
   // don't complete if another mul/div is waiting
1477
   assign exu_lop_done = (exu_ifu_longop_done_g &
1478
                                            (~mul_busy_e | {4{~mul_wait_any}}) &
1479
                                            (~div_busy_e | {4{~div_wait_any}}));
1480
 
1481
   // TBD:
1482
   // 1.  Put in similar wakeup sequence for fp completion -- done
1483
   // 2.  Is it worth doing a round robin wakeup when a deadlock problem
1484
   //     exists even in that case? -- no need with lru scheduler
1485
 
1486
 
1487
   //--------------------------
1488
   // Store buffer flow control
1489
   //--------------------------
1490
   // store pipe
1491
   assign st_inst_qual_d = dec_swl_st_inst_d & fcl_dtu_inst_vld_d;
1492 113 albert.wat
   dff_s ste_ff(.din (st_inst_qual_d),
1493 95 fafa1971
                    .q   (st_inst_e),
1494
                    .clk (clk),
1495 113 albert.wat
                    .se  (se), `SIMPLY_RISC_SCANIN, .so());
1496 95 fafa1971
   assign st_inst_qual_e = st_inst_e & ~dtu_inst_anull_e;
1497
 
1498 113 albert.wat
   dff_s stm_ff(.din (st_inst_qual_e),
1499 95 fafa1971
                    .q   (st_inst_m),
1500
                    .clk (clk),
1501 113 albert.wat
                    .se  (se), `SIMPLY_RISC_SCANIN, .so());
1502
   dff_s stg_ff(.din (st_inst_m),
1503 95 fafa1971
                    .q   (st_inst_g),
1504
                    .clk (clk),
1505 113 albert.wat
                    .se  (se), `SIMPLY_RISC_SCANIN, .so());
1506 95 fafa1971
 
1507
//   assign st_inst_qual_g = st_inst_g & ifu_tlu_inst_vld_w;
1508
//   dff stw2_ff(.din (st_inst_qual_g),
1509
//                   .q   (st_inst_w2),
1510
//                   .clk (clk),
1511 113 albert.wat
//               .se  (se), `SIMPLY_RISC_SCANIN, .so());
1512 95 fafa1971
 
1513
   // determine which of the above thread is to the D thread
1514
   assign same_thr_de = (thr_d[0] & thr_e[0] |
1515
                                           thr_d[1] & thr_e[1] |
1516
                                           thr_d[2] & thr_e[2] |
1517
                                           thr_d[3] & thr_e[3]);
1518
   assign same_thr_dg = (thr_d[0] & thr_w[0] |
1519
                                           thr_d[1] & thr_w[1] |
1520
                                           thr_d[2] & thr_w[2] |
1521
                                           thr_d[3] & thr_w[3]);
1522
 
1523
   assign same_thr_fd = (thr_f[0] & thr_d[0] |
1524
                                           thr_f[1] & thr_d[1] |
1525
                                           thr_f[2] & thr_d[2] |
1526
                                           thr_f[3] & thr_d[3]);
1527
   assign same_thr_fe = (thr_f[0] & thr_e[0] |
1528
                                           thr_f[1] & thr_e[1] |
1529
                                           thr_f[2] & thr_e[2] |
1530
                                           thr_f[3] & thr_e[3]);
1531
   assign same_thr_fm = (thr_f[0] & thr_m[0] |
1532
                                           thr_f[1] & thr_m[1] |
1533
                                           thr_f[2] & thr_m[2] |
1534
                                           thr_f[3] & thr_m[3]);
1535
   assign same_thr_fg = (thr_f[0] & thr_w[0] |
1536
                                           thr_f[1] & thr_w[1] |
1537
                                           thr_f[2] & thr_w[2] |
1538
                                           thr_f[3] & thr_w[3]);
1539
 
1540
   assign pipe_st_e = same_thr_fe & st_inst_e;
1541
   assign pipe_st_m = same_thr_fm & st_inst_m;
1542
   assign pipe_st_g = same_thr_fg & st_inst_g;
1543
   assign pipe_st_d = same_thr_fd & st_inst_qual_d;
1544
 
1545 113 albert.wat
   dff_s #(1) pste_ff(.din (pipe_st_d),
1546 95 fafa1971
                    .q   (st_thisthr_e),
1547 113 albert.wat
                    .clk (clk), .se(se), `SIMPLY_RISC_SCANIN, .so());
1548 95 fafa1971
 
1549
   // count the number of stores in the pipe to this thread (0-4)
1550
   assign pipe_st_cnt_ge1 = pipe_st_e | pipe_st_m | pipe_st_g;
1551
//                                pipe_st_w2;
1552
 
1553
   assign pipe_st_cnt_ge2 = (pipe_st_e & pipe_st_m |
1554
                                               pipe_st_e & pipe_st_g |
1555
                             pipe_st_m & pipe_st_g);
1556
 
1557
//   assign pipe_st_cnt_ge2 = (pipe_st_e & pipe_st_m |
1558
//                                             pipe_st_e & pipe_st_g |
1559
//                                             pipe_st_e & pipe_st_w2 |
1560
//                                             pipe_st_m & pipe_st_g |
1561
//                                             pipe_st_m & pipe_st_w2 |
1562
//                                 pipe_st_g & pipe_st_w2);
1563
 
1564
   assign pipe_st_cnt_ge3 = (pipe_st_e & pipe_st_m & pipe_st_g);
1565
//                                             pipe_st_e & pipe_st_m & pipe_st_w2 |
1566
//                                             pipe_st_e & pipe_st_g & pipe_st_w2 |
1567
//                                             pipe_st_m & pipe_st_g & pipe_st_w2);
1568
 
1569
//   assign pipe_st_cnt_eq4 = pipe_st_e & pipe_st_m & pipe_st_g & 
1570
//                                pipe_st_w2;
1571
 
1572 113 albert.wat
   dff_s #(3) pstc_reg(.din ({pipe_st_cnt_ge1,
1573 95 fafa1971
                            pipe_st_cnt_ge2,
1574
                            pipe_st_cnt_ge3}),
1575
                     .q   ({dst_cnt_ge1,
1576
                            dst_cnt_ge2,
1577
                            dst_cnt_ge3}),
1578 113 albert.wat
                     .clk (clk), .se(se), `SIMPLY_RISC_SCANIN, .so());
1579 95 fafa1971
 
1580
   // get the number of taken store buffer entries to this thread
1581
   mux4ds #(4) stbcnt_mux(.dout (stbcnt_s),
1582
                                            .in0  (lsu_ifu_stbcnt0),
1583
                                            .in1  (lsu_ifu_stbcnt1),
1584
                                            .in2  (lsu_ifu_stbcnt2),
1585
                                            .in3  (lsu_ifu_stbcnt3),
1586
                                            .sel0 (thr_f[0]),
1587
                                            .sel1 (thr_f[1]),
1588
                                            .sel2 (thr_f[2]),
1589
                                            .sel3 (thr_f[3]));
1590
 
1591 113 albert.wat
   dff_s #(4) stbd_reg(.din (stbcnt_s),
1592 95 fafa1971
                                 .q   (stbcnt_d),
1593
                                 .clk (clk),
1594 113 albert.wat
                                 .se  (se), `SIMPLY_RISC_SCANIN, .so());
1595 95 fafa1971
 
1596
   assign all_dst_ge1 = dst_cnt_ge1 | st_thisthr_e;
1597
   assign all_dst_ge2 = dst_cnt_ge1 & st_thisthr_e | dst_cnt_ge2;
1598
   assign all_dst_ge3 = dst_cnt_ge2 & st_thisthr_e | dst_cnt_ge3;
1599
   assign all_dst_eq4 = dst_cnt_ge3 & st_thisthr_e;
1600
 
1601
   // switch if taken entries + stores in pipe >= 8
1602
   assign switch_store_d = stbcnt_d[3] & fcl_dtu_inst_vld_d | // 8
1603
                    dec_swl_st_inst_d & fcl_dtu_inst_vld_d &
1604
                    (stbcnt_d[2] & stbcnt_d[1] & stbcnt_d[0] | // 7
1605
                           stbcnt_d[2] & stbcnt_d[1] & all_dst_ge1 | // 6 + 1
1606
                           stbcnt_d[2] & stbcnt_d[0] & all_dst_ge2 | // 5 + 2
1607
                           stbcnt_d[2]               & all_dst_ge3 | // 4 + 3
1608
                           stbcnt_d[1] & stbcnt_d[0] & all_dst_eq4); // 3 + 4
1609
 
1610
   assign stb_stall = {4{switch_store_d}} & thr_d;
1611
   assign stb_blocked = {lsu_ifu_stbcnt3[3], lsu_ifu_stbcnt2[3],
1612
                                           lsu_ifu_stbcnt1[3], lsu_ifu_stbcnt0[3]};
1613
 
1614 113 albert.wat
   dff_s #(4) stbb_reg(.din (stb_blocked),
1615 95 fafa1971
                                 .q   (stb_blocked_d1),
1616 113 albert.wat
                                 .clk (clk), .se(se), `SIMPLY_RISC_SCANIN, .so());
1617 95 fafa1971
 
1618
   // retract this thread if taken entries + stores in pipe >= 9
1619
   assign retract_store_d = dec_swl_st_inst_d & fcl_dtu_inst_vld_d &
1620
                (stbcnt_d[3] | // 8
1621
                 stbcnt_d[2] & stbcnt_d[1] & stbcnt_d[0] & all_dst_ge1 | // 7 + 1
1622
                 stbcnt_d[2] & stbcnt_d[1] & all_dst_ge2 |  // 6 + 2
1623
                 stbcnt_d[2] & stbcnt_d[0] & all_dst_ge3 |  // 5 + 3
1624
                 stbcnt_d[2] & all_dst_eq4);                // 4 + 4
1625
 
1626
   // remember if we retracted a store so that we can clear wmo in 
1627
   // the next cycle
1628
   assign retract_st_next_d = (retract_store_d | retract_iferr_d) &
1629
                              ~(same_thr_dg & rollback_g) &
1630
                              ~trp_noretr_d;
1631
 
1632 113 albert.wat
   dff_s #(1) retr_se(.din (retract_st_next_d),
1633 95 fafa1971
                                .q   (retract_store_e),
1634 113 albert.wat
                                .clk (clk), .se (se), `SIMPLY_RISC_SCANIN, .so());
1635 95 fafa1971
 
1636
   // clear wmo if you set it already
1637
   assign clear_wmo_e = retract_store_e & (swc_d & same_thr_de | swc_e);
1638
// assign clear_wmo_e = retract_store_e;   
1639
 
1640
 
1641
   // mark a switched out thread for wakeup
1642
//   assign stb_wait_nxt = ({4{switch_store_d}} & thr_d & ~rb_thr_w |   // set
1643
//                                          wm_stbwait & ~stb_retry 
1644
//                                      ~(thr_d & {4{swc_d}}) & 
1645
//                                          ~(thr_e & {4{dec_swl_sta_inst_e & 
1646
//                                                             lsu_ifu_ldsta_internal_e}})   // reset
1647
//                                          ) & ~trp_no_retr;  // this reset wins
1648
 
1649
//   assign stb_wait_nxt = ({4{switch_store_d}} & thr_d & ~rb_thr_w |   // set
1650
//                                          wm_stbwait & ~stb_retry) & ~trp_no_retr;
1651
 
1652
   assign stb_wait_nxt = ({4{switch_store_d}} & thr_d |   // set
1653 113 albert.wat
                                            wm_stbwait & ~stb_retry);
1654 95 fafa1971
 
1655 113 albert.wat
   dffr_s #(4) stbw_reg(.din (stb_wait_nxt),
1656 95 fafa1971
                                  .q   (wm_stbwait),
1657
                                  .clk (clk),
1658
                                  .rst (dtu_reset),
1659 113 albert.wat
                                  .se  (se), `SIMPLY_RISC_SCANIN, .so());
1660 95 fafa1971
 
1661
   // count to 4 and retry 
1662 113 albert.wat
   dff_s stbrete_ff(.din (switch_store_d),
1663 95 fafa1971
                              .q   (sw_st_e),
1664
                              .clk (clk),
1665 113 albert.wat
                              .se  (se), `SIMPLY_RISC_SCANIN, .so());
1666
   dff_s stbretm_ff(.din (sw_st_e),
1667 95 fafa1971
                              .q   (sw_st_m),
1668
                              .clk (clk),
1669 113 albert.wat
                              .se  (se), `SIMPLY_RISC_SCANIN, .so());
1670
   dff_s stbretg_ff(.din (sw_st_m),
1671 95 fafa1971
                              .q   (sw_st_g),
1672
                              .clk (clk),
1673 113 albert.wat
                              .se  (se), `SIMPLY_RISC_SCANIN, .so());
1674
   dff_s stbretw2_ff(.din (sw_st_g),
1675 95 fafa1971
                               .q   (sw_st_w2),
1676
                               .clk (clk),
1677 113 albert.wat
                               .se  (se), `SIMPLY_RISC_SCANIN, .so());
1678 95 fafa1971
//   assign stb_retry = {4{sw_st_w2}} & st_thr_w2 & ~stb_blocked;
1679
 
1680
   assign st_in_pipe = ({4{sw_st_e}} & thr_e |
1681
                                          {4{sw_st_m}} & thr_m |
1682
                                          {4{sw_st_g}} & thr_w |
1683
                                          {4{sw_st_w2}} & st_thr_w2);
1684
 
1685
   // don't really need to AND with wm_stbwait with current logic, but
1686
   // for future use, this is left as is 
1687
   assign stb_retry = ~stb_blocked_d1 & ~st_in_pipe & wm_stbwait;
1688
 
1689
 
1690
   //
1691
   // Quad Stores
1692
   //
1693 113 albert.wat
   dff_s #(1) stde_ff(.din (dec_swl_std_inst_d),
1694 95 fafa1971
                                .q   (std_inst_e),
1695 113 albert.wat
                                .clk (clk), .se(se), `SIMPLY_RISC_SCANIN, .so());
1696 95 fafa1971
 
1697
//   assign stq_inst_e = std_inst_e & lsu_ifu_quad_asi_e & fcl_dtu_inst_vld_e;
1698
   assign std_done_e = std_inst_e & ~lsu_ifu_quad_asi_e & fcl_dtu_inst_vld_e;
1699 113 albert.wat
   dff_s #(1) stdm_ff(.din (std_done_e),
1700 95 fafa1971
                                .q   (std_done_m),
1701 113 albert.wat
                                .clk (clk), .se(se), `SIMPLY_RISC_SCANIN, .so());
1702 95 fafa1971
 
1703
//   dff #(1) stqm_ff(.din (stq_inst_e),
1704
//                              .q   (stq_inst_m),
1705 113 albert.wat
//                              .clk (clk), .se(se), `SIMPLY_RISC_SCANIN, .so());
1706 95 fafa1971
//   dff #(1) stqw_ff(.din (stq_inst_m),
1707
//                              .q   (stq_inst_w),
1708 113 albert.wat
//                              .clk (clk), .se(se), `SIMPLY_RISC_SCANIN, .so());
1709 95 fafa1971
//   dff #(1) stqw2_ff(.din (stq_inst_w),
1710
//                               .q   (stq_inst_w2),
1711 113 albert.wat
//                               .clk (clk), .se(se), `SIMPLY_RISC_SCANIN, .so());
1712 95 fafa1971
 
1713
//   assign stq_in_pipe = ({4{stq_inst_m}} & thr_m |
1714
//                                         {4{stq_inst_w}} & thr_w |
1715
//                                         {4{stq_inst_w2}} & st_thr_w2);
1716
 
1717
//   assign stq_busy = (stq_in_pipe | lsu_ifu_stq_busy);
1718
//   assign stq_wait_next = thr_e & {4{stq_inst_e}} | 
1719
//                                          stq_wait & stq_busy;
1720
 
1721
//   dffr #(4) stqwait_reg(.din (stq_wait_next),
1722
//                                   .q   (stq_wait),
1723
//                                   .rst (dtu_reset),
1724 113 albert.wat
//                                   .clk (clk), .se(se), `SIMPLY_RISC_SCANIN, .so());
1725 95 fafa1971
//
1726
//   assign stq_done_thr = stq_wait & ~stq_busy | thr_m & {4{std_done_m}};
1727
 
1728
 
1729
   //-----------------------------
1730
   // FPRS
1731
   //-----------------------------
1732 113 albert.wat
   dff_s #(3) wrtd_w_reg(.din (thr_config_in_m[2:0]),
1733 95 fafa1971
                        .q   (thr_config_in_w[2:0]),
1734 113 albert.wat
                        .clk (clk), .se(se), `SIMPLY_RISC_SCANIN, .so());
1735 95 fafa1971
 
1736 113 albert.wat
   dff_s #(3) wrtd_w2_reg(.din (thr_config_in_w[2:0]),
1737 95 fafa1971
                        .q   (thr_config_in_w2[2:0]),
1738 113 albert.wat
                        .clk (clk), .se(se), `SIMPLY_RISC_SCANIN, .so());
1739 95 fafa1971
 
1740
   assign fprs_wrt_data = thr_config_in_w2;
1741
   mux3ds #(3) fprs_mx0(.dout (fprs0_nxt),
1742
                                    .in0  (fprs_wrt_data),
1743
                                    .in1  (fprs0),
1744
                                    .in2  ({fprs0[2], new_fprs[1:0]}),
1745
                                    .sel0 (fprs_sel_wrt[0]),
1746
                                    .sel1 (fprs_sel_old[0]),
1747
                                    .sel2 (fprs_sel_set[0]));
1748
   mux3ds #(3) fprs_mx1(.dout (fprs1_nxt),
1749
                                    .in0  (fprs_wrt_data),
1750
                                    .in1  (fprs1),
1751
                                    .in2  ({fprs1[2], new_fprs[1:0]}),
1752
                                    .sel0 (fprs_sel_wrt[1]),
1753
                                    .sel1 (fprs_sel_old[1]),
1754
                                    .sel2 (fprs_sel_set[1]));
1755
   mux3ds #(3) fprs_mx2(.dout (fprs2_nxt),
1756
                                    .in0  (fprs_wrt_data),
1757
                                    .in1  (fprs2),
1758
                                    .in2  ({fprs2[2], new_fprs[1:0]}),
1759
                                    .sel0 (fprs_sel_wrt[2]),
1760
                                    .sel1 (fprs_sel_old[2]),
1761
                                    .sel2 (fprs_sel_set[2]));
1762
   mux3ds #(3) fprs_mx3(.dout (fprs3_nxt),
1763
                                    .in0  (fprs_wrt_data),
1764
                                    .in1  (fprs3),
1765
                                    .in2  ({fprs3[2], new_fprs[1:0]}),
1766
                                    .sel0 (fprs_sel_wrt[3]),
1767
                                    .sel1 (fprs_sel_old[3]),
1768
                                    .sel2 (fprs_sel_set[3]));
1769
 
1770
   // make resettable for now.  Eventually change to non-reset
1771
   // Done
1772 113 albert.wat
   dff_s #(3) t0_fprs(.din (fprs0_nxt),
1773 95 fafa1971
                                 .q   (fprs0),
1774
//                               .rst (dtu_reset),
1775 113 albert.wat
                                 .clk (clk), .se(se), `SIMPLY_RISC_SCANIN, .so());
1776
   dff_s #(3) t1_fprs(.din (fprs1_nxt),
1777 95 fafa1971
                                 .q   (fprs1),
1778
//                               .rst (dtu_reset),
1779 113 albert.wat
                                 .clk (clk), .se(se), `SIMPLY_RISC_SCANIN, .so());
1780
   dff_s #(3) t2_fprs(.din (fprs2_nxt),
1781 95 fafa1971
                                 .q   (fprs2),
1782
//                               .rst (dtu_reset),
1783 113 albert.wat
                                 .clk (clk), .se(se), `SIMPLY_RISC_SCANIN, .so());
1784
   dff_s #(3) t3_fprs(.din (fprs3_nxt),
1785 95 fafa1971
                                 .q   (fprs3),
1786
//                               .rst (dtu_reset),
1787 113 albert.wat
                                 .clk (clk), .se(se), `SIMPLY_RISC_SCANIN, .so());
1788 95 fafa1971
 
1789
   assign fprs_en_s = {fprs3[2],fprs2[2],fprs1[2],fprs0[2]};
1790
   assign fpen_vec_s = (tlu_ifu_pstate_pef & fprs_en_s & thr_f);
1791
   assign fpen_s = (|fpen_vec_s[3:0]);
1792 113 albert.wat
   dff_s #(1) fpend_ff(.din (fpen_s),
1793 95 fafa1971
                                 .q   (swl_dec_fp_enable_d),
1794 113 albert.wat
                                 .clk (clk), .se(se), `SIMPLY_RISC_SCANIN, .so());
1795 95 fafa1971
 
1796
   // unprotected since synopsys does not use one hot mux
1797
   mux4ds #(3) curr_fprs_mx(.dout (fprs_d),
1798
                                              .in0  (fprs0),
1799
                                              .in1  (fprs1),
1800
                                              .in2  (fprs2),
1801
                                              .in3  (fprs3),
1802
                                              .sel0 (thr_d[0]),
1803
                                              .sel1 (thr_d[1]),
1804
                                              .sel2 (thr_d[2]),
1805
                                              .sel3 (thr_d[3]));
1806
 
1807 113 albert.wat
   dff_s #(3) fprse_reg(.din (fprs_d),
1808 95 fafa1971
                                  .q   (fprs_e),
1809 113 albert.wat
                                  .clk (clk), .se(se), `SIMPLY_RISC_SCANIN, .so());
1810 95 fafa1971
 
1811
   assign new_fprs[1] = dec_swl_frf_upper_d | fprs_d[1];
1812
   assign new_fprs[0] = dec_swl_frf_lower_d | fprs_d[0];
1813
 
1814
   // writes to fprs are done by software
1815
   assign wrt_fprs_w = ifu_tlu_inst_vld_w & dec_swl_wrtfprs_w &
1816
                                         ~flush_all_w;
1817
 
1818 113 albert.wat
   dff_s #(1) fpwr_ff(.din (wrt_fprs_w),
1819 95 fafa1971
                    .q   (wrt_fprs_w2),
1820 113 albert.wat
                    .clk (clk), .se(se), `SIMPLY_RISC_SCANIN, .so());
1821 95 fafa1971
 
1822
   assign sel_wrt = st_thr_w2 & {4{wrt_fprs_w2}};
1823
   assign fprs_sel_set = thr_d & {4{dec_swl_fpop_d & swl_dec_fp_enable_d &
1824
                                    fcl_dtu_inst_vld_d}};
1825
   assign fprs_sel_wrt = ~fprs_sel_set & sel_wrt;
1826
   assign fprs_sel_old = ~sel_wrt & ~fprs_sel_set;
1827
 
1828
   sink #(52) s0(.in (thrconf_out_e));
1829
 
1830
 
1831
endmodule // sparc_ifu_swl
1832
 
1833
// Local Variables:
1834
// verilog-library-directories:("../../rtl" ".")
1835
// End:
1836
 

powered by: WebSVN 2.1.0

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