source: XOpenSparcT1/trunk/T1-CPU/ifu/sparc_ifu_ifqctl.v @ 6

Revision 6, 70.5 KB checked in by pntsvt00, 13 years ago (diff)

versione iniziale opensparc

Line 
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T1 Processor File: sparc_ifu_ifqctl.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////////////////////////////////////////////////////////////////////////
22/*
23//  Module Name: sparc_ifu_ifqctl
24//  Description:       
25//  Contains the control logic for the ifq and mil.
26*/
27////////////////////////////////////////////////////////////////////////
28// Global header file includes
29////////////////////////////////////////////////////////////////////////
30
31`include "iop.h"
32`include "ifu.h"
33
34
35module sparc_ifu_ifqctl(/*AUTOARG*/
36   // Outputs
37   ifu_lsu_inv_clear, ifu_lsu_ibuf_busy, ifu_lsu_asi_ack, 
38   ifu_lsu_ldxa_illgl_va_w2, ifu_lsu_fwd_wr_ack, ifu_lsu_pcxreq_d, 
39   ifu_lsu_destid_s, ifu_tlu_l2imiss, ifq_fcl_stallreq, 
40   ifq_swl_stallreq, ifq_fcl_flush_sonly_e, ifq_fcl_wrreq_bf, 
41   ifq_fcl_rdreq_bf, ifq_fcl_icd_wrreq_bf, ifq_fcl_ictv_wrreq_bf, 
42   ifq_erb_fwdrd_bf, ifq_erb_rdtag_f, ifq_erb_rdinst_f, 
43   ifq_erb_asi_erren_i2, ifq_erb_asi_errstat_i2, 
44   ifq_erb_asi_errinj_i2, ifq_erb_asi_erraddr_i2, 
45   ifq_erb_asi_imask_i2, ifq_erb_asiwr_i2, ifq_fcl_asird_bf, 
46   ifq_fcl_asi_tid_bf, ifq_erb_ue_rep, ifq_erb_ce_rep, ifq_erb_l2_ue, 
47   ifq_erb_io_ue, ifq_erb_ifet_ce, ifq_erb_l2err_tid, 
48   ifq_icv_wrdata_bf, ifq_icd_worden_bf, ifq_fcl_fill_thr, 
49   ifq_dtu_thrrdy, ifq_dtu_pred_rdy, ifc_ifd_filladdr4_i2, 
50   ifc_ifd_reqvalid_e, ifc_ifd_idx_sel_fwd_i2, ifc_ifd_errinv_e, 
51   ifc_ifd_uncached_e, ifc_ifd_thrid_e, ifc_ifd_pcxline_adj_d, 
52   ifc_inv_asireq_i2, ifc_ifd_repway_s, ifq_sscan_data, 
53   ifc_ifd_milfill_sel_i2_l, ifc_ifd_finst_sel_l, 
54   ifc_ifd_milreq_sel_d_l, ifc_ifd_ifqbyp_sel_fwd_l, 
55   ifc_ifd_ifqbyp_sel_inq_l, ifc_ifd_ifqbyp_sel_asi_l, 
56   ifc_ifd_ifqbyp_sel_lsu_l, ifc_ifd_ifqbyp_en_l, 
57   ifc_ifd_addr_sel_bist_i2_l, ifc_ifd_addr_sel_asi_i2_l, 
58   ifc_ifd_addr_sel_old_i2_l, ifc_ifd_addr_sel_fill_i2_l, 
59   ifq_icd_data_sel_bist_i2, ifq_icd_data_sel_fill_i2, 
60   ifq_icd_data_sel_old_i2, ifc_ifd_ldmil_sel_new, ifc_ifd_ld_inq_i1, 
61   ifc_inv_ifqadv_i2, so, 
62   // Inputs
63   lsu_ifu_cpxpkt_wayvld_i1, ifd_ifc_milhit_s, ifd_ifc_instoffset0, ifd_ifc_instoffset1, 
64   ifd_ifc_instoffset2, ifd_ifc_instoffset3, ifd_ifc_cpxvalid_i1, 
65   ifd_ifc_cpxreq_i1, ifd_ifc_cpxreq_nxt, ifd_ifc_cpxthr_nxt, 
66   ifd_ifc_cpxvld_i2, ifd_ifc_iobpkt_i2, ifd_ifc_4bpkt_i2, 
67   ifd_ifc_cpxnc_i2, ifd_ifc_fwd2ic_i2, ifd_ifc_cpxce_i2, 
68   ifd_ifc_cpxue_i2, ifd_ifc_cpxms_i2, ifd_ifc_miladdr4_i2, 
69   ifd_ifc_asiaddr_i2, ifd_ifc_asi_vachklo_i2, ifd_ifc_destid0, 
70   ifd_ifc_destid1, ifd_ifc_destid2, ifd_ifc_destid3, 
71   ifd_ifc_newdestid_s, ifd_ifc_pcxline_d, inv_ifc_inv_pending, 
72   fcl_ifq_icmiss_s1, fcl_ifq_rdreq_s1, fcl_ifq_thr_s1, 
73   fcl_ifq_canthr, fcl_ifq_grant_bf, dtu_ifq_kill_latest_d, 
74   erb_ifq_ifeterr_d1, erb_ifq_itlberr_s1, lsu_ifu_pcxpkt_ack_d, 
75   lsu_ifu_direct_map_l1, lsu_ifu_asi_vld, lsu_ifu_asi_state, 
76   lsu_ifu_asi_load, lsu_ifu_asi_thrid, fcl_ifq_icache_en_s_l, 
77   mbist_ifq_run_bist, mbist_icache_write, mbist_icache_read, 
78   ctu_sscan_tid, rclk, se, si, gdbginit_l, arst_l, grst_l, 
79   rst_tri_en, sehold
80   );
81
82   input          lsu_ifu_cpxpkt_wayvld_i1;
83   input [3:0]    ifd_ifc_milhit_s;      // if an Imiss hits in MIL
84   input [1:0]    ifd_ifc_instoffset0; // to select inst to TIR
85   input [1:0]    ifd_ifc_instoffset1; // to select inst to TIR
86   input [1:0]    ifd_ifc_instoffset2; // to select inst to TIR
87   input [1:0]    ifd_ifc_instoffset3; // to select inst to TIR
88
89   input         ifd_ifc_cpxvalid_i1;
90   input [`CPX_RQ_SIZE:0] ifd_ifc_cpxreq_i1;
91
92   input [3:0]   ifd_ifc_cpxreq_nxt;
93   input [1:0]   ifd_ifc_cpxthr_nxt;
94   input         ifd_ifc_cpxvld_i2;
95   
96   input         ifd_ifc_iobpkt_i2;
97   input         ifd_ifc_4bpkt_i2;
98   input         ifd_ifc_cpxnc_i2;
99   input         ifd_ifc_fwd2ic_i2;
100   input         ifd_ifc_cpxce_i2,
101                             ifd_ifc_cpxue_i2,
102                 ifd_ifc_cpxms_i2;
103   
104   input [3:0]   ifd_ifc_miladdr4_i2;
105
106   input [3:2]   ifd_ifc_asiaddr_i2;
107   input         ifd_ifc_asi_vachklo_i2;
108
109   input [2:0]   ifd_ifc_destid0,
110                             ifd_ifc_destid1,
111                             ifd_ifc_destid2,
112                             ifd_ifc_destid3,
113                             ifd_ifc_newdestid_s;
114   input [4:2]   ifd_ifc_pcxline_d;
115//   input [7:0]   ifd_ifc_mil_repway_s;   
116
117   input         inv_ifc_inv_pending;
118   
119   input         fcl_ifq_icmiss_s1;   // icache miss
120   input         fcl_ifq_rdreq_s1;
121
122   input [1:0]   fcl_ifq_thr_s1;
123
124   input [3:0]   fcl_ifq_canthr;        // cancel the imiss reqs to
125                                        // these threads
126   input         fcl_ifq_grant_bf;
127
128   input         dtu_ifq_kill_latest_d;
129   input         erb_ifq_ifeterr_d1;
130   input         erb_ifq_itlberr_s1;
131   
132   input         lsu_ifu_pcxpkt_ack_d;
133   input         lsu_ifu_direct_map_l1;
134
135   input         lsu_ifu_asi_vld;
136   input [7:0]   lsu_ifu_asi_state;
137   input         lsu_ifu_asi_load;
138   input [1:0]   lsu_ifu_asi_thrid;
139
140   input         fcl_ifq_icache_en_s_l;
141   
142   input         mbist_ifq_run_bist,
143                 mbist_icache_write,
144                             mbist_icache_read;
145
146   input [3:0]   ctu_sscan_tid;
147
148   input         rclk, 
149                 se, 
150                 si,
151                 gdbginit_l,
152                 arst_l,
153                 grst_l;
154
155   input         rst_tri_en;
156   input         sehold;
157   
158   // outputs
159   output        ifu_lsu_inv_clear;
160   output        ifu_lsu_ibuf_busy;
161   output        ifu_lsu_asi_ack;
162   output        ifu_lsu_ldxa_illgl_va_w2;
163
164   output        ifu_lsu_fwd_wr_ack;
165   
166   output        ifu_lsu_pcxreq_d;
167   output [2:0]  ifu_lsu_destid_s;
168
169   output [3:0]  ifu_tlu_l2imiss;
170   
171   output        ifq_fcl_stallreq;
172   output        ifq_swl_stallreq;
173   output        ifq_fcl_flush_sonly_e;
174   
175   output        ifq_fcl_wrreq_bf;
176   output        ifq_fcl_rdreq_bf;
177   
178   output        ifq_fcl_icd_wrreq_bf,
179                             ifq_fcl_ictv_wrreq_bf;
180   output        ifq_erb_fwdrd_bf;
181   output        ifq_erb_rdtag_f;
182   output        ifq_erb_rdinst_f;
183   output        ifq_erb_asi_erren_i2;
184   output        ifq_erb_asi_errstat_i2;
185   output        ifq_erb_asi_errinj_i2;
186   output        ifq_erb_asi_erraddr_i2;
187   output        ifq_erb_asi_imask_i2;
188   output        ifq_erb_asiwr_i2;
189   
190   output        ifq_fcl_asird_bf;
191   output [1:0]  ifq_fcl_asi_tid_bf;
192
193   output        ifq_erb_ue_rep;
194   output        ifq_erb_ce_rep;
195   output        ifq_erb_l2_ue;
196   output        ifq_erb_io_ue;
197   output        ifq_erb_ifet_ce;
198   output [1:0]  ifq_erb_l2err_tid;
199
200   output        ifq_icv_wrdata_bf;
201   output [3:0]  ifq_icd_worden_bf;
202
203   output [3:0]  ifq_fcl_fill_thr;     // should be same stage as
204   // fill_inst
205   output [3:0]  ifq_dtu_thrrdy;
206   output [3:0]  ifq_dtu_pred_rdy;
207   
208   output        ifc_ifd_filladdr4_i2;
209   output        ifc_ifd_reqvalid_e;
210   output        ifc_ifd_idx_sel_fwd_i2;
211
212   output        ifc_ifd_errinv_e;
213   output        ifc_ifd_uncached_e;
214   output [1:0]  ifc_ifd_thrid_e;
215   output [4:2]  ifc_ifd_pcxline_adj_d;
216
217   output        ifc_inv_asireq_i2;
218
219   output [1:0]  ifc_ifd_repway_s;
220
221   output [3:0]  ifq_sscan_data;
222   
223   // mux selects
224   output [3:0]  ifc_ifd_milfill_sel_i2_l;
225   output [3:0]  ifc_ifd_finst_sel_l;
226   output [3:0]  ifc_ifd_milreq_sel_d_l;
227   output        ifc_ifd_ifqbyp_sel_fwd_l, // select next input to ifq pipe
228                             ifc_ifd_ifqbyp_sel_inq_l,
229                             ifc_ifd_ifqbyp_sel_asi_l,
230                             ifc_ifd_ifqbyp_sel_lsu_l;
231         output        ifc_ifd_ifqbyp_en_l;
232   
233   output        ifc_ifd_addr_sel_bist_i2_l,
234                             ifc_ifd_addr_sel_asi_i2_l,
235                 ifc_ifd_addr_sel_old_i2_l,
236                             ifc_ifd_addr_sel_fill_i2_l;
237
238   output        ifq_icd_data_sel_bist_i2,
239                             ifq_icd_data_sel_fill_i2,
240                             ifq_icd_data_sel_old_i2;
241         
242   // 2:1 mux selects
243   output [3:0]  ifc_ifd_ldmil_sel_new;     // mil load enable
244
245   
246   output        ifc_ifd_ld_inq_i1;
247   
248   output        ifc_inv_ifqadv_i2;         // move a new op from ifq
249         // pipe to icache
250
251   output        so;
252   
253   //----------------------------------------------------------------------
254   // Declarations
255   //----------------------------------------------------------------------   
256   // local signals
257   wire [3:0]    thr_s1,      // s1 thread which missed in I$
258                             thr_d1,
259                 thr_e1,
260                             dfthr_f,     // thread currently being filled in I$
261                 dfthr_next_i2,
262                             dfthr_i2,    // next thread to be filled from CPX
263                 milfthr_i2,
264                             dpcxthr_s,
265                             dpcxthr_d;   // thread being transmitted to lsu
266
267   wire [1:0]    thrid_d,
268                 thrid_e;
269   
270   wire [3:0]    pcx_accept_d;
271
272   wire          req_pending_d,
273//                           req_pending_e,
274                             req_accept_d,
275//                 can_pcx_d,
276                 pcxreq_vbit_d;
277   
278   wire [3:0]    comp_valid_s,
279                             mil_valid_s,
280                 mil_cancel;
281
282   wire [3:0]    finst_i2,
283                 finst0,
284                 finst1,
285                 finst2,
286                 finst3;
287
288   wire [2:0]    milchld0,
289                             milchld1,
290                             milchld2,
291                             milchld3,
292                             next_milchld,
293                             milchld_d1;
294   wire          milchld_vld_f,
295                             next_milchld_i2,
296                             milchld_vld_i2;
297
298   wire [3:0]    mil0_state,
299                 mil1_state,
300                 mil2_state,
301                 mil3_state;
302
303   wire [2:0]    i2out;         // state machine output in i2 stage
304   
305   wire          any_milhit_qual_s,     // hit in MIL
306                 any_qualhit_or_io_s,
307                             icmiss_qual_s,
308//                           reqq_empty,    // no pending requests in MIL
309                             oldreq_valid,
310                             next_wrreq_i2,
311                             wrreq_f;
312   wire          block_fetch_s1,
313                 block_fetch_d1;
314
315   wire [3:0]    mil_thr_ready,
316                 all_retry_rdy_e1,
317                 all_retry_rdy_m1;
318   wire          retry_rdy_final_d1,
319                 retry_rdy_e1;
320
321   wire          rst_starv_ctr_l;
322   wire          starv_alert;
323
324   wire [3:0]    milhit_vec_s;
325   wire          any_milhit_s;
326
327   wire [1:0]    rand_repway_s;
328//   wire [1:0]    mil_repway_s;
329
330   wire [3:0]    errthr_d1,
331                             err_vec_d1,
332                             err_req;
333   wire          errinv_d1;
334
335   wire          ifeterr_qual_d1,
336                 ifeterr_e1;
337   wire          thr_match_d1e1;
338   wire          ifqadv_i1;
339
340   wire          ifqadvi2_nxt,
341                 ifqadv_i2_ff;
342   wire          access_grant_l;
343
344   wire          addrbit4_i2;
345   wire          addrbit4_nxt_i2;
346   
347   wire [3:0]    cpxreq_i2;
348   wire [1:0]    cpxthr_i2;
349   
350
351   wire          uncached_i2,
352                 uncached_s,
353                 mil_vld_i2,
354                 mil_uncan_i2,
355                 mil_nc_i2,
356                 mil_nc_e,
357                 mil_nc_d,
358                             uncached_fill_i2,
359                             uncached_f;
360
361   wire [3:0]    mil_nc_vec,
362                 mil_nc_vec_nxt;
363                 
364   
365   wire [3:0]    pcxreq_s,          // req bit from MIL
366                 pcxreq_qual_s,
367//                           newpcxreq_s,       // valid new request from latest miss
368//                           oldpcxreq_s,
369                             rr_gnt,          // round robin grant signal
370                             fill_addr4_i2;    // fill address bit 4 - determines
371         // which 16B of the 32B line gets
372         // written. Assume 0 first then 1
373
374   wire          newreq_valid,    // latest S stage miss creates request.
375                             nextreq_valid_s, // if either a new req from i$ or old
376                                         // req from MIL is made in this cycle.
377                             req_valid_d;     // req to LSU is valid
378
379   wire          inq_vld,
380                             inq_vld_nxt;
381
382   wire          ic_pkt_i1;
383   
384//   wire          fill_this16b;
385
386   wire [1:0]    filltid_i2,
387                             next_filltid_i2,
388                             filltid_f;
389
390   wire          imissrtn_i2,   // input cpx is ifill return
391                 imissrtn_next_i2,
392                 imissrtn_f,
393                             imissrtn_i1;   // pkt in inq is ifill ret
394
395   wire          invalidate_i1;
396
397   wire [3:0]    icmiss_thr_s,
398                             icmiss_thr_d;
399   wire          icmiss_d1,
400                 icmiss_qual_d1;
401   wire          canthr_s1,
402                 canthr_d1,
403                 canthr_s1_del1;
404   wire          itlberr_d1;
405
406   wire [2:0]    old_destid_s;
407
408   wire          destid_iob_s,
409                 destid_iob_d;
410
411   wire          iosp_d1_l,
412                 n763;
413   
414   wire [3:0]    wrt_tir;
415
416   wire [3:0]    wr_complete_f;
417   wire [3:0]    pred_rdy_i2;
418   wire [3:0]    fill_retn_thr_i2;
419
420   wire          filladdr4_f;
421   
422   wire [3:0]    milhit_to_thr_s,
423                             icmiss_for_milchk,
424                 qualhit_pe_s,
425                 qualhit_or_io_s;
426//                           milhit_qual_s;
427
428   wire          l2_ue_i2,
429                             l2_ce_i2,
430                             io_ue_i2;
431   wire          l2_miss_i2,
432                 l2_miss_f;
433//   wire [3:0]    l2ms_thr;
434   
435   wire          ce_rep_i2,
436                             ue_rep_i2;
437
438   wire          fwdreq_i2,
439                 fwdreq_i3,
440                 fwd_stall,
441                 fwdwr_i3,
442                 fwdrd_i3;
443
444   wire          cpxnc_i3;
445
446   wire          stallreq_d0,
447                 stallreq_d1;
448
449   wire          ifu_asireq_i1,
450                 ifu_asireq_i0,
451                 byp_sel_asi_l,
452                 asird_i1,
453                             asireq_i2,
454                 asireq_i2_l,
455                             asi_load_i1,
456                             asi_load_i2,
457                             asi_vld_next,
458                 asi_vld_i0,
459                 asi_vld_qual_i0;
460   
461   wire [7:0]    asi_state_i1;
462   wire          asi_ic_data_i1,
463                             asi_ic_data_i2,
464                             asi_ic_tag_i1,
465                             asi_ic_tag_i2;
466
467   wire          asi_erren_i1,
468                             asi_errstat_i1,
469                             asi_errinj_i1,
470                             asi_erraddr_i1,
471                             asi_imask_i1;
472
473   wire          asi_ic_data_unchk_i1,
474                             asi_ic_tag_unchk_i1;
475
476   wire          asi_erren_unchk_i1,
477                             asi_errstat_unchk_i1,
478                             asi_errinj_unchk_i1,
479                             asi_erraddr_unchk_i1,
480                             asi_imask_unchk_i1;
481
482   wire          illva_i0,
483                 illva_i1,
484                 illva_i2,
485                 illva_f,
486                 illva_s,
487                 illva_w2;
488
489   wire [3:0]    word_sel_i2;
490   wire          bist_op;
491
492   wire          rdinst_bf,
493                             rd_tag_bf;
494   
495   wire          errpkt_i1;
496   
497   wire          stpkt_i1,
498                 strmack_i1,
499                             ldpkt_i1,
500                             evpkt_i1,
501                             errpkt_i2;
502   
503   wire          icv_wrdata_i2,
504                             icv_wbit_i2,
505                             icv_wrdata_f;
506
507   wire          rst_way_lfsr;
508
509   wire          inq_wayvld_i1;
510   wire          inq_wayvld_i1_nxt;
511   wire          ldinv_i1;
512   wire          ldinv_i2_nxt;
513   wire          ldinv_i2;
514         
515   wire          ifq_reset,
516                 rnd_reset,
517                 ifq_reset_l;
518   
519
520   wire          clk;
521   
522   
523//----------------------------------------------------------------------
524// Code start here
525//----------------------------------------------------------------------
526
527   assign        clk = rclk;
528   
529
530   // reset buffer
531   dffrl_async rstff(.din (grst_l),
532                     .q   (ifq_reset_l),
533                     .clk (clk), .se(se), .si(), .so(),
534                     .rst_l (arst_l));
535
536   assign       ifq_reset = ~ifq_reset_l;
537
538   
539//---------
540// MIL fsm
541//---------   
542   sparc_ifu_milfsm mil0(
543                               .ifc_fsm_can_thisthr      (fcl_ifq_canthr[0]),       
544                         //     .ifc_fsm_orphan_thisthr (orphan_thr_d1[0]),
545
546
547                               .ifc_fsm_fill_thisthr_i2  (fill_retn_thr_i2[0]),   
548                               .ifc_fsm_wr_complete_f    (wr_complete_f[0]),
549
550                         .ifqadv_i2  (ifc_inv_ifqadv_i2),
551
552                         .ifd_ifc_4bpkt_i2         (ifd_ifc_4bpkt_i2),
553                               .fcl_ifq_thr_s1           (fcl_ifq_thr_s1),
554                               .ifc_fsm_imiss_thisthr_s  (icmiss_thr_s[0]),         
555                               .ifc_fsm_milhit_s         (any_milhit_qual_s),
556
557                               .ifc_fsm_hiton_thismil_s  (milhit_to_thr_s[0]),   
558
559                               .ifc_fsm_pcxaccept_thisthr(pcx_accept_d[0]),
560                         .ifc_fsm_miladdr4         (ifd_ifc_miladdr4_i2[0]),
561
562                               .clk                      (clk),
563                         .se                       (se),
564                         .si                       (si),
565                               .reset                    (ifq_reset),
566
567                         .so                       (),
568
569                               .ifc_fsm_err_thisthr      (errthr_d1[0]),
570                       
571                               // outputs       
572                         .fsm_ifc_errreq           (err_req[0]),
573                 
574                               .fsm_ifc_wrt_tir          (wrt_tir[0]),
575                               .fsm_ifc_comp_valid       (comp_valid_s[0]),
576                               .fsm_ifc_mil_valid        (mil_valid_s[0]),
577                               .fsm_ifc_mil_cancel       (mil_cancel[0]),
578                         .fsm_ifc_milstate         (mil0_state[3:0]),
579                       
580                               .fsm_ifc_thr_ready        (mil_thr_ready[0]),
581                               .fsm_ifc_pred_rdy         (pred_rdy_i2[0]),
582                               .fsm_ifc_pcxreq           (pcxreq_s[0]),       
583                               .fsm_ifc_addrbit4_i2      (fill_addr4_i2[0]),
584                               .fsm_ifc_milchld          (milchld0[2:0]));
585   
586
587   sparc_ifu_milfsm mil1(
588                         .ifc_fsm_can_thisthr      (fcl_ifq_canthr[1]),       
589                         //        .ifc_fsm_orphan_thisthr   (orphan_thr_d1[1]),     
590
591                               .ifc_fsm_fill_thisthr_i2  (fill_retn_thr_i2[1]),   
592                               .ifc_fsm_wr_complete_f    (wr_complete_f[1]),         
593     
594                         .ifqadv_i2  (ifc_inv_ifqadv_i2),
595
596                         .ifd_ifc_4bpkt_i2         (ifd_ifc_4bpkt_i2),
597                               .fcl_ifq_thr_s1           (fcl_ifq_thr_s1),             
598                               .ifc_fsm_milhit_s         (any_milhit_qual_s),           
599                               .ifc_fsm_hiton_thismil_s (milhit_to_thr_s[1]),   
600                               .ifc_fsm_imiss_thisthr_s   (icmiss_thr_s[1]),         
601
602                               .ifc_fsm_pcxaccept_thisthr   (pcx_accept_d[1]),     
603                         //        .ifc_fsm_reqq_empty       (reqq_empty),         
604                         .ifc_fsm_miladdr4         (ifd_ifc_miladdr4_i2[1]),
605
606                               .clk                      (clk),
607                         .se                       (se),
608                         .si                       (si),
609                               .reset                    (ifq_reset),
610
611                               .ifc_fsm_err_thisthr      (errthr_d1[1]),
612                       
613                               // outputs       
614                         .fsm_ifc_errreq           (err_req[1]),
615
616                               .fsm_ifc_wrt_tir          (wrt_tir[1]),
617                         .so                       (),     
618                         //        .fsm_ifc_cm_pending       (can_miss_pending[1]),
619                         //        .fsm_ifc_delay_mil        (delay_mil[1]),
620                               .fsm_ifc_comp_valid       (comp_valid_s[1]), 
621                               .fsm_ifc_mil_valid        (mil_valid_s[1]),
622                               .fsm_ifc_mil_cancel       (mil_cancel[1]),
623                         .fsm_ifc_milstate         (mil1_state[3:0]),
624
625                               .fsm_ifc_pcxreq           (pcxreq_s[1]),       
626                               .fsm_ifc_thr_ready        (mil_thr_ready[1]),
627                               .fsm_ifc_pred_rdy         (pred_rdy_i2[1]),
628                               .fsm_ifc_addrbit4_i2      (fill_addr4_i2[1]), 
629                               .fsm_ifc_milchld          (milchld1[2:0]));
630
631   sparc_ifu_milfsm mil2(
632                         .ifc_fsm_can_thisthr      (fcl_ifq_canthr[2]),       
633                         //        .ifc_fsm_orphan_thisthr   (orphan_thr_d1[2]),     
634
635                               .ifc_fsm_fill_thisthr_i2  (fill_retn_thr_i2[2]),
636                               .ifc_fsm_wr_complete_f    (wr_complete_f[2]),         
637                       
638                         .ifqadv_i2  (ifc_inv_ifqadv_i2),
639
640                         .ifd_ifc_4bpkt_i2         (ifd_ifc_4bpkt_i2),
641                               .fcl_ifq_thr_s1           (fcl_ifq_thr_s1),             
642                               .ifc_fsm_milhit_s         (any_milhit_qual_s),           
643                               .ifc_fsm_hiton_thismil_s (milhit_to_thr_s[2]),   
644                               .ifc_fsm_imiss_thisthr_s  (icmiss_thr_s[2]),         
645
646                               .ifc_fsm_pcxaccept_thisthr(pcx_accept_d[2]),     
647                         //        .ifc_fsm_reqq_empty       (reqq_empty),         
648
649                         .ifc_fsm_miladdr4         (ifd_ifc_miladdr4_i2[2]),
650
651                               .clk                      (clk),
652                         .se                       (se),
653                         .si                       (si),
654                               .reset                    (ifq_reset),
655
656                               .ifc_fsm_err_thisthr      (errthr_d1[2]),
657                       
658                               // outputs       
659                         .fsm_ifc_errreq           (err_req[2]),
660
661                         .so                       (),     
662                         //        .fsm_ifc_cm_pending       (can_miss_pending[2]),
663                         //        .fsm_ifc_delay_mil        (delay_mil[2]),
664                               .fsm_ifc_wrt_tir          (wrt_tir[2]),
665                               .fsm_ifc_comp_valid       (comp_valid_s[2]),
666                               .fsm_ifc_mil_valid        (mil_valid_s[2]),
667                               .fsm_ifc_mil_cancel       (mil_cancel[2]),
668                         .fsm_ifc_milstate         (mil2_state[3:0]),
669                       
670                               .fsm_ifc_pcxreq           (pcxreq_s[2]),       
671                               .fsm_ifc_thr_ready        (mil_thr_ready[2]),
672                               .fsm_ifc_pred_rdy         (pred_rdy_i2[2]),
673                               .fsm_ifc_addrbit4_i2      (fill_addr4_i2[2]), 
674                               .fsm_ifc_milchld          (milchld2[2:0]));
675
676
677   sparc_ifu_milfsm mil3(
678                         .ifc_fsm_can_thisthr      (fcl_ifq_canthr[3]),       
679                         //        .ifc_fsm_orphan_thisthr   (orphan_thr_d1[3]),     
680
681                               .ifc_fsm_fill_thisthr_i2  (fill_retn_thr_i2[3]),
682                               .ifc_fsm_wr_complete_f    (wr_complete_f[3]), 
683                       
684                         .ifqadv_i2  (ifc_inv_ifqadv_i2),
685
686                         .ifd_ifc_4bpkt_i2         (ifd_ifc_4bpkt_i2),
687                               .fcl_ifq_thr_s1           (fcl_ifq_thr_s1),             
688                               .ifc_fsm_milhit_s         (any_milhit_qual_s),           
689                               .ifc_fsm_hiton_thismil_s (milhit_to_thr_s[3]),   
690                               .ifc_fsm_imiss_thisthr_s   (icmiss_thr_s[3]),         
691
692                               .ifc_fsm_pcxaccept_thisthr(pcx_accept_d[3]),     
693                         //        .ifc_fsm_reqq_empty       (reqq_empty),         
694
695                         .ifc_fsm_miladdr4         (ifd_ifc_miladdr4_i2[3]),
696
697                               .clk                      (clk),
698                         .se                       (se),
699                         .si                       (si),
700                               .reset                    (ifq_reset),
701
702                               .ifc_fsm_err_thisthr      (errthr_d1[3]),
703                       
704                               // outputs       
705                         .fsm_ifc_errreq           (err_req[3]),
706
707                         .so                       (), 
708                         //        .fsm_ifc_cm_pending       (can_miss_pending[3]),
709                         //        .fsm_ifc_delay_mil        (delay_mil[3]),
710                               .fsm_ifc_wrt_tir          (wrt_tir[3]),
711                               .fsm_ifc_comp_valid       (comp_valid_s[3]),
712                               .fsm_ifc_mil_valid        (mil_valid_s[3]),
713                               .fsm_ifc_mil_cancel       (mil_cancel[3]),
714                         .fsm_ifc_milstate         (mil3_state[3:0]),
715                       
716                               .fsm_ifc_pcxreq           (pcxreq_s[3]),           
717                               .fsm_ifc_thr_ready        (mil_thr_ready[3]),
718                               .fsm_ifc_pred_rdy         (pred_rdy_i2[3]),
719                               .fsm_ifc_addrbit4_i2      (fill_addr4_i2[3]),   
720                               .fsm_ifc_milchld          (milchld3[2:0]));
721
722
723   
724//-------------------------------------------
725// Fill Return Control (IFU interfac to CPX)
726//-------------------------------------------
727
728   // use soffm2 for lower setup
729   dffe_s #(4) cpxreq_reg(.din (ifd_ifc_cpxreq_nxt),
730                        .q   (cpxreq_i2),
731                        .en  (ifqadv_i1),
732                        .clk (clk), .se(se), .si(), .so());
733   dffe_s #(2) cpxthr_reg(.din (ifd_ifc_cpxthr_nxt),
734                        .q   (cpxthr_i2),
735                        .en  (ifqadv_i1),
736                        .clk (clk), .se(se), .si(), .so());
737   
738
739   // Decode CPX request
740   assign imissrtn_i1 = (ifd_ifc_cpxreq_i1 == `CPX_IFILLPKT) ? 1'b1 : 1'b0;   
741   assign imissrtn_i2 = (cpxreq_i2 == `IFILL_RET) ? ifd_ifc_cpxvld_i2 : 1'b0;
742
743   assign imissrtn_next_i2 = ifc_inv_ifqadv_i2 ? imissrtn_i2 : imissrtn_f;
744   
745   dff_s #(1) imsf_ff(.din (imissrtn_next_i2),
746                    .q   (imissrtn_f),
747                    .clk (clk), .se (se), .si(), .so());
748   
749   // Determine if this is an IFILL RET to one of the threads
750   assign fill_retn_thr_i2 = dfthr_i2 & {4{imissrtn_i2}};
751   
752   // decode current icache fill thread
753   assign dfthr_f[0] = ~filltid_f[1] & ~filltid_f[0];
754   assign dfthr_f[1] = ~filltid_f[1] &  filltid_f[0];
755   assign dfthr_f[2] =  filltid_f[1] & ~filltid_f[0];
756   assign dfthr_f[3] =  filltid_f[1] &  filltid_f[0];
757
758//`ifdef IFU_SAT
759//   assign ifc_ifd_uncached_s = fcl_ifq_icache_en_s_l;   
760//`else   
761//`endif
762
763   assign uncached_s = ifd_ifc_newdestid_s[2] | fcl_ifq_icache_en_s_l;
764
765   // timing fix: keep nc bit locally instead of in DP
766   assign mil_nc_vec_nxt = ({4{uncached_s & fcl_ifq_rdreq_s1}} & 
767                              thr_s1 & ~errthr_d1 |
768                              mil_nc_vec & (mil_valid_s |
769                                            errthr_d1));
770
771   dff_s #(4) nc_reg(.din (mil_nc_vec_nxt),
772                   .q   (mil_nc_vec),
773                   .clk (clk), .se(se), .si(), .so());
774
775   assign mil_nc_i2 = (dfthr_i2[0] & mil_nc_vec[0] |
776                       dfthr_i2[1] & mil_nc_vec[1] |
777                       dfthr_i2[2] & mil_nc_vec[2] |
778                       dfthr_i2[3] & mil_nc_vec[3]);
779
780   assign mil_nc_d = (dpcxthr_d[0] & mil_nc_vec[0] |
781                      dpcxthr_d[1] & mil_nc_vec[1] |
782                      dpcxthr_d[2] & mil_nc_vec[2] |
783                      dpcxthr_d[3] & mil_nc_vec[3]);
784
785   dff_s #(1) nce_ff(.din (mil_nc_d),
786                   .q   (mil_nc_e),
787                   .clk (clk), .se(se), .si(), .so());
788   assign ifc_ifd_uncached_e = mil_nc_e;
789   
790//   assign uncached_fill_i2 = ifd_ifc_uncached_i2 | ifd_ifc_cpxnc_i2;
791   assign uncached_fill_i2 = mil_nc_i2 | ifd_ifc_cpxnc_i2;   
792   
793   // uncached fill -- do not write to icache
794   assign uncached_i2 = ifc_inv_ifqadv_i2 ? 
795                                  uncached_fill_i2 : uncached_f;
796
797   dff_s unc_ff(.din (uncached_i2),
798                    .q   (uncached_f),
799                    .clk (clk),
800                    .se  (se), .si(), .so());
801
802   // Determine if Icache write is done or
803   // if none is necessary (i.e. if this is a child process or NC)
804   assign wr_complete_f = dfthr_f & {4{(wrreq_f & ifc_inv_ifqadv_i2 | 
805                                        milchld_vld_f |
806                                                                uncached_f) & imissrtn_f}};
807
808   // State Machine Outputs
809   // One of these has to be chosen for I2 stage operation
810   mux4ds #(3)  i2out_mux(.dout  (i2out),
811                       .in0   (milchld0),
812                       .in1   (milchld1),
813                       .in2   (milchld2),
814                       .in3   (milchld3),
815                       .sel0  (dfthr_i2[0]),
816                       .sel1  (dfthr_i2[1]),
817                       .sel2  (dfthr_i2[2]),
818                       .sel3  (dfthr_i2[3]));
819
820   assign mil_vld_i2 = (mil_valid_s[0] & dfthr_i2[0] |
821                        mil_valid_s[1] & dfthr_i2[1] |
822                        mil_valid_s[2] & dfthr_i2[2] |
823                        mil_valid_s[3] & dfthr_i2[3]);
824
825   assign mil_uncan_i2 = (mil_valid_s[0] & ~mil_cancel[0] & dfthr_i2[0] |
826                          mil_valid_s[1] & ~mil_cancel[1] & dfthr_i2[1] |
827                          mil_valid_s[2] & ~mil_cancel[2] & dfthr_i2[2] |
828                          mil_valid_s[3] & ~mil_cancel[3] & dfthr_i2[3]);
829
830   // Don't make a wrreq if this is a child entry.  However, if this is
831   // a child and the parent was cancelled, then go ahead and
832   // write... is this really necessary?  Not for functionality.
833   // 3/19: parent will write even if cancelled.  So never write child
834   assign next_wrreq_i2 = imissrtn_i2 & mil_vld_i2 & ~uncached_fill_i2 &
835                          ~milchld_vld_i2 & ~ifd_ifc_4bpkt_i2; // was: iobpkt_i2
836
837   assign addrbit4_i2 = (milfthr_i2[0] & fill_addr4_i2[0] |
838                         milfthr_i2[1] & fill_addr4_i2[1] |
839                         milfthr_i2[2] & fill_addr4_i2[2] |
840                         milfthr_i2[3] & fill_addr4_i2[3]);
841
842   assign addrbit4_nxt_i2= ifc_inv_ifqadv_i2 ? addrbit4_i2 : filladdr4_f;
843   dff_s #(1) ab4_ff(.din (addrbit4_nxt_i2),
844                   .q   (filladdr4_f),
845                   .clk (clk),
846                   .se  (se), .si(), .so());
847   
848   assign ifc_ifd_filladdr4_i2 = addrbit4_nxt_i2;
849
850   assign next_milchld = ifc_inv_ifqadv_i2 ? 
851                                  {(i2out[2] & imissrtn_i2), i2out[1:0]} :
852                                  milchld_d1;
853
854   // After the packet is processed, the child entry in the MIL,
855   // pointed to by the reg below is processed next (if valid)
856   dffr_s #(3)  milchldd_reg(.din  (next_milchld),
857                                             .clk  (clk),
858                                             .rst  (ifq_reset),
859                                             .q    (milchld_d1),
860                                             .se   (se), .si(), .so());
861
862   assign milchld_vld_i2 = milchld_d1[2];
863   assign next_milchld_i2 = ifc_inv_ifqadv_i2 ? milchld_d1[2] :
864                                                      milchld_vld_f;
865   
866   dffr_s #(1) milchldf_ff(.din  (next_milchld_i2),
867                       .q    (milchld_vld_f),
868                       .clk  (clk),
869                       .rst  (ifq_reset),
870                       .se   (se), .si(), .so());
871
872   // need this to avoid x's in the simulation
873//   assign cpxthrid_adj_i2 = ifd_ifc_cpxthr_i2 &
874//                                {2{ifd_ifc_cpxreq_i2[`CPX_RQ_SIZE]}};
875
876   // Determine if we should process the child or a new entry
877//   assign next_thr_sel_milchld_i2 = ifc_inv_ifqadv_i2 & milchld_vld_i2 &
878//                                  ~errpkt_i2;
879//   assign next_thr_sel_milchld_i2 = milchld_vld_i2 & ~errpkt_i2;
880   
881   
882   // if previous mil entry had a child, process that next
883//   mux2ds  #(2) filltid_mux(.dout  (filltid_i2),
884//                                      .in0   (cpxthrid_adj_i2),
885//                                      .in1   (milchld_d1[1:0]),
886//                                      .sel0  (~milchld_vld_i2),
887//                                      .sel1  (milchld_vld_i2));
888   assign filltid_i2 = milchld_vld_i2 ? milchld_d1[1:0] :
889                                        cpxthr_i2[1:0];
890
891   // decode fill thread  (either cpx thread or MIL child thread from above)
892   // need to qual with valid bit to avoid X's in simulation
893//   assign cpxvld_or_milc_i2 = ifd_ifc_cpxreq_i2[`CPX_RQ_SIZE] | milchld_vld_i2;
894   assign dfthr_i2[0] = ~filltid_i2[1] & ~filltid_i2[0];
895   assign dfthr_i2[1] = ~filltid_i2[1] &  filltid_i2[0];
896   assign dfthr_i2[2] =  filltid_i2[1] & ~filltid_i2[0];
897   assign dfthr_i2[3] =  filltid_i2[1] &  filltid_i2[0];
898
899   dp_mux2es  #(2)  thren_mux(.dout (next_filltid_i2),
900                                                .in0  (filltid_f),
901                                                .in1  (filltid_i2),
902                                                .sel  (ifc_inv_ifqadv_i2));
903
904   dff_s #(2) wrthr_reg(.din  (next_filltid_i2),
905                                  .clk  (clk),
906                                  .q    (filltid_f),
907                                  .se   (se), .si(), .so());   
908
909
910   dp_mux2es  #(4)  dthren_mux(.dout (dfthr_next_i2),
911                                                 .in0  (dfthr_f),
912                                                 .in1  (dfthr_i2),
913                                                 .sel  (ifc_inv_ifqadv_i2));
914   
915
916   // Early start of threads
917   // Do we need a control bit to turn this off?
918   // -- do it in SWL
919   assign ifq_dtu_pred_rdy =  pred_rdy_i2 & {dfthr_next_i2[3:0]} &
920                              {4{imissrtn_next_i2}};
921
922// If timing is a problem resort to:
923//   assign ifq_dtu_pred_rdy =  pred_rdy_i2 & {4{ifc_inv_ifqadv_i2}} &
924//                              dfthr_i2 & {4{imissrtn_i2}};
925   
926   
927
928   // pick 16B half cache line which contains the instruction we want
929//   assign fill_this16b = ~(ifc_ifd_filladdr4_i2 ^ ifd_ifc_missaddr4_i2);
930                         // | ifd_ifc_4bpkt_i2;
931
932   // write to thread instruction register
933//   assign ifq_fcl_fill_thr = wrt_tir & {4{fill_this16b | ifd_ifc_4bpkt_i2}};
934//   assign ifq_fcl_fill_thr = wrt_tir & {4{fill_this16b}};
935   assign ifq_fcl_fill_thr = wrt_tir | thr_d1 & {4{itlberr_d1 & 
936                                                   ~canthr_d1 & 
937                                                   icmiss_d1 & 
938                                                   ~canthr_s1_del1}};
939
940   // Select instruction to send to TIR
941   // TBD: Need to find out how the inst from boot PROM is aligned -- Done
942   // From kinkee 02/21/03: It is aligned to the correct 4B of the 16B
943   // packet.  The other locations are X.
944   assign finst0[0] = ~ifd_ifc_instoffset0[1] & ~ifd_ifc_instoffset0[0];
945   assign finst0[1] = ~ifd_ifc_instoffset0[1] &  ifd_ifc_instoffset0[0];
946   assign finst0[2] =  ifd_ifc_instoffset0[1] & ~ifd_ifc_instoffset0[0];
947   assign finst0[3] =  ifd_ifc_instoffset0[1] &  ifd_ifc_instoffset0[0];
948
949   assign finst1[0] = ~ifd_ifc_instoffset1[1] & ~ifd_ifc_instoffset1[0];
950   assign finst1[1] = ~ifd_ifc_instoffset1[1] &  ifd_ifc_instoffset1[0];
951   assign finst1[2] =  ifd_ifc_instoffset1[1] & ~ifd_ifc_instoffset1[0];
952   assign finst1[3] =  ifd_ifc_instoffset1[1] &  ifd_ifc_instoffset1[0];
953
954   assign finst2[0] = ~ifd_ifc_instoffset2[1] & ~ifd_ifc_instoffset2[0];
955   assign finst2[1] = ~ifd_ifc_instoffset2[1] &  ifd_ifc_instoffset2[0];
956   assign finst2[2] =  ifd_ifc_instoffset2[1] & ~ifd_ifc_instoffset2[0];
957   assign finst2[3] =  ifd_ifc_instoffset2[1] &  ifd_ifc_instoffset2[0];
958
959   assign finst3[0] = ~ifd_ifc_instoffset3[1] & ~ifd_ifc_instoffset3[0];
960   assign finst3[1] = ~ifd_ifc_instoffset3[1] &  ifd_ifc_instoffset3[0];
961   assign finst3[2] =  ifd_ifc_instoffset3[1] & ~ifd_ifc_instoffset3[0];
962   assign finst3[3] =  ifd_ifc_instoffset3[1] &  ifd_ifc_instoffset3[0];
963
964//   mux4ds #(4) finst_mx(.dout (finst_i2),
965//                        .in0  (finst0),
966//                        .in1  (finst1),
967//                        .in2  (finst2),
968//                        .in3  (finst3),
969//                        .sel0 (dfthr_i2[0]),
970//                        .sel1 (dfthr_i2[1]),
971//                        .sel2 (dfthr_i2[2]),
972//                        .sel3 (dfthr_i2[3]));
973
974   wire [3:0] finst_ev,
975              finst_od,
976              finst_i2_l;
977   wire [1:0] filltid_i2_l;
978   bw_u1_inv_10x UZsize_ftid_bf0(.z (filltid_i2_l[0]),
979                                 .a (filltid_i2[0]));
980   bw_u1_inv_20x UZsize_ftid_bf1(.z (filltid_i2_l[1]),
981                                 .a (filltid_i2[1]));
982   // use bw_u1_muxi21_4x
983   assign finst_ev = filltid_i2_l[1] ? finst0 : finst2;
984   assign finst_od = filltid_i2_l[1] ? finst1 : finst3;
985   assign finst_i2_l = filltid_i2_l[0] ? (~finst_ev) : (~finst_od);
986   assign finst_i2 = ~finst_i2_l;
987
988   assign ifc_ifd_finst_sel_l = ~finst_i2;
989
990   // pick MIL entry corresponding to current thread
991   assign milfthr_i2[0] = ~cpxthr_i2[1] & ~cpxthr_i2[0];
992   assign milfthr_i2[1] = ~cpxthr_i2[1] &  cpxthr_i2[0];
993   assign milfthr_i2[2] =  cpxthr_i2[1] & ~cpxthr_i2[0];
994   assign milfthr_i2[3] =  cpxthr_i2[1] &  cpxthr_i2[0];
995   assign ifc_ifd_milfill_sel_i2_l = ~milfthr_i2;
996
997   // write request
998   // assign ifq_fcl_wrreq_bf = ifc_inv_ifqadv_i2 ? next_wrreq_i2 : wrreq_f;
999   // assign ifq_fcl_wrreq_bf = ~ifc_inv_ifqadv_i2 | next_wrreq_i2;
1000   assign ifq_fcl_wrreq_bf = wrreq_f & ~ifc_inv_ifqadv_i2 | next_wrreq_i2;
1001   
1002   dffr_s #(1) wrreq_ff(.din (ifq_fcl_wrreq_bf),
1003                                  .clk (clk),
1004                                  .q   (wrreq_f),
1005                                  .rst (ifq_reset),
1006                                  .se  (se), .si(), .so());
1007
1008   // starvation check
1009   // if a write is not granted for 24 cycles, sound the alarm
1010   sparc_ifu_ctr5 starv_ctr(
1011                                              // Outputs
1012                                              .limit    (starv_alert),
1013                                              .so       (so),
1014                                              // Inputs
1015                                              .clk      (clk),
1016                                              .se       (se),
1017                                              .si       (si),
1018                                              .rst_ctr_l (rst_starv_ctr_l));
1019   assign rst_starv_ctr_l = ~ifq_reset & wrreq_f;
1020
1021   // advance in i2 when a write ack is received or if not a fill
1022   // Can help timing of this signal by doing
1023   //  ifqadv_nxt = ~ifq_fcl_wrreq_bf | fcl_icd_index_sel_ifq_bf
1024   assign access_grant_l = ~fcl_ifq_grant_bf;
1025   bw_u1_nand2_2x UZsize_acc_n2(.z (ifqadvi2_nxt),
1026                                .a (ifq_fcl_wrreq_bf),
1027                                .b (access_grant_l));
1028   dff_s #(1) qadv_ff(.din (ifqadvi2_nxt),
1029                    .q   (ifqadv_i2_ff),
1030                    .clk (clk), .se(se), .si(), .so());
1031   assign ifc_inv_ifqadv_i2 = ifqadv_i2_ff;
1032
1033   
1034
1035   // advance in i1 when a write ack is received AND there are no
1036   // child threads to be taken care of
1037   assign ifqadv_i1 = (ifc_inv_ifqadv_i2 & ~next_milchld[2] & ~fwd_stall) | 
1038                        ifq_reset; 
1039
1040//-----------------------------------
1041// Errors and Error Packet
1042//-----------------------------------   
1043
1044   assign errpkt_i1 = (ifd_ifc_cpxreq_i1 == `CPX_ERRPKT) ? 1'b1 : 1'b0;
1045   assign errpkt_i2 = (cpxreq_i2 == `ERR_RET) ? ifd_ifc_cpxvld_i2 : 1'b0;
1046
1047   // Reported Errors are not logged in ERB
1048   assign ce_rep_i2 = ifd_ifc_cpxce_i2 & ~ifd_ifc_cpxue_i2 & errpkt_i2 &
1049                            ifc_inv_ifqadv_i2;
1050   assign ue_rep_i2 = ifd_ifc_cpxue_i2 & errpkt_i2 & ifc_inv_ifqadv_i2;
1051
1052   dff_s #(1) cerep_ff(.din (ce_rep_i2),
1053                                 .q   (ifq_erb_ce_rep),
1054                                 .clk (clk), .se(se), .si(), .so());
1055   dff_s #(1) uerep_ff(.din (ue_rep_i2),
1056                                 .q   (ifq_erb_ue_rep),
1057                                 .clk (clk), .se(se), .si(), .so());
1058
1059//   dff #(2) ertid_reg(.din (filltid_i2),
1060//                                .q   (ifq_erb_l2err_tid),
1061//                                .clk (clk), .se(se), .si(), .so());
1062   // send thread id one cycle earlier to help crit path
1063   assign ifq_erb_l2err_tid = filltid_i2;
1064   
1065   // Ifetch Errors are logged in ERB
1066   assign l2_ce_i2 = ifd_ifc_cpxce_i2 & ~ifd_ifc_cpxue_i2 & imissrtn_i2 &
1067                           ifc_inv_ifqadv_i2 & mil_uncan_i2;
1068   assign l2_ue_i2 = ifd_ifc_cpxue_i2 & imissrtn_i2 & ~ifd_ifc_iobpkt_i2 &
1069                           ifc_inv_ifqadv_i2 & mil_uncan_i2;
1070   assign io_ue_i2 = ifd_ifc_cpxue_i2 & imissrtn_i2 & ifd_ifc_iobpkt_i2 &
1071                           ifc_inv_ifqadv_i2 & mil_uncan_i2;
1072
1073   dff_s #(1) l2ce_ff(.din (l2_ce_i2),
1074                                .q   (ifq_erb_ifet_ce),
1075                                .clk (clk), .se(se), .si(), .so());
1076   dff_s #(1) l2ue_ff(.din (l2_ue_i2),
1077                                .q   (ifq_erb_l2_ue),
1078                                .clk (clk), .se(se), .si(), .so());
1079   dff_s #(1) ioue_ff(.din (io_ue_i2),
1080                                .q   (ifq_erb_io_ue),
1081                                .clk (clk), .se(se), .si(), .so());
1082
1083   assign l2_miss_i2 = ifd_ifc_cpxms_i2 & imissrtn_i2 & ifc_inv_ifqadv_i2;
1084   dff_s #(1) l2ms_ff(.din (l2_miss_i2),
1085                                .q   (l2_miss_f),
1086                                .clk (clk), .se(se), .si(), .so());
1087
1088   assign ifu_tlu_l2imiss = dfthr_f & {4{l2_miss_f}};
1089   
1090//--------------------------------------------
1091// Miss Request Control (IFU interface to PCX)
1092//--------------------------------------------
1093
1094   // decode imiss thread
1095   assign thr_s1[0] = ~fcl_ifq_thr_s1[0] & ~fcl_ifq_thr_s1[1];
1096   assign thr_s1[1] =  fcl_ifq_thr_s1[0] & ~fcl_ifq_thr_s1[1];
1097   assign thr_s1[2] = ~fcl_ifq_thr_s1[0] & fcl_ifq_thr_s1[1];
1098   assign thr_s1[3] =  fcl_ifq_thr_s1[0] & fcl_ifq_thr_s1[1];
1099
1100   // signal ic miss to thread MIL state machines
1101   assign icmiss_thr_s = {4{fcl_ifq_icmiss_s1 & ~block_fetch_s1}} & thr_s1 & 
1102                               ~icmiss_thr_d;
1103
1104//   dff #(4) icmsreg(.din  (icmiss_thr_s),
1105//                              .clk  (clk),
1106//                              .q    (icmiss_thr_d),
1107//                              .se   (se), .si(), .so());
1108
1109   dff_s #(1) icmsd_ff(.din  (fcl_ifq_icmiss_s1),
1110                                 .clk  (clk),
1111                                 .q    (icmiss_d1),
1112                                 .se   (se), .si(), .so());
1113
1114   assign icmiss_qual_d1 = icmiss_d1 & ~(thr_match_d1e1 & ifeterr_e1);
1115
1116   // bug 5926
1117   assign n763 = ~ifd_ifc_newdestid_s[2];
1118   dff_s #(1) iosp_ff(.din (n763),
1119                                .q   (iosp_d1_l),
1120                                .clk (clk), .se(se), .si(), .so());
1121   
1122   assign icmiss_thr_d = {4{icmiss_d1 | erb_ifq_ifeterr_d1 & iosp_d1_l}} & thr_d1 |
1123                         {4{ifeterr_e1}} & thr_e1;
1124   
1125   dff_s #(4) thrdreg(.din  (thr_s1),
1126                                .clk  (clk),
1127                                .q    (thr_d1),
1128                                .se   (se), .si(), .so());
1129
1130   dff_s #(4) threreg(.din  (thr_d1),
1131                                .clk  (clk),
1132                                .q    (thr_e1),
1133                                .se   (se), .si(), .so());
1134
1135   dff_s #(1) erre_ff(.din (ifeterr_qual_d1),
1136                    .q   (ifeterr_e1),
1137                    .clk (clk), .se(se), .si(), .so());
1138   assign thr_match_d1e1 =  (thr_d1[0] & thr_e1[0] |
1139                             thr_d1[1] & thr_e1[1] |
1140                             thr_d1[2] & thr_e1[2] |
1141                             thr_d1[3] & thr_e1[3]);
1142
1143//   assign ifeterr_qual_d1 = ~(thr_match_d1e1 & ifeterr_e1) & ~canthr_d1 &
1144//                               erb_ifq_ifeterr_d1;
1145   assign ifeterr_qual_d1 = ~(thr_match_d1e1 & ifeterr_e1) & 
1146                               erb_ifq_ifeterr_d1 & iosp_d1_l;
1147     
1148   assign errthr_d1 = (thr_d1 & {4{ifeterr_qual_d1 & ~block_fetch_d1}});
1149   
1150   // If misses to same thread, (in successive cycles), ignore
1151   assign ifc_ifd_ldmil_sel_new = (thr_s1 & {4{fcl_ifq_rdreq_s1}} &
1152                                                           ~errthr_d1 & ~mil_valid_s);
1153
1154   // Check hit in MIL -- a thread cannot hit
1155   //   1. its own MIL
1156   //   2. an MIL that is being filled
1157   //   3. if it is to an IOB line
1158   assign qualhit_or_io_s = ifd_ifc_milhit_s & comp_valid_s & 
1159                                  ~thr_s1 & 
1160                            ~fill_retn_thr_i2 & 
1161                            {4{~ifd_ifc_newdestid_s[2]}};
1162
1163   assign any_qualhit_or_io_s = (qualhit_or_io_s[0] |
1164                                             qualhit_or_io_s[1] |
1165                                             qualhit_or_io_s[2] |
1166                                             qualhit_or_io_s[3]);
1167   
1168//   assign milhit_qual_s = ifd_ifc_milhit_s & comp_valid_s &
1169//                              ~thr_s1 &
1170//                          ~fill_retn_thr_i2 &
1171//                          {4{~ifd_ifc_newdestid_s[2]}};
1172   
1173//   assign any_milhit_qual_s = any_qualhit_or_io_s & ~ifd_ifc_newdestid_s[2];
1174   assign any_milhit_qual_s = any_qualhit_or_io_s;   
1175   
1176   // Generate Replacement Way
1177   // Make sure a req doesn't go out to a different way than
1178   // what is pending
1179   assign milhit_vec_s = ifd_ifc_milhit_s & (mil_valid_s | errthr_d1);
1180   assign any_milhit_s = (|milhit_vec_s[3:0]);
1181   
1182//   assign mil_repway_s = (ifd_ifc_mil_repway_s[7:6] & {2{milhit_vec_s[3]}} |
1183//                          ifd_ifc_mil_repway_s[5:4] & {2{milhit_vec_s[2]}} |
1184//                          ifd_ifc_mil_repway_s[3:2] & {2{milhit_vec_s[1]}} |
1185//                          ifd_ifc_mil_repway_s[1:0] & {2{milhit_vec_s[0]}});
1186
1187//   assign ifc_ifd_repway_s = any_milhit_s ? mil_repway_s : rand_repway_s;
1188   assign ifc_ifd_repway_s = rand_repway_s;   
1189
1190   // pick any way at random
1191   // reset with dbg_init as well
1192   sparc_ifu_lfsr5  lfsr(.out (rand_repway_s),
1193                                           .clk  (clk),
1194                                           .advance (fcl_ifq_icmiss_s1),
1195                                           .reset (rst_way_lfsr),
1196                                           .se (se),
1197                                           .si (si),
1198                                           .so (so));
1199
1200   assign rst_way_lfsr = ifq_reset | lsu_ifu_direct_map_l1 | ~gdbginit_l;
1201
1202   // check if miss req is valid in a given pipe stage
1203   assign canthr_s1 = (fcl_ifq_canthr[0] & thr_s1[0] |
1204                       fcl_ifq_canthr[1] & thr_s1[1] |
1205                       fcl_ifq_canthr[2] & thr_s1[2] |
1206                       fcl_ifq_canthr[3] & thr_s1[3]);
1207   assign canthr_d1 = (fcl_ifq_canthr[0] & thr_d1[0] |
1208                       fcl_ifq_canthr[1] & thr_d1[1] |
1209                       fcl_ifq_canthr[2] & thr_d1[2] |
1210                       fcl_ifq_canthr[3] & thr_d1[3]);
1211   
1212   // retry a fetch if the imiss occurs while it is being filled
1213//   assign block_fetch_s1 = any_milhit_s &
1214//                           ~(any_qualhit_or_io_s | ifd_ifc_newdestid_s[2]) |
1215//                           dtu_ifq_kill_latest_d;
1216   assign block_fetch_s1 = any_milhit_s & ~ifd_ifc_newdestid_s[2] &
1217                           ~any_qualhit_or_io_s | 
1218                           dtu_ifq_kill_latest_d |
1219                           erb_ifq_itlberr_s1;
1220
1221   dff_s #(1) bfd_ff(.din (block_fetch_s1),
1222                   .q   (block_fetch_d1),
1223                   .clk (clk), .se(se), .si(), .so());
1224
1225   dff_s #(1) tlbe_ff(.din (erb_ifq_itlberr_s1),
1226                    .q   (itlberr_d1),
1227                    .clk (clk), .se(se), .si(), .so());
1228   
1229//   assign retry_rdy_s1 = block_fetch_s1 & fcl_ifq_icmiss_s1;
1230//   dff #(1) retrd_ff(.din (retry_rdy_s1),
1231//                     .q   (retry_rdy_d1),
1232//                     .clk (clk), .se(se), .si(), .so());
1233   
1234   assign retry_rdy_final_d1 = block_fetch_d1 & (icmiss_qual_d1 | 
1235                                                 ifeterr_qual_d1);
1236   dff_s #(1) retre_ff(.din (retry_rdy_final_d1),
1237                     .q   (retry_rdy_e1),
1238                     .clk (clk), .se(se), .si(), .so());
1239
1240   assign all_retry_rdy_e1 = {4{retry_rdy_e1}} & thr_e1;
1241   dff_s #(4) retrm_reg(.din (all_retry_rdy_e1),
1242                      .q   (all_retry_rdy_m1),
1243                     .clk (clk), .se(se), .si(), .so());
1244   
1245   assign ifq_dtu_thrrdy = mil_thr_ready | all_retry_rdy_m1;
1246
1247//   assign retry_fetch_s1 = block_fetch_s1 & fcl_ifq_icmiss_s1 &
1248//                           ~canthr_s1;
1249   dff_s #(1) cans_ff(.din (canthr_s1),
1250                    .q   (canthr_s1_del1),
1251                    .clk (clk), .se(se), .si(), .so());
1252
1253   assign ifq_fcl_flush_sonly_e = (block_fetch_d1 & 
1254                                   (icmiss_qual_d1 & ~canthr_s1_del1 |
1255                                    ifeterr_qual_d1) & 
1256                                   ~canthr_d1 & ~itlberr_d1);
1257
1258   // Determine which thread's MIL was hit, if at all
1259   // first check if this really was an imiss
1260   assign icmiss_for_milchk = thr_s1 & ~icmiss_thr_d & ~errthr_d1;
1261   assign icmiss_qual_s = (|icmiss_for_milchk[3:0]) & fcl_ifq_icmiss_s1 & 
1262                          ~dtu_ifq_kill_latest_d & ~erb_ifq_itlberr_s1;
1263
1264   // since multiple requests can be outstanding when an error is
1265   // encountered, need to prioritise the mil hits.
1266   // TBD: there must be a cleaner way to do this!
1267   assign qualhit_pe_s[0] = qualhit_or_io_s[0];
1268   assign qualhit_pe_s[1] = ~qualhit_or_io_s[0] & qualhit_or_io_s[1];
1269   assign qualhit_pe_s[2] = ~qualhit_or_io_s[0] & ~qualhit_or_io_s[1] &
1270                             qualhit_or_io_s[2];
1271   assign qualhit_pe_s[3] = ~qualhit_or_io_s[0] & ~qualhit_or_io_s[1] &
1272                            ~qualhit_or_io_s[2] & qualhit_or_io_s[3];
1273   
1274   // A thread cannot hit on an MIL to the IOB
1275   assign milhit_to_thr_s = qualhit_pe_s & {4{icmiss_qual_s & 
1276                                                 ~ifd_ifc_newdestid_s[2]}};
1277
1278   // Make Request to PCX if miss in Icache and MIL
1279   // determine if we need to send req to L2
1280//   assign newpcxreq_s = icmiss_for_milchk & ~fcl_ifq_canthr;
1281//   assign newreq_valid = fcl_ifq_icmiss_s1 & ~dtu_ifq_kill_latest_d &
1282//                             (newpcxreq_s[0] |
1283//                                          newpcxreq_s[1] |
1284//                                          newpcxreq_s[2] |
1285//                                          newpcxreq_s[3]) &
1286//                           (~any_milhit_s | ifd_ifc_newdestid_s[2]);
1287
1288   assign newreq_valid = icmiss_qual_s &
1289                          (~any_milhit_s | ifd_ifc_newdestid_s[2]);
1290
1291   // check if there are any old requests outstanding, that are not
1292   // current in  the D stage.
1293   assign pcxreq_qual_s = pcxreq_s & ~(dpcxthr_d & {4{req_valid_d}});
1294   
1295//   assign reqq_empty = ~(|pcxreq_qual_s[3:0]);
1296//   assign oldpcxreq_s = pcxreq_qual_s & rr_gnt & ~fcl_ifq_canthr;
1297//   assign oldreq_valid = (|oldpcxreq_s);
1298//   assign oldpcxreq_s = pcxreq_qual_s & rr_gnt;   
1299   assign oldreq_valid = (|pcxreq_qual_s);
1300         
1301   // Send out PCX request in round robin order if there are other
1302   // reqests pending.  If the request queue is empty send this req
1303//   assign nextreq_valid_s = ~reqq_empty | newreq_valid;
1304   
1305   assign nextreq_valid_s = oldreq_valid | newreq_valid | req_pending_d;
1306
1307   assign rnd_reset = ifq_reset | ~gdbginit_l;
1308   
1309   // round robin assignment to pcx
1310   sparc_ifu_rndrob  pcxrndrob(.req_vec   (pcxreq_qual_s),
1311                                                 .grant_vec (rr_gnt),
1312                                                 .advance   (req_accept_d),
1313                                                 .rst_tri_enable (rst_tri_en),
1314                                                 .clk       (clk),
1315                                                 .reset     (rnd_reset),
1316                                                 .se  (se),
1317                                                 .si (si),
1318                                                 .so ());
1319
1320   // if req queue is empty forward the new request to pcx
1321   // if not store it in the MIL
1322   assign dpcxthr_s  = req_pending_d ? dpcxthr_d :
1323                             ~oldreq_valid ? thr_s1    : 
1324                                             rr_gnt;
1325   dff_s #(4) pcxthr_ff(.din (dpcxthr_s),
1326                                  .clk (clk),
1327                                  .q   (dpcxthr_d),
1328                                  .se  (se), .si(), .so());
1329
1330   assign thrid_d[0] = dpcxthr_d[3] | dpcxthr_d[1];
1331   assign thrid_d[1] = dpcxthr_d[3] | dpcxthr_d[2];
1332   dff_s #(2) tide_reg(.din (thrid_d),
1333                     .q   (thrid_e),
1334                     .clk (clk), .se(se), .si(), .so());
1335   assign ifc_ifd_thrid_e = thrid_e;
1336   
1337   // Determine the destination to which the request is made:
1338   mux4ds #(3) dest_mux(.dout (old_destid_s),
1339                                    .in0  (ifd_ifc_destid0[2:0]),
1340                                    .in1  (ifd_ifc_destid1[2:0]),
1341                                    .in2  (ifd_ifc_destid2[2:0]),
1342                                    .in3  (ifd_ifc_destid3[2:0]),
1343                                    .sel0 (rr_gnt[0]),
1344                                    .sel1 (rr_gnt[1]),
1345                                    .sel2 (rr_gnt[2]),
1346                                    .sel3 (rr_gnt[3]));
1347   
1348//   mux2ds #(3) fdest_mux(.dout (destid_s),
1349//                                   .in0  (ifd_ifc_newdestid_s),
1350//                                   .in1  (old_destid_s),
1351//                                   .sel0 (~oldreq_valid),
1352//                                   .sel1 (oldreq_valid));
1353
1354//   assign destid_s  = req_pending_d ? ifu_lsu_destid_d    :
1355//                          ~oldreq_valid ? ifd_ifc_newdestid_s :
1356//                                          old_destid_s;
1357   assign ifu_lsu_destid_s = oldreq_valid ? old_destid_s :
1358                                            ifd_ifc_newdestid_s;
1359
1360   // remove this
1361   assign destid_iob_s  = req_pending_d ? destid_iob_d :
1362                                          ifu_lsu_destid_s[2];
1363   dff_s #(1) destd_reg(.din (destid_iob_s),
1364                                  .q   (destid_iob_d),
1365                                  .clk (clk), .se(se), .si(), .so());
1366
1367   // If this is going to any L2 bank, zero out the line address
1368   // for Rams
1369   assign ifc_ifd_pcxline_adj_d[4:2] = ifd_ifc_pcxline_d[4:2] & 
1370                                       {3{destid_iob_d}};
1371   
1372   // advace req
1373   dffr_s #(1) pcxreqvd_ff(.din  (nextreq_valid_s),
1374                                     .clk  (clk),
1375                                     .rst  (ifq_reset),
1376                                     .q    (req_valid_d),
1377                                     .se   (se), .si(), .so());
1378
1379   assign ifu_lsu_pcxreq_d = req_valid_d;
1380
1381//   assign req_pending_d = req_valid_d & ~can_pcx_d & ~lsu_ifu_pcxpkt_ack_d;
1382   assign req_pending_d = req_valid_d & ~(lsu_ifu_pcxpkt_ack_d & ~errinv_d1);
1383   assign req_accept_d = req_valid_d & lsu_ifu_pcxpkt_ack_d;
1384//   assign rr_advance_d = req_accept_d & ~errinv_d1
1385
1386   // Signal to FSM if pcx request has been accepted by LSU
1387   assign pcx_accept_d = dpcxthr_d & {4{req_accept_d}};
1388   // Alternate implementation with canthr delayed by a cycle
1389//   assign pcxreq_vbit_d = req_valid_d & ~can_pcx_d;
1390//   assign pcx_accept_d = dpcxthr_d & {4{req_accept_d}} & ~fcl_ifq_canthr;
1391
1392   // check if there was an error to this thread
1393   assign err_vec_d1 = dpcxthr_d & (errthr_d1 | err_req);
1394   assign errinv_d1 = (|err_vec_d1[3:0]);
1395
1396   dff_s #(1) errinv_ff(.din (errinv_d1),
1397                                  .q   (ifc_ifd_errinv_e),
1398                                  .clk (clk), .se(se), .si(), .so());
1399   
1400   assign pcxreq_vbit_d = req_valid_d;   
1401   dff_s #(1) pcxreqve_ff(.din  (pcxreq_vbit_d),  // same as ifu_lsu_pcxreq_d
1402                                    .clk  (clk),
1403                                    .q    (ifc_ifd_reqvalid_e),
1404                                    .se   (se), .si(), .so());
1405
1406//   dff #(1) pcxreqpe_ff(.din  (req_pending_d),
1407//                                  .clk  (clk),
1408//                                  .q    (req_pending_e),
1409//                                  .se   (se), .si(), .so());
1410
1411   // advance pcx request if there is no prev request pending
1412   // the data is deliberately held valid for one extra cycle.  this
1413   // is legacy stuff.  LSU guarantees that the data is picked up
1414   // minimum 1 cycle after request is made.
1415//   assign ifc_ifd_nxtpcx_sel_new_d = ~req_pending_e;
1416//   assign ifc_ifd_nxtpcx_sel_new_d = 1'b1;   
1417
1418   // Select which MIL request to send out to PCX
1419   assign ifc_ifd_milreq_sel_d_l[0] = ~dpcxthr_d[0] & ~rst_tri_en;
1420   assign ifc_ifd_milreq_sel_d_l[1] = ~dpcxthr_d[1] | rst_tri_en;
1421   assign ifc_ifd_milreq_sel_d_l[2] = ~dpcxthr_d[2] | rst_tri_en;
1422   assign ifc_ifd_milreq_sel_d_l[3] = ~dpcxthr_d[3] | rst_tri_en;
1423
1424
1425//-----------------------------
1426// Invalidate Controls
1427//----------------------------
1428   assign stpkt_i1 = (ifd_ifc_cpxreq_i1 == `CPX_STRPKT) ? 1'b1 : 1'b0;
1429   assign strmack_i1 = (ifd_ifc_cpxreq_i1 == `CPX_STRMACK) ? 1'b1 : 1'b0;
1430   assign evpkt_i1 = (ifd_ifc_cpxreq_i1 == `CPX_EVPKT) ? 1'b1 : 1'b0;
1431   assign ldpkt_i1 = (ifd_ifc_cpxreq_i1 == `CPX_LDPKT) ? 1'b1 : 1'b0;
1432   
1433   assign invalidate_i1 = (stpkt_i1 | strmack_i1 | evpkt_i1 | ldpkt_i1);
1434   assign ifu_lsu_inv_clear = ~(invalidate_i1 | inv_ifc_inv_pending);
1435//       assign ifc_inv_wrreq_i2 = (imissrtn_i2 |
1436//                              asireq_i2 & asi_ic_tag_i2 & ~asi_load_i2 |
1437//                                              mbist_icache_write);
1438   
1439//   assign wrt_en_wd0_i2 = inv_ifc_word0_inv_i2 & (stpkt_i2 | evpkt_i2) |
1440//                          ldinv_i2 & ~ifd_ifc_ldaddr5_i2 |
1441//                                    (imissrtn_i2 |
1442//                           asireq_i2 & asi_ic_tag_i2 & ~asi_load_i2 |
1443//                                           mbist_icache_write) &
1444//                             ~ifd_ifc_missaddr5_i2;
1445//
1446//   assign wrt_en_wd1_i2 = inv_ifc_word1_inv_i2 & (stpkt_i2 | evpkt_i2) |
1447//                                            ldinv_i2 & ifd_ifc_ldaddr5_i2 |
1448//                                      (imissrtn_i2 |
1449//                                             asireq_i2 & asi_ic_tag_i2 & ~asi_load_i2 |
1450//                                             mbist_icache_write) &
1451//                              ifd_ifc_missaddr5_i2;
1452   
1453   // calculate the ICV write data
1454   assign icv_wbit_i2 = imissrtn_i2 & ifc_ifd_filladdr4_i2 |
1455                           asireq_i2 & asi_ic_tag_i2 & ~asi_load_i2 & 
1456                           cpxreq_i2[2];
1457   
1458   assign icv_wrdata_i2 = ifc_inv_ifqadv_i2 ? icv_wbit_i2 : icv_wrdata_f;
1459   
1460//   mux2ds #(2) icv_damux(.dout (icv_wrdata_i2),
1461//                                   .in0  (icv_wrdata_f),
1462//                                   .in1  (icv_wbit_i2),
1463//                                   .sel0 (~ifc_inv_ifqadv_i2),
1464//                                   .sel1 (ifc_inv_ifqadv_i2));
1465
1466   dff_s #(1) icv_daff(.din  (icv_wrdata_i2),
1467                                 .q    (icv_wrdata_f),
1468                                 .clk  (clk),
1469                                 .se   (se), .si(), .so());
1470   assign ifq_icv_wrdata_bf = icv_wrdata_i2;
1471
1472
1473// Begin ECO7010
1474   dp_mux2es #(1) wayvld_mux (.dout (inq_wayvld_i1_nxt),        //done
1475                              .in0 (lsu_ifu_cpxpkt_wayvld_i1),
1476                              .in1 (inq_wayvld_i1),
1477                              .sel(inq_vld));
1478
1479   dff_s #(1) wayvld_ff (.din (inq_wayvld_i1_nxt),             //done
1480                       .q   (inq_wayvld_i1),
1481                       .clk (clk), .se(se), .si(), .so());
1482   
1483   assign ldinv_i1 = ldpkt_i1 & inq_wayvld_i1;  //done
1484
1485   dp_mux2es #(1) ldinv_i2_mux (.dout (ldinv_i2_nxt),  //done
1486                              .in0 (ldinv_i1),
1487                              .in1 (ldinv_i2),
1488                              .sel(ifc_ifd_ifqbyp_en_l));
1489
1490   dff_s #(1) ldinv_i2_ff (.din (ldinv_i2_nxt),   //done
1491                         .q   (ldinv_i2),
1492                         .clk (clk), .se(se), .si(), .so());   
1493
1494//End ECO7010
1495
1496//------------------------------------------------
1497// Fwd Request to read/write Icache
1498//------------------------------------------------
1499   // is this a fwd req to the L1I?
1500   assign fwdreq_i2 = (cpxreq_i2 == `FWD_RQ_RET) ? 
1501                        (ifd_ifc_fwd2ic_i2 & ifd_ifc_4bpkt_i2 &
1502                         ifd_ifc_cpxvld_i2) : 1'b0;
1503
1504   // detect first cycle of fwdpkt and stall
1505   assign fwd_stall = fwdreq_i2 & ~fwdreq_i3;
1506   
1507   dff_s #(1) freq_ff(.din (fwd_stall),
1508                    .q   (fwdreq_i3),
1509                    .clk (clk), .se(se), .si(), .so());
1510
1511   dff_s #(1) cpx3_ff(.din (ifd_ifc_cpxnc_i2),
1512                    .q   (cpxnc_i3),
1513                    .clk (clk), .se(se), .si(), .so());
1514
1515   // NC bit is also R/W_bar bit
1516   assign fwdrd_i3 = fwdreq_i3 & cpxnc_i3;
1517   assign fwdwr_i3 = fwdreq_i3 & ~cpxnc_i3;
1518
1519   // ack back to the LSU to send fwd reply
1520   assign ifu_lsu_fwd_wr_ack = fwdwr_i3;
1521   assign ifc_ifd_idx_sel_fwd_i2 = fwdreq_i2;
1522
1523   // let errctl know a fwd packet is coming
1524   assign ifq_erb_fwdrd_bf = fwdrd_i3;
1525   
1526//----------------------------------
1527// INQ controls -- now ibuf controls
1528//----------------------------------
1529
1530// INQ removed 2/13/02   
1531
1532   // Is the pkt in the inq a pkt that affects the icache?
1533   assign ic_pkt_i1 = invalidate_i1 | imissrtn_i1 | errpkt_i1;
1534   
1535//   assign inq_vld_nxt = ~inq_vld & ifd_ifc_cpxvalid_i1 &
1536//                            (~ifqadv_i1 | asireq_i1) |
1537//                            inq_vld & ((~ifqadv_i1 | asireq_i1) & ic_pkt_i1 |
1538//                                                           ifd_ifc_cpxvalid_i1);
1539
1540   // cut this down to 1 aoi gate
1541   assign inq_vld_nxt = (ifd_ifc_cpxvalid_i1 |
1542                         inq_vld & ic_pkt_i1) & (~ifqadv_i1 | ifu_asireq_i1);
1543   
1544   dffr_s #(1) inqv_ff(.din (inq_vld_nxt),
1545                                 .q   (inq_vld),
1546                                 .rst (ifq_reset),
1547                                 .clk (clk), .se(se), .si(), .so());
1548
1549   assign ifc_ifd_ifqbyp_en_l = ~(ifqadv_i1 | fwd_stall);
1550   
1551   assign ifc_ifd_ifqbyp_sel_fwd_l = ~(fwd_stall & ~ifq_reset);
1552   assign ifc_ifd_ifqbyp_sel_asi_l = ~(~fwd_stall & ~ifq_reset & 
1553                                       ifu_asireq_i1);
1554   assign ifc_ifd_ifqbyp_sel_inq_l = ~(~fwd_stall & ~ifq_reset & 
1555                                       ~ifu_asireq_i1 & inq_vld);
1556   assign ifc_ifd_ifqbyp_sel_lsu_l = ~(~fwd_stall & ~ifu_asireq_i1 & 
1557                                       ~inq_vld | ifq_reset);
1558
1559   assign byp_sel_asi_l = ~(ifqadv_i1 & ifu_asireq_i1);
1560   
1561//   assign ifu_lsu_ibuf_busy = inq_vld & (~ifqadv_i1 | asireq_i1);
1562//   assign ifc_ifd_ld_inq_i1 = ~inq_vld | ifqadv_i1 & ~asireq_i1;
1563
1564   assign ifu_lsu_ibuf_busy = inq_vld;
1565   assign ifc_ifd_ld_inq_i1 = ~inq_vld;
1566
1567//-----------------------------------------
1568// ASI access controls
1569//-----------------------------------------
1570
1571   // need this to help with timing
1572   // - asi_vld is asserted only if the asi transaction is to an IFU asi
1573   //   register AND that register is not in the IMMU.
1574   // - it is held valid until an ack is signalled .
1575   // - the ack is not signalled for atleast 2 cycles
1576   assign asi_vld_next = lsu_ifu_asi_vld & byp_sel_asi_l & 
1577                               ~asireq_i2 & ~illva_i2;  // not when ack is sent
1578   
1579   dff_s #(1) asiv0_ff(.din (asi_vld_next),
1580                                .q   (asi_vld_i0),
1581                                .clk (clk), .se(se), .si(), .so());
1582   assign asi_vld_qual_i0 = asi_vld_i0 & ~asireq_i2 & ~illva_i2 &
1583                            byp_sel_asi_l & ~illva_i1 &
1584                            lsu_ifu_asi_vld;
1585
1586   dff_s #(8) asi_reg(.din (lsu_ifu_asi_state[7:0]),
1587                                .q   (asi_state_i1),
1588                                .clk (clk), .se(se), .si(), .so());
1589
1590   dff_s #(2) asi_tid_reg(.din (lsu_ifu_asi_thrid[1:0]),
1591                                    .q   (ifq_fcl_asi_tid_bf[1:0]),
1592                                    .clk (clk), .se(se), .si(), .so());
1593
1594//   assign ifu_lsu_asi_ack = ~byp_sel_asi_l;
1595   // Decided to wait one more cycle before sending the ack.
1596   assign ifu_lsu_asi_ack = asireq_i2 | illva_i2;   
1597   
1598   // ifu ASIs
1599   // icache data = 0x66
1600   assign asi_ic_data_unchk_i1 = ~asi_state_i1[7] & 
1601                asi_state_i1[6] & 
1602                asi_state_i1[5] & 
1603                ~asi_state_i1[4] & 
1604                ~asi_state_i1[3] & 
1605                      asi_state_i1[2] & 
1606                      asi_state_i1[1] & 
1607                      ~asi_state_i1[0];
1608   assign asi_ic_data_i1 = asi_ic_data_unchk_i1;
1609   
1610   // icache tags = 0x67
1611   // writing to tag also writes to vbits
1612   assign asi_ic_tag_unchk_i1 = ~asi_state_i1[7] & 
1613                      asi_state_i1[6] & 
1614                      asi_state_i1[5] & 
1615                      ~asi_state_i1[4] & 
1616                      ~asi_state_i1[3] & 
1617                      asi_state_i1[2] & 
1618                      asi_state_i1[1] & 
1619                      asi_state_i1[0];
1620   assign asi_ic_tag_i1 = asi_ic_tag_unchk_i1;
1621
1622   // error enable 0x4B
1623   assign asi_erren_unchk_i1 = ~asi_state_i1[7] & 
1624                      asi_state_i1[6] & 
1625                      ~asi_state_i1[5] & 
1626                      ~asi_state_i1[4] & 
1627                      asi_state_i1[3] & 
1628                      ~asi_state_i1[2] & 
1629                      asi_state_i1[1] & 
1630                      asi_state_i1[0];
1631   assign asi_erren_i1 =  asi_erren_unchk_i1 &
1632          ~ifd_ifc_asi_vachklo_i2 &
1633          ~ifd_ifc_asiaddr_i2[2];
1634   
1635   // error status 0x4C
1636   assign asi_errstat_unchk_i1 = ~asi_state_i1[7] & 
1637                      asi_state_i1[6] & 
1638                      ~asi_state_i1[5] & 
1639                      ~asi_state_i1[4] & 
1640                      asi_state_i1[3] & 
1641                      asi_state_i1[2] & 
1642                      ~asi_state_i1[1] & 
1643                      ~asi_state_i1[0];
1644   assign asi_errstat_i1 = asi_errstat_unchk_i1 &
1645          ~ifd_ifc_asi_vachklo_i2 &
1646          ~ifd_ifc_asiaddr_i2[2];
1647
1648   // error addr 0x4D
1649   assign asi_erraddr_unchk_i1 = ~asi_state_i1[7] & 
1650                      asi_state_i1[6] & 
1651                      ~asi_state_i1[5] & 
1652                      ~asi_state_i1[4] & 
1653                      asi_state_i1[3] & 
1654                      asi_state_i1[2] & 
1655                      ~asi_state_i1[1] & 
1656                      asi_state_i1[0];
1657   assign asi_erraddr_i1 =  asi_erraddr_unchk_i1 &
1658          ~ifd_ifc_asi_vachklo_i2 &
1659          ~ifd_ifc_asiaddr_i2[2];
1660
1661   // error inject 0x43
1662   assign asi_errinj_unchk_i1 = ~asi_state_i1[7] & 
1663                      asi_state_i1[6] & 
1664                      ~asi_state_i1[5] & 
1665                      ~asi_state_i1[4] & 
1666                      ~asi_state_i1[3] & 
1667                      ~asi_state_i1[2] & 
1668                      asi_state_i1[1] & 
1669                      asi_state_i1[0];
1670   assign asi_errinj_i1 =  asi_errinj_unchk_i1 &
1671          ~ifd_ifc_asi_vachklo_i2 &
1672          ~ifd_ifc_asiaddr_i2[2];
1673
1674   // imask 0x42, va=0x8
1675   assign asi_imask_unchk_i1 = ~asi_state_i1[7] & 
1676                      asi_state_i1[6] & 
1677                      ~asi_state_i1[5] & 
1678                      ~asi_state_i1[4] & 
1679                      ~asi_state_i1[3] & 
1680                      ~asi_state_i1[2] & 
1681                      asi_state_i1[1] & 
1682                      ~asi_state_i1[0];
1683   assign asi_imask_i1 = asi_imask_unchk_i1  &
1684          ~ifd_ifc_asi_vachklo_i2 &
1685          ifd_ifc_asiaddr_i2[2];  // this is actually va[3]
1686
1687   // illegal va check
1688   assign illva_i0 = ((asi_erren_unchk_i1 |
1689                       asi_errstat_unchk_i1 |
1690                       asi_errinj_unchk_i1 |
1691                       asi_erraddr_unchk_i1) & (ifd_ifc_asi_vachklo_i2 |
1692                                                ifd_ifc_asiaddr_i2[2])) &
1693                       asi_vld_qual_i0;
1694
1695   dff_s #(1) illvai1_ff(.din (illva_i0),
1696                       .q   (illva_i1),
1697                       .clk (clk), .se(se), .si(), .so());
1698   dff_s #(1) illvabf_ff(.din (illva_i1),
1699                     .q   (illva_i2),
1700                     .clk (clk), .se(se), .si(), .so());
1701   dff_s #(1) illvaf_ff(.din (illva_i2),
1702                     .q   (illva_f),
1703                     .clk (clk), .se(se), .si(), .so());
1704   dff_s #(1) illvas_ff(.din (illva_f),
1705                      .q   (illva_s),
1706                      .clk (clk), .se(se), .si(), .so());
1707   dff_s #(1) illvaw2_ff(.din (illva_s),
1708                       .q   (illva_w2),
1709                       .clk (clk), .se(se), .si(), .so());
1710   assign ifu_lsu_ldxa_illgl_va_w2 = illva_w2;
1711
1712   dff_s #(1) tagasi_ff(.din (asi_ic_tag_i1),
1713                                  .q   (asi_ic_tag_i2),
1714                                  .clk (clk), .se(se), .si(), .so());
1715   dff_s #(1) datasi_ff(.din (asi_ic_data_i1),
1716                                  .q   (asi_ic_data_i2),
1717                                  .clk (clk), .se(se), .si(), .so());
1718
1719   dff_s #(1) asieeni2_ff(.din (asi_erren_i1),
1720                                    .q   (ifq_erb_asi_erren_i2),
1721                                    .clk (clk), .se(se), .si(), .so());
1722   dff_s #(1) asieini2_ff(.din (asi_errinj_i1),
1723                                    .q   (ifq_erb_asi_errinj_i2),
1724                                    .clk (clk), .se(se), .si(), .so());
1725   dff_s #(1) asiesti2_ff(.din (asi_errstat_i1),
1726                                    .q   (ifq_erb_asi_errstat_i2),
1727                                    .clk (clk), .se(se), .si(), .so());
1728   dff_s #(1) asieadi2_ff(.din (asi_erraddr_i1),
1729                                    .q   (ifq_erb_asi_erraddr_i2),
1730                                    .clk (clk), .se(se), .si(), .so());
1731   dff_s #(1) imaski2_ff(.din (asi_imask_i1),
1732                                   .q   (ifq_erb_asi_imask_i2),
1733                                   .clk (clk), .se(se), .si(), .so());
1734
1735   // All IFU asi requests
1736   assign ifu_asireq_i0 = (asi_ic_tag_i1 | asi_ic_data_i1 | asi_erren_i1 |
1737                                       asi_errinj_i1 | asi_errstat_i1 | asi_erraddr_i1 |
1738                                       asi_imask_i1) & asi_vld_qual_i0;
1739
1740   dff_s #(1) asireq1_ff(.din  (ifu_asireq_i0),
1741                                   .q    (ifu_asireq_i1),
1742                                   .clk  (clk), .se(se), .si(), .so());
1743   
1744   dff_s #(1) asivld_ff(.din  (byp_sel_asi_l),
1745                                  .q    (asireq_i2_l),
1746                                  .clk  (clk), .se(se), .si(), .so());
1747   assign asireq_i2 = ~asireq_i2_l;
1748   assign ifc_inv_asireq_i2 = asireq_i2;
1749
1750   // Stall if we are doing an asi op or fwdreq
1751  assign stallreq_d0 = (ifu_asireq_i0 | 
1752                         ~byp_sel_asi_l |
1753                         fwdreq_i2) | 
1754                          starv_alert | 
1755                          mbist_ifq_run_bist |
1756                          ldinv_i1 & ~ifqadv_i1 |        //ECO 7010
1757                          ldinv_i2 & ~ifc_inv_ifqadv_i2; //ECO 7010
1758
1759   dff_s #(1) stal_ff(.din (stallreq_d0),
1760                    .q   (stallreq_d1),
1761                    .clk (clk), .se(se), .si(), .so());
1762
1763   // split into two to save repeater
1764   assign ifq_fcl_stallreq = stallreq_d1;
1765   assign ifq_swl_stallreq = stallreq_d1;
1766
1767   dff_s #(1) asil1_ff(.din (lsu_ifu_asi_load),
1768                                 .q   (asi_load_i1),
1769                                 .clk (clk), .se(se), .si(), .so());
1770
1771   dff_s #(1) asil2_ff(.din (asi_load_i1),
1772                                 .q   (asi_load_i2),
1773                                 .clk (clk), .se(se), .si(), .so());
1774
1775   // insert parity error in data and/or tag
1776   // Don't need to qualify with asireq and imissrtn...
1777   //   -- moved this to the DP since the qual is not necessary
1778//   assign ifc_ifd_insert_pe = (asireq_i2 | imissrtn_i2) &
1779//                              ifd_ifc_cpxue_i2;
1780
1781   // decode asi
1782   // generate word selects
1783   // can use finst instead of word_sel_i2, but it screws up timing
1784   
1785   assign word_sel_i2[0] = ~ifd_ifc_asiaddr_i2[3] & ~ifd_ifc_asiaddr_i2[2];
1786   assign word_sel_i2[1] = ~ifd_ifc_asiaddr_i2[3] &  ifd_ifc_asiaddr_i2[2];
1787   assign word_sel_i2[2] =  ifd_ifc_asiaddr_i2[3] & ~ifd_ifc_asiaddr_i2[2];
1788   assign word_sel_i2[3] =  ifd_ifc_asiaddr_i2[3] &  ifd_ifc_asiaddr_i2[2];
1789
1790   // this assumes asi requests are never stalled
1791   assign ifq_icd_worden_bf = (word_sel_i2 | {4{~asireq_i2 & ~fwdwr_i3  |
1792//                                                ~ifc_inv_ifqadv_i2 |
1793                                                mbist_icache_write}});
1794// & (mbist_icache_worden | {4{~bist_op}});
1795
1796   // choose where the ic address should come from
1797//   assign bist_op = (mbist_icache_read | mbist_icache_write);
1798   dff_s #(1) bist_run_ff(.din (mbist_ifq_run_bist),
1799                        .q   (bist_op),
1800                        .clk (clk), .se(se), .si(), .so());
1801   
1802   assign ifc_ifd_addr_sel_bist_i2_l = ~bist_op | sehold;
1803   assign ifc_ifd_addr_sel_old_i2_l = (bist_op | ifc_inv_ifqadv_i2) & ~sehold;
1804   assign ifc_ifd_addr_sel_asi_i2_l = bist_op | ~ifc_inv_ifqadv_i2 | 
1805                                      sehold | ~(asireq_i2 | fwdreq_i3);
1806   assign ifc_ifd_addr_sel_fill_i2_l = bist_op | ~ifc_inv_ifqadv_i2 | 
1807                                       sehold | asireq_i2 | fwdreq_i3;
1808
1809   // choose where the data should come from
1810   assign ifq_icd_data_sel_bist_i2 = mbist_icache_write & ~sehold;
1811   assign ifq_icd_data_sel_fill_i2 = ~mbist_icache_write & ifc_inv_ifqadv_i2 &
1812                                     ~sehold;
1813   assign ifq_icd_data_sel_old_i2 = ~mbist_icache_write & ~ifc_inv_ifqadv_i2 |
1814                                     sehold;
1815   
1816   // generate icache controls
1817   assign ifq_fcl_rdreq_bf = asireq_i2 & asi_load_i2 & 
1818                                   (asi_ic_data_i2 | asi_ic_tag_i2) |
1819                                   mbist_icache_read |
1820                             fwdrd_i3;
1821
1822   assign ifq_fcl_icd_wrreq_bf = asi_ic_data_i2 & asireq_i2 & ~asi_load_i2 |
1823                                       mbist_icache_write |
1824                                 fwdwr_i3;
1825
1826   assign ifq_fcl_ictv_wrreq_bf = asi_ic_tag_i2 & asireq_i2 & ~asi_load_i2;
1827
1828   assign rd_tag_bf = asi_ic_tag_i2 & asi_load_i2;
1829   dff_s #(1) asi_srcf_ff(.din (rd_tag_bf),
1830                               .q   (ifq_erb_rdtag_f),
1831                               .clk (clk), .se(se), .si(), .so());
1832   
1833   assign rdinst_bf = asi_ic_data_i2 & asi_load_i2;
1834   dff_s #(1) asi_inst_ff(.din (rdinst_bf),
1835                               .q   (ifq_erb_rdinst_f),
1836                               .clk (clk), .se(se), .si(), .so());
1837
1838   assign asird_i1 = asi_load_i1 & (~byp_sel_asi_l | illva_i1);
1839   dff_s #(1) asirdq_ff(.din (asird_i1),
1840                      .q   (ifq_fcl_asird_bf),
1841                      .clk (clk), .se(se), .si(), .so());
1842
1843   assign ifq_erb_asiwr_i2 = ~asi_load_i2 & asireq_i2;
1844
1845
1846
1847   // Shadow scan mux
1848   mux4ds #(4) milss_mux(.dout (ifq_sscan_data[3:0]),
1849                         .in0  (mil0_state),
1850                         .in1  (mil1_state),
1851                         .in2  (mil2_state),
1852                         .in3  (mil3_state),
1853                         .sel0 (ctu_sscan_tid[0]),
1854                         .sel1 (ctu_sscan_tid[1]),
1855                         .sel2 (ctu_sscan_tid[2]),
1856                         .sel3 (ctu_sscan_tid[3]));
1857   
1858
1859   
1860endmodule // sparc_ifu_ifqctl
1861
Note: See TracBrowser for help on using the repository browser.