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

Revision 6, 140.6 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_fcl.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_fcl
24//  Description:       
25//  The FCL is the fetch control logic.  It controls the PC datapath
26//  and the fetch/next instruction datapath.  It also manages access
27//  to the icache data, tags, vbits and to the tlb.
28//  The FCL starts fetching from the reset PC upon reset.  It is up to
29//  the DTU to specify which thread to fetch from.  Only T0 is set to
30//  the reset PC.  If the decode unit specifies any other thread, it
31//  will fetch from an indeterminate address.
32//  The fetch block automatically stalls the machine when an Imiss is
33//  detected and there is no thread to switch to. 
34//
35*/
36////////////////////////////////////////////////////////////////////////
37// Global header file includes
38////////////////////////////////////////////////////////////////////////
39
40`include "ifu.h"
41
42
43module sparc_ifu_fcl(/*AUTOARG*/
44   // Outputs
45   fcl_icd_rdreq_bf, fcl_icv_rdreq_bf, fcl_icd_wrreq_bf, 
46   fcl_ict_wrreq_bf, fcl_icv_wrreq_bf, fcl_icd_index_sel_ifq_bf, 
47   fcl_ifq_grant_bf, fcl_ifq_icmiss_s1, fcl_ifq_rdreq_s1, 
48   fcl_ifq_icache_en_s_l, fcl_ifq_thr_s1, fcl_ifq_canthr, 
49   fcl_itlb_cam_vld_bf, fcl_itlb_cam_bypass_bf, fcl_itlb_addr_mask_l, 
50   fcl_itlb_cam_real_bf, fcl_itlb_cam_pid_bf, fcl_itlb_wr_vld_bf, 
51   fcl_itlb_dmp_vld_bf, fcl_itlb_dmp_all_bf, fcl_itlb_tag_rd_vld_bf, 
52   fcl_itlb_invall_f_l, fcl_itlb_data_rd_vld_bf, fcl_erb_ievld_s1, 
53   fcl_erb_tevld_s1, fcl_erb_immuevld_s1, ifu_lsu_thrid_s, 
54   fcl_erb_asi_tid_f, fcl_erb_clear_iferr, fcl_erb_itlbrd_vld_s, 
55   fcl_erb_itlbrd_data_s, fcl_dec_dslot_s, fcl_dtu_inst_vld_e, 
56   fcl_dtu_intr_vld_e, fcl_dtu_inst_vld_d, fcl_dtu_ely_inst_vld_d, 
57   fcl_dec_intr_vld_d, fcl_erb_inst_issue_d, fcl_erb_inst_vld_d1, 
58   ifu_tlu_inst_vld_m, ifu_exu_inst_vld_e, ifu_exu_inst_vld_w, 
59   ifu_spu_inst_vld_w, ifu_tlu_inst_vld_w, ifu_tlu_flush_w, 
60   ifu_tlu_flush_m, fcl_swl_int_activate_i3, fcl_swl_flush_wake_w, 
61   fcl_swl_flush_w, fcl_dcl_regz_e, ifu_tlu_thrid_e, ifu_tlu_thrid_d, 
62   ifu_tlu_immu_miss_m, ifu_tlu_priv_violtn_m, ifu_tlu_icmiss_e, 
63   ifu_tlu_ttype_vld_m, ifu_exu_ttype_vld_m, ifu_mmu_trap_m, 
64   ifu_tlu_trap_m, ifu_tlu_ttype_m, ifu_tlu_hwint_m, 
65   ifu_tlu_sftint_m, ifu_tlu_rstint_m, fcl_dtu_rst_thr_w, 
66   fcl_dtu_resum_thr_w, ifu_tlu_itlb_done, ifu_spu_trap_ack, 
67   ifu_exu_tid_s2, ifu_exu_ren1_s, ifu_exu_ren2_s, ifu_exu_ren3_s, 
68   ifu_exu_disable_ce_e, fcl_dtu_sync_intr_d, fcl_dtu_tlzero_d, 
69   fcl_dtu_privmode_d, fcl_dtu_hprivmode_d, fcl_dtu_hprivmode_w2, 
70   fcl_dtu_nuke_thr_w, fcl_swl_swout_f, fcl_dtu_stall_bf, 
71   fcl_swl_swcvld_s, fcl_dtu_thr_f, fcl_imd_oddwin_d, 
72   fcl_fdp_oddwin_s, fcl_fdp_pcoor_vec_f, fcl_fdp_pcoor_f, 
73   fcl_fdp_mask32b_f, fcl_fdp_addr_mask_d, fcl_fdp_tctxt_sel_prim, 
74   fcl_fdp_usenir_sel_nir_s1, fcl_fdp_rbinst_sel_inste_s, 
75   fcl_fdp_thrtnpc_sel_tnpc_l, fcl_fdp_thrtnpc_sel_npcw_l, 
76   fcl_fdp_thrtnpc_sel_pcf_l, fcl_fdp_thrtnpc_sel_old_l, 
77   fcl_fdp_thr_s1_l, fcl_fdp_next_thr_bf_l, fcl_fdp_next_ctxt_bf_l, 
78   fcl_fdp_nirthr_s1_l, fcl_fdp_thr_s2_l, 
79   fcl_fdp_tpcbf_sel_pcp4_bf_l, fcl_fdp_tpcbf_sel_brpc_bf_l, 
80   fcl_fdp_tpcbf_sel_trap_bf_l, fcl_fdp_tpcbf_sel_old_bf_l, 
81   fcl_fdp_pcbf_sel_nosw_bf_l, fcl_fdp_pcbf_sel_swpc_bf_l, 
82   fcl_fdp_pcbf_sel_br_bf_l, fcl_fdp_trrbpc_sel_trap_bf_l, 
83   fcl_fdp_trrbpc_sel_rb_bf_l, fcl_fdp_trrbpc_sel_err_bf_l, 
84   fcl_fdp_trrbpc_sel_pcs_bf_l, fcl_fdp_noswpc_sel_tnpc_l_bf, 
85   fcl_fdp_noswpc_sel_old_l_bf, fcl_fdp_noswpc_sel_inc_l_bf, 
86   fcl_fdp_nextpcs_sel_pce_f_l, fcl_fdp_nextpcs_sel_pcd_f_l, 
87   fcl_fdp_nextpcs_sel_pcs_f_l, fcl_fdp_nextpcs_sel_pcf_f_l, 
88   fcl_fdp_inst_sel_curr_s_l, fcl_fdp_inst_sel_switch_s_l, 
89   fcl_fdp_inst_sel_nir_s_l, fcl_fdp_inst_sel_nop_s_l, 
90   fcl_fdp_tinst_sel_curr_s_l, fcl_fdp_tinst_sel_rb_s_l, 
91   fcl_fdp_tinst_sel_old_s_l, fcl_fdp_tinst_sel_ifq_s_l, 
92   fcl_fdp_dmpthr_l, fcl_fdp_ctxt_sel_dmp_bf_l, 
93   fcl_fdp_ctxt_sel_sw_bf_l, fcl_fdp_ctxt_sel_curr_bf_l, 
94   fcl_fdp_rdsr_sel_pc_e_l, fcl_fdp_rdsr_sel_thr_e_l, 
95   fcl_fdp_rdsr_sel_ver_e_l, so, ifu_reset_l, 
96   // Inputs
97   rclk, grst_l, arst_l, se, sehold, si, rst_tri_en, 
98   tlu_ifu_flush_pipe_w, exu_ifu_va_oor_m, exu_ifu_oddwin_s, 
99   spu_ifu_ttype_tid_w2, spu_ifu_ttype_vld_w2, spu_ifu_ttype_w2, 
100   erb_fcl_spu_uetrap, exu_ifu_regz_e, dcl_fcl_bcregz0_e, 
101   dcl_fcl_bcregz1_e, dtu_fcl_rollback_g, dtu_fcl_retract_d, 
102   dtu_fcl_br_inst_d, dtu_fcl_sir_inst_e, dtu_fcl_privop_e, 
103   dtu_fcl_fpdis_e, dtu_fcl_imask_hit_e, dtu_fcl_illinst_e, 
104   dtu_fcl_thr_active, dec_fcl_rdsr_sel_pc_d, dec_fcl_rdsr_sel_thr_d, 
105   ifq_fcl_wrreq_bf, ifq_fcl_icd_wrreq_bf, ifq_fcl_ictv_wrreq_bf, 
106   ifq_fcl_rdreq_bf, ifq_fcl_asi_tid_bf, ifq_fcl_asird_bf, 
107   ifq_fcl_invreq_bf, erb_fcl_itlb_ce_d1, erb_dtu_ifeterr_d1, 
108   erb_fcl_ifet_uevec_d1, erb_fcl_ue_trapvec, erb_fcl_ce_trapvec, 
109   dtu_fcl_nextthr_bf, dtu_fcl_ntr_s, dtu_fcl_running_s, 
110   dtu_fcl_flush_sonly_e, fdp_fcl_swc_s2, fdp_fcl_va2_bf, 
111   itlb_fcl_tlbmiss_f_l, itlb_fcl_priv_s1, itlb_fcl_cp_s1, 
112   itlb_fcl_imiss_s_l, fdp_fcl_pc_oor_vec_f, fdp_fcl_pc_oor_e, 
113   fdp_fcl_op_s, fdp_fcl_op3_s, fdp_fcl_ibit_s, lsu_ifu_stallreq, 
114   ffu_ifu_stallreq, ifq_fcl_stallreq, dtu_inst_anull_e, 
115   ifq_fcl_fill_thr, ifq_fcl_flush_sonly_e, tlu_ifu_trap_tid_w1, 
116   tlu_ifu_trappc_vld_w1, tlu_ifu_trapnpc_vld_w1, 
117   tlu_lsu_pstate_priv, tlu_lsu_pstate_am, tlu_hpstate_priv, 
118   tlu_lsu_redmode, tlu_hpstate_enb, lsu_ifu_addr_real_l, 
119   lsu_pid_state0, lsu_pid_state1, lsu_pid_state2, lsu_pid_state3, 
120   lsu_ifu_icache_en, lsu_ifu_dc_parity_error_w2, lsu_ifu_t0_tlz, 
121   lsu_ifu_t1_tlz, lsu_ifu_t2_tlz, lsu_ifu_t3_tlz, tlu_ifu_hwint_i3, 
122   tlu_ifu_pstate_ie, tlu_ifu_sftint_vld, tlu_ifu_hintp_vld, 
123   tlu_ifu_rerr_vld, tlu_ifu_rstthr_i2, tlu_ifu_rstint_i2, 
124   tlu_ifu_resumint_i2, tlu_ifu_nukeint_i2, tlu_itlb_wr_vld_g, 
125   tlu_itlb_dmp_vld_g, tlu_itlb_dmp_all_g, tlu_itlb_data_rd_g, 
126   tlu_itlb_tag_rd_g, tlu_itlb_invalidate_all_g, tlu_fcl_dmp_pid_bf, 
127   tlu_fcl_dmp_real_bf, tlu_idtlb_dmp_thrid_g, exu_ifu_ecc_ce_m, 
128   ffu_ifu_fst_ce_w
129   );
130
131   input  rclk,
132                grst_l,
133          arst_l,
134                se,
135          sehold,
136                si;
137
138   input  rst_tri_en;
139
140
141   input  tlu_ifu_flush_pipe_w; // flush pipe on a trap
142   input  exu_ifu_va_oor_m;
143   input [3:0] exu_ifu_oddwin_s;
144
145   input [1:0] spu_ifu_ttype_tid_w2;
146   input       spu_ifu_ttype_vld_w2;
147   input       spu_ifu_ttype_w2;
148
149   input [3:0] erb_fcl_spu_uetrap;  // use m3
150   
151//   input       dtu_fcl_brtaken_e;    // branch taken
152   input       exu_ifu_regz_e;
153   input       dcl_fcl_bcregz0_e,
154               dcl_fcl_bcregz1_e;
155   
156   input       dtu_fcl_rollback_g;
157   input       dtu_fcl_retract_d;
158   input       dtu_fcl_br_inst_d;
159   input       dtu_fcl_sir_inst_e;
160   input       dtu_fcl_privop_e,
161                           dtu_fcl_fpdis_e,
162               dtu_fcl_imask_hit_e,
163                           dtu_fcl_illinst_e;
164   input [3:0] dtu_fcl_thr_active;
165
166   input       dec_fcl_rdsr_sel_pc_d,
167                           dec_fcl_rdsr_sel_thr_d;
168   
169   input       ifq_fcl_wrreq_bf;
170   input       ifq_fcl_icd_wrreq_bf,
171                           ifq_fcl_ictv_wrreq_bf,
172                           ifq_fcl_rdreq_bf;
173
174   input [1:0] ifq_fcl_asi_tid_bf;
175   input       ifq_fcl_asird_bf;
176   
177   input       ifq_fcl_invreq_bf;
178
179   input       erb_fcl_itlb_ce_d1;
180   input       erb_dtu_ifeterr_d1;
181   input [3:0] erb_fcl_ifet_uevec_d1,
182                           erb_fcl_ue_trapvec,
183                           erb_fcl_ce_trapvec;   
184   
185   input [3:0] dtu_fcl_nextthr_bf;   // thread to switch to
186   input       dtu_fcl_ntr_s,        // next thread ready for ex
187               dtu_fcl_running_s;
188
189   input       dtu_fcl_flush_sonly_e;
190//               dec_fcl_kill4sta_e;
191
192   input       fdp_fcl_swc_s2,       // instruction switch condition
193                           fdp_fcl_va2_bf,       // bit 2 of vaddr
194                           itlb_fcl_tlbmiss_f_l,  // itlb miss
195                           itlb_fcl_priv_s1,     // privileged access page
196                           itlb_fcl_cp_s1,       // uncached access page
197                           itlb_fcl_imiss_s_l;     // icache miss in s1
198
199   input [3:0] fdp_fcl_pc_oor_vec_f;
200   input       fdp_fcl_pc_oor_e;
201
202   input [1:0] fdp_fcl_op_s;
203   input [5:2] fdp_fcl_op3_s;
204   input       fdp_fcl_ibit_s;
205
206   input       lsu_ifu_stallreq,
207                     ffu_ifu_stallreq,
208               ifq_fcl_stallreq;
209   
210   input       dtu_inst_anull_e;
211
212   input [3:0] ifq_fcl_fill_thr;     // fill inst goes to this
213                                         // thread instruction register
214   input       ifq_fcl_flush_sonly_e;
215
216   input [1:0] tlu_ifu_trap_tid_w1;     // thr for which trappc is sent
217   input       tlu_ifu_trappc_vld_w1,   // ld pc on trap or done/retry
218                           tlu_ifu_trapnpc_vld_w1;  // ld Npc for a retry
219
220   input [3:0] tlu_lsu_pstate_priv;     // may need to flop these three
221   input [3:0] tlu_lsu_pstate_am;
222   input [3:0] tlu_hpstate_priv;
223   input [3:0] tlu_lsu_redmode;
224   input [3:0] tlu_hpstate_enb;
225
226   input [3:0] lsu_ifu_addr_real_l;
227   input [2:0] lsu_pid_state0,
228               lsu_pid_state1,
229               lsu_pid_state2,
230               lsu_pid_state3;
231   input [3:0] lsu_ifu_icache_en;
232
233   input       lsu_ifu_dc_parity_error_w2;
234   
235
236//   input       lsu_ifu_flush_ireg;  // not needed any more
237   input       lsu_ifu_t0_tlz,
238                           lsu_ifu_t1_tlz,
239                           lsu_ifu_t2_tlz,
240                           lsu_ifu_t3_tlz;
241
242   input [3:0] tlu_ifu_hwint_i3,        // normal interrupt
243                           tlu_ifu_pstate_ie,
244                           tlu_ifu_sftint_vld,
245                           tlu_ifu_hintp_vld,
246                           tlu_ifu_rerr_vld,
247                           tlu_ifu_rstthr_i2;       // reset or idle interrupt
248
249   input       tlu_ifu_rstint_i2,       // reset to a dead thread
250                           tlu_ifu_resumint_i2,
251                           tlu_ifu_nukeint_i2;
252
253   input       tlu_itlb_wr_vld_g,
254                           tlu_itlb_dmp_vld_g,
255               tlu_itlb_dmp_all_g,
256                           tlu_itlb_data_rd_g,
257                           tlu_itlb_tag_rd_g;
258   input       tlu_itlb_invalidate_all_g;
259
260   input [2:0] tlu_fcl_dmp_pid_bf;
261   input       tlu_fcl_dmp_real_bf;
262   input [1:0] tlu_idtlb_dmp_thrid_g;
263
264   input       exu_ifu_ecc_ce_m;
265   input       ffu_ifu_fst_ce_w;
266   
267   // to icd
268   output      fcl_icd_rdreq_bf,
269               fcl_icv_rdreq_bf,
270                           fcl_icd_wrreq_bf,
271                           fcl_ict_wrreq_bf,
272                           fcl_icv_wrreq_bf;
273
274   output      fcl_icd_index_sel_ifq_bf;
275   output      fcl_ifq_grant_bf;
276   
277   // to ifq
278   output      fcl_ifq_icmiss_s1;  // if icache turned off
279   output      fcl_ifq_rdreq_s1;
280   output      fcl_ifq_icache_en_s_l;
281   
282   output [1:0] fcl_ifq_thr_s1;
283   output [3:0] fcl_ifq_canthr;     // cancel ifetch to this thread
284
285   // to itlb
286   output       fcl_itlb_cam_vld_bf,
287                fcl_itlb_cam_bypass_bf,
288                            fcl_itlb_addr_mask_l,
289                fcl_itlb_cam_real_bf;
290
291   output [2:0] fcl_itlb_cam_pid_bf;
292   
293   output       fcl_itlb_wr_vld_bf,
294                            fcl_itlb_dmp_vld_bf,
295                fcl_itlb_dmp_all_bf,
296                            fcl_itlb_tag_rd_vld_bf,
297                            fcl_itlb_invall_f_l,
298                            fcl_itlb_data_rd_vld_bf;
299   
300   // to erb
301   output       fcl_erb_ievld_s1,
302                            fcl_erb_tevld_s1,
303                            fcl_erb_immuevld_s1;
304
305   output [1:0] ifu_lsu_thrid_s,
306                            fcl_erb_asi_tid_f;
307
308   output [3:0] fcl_erb_clear_iferr;
309   
310
311   output       fcl_erb_itlbrd_vld_s,
312                            fcl_erb_itlbrd_data_s;
313
314   output       fcl_dec_dslot_s;
315   output       fcl_dtu_inst_vld_e,
316                fcl_dtu_intr_vld_e,
317                            fcl_dtu_inst_vld_d,
318                fcl_dtu_ely_inst_vld_d,
319                fcl_dec_intr_vld_d,
320                            fcl_erb_inst_issue_d,
321                            fcl_erb_inst_vld_d1,
322                            ifu_tlu_inst_vld_m,
323//                          ifu_lsu_inst_vld_m,
324                            ifu_exu_inst_vld_e,
325                            ifu_exu_inst_vld_w,
326                            ifu_spu_inst_vld_w,
327                            ifu_tlu_inst_vld_w;
328   
329   output       ifu_tlu_flush_w;
330   output       ifu_tlu_flush_m;
331
332   output [3:0] fcl_swl_int_activate_i3;
333   output       fcl_swl_flush_wake_w;
334   output       fcl_swl_flush_w;
335
336   output       fcl_dcl_regz_e;
337   
338   // to tlu
339   output [1:0] ifu_tlu_thrid_e;
340   output [1:0] ifu_tlu_thrid_d;
341
342   output       ifu_tlu_immu_miss_m,
343                            ifu_tlu_priv_violtn_m;
344         
345   output       ifu_tlu_icmiss_e;
346   output       ifu_tlu_ttype_vld_m;
347   output       ifu_exu_ttype_vld_m;
348   output       ifu_mmu_trap_m;
349   output       ifu_tlu_trap_m;
350   output [8:0] ifu_tlu_ttype_m;
351   
352   output       ifu_tlu_hwint_m;
353   output       ifu_tlu_sftint_m;
354//   output       ifu_tlu_hintp_m;
355//   output       ifu_tlu_rerr_m;
356   output       ifu_tlu_rstint_m;
357   output       fcl_dtu_rst_thr_w;
358   output       fcl_dtu_resum_thr_w;
359
360   output       ifu_tlu_itlb_done;
361
362   output       ifu_spu_trap_ack;
363   
364   // to exu
365   output [1:0] ifu_exu_tid_s2;
366   output       ifu_exu_ren1_s,
367                            ifu_exu_ren2_s,
368                            ifu_exu_ren3_s;
369
370   output       ifu_exu_disable_ce_e;  // to exu and ffu
371   
372   
373   // to dtu
374   output       fcl_dtu_sync_intr_d;
375   output       fcl_dtu_tlzero_d;
376   output       fcl_dtu_privmode_d;
377   output       fcl_dtu_hprivmode_d;
378   output       fcl_dtu_hprivmode_w2;
379   output       fcl_dtu_nuke_thr_w;
380   output       fcl_swl_swout_f;
381   output       fcl_dtu_stall_bf;
382//   output       fcl_dtu_switch_s;     // indicates to the DTU that a
383                                      // switch took place to next_thr
384   output       fcl_swl_swcvld_s;
385   output [3:0] fcl_dtu_thr_f;
386   output       fcl_imd_oddwin_d;
387   
388   // to fdp
389   output       fcl_fdp_oddwin_s;
390   output [3:0] fcl_fdp_pcoor_vec_f;
391   output       fcl_fdp_pcoor_f;
392   output       fcl_fdp_mask32b_f;
393   output       fcl_fdp_addr_mask_d;
394
395   output [3:0] fcl_fdp_tctxt_sel_prim;
396
397   
398   // 2:1 mux selects
399   output       fcl_fdp_usenir_sel_nir_s1;   // same as usenir_d2
400   output [3:0] fcl_fdp_rbinst_sel_inste_s;
401
402   output [3:0] fcl_fdp_thrtnpc_sel_tnpc_l,  // load npc
403                            fcl_fdp_thrtnpc_sel_npcw_l,
404                            fcl_fdp_thrtnpc_sel_pcf_l,
405                            fcl_fdp_thrtnpc_sel_old_l;
406   
407   output [3:0] fcl_fdp_thr_s1_l;            // s1 thr for thrNIR input mux
408   
409   // other mux selects   
410   output [3:0] fcl_fdp_next_thr_bf_l,  // for thrpc output mux
411                fcl_fdp_next_ctxt_bf_l, // for ctxt output mux
412                            fcl_fdp_nirthr_s1_l,    // select NIR in s1 stage
413                            fcl_fdp_thr_s2_l;       // s2 thr for thr_inst_reg
414
415   output [3:0] fcl_fdp_tpcbf_sel_pcp4_bf_l, // selects for thread PC muxes
416                            fcl_fdp_tpcbf_sel_brpc_bf_l,
417                            fcl_fdp_tpcbf_sel_trap_bf_l,
418                            fcl_fdp_tpcbf_sel_old_bf_l;
419
420   output       fcl_fdp_pcbf_sel_nosw_bf_l,      // F stage pc mux selects
421                            fcl_fdp_pcbf_sel_swpc_bf_l,
422                            fcl_fdp_pcbf_sel_br_bf_l;
423
424   output [3:0] fcl_fdp_trrbpc_sel_trap_bf_l, 
425                            fcl_fdp_trrbpc_sel_rb_bf_l,
426                            fcl_fdp_trrbpc_sel_err_bf_l,
427                            fcl_fdp_trrbpc_sel_pcs_bf_l;
428
429   output       fcl_fdp_noswpc_sel_tnpc_l_bf,    // next pc select,
430                            fcl_fdp_noswpc_sel_old_l_bf,                 // dont need anymore
431                            fcl_fdp_noswpc_sel_inc_l_bf;
432
433   output [3:0] fcl_fdp_nextpcs_sel_pce_f_l, 
434                            fcl_fdp_nextpcs_sel_pcd_f_l,
435                            fcl_fdp_nextpcs_sel_pcs_f_l, 
436                            fcl_fdp_nextpcs_sel_pcf_f_l;
437
438   output       fcl_fdp_inst_sel_curr_s_l,   // selects for inst_s2
439                            fcl_fdp_inst_sel_switch_s_l,
440                            fcl_fdp_inst_sel_nir_s_l,
441                            fcl_fdp_inst_sel_nop_s_l;
442
443   output [3:0] fcl_fdp_tinst_sel_curr_s_l,  // selects for tinst regs
444                            fcl_fdp_tinst_sel_rb_s_l,           
445                            fcl_fdp_tinst_sel_old_s_l,
446                            fcl_fdp_tinst_sel_ifq_s_l;
447
448   output [3:0] fcl_fdp_dmpthr_l;
449
450   output       fcl_fdp_ctxt_sel_dmp_bf_l,
451                            fcl_fdp_ctxt_sel_sw_bf_l,
452                            fcl_fdp_ctxt_sel_curr_bf_l;
453
454   output       fcl_fdp_rdsr_sel_pc_e_l,
455                fcl_fdp_rdsr_sel_thr_e_l,
456                fcl_fdp_rdsr_sel_ver_e_l;
457   
458   output       so,
459                ifu_reset_l;
460
461
462   //----------------------------------------------------------------------
463   // Declarations
464   //----------------------------------------------------------------------
465   reg [3:0]    fcl_fdp_tpcbf_sel_old_bf_l,
466                            fcl_fdp_tpcbf_sel_pcp4_bf_l,
467                            fcl_fdp_tpcbf_sel_trap_bf_l,
468                            fcl_fdp_tpcbf_sel_brpc_bf_l;
469   
470   wire         fcl_fdp_inst_sel_nop_s_l,
471                fcl_fdp_inst_sel_nir_s_l,
472                            fcl_fdp_inst_sel_curr_s_l,
473                            fcl_fdp_inst_sel_switch_s_l;
474   
475
476   // local signals
477   wire         //sw_itlb_on,
478                sw_itlb_real,
479                            sw_itlb_am,
480                            //this_itlb_on,
481                this_itlb_real,
482                            itlb_on;
483
484   wire [3:0]   xlate_en,
485                xlate_en_d1;
486   
487   wire [2:0]   sw_pid_bf,
488                curr_pid_bf;
489
490   wire         pid_sel_sw,
491                pid_sel_curr,
492                pid_sel_dmp;
493   
494   wire         itlb_access_gnt,
495                            itlb_access_en,
496                itlb_write_en,
497                ctxt_sel_dmp,
498                            itlb_access_done,
499                itlb_write_done,
500                            itlb_rd_access_done,
501                            itlb_rd_access_done_d1,
502                            itlb_rd_access_done_d2,
503                            itlb_rd_req_bf,
504                            itlb_rd_req_f,
505                            itlb_data_rd_f,
506                itlb_data_rd_s;
507   
508   wire [1:0]   asi_tid_bf;
509   wire [1:0]   spu_tid_w2;
510   
511   wire         fetch_bf,       // fetch an instruction next cycle
512                allow_ifq_access_icd_bf,
513                inst_access_bf,
514                ia1_bf,
515                ia0_bf,
516                no_instacc_bf;
517   
518   wire         cam_vld_bf,
519                tlb_invall_bf,
520                tlb_invall_f,
521//                tlb_invall_req_bf,
522                inst_vld_bf;
523   
524   wire         rdreq_bf,     // read from I$ next cycle
525                            rdreq_f;
526   
527   wire         ic_wrreq_bf;
528   
529   wire         running_s2,
530                valid_s,
531                            running_s1,
532                ely_running_s1,
533                            running_d,
534                            running_e,
535                            running_m,
536                        inst_vld_f,
537                            inst_vld_s,
538                inst_vld_s_crit,
539                            inst_vld_s1,
540                            inst_vld_s2,    // valid bit of S stage
541                                            // instruction.  If this is 0,
542                                            // convert inst to no-op
543                            inst_vld_d,
544                inst_vld_d_crit,
545                            inst_vld_d1,
546                            inst_vld_e,
547                            inst_vld_qual_e,
548                            inst_vld_m,
549                            inst_vld_w;
550
551   wire         inst_vld_w_crit;
552   
553   wire         no_iftrap_m,
554                no_iftrap_w;
555
556   wire         stall_f,
557                            stall_s1,
558                            stall_s1_nxt,
559                ely_stall_thisthr_f,
560                part_stall_thisthr_f,
561                            stall_thisthr_f;
562   wire         rdreq_s1;
563
564   wire         usenir_bf,
565                            usenir_f,
566                            usenir_s1;
567   
568   wire [3:0]   tinst_vld_s,    // valid bit of thr instr register
569                                            // in s stage
570                            tinst_vld_nxt;
571
572   wire [3:0]   val_thr_s1,
573                            val_thr_f,
574                thr_e_v2,
575                            val_thr_e;
576   
577   wire         flush_sonly_qual_e,
578                flush_sonly_all_m,
579                flush_sonly_qual_m,
580                ims_flush_sonly_m,
581                ims_flush_sonly_w,
582                ims_flush_coll_m,
583                ims_flush_coll_w,
584                flush_sonly_m;
585
586   wire         flush_pipe_w;
587   
588   wire         kill_thread_d,
589//                          kill_thread_e,
590                            kill_thread_m,
591                kill_local_m,
592                ely_kill_thread_s2,
593                ely_kill_thread_m,
594                            kill_thread_s2;
595   
596   wire [3:0]   clear_s_d1,
597                flush_thr_w,
598                late_flush_w2;
599
600   wire         utrap_flush_w,
601                utrap_flush_m,
602                flush_pipe_w2;
603   
604   wire         kill_curr_f,
605                kill_curr_d,
606                kill_curr_e,
607                kill_curr_m;
608   
609   wire [3:0]   canthr_f,
610                canthr_s_early,
611                            canthr_s;
612   wire         canthr_sw;
613   wire         canthr_sm,
614                canthr_sd;
615
616   wire         forcemiss_f,   // force an icache miss (if icache is off)
617                            forcemiss_s1,
618                icmiss_for_perf,
619//                ic_miss_sw_s1,
620                            ic_miss_s1;    // icache miss (forced or not)
621
622   wire [3:0]   icache_en_d1;
623
624   wire         icache_on_bf,
625                            icache_on_f,
626                            icache_on_s1,
627                uncached_page_s1;
628//                          sw_icache_on,
629//                          this_icache_on;
630   
631   wire         imsto_thisthr_s1,
632                iferrto_thisthr_d1,
633                retract_iferr_d1,
634                retract_iferr_qual_d1,
635                retract_inst_d,
636                retract_iferr_e;
637//   wire         intrto_thisthr_d;
638//   wire         imsto_nextthr_s1;
639
640   wire         mark4rb_w,
641                mark4rb_m,
642                mark4rb_e,
643                mark4rb_d,
644                mark4rb_s;
645   
646   wire [3:0]   tlbmiss_s2,
647                            tlbmiss_d,
648                            nir_tlbmiss_vec,
649                            nir_tlbmiss_next;
650
651   wire [3:0]   delay_slot_vec,
652                delay_slot_vec_nxt;
653   
654   wire         tlb_cam_miss_f,
655                tlb_cam_miss_s1,
656                nir_tlbmiss_s1,
657                            tlbmiss_s1_crit,
658                            tlbmiss_s1;
659   
660   wire         cam_vld_f,
661                            cam_vld_s1;
662   
663   wire         immu_fault_f,
664                            immu_miss_d,
665                            immu_miss_crit_d,
666                            immu_miss_qual_d,
667                            immu_miss_e,
668//                immu_miss_qual_e,
669                immu_miss_m,
670                addr_real_e;
671   wire [3:0]   itlb_addr_real_l,
672                itlb_addr_real;
673   wire [3:0]   pstate_am_d1;
674   
675   wire         pc_oor_s1,
676                pc_oor_s2,
677                pc_oor_s,
678                            pc_oor_f;
679   wire         set_oor_m;
680   wire         addr_mask_32b_m;
681   
682   wire         priv_mode_s1,
683                priv_mode_f,
684                hpriv_mode_s1,
685                hpriv_mode_w,
686                hpriv_mode_w2,
687                hpriv_mode_f;
688
689   wire         inst_acc_exc_s1,
690                            inst_acc_exc_d,
691                            inst_acc_exc_e;
692   wire [3:0]   inst_acc_vec_s2,
693                            inst_acc_vec_d;
694   
695   wire         priv_violtn_e,
696                priv_violtn_m;
697
698   wire         trap_e,
699                            trap_m;
700   
701   wire         ttype_sel_spuma_e,
702                            ttype_sel_spuenc_e,
703                            ttype_sel_corr_err_e,
704                            ttype_sel_unc_err_e,               
705                            ttype_sel_res_err_e,               
706                            ttype_sel_hstk_cmp_e,               
707                            ttype_sel_pcoor_e,
708                            ttype_sel_immu_miss_e, 
709                            ttype_sel_real_trans_e, 
710                            ttype_sel_icache_err_e,
711                            ttype_sel_priv_viol_e, 
712                            ttype_sel_privop_e,   
713                            ttype_sel_illinst_e,
714                            ttype_sel_ibe_e,
715                            ttype_sel_sir_e,
716                            ttype_sel_fpdis_e;
717   
718   wire [8:0]   ttype_e;
719   
720   wire [3:0]   next_nir_privvec,
721                            nir_privvec;
722   wire         nir_priv_s1,
723                            priv_inst_s1;
724   
725   wire         tlzero_s2;
726   wire [3:0]   tlzero_vec_d1;
727
728   wire         nuke_thr_w,
729                resum_thr_w,
730                rst_thr_w;
731
732   wire [3:0]   spu_thr;
733//   wire [3:0]   rst_thr_bf;
734   
735   wire [3:0]   async_rst_i3,
736                async_rst_i4,
737                            next_rst_i2,
738                            rstint_i2,
739                            rstint_i3,
740                            resumint_i2,
741                            resumint_i3,
742                next_resum_i2,
743                            nuke_thr_i2,
744                            next_nuke_i2,
745                            nuke_thr_i3,
746                            next_sftint_i2,
747                next_hintp_i2,
748                next_rerr_i2,
749                            next_hwint_i3,
750                            sftint_i3,
751                hintp_i3,
752                rerr_i3,
753                            hwint_i4,
754                            next_ceint_i2,
755                            ceint_i3,
756                            next_ueint_i2,
757                            ueint_i3,
758                            next_spuint0_i2,
759                            spuint0_i3,
760                            next_spuint1_i2,
761                            spuint1_i3;
762
763   wire [3:0]   intr_in_pipe;
764
765   wire [3:0]   hypv_int_en,
766                hypv_int_en_d1;
767   wire [3:0]   supv_int_en,
768                supv_int_en_d1;
769
770   wire [3:0]   ifet_ue_vec_d1,
771                            ifet_ue_vec_e;
772   wire         ifet_ue_e;
773
774   wire [3:0]   any_intr_vec_f,
775                any_intr_vec_s,
776                intr_pending_nxt,
777                intr_pending_s,
778                supv_masked_intr_s,
779                hypv_masked_intr_s;
780
781   wire         spuint0_m,
782                spuint0_trap_m,
783//                spuint0_qual_m,
784                            spuint0_e,
785                            spuint0_qual_e,
786                spuint0_w,
787                spuint0_trap_w,
788                            spuint1_m,
789                spuint1_trap_m,
790//                spuint1_qual_m,
791                            spuint1_e,
792                            spuint1_qual_e,
793                spuint1_w,
794                spuint1_trap_w,
795                hwint_m,
796                hwint_e,
797                rstint_m,
798//                rstint_qual_m,
799                resumint_m,
800                resumint_qual_m,
801                sftint_m,
802                sftint_e,
803                sftint_qual_e,
804                hintp_e,
805                hintp_qual_e,
806                hintp_m,
807                rerr_e,
808                rerr_qual_e,
809                rerr_m,
810                nuke_thr_m,
811                nuke_thr_qual_m,
812                            ceint_m,
813                ceint_trap_m,
814                ceint_trap_w,
815//                ceint_qual_m,
816                ceint_qual_w,
817                            ceint_e,
818                            ceint_qual_e,
819                            ueint_m,
820                ueint_trap_m,
821                ueint_trap_w,
822//                ueint_qual_m,
823                ueint_qual_w,
824                ueint_qual_e,
825                            ueint_e;
826
827   wire         disr_trap_m,
828                rb_intr_m,
829                rb_intr_w,
830                any_intr_m;
831   
832   wire         force_intr_s;
833   wire         intr_vld_s,
834                            intr_vld_d,
835                            intr_vld_e,
836                            intr_vld_m,
837                            intr_vld_w,
838                intr_vld_qual_s,
839                            intr_vld_qual_d,
840                            intr_vld_qual_e,
841                            intr_vld_qual_m;
842   
843   wire         kill_intr_f,
844                            kill_intr_d,
845                            kill_intr_e;
846   
847//       wire         kill_intr_m;
848   
849   wire         rst_stallreq,
850                rst_stallreq_l,
851                all_stallreq,
852                rst_itlb_stv_l,
853                arst_vld_f,
854                arst_vld_f_l,
855                arst_vld_s,
856                arst_vld_s_l,
857                async_intr_vld_s,
858                itlb_starv_alert,
859                rst_sw_bf,
860                rst_sw_bf_l,
861                sw_for_real_rst_bf,
862                rst_stallreq_d0,
863                            rst_stallreq_d1,
864                            rst_stallreq_d2;
865
866   wire         lsu_stallreq_d1,
867                ffu_stallreq_d1;
868   
869   wire [3:0]   rstint_penc;
870   
871   wire         usep_bf,
872                set_usen_bf,
873                usen_iso_bf,
874                            usen_bf;
875   wire         va2_f;
876   wire         ntpc_thisthr;
877   
878   wire [3:0]   thr_usen_nxt,
879                            thr_usen_bf;
880   
881   wire         brto_nxtthr_bf_l,  // intermediate signal for icadr sel
882//                brto_nxtthr_bf,
883//                thr_match_ne_norst,
884                sw_match_ne_norst,
885                brtaken_buf_e,
886                brtaken_unq_e,
887                brtaken_e,
888                brtaken_m;
889   
890   wire         switch_bf,   // switch in next cycle unless stall
891                switch_qual_bf,
892                            switch_s2;  // switch in this cycle
893   
894   wire         rstt,       // set thr_f to the reset pkt thread
895                            swt,        // switch to nextthr_bf
896                            samet;      // don't change thread
897
898   wire [3:0]   thr_f_crit,
899                thr_f_dec,
900                thr_f_flop;
901
902   wire [3:0]   thr_f,      // = thr_s2
903                            thr_bf,
904                            thr_s1,     // = thr_d
905                            thr_s1_next,
906                dec_thr_s1_l,
907                            thr_d,
908                            thr_e,
909                            thr_m,
910                            thr_w2,
911                            thr_w;
912
913   wire         tm_fd_l;
914   
915   wire         thr_match_fw,
916                            thr_match_fw2,
917                            thr_match_dw,
918                            thr_match_dw2,
919                            thr_match_em,
920                            thr_match_ew,
921                            thr_match_ew2,
922                            same_thr_mw2,
923                            thr_match_mw,
924                            thr_match_fm,
925                            thr_match_de,
926                            thr_match_dm,
927                            thr_match_fe,
928                            thr_match_fd,
929                            thr_match_fs1,
930                            thr_match_nw,
931                            thr_match_nd,
932                            thr_match_ne;
933//                          thr_match_ft;
934
935   wire         rb2_inst_d,
936                            rb2_inst_e,
937                            rb1_inst_s,
938                            rb1_inst_d,
939                            rb0_inst_bf,
940                            rb0_inst_s,
941                            rt2_inst_e,
942                            rt1_inst_s,
943                            rt1_inst_d,
944                            rt0_inst_bf,
945                            rt0_inst_s;
946   
947   wire [3:0]   rb_w2,
948                rb_for_iferr_e,
949                            rb_froms,
950                            rb_frome,
951                            rb_fromd;
952   
953   wire         rb_stg_s,
954                            rb_stg_d,
955                rb_stg_d_crit,
956                            rb_stg_e;
957   
958   wire         icadr_selbr_l,
959//                          icadr_selsw,
960//                icadr_selbr,
961                icadr_selsw_l;
962
963   wire         sw_or_async_stall;
964   
965   wire [3:0]   trap_thr;
966   
967   wire [3:0]   load_tpc,     // thread pc reg input select
968                            load_bpc,     // these should be exclusive in normal mode
969                            load_pcp4;    // but not during scan shift or reset
970   
971   wire         irf_ce_w,
972                            irf_ce_m,
973                any_ce_w,
974                            rb_stg_w;
975
976   wire [3:0]   ce_cnt0,
977                ce_cnt0_nxt,
978                ce_cnt1,
979                ce_cnt1_nxt,
980                ce_cnt_rst;
981   
982   wire         ce_val0_d,
983                ce_val1_d,
984                disable_ce_e,
985                disable_ce_d;
986   
987   wire [3:0]   ntpc_vld,     // use thr_nextpc_f
988                            ntpc_vld_nxt;
989   
990   wire [1:0]   sas_thrid_w;
991   
992   wire         rdsr_sel_pc_e,
993                                    rdsr_sel_thr_e;
994
995   wire [1:0]   trap_tid_w2;
996   wire         trappc_vld_w2, 
997                trapnpc_vld_w2;
998
999   wire         fcl_reset,
1000                fcl_reset_l;
1001
1002   // some monitor is looking for this signal
1003//   wire         fcl_swl_flush_wait_w=1'b0;
1004   wire         clk;
1005   
1006   wire [3:0]   nextthr_bf_buf,
1007                nextthr_final_bf;
1008
1009
1010//
1011// Code start here
1012//
1013   assign       clk = rclk;
1014   
1015//----------------------------------------------------------------------
1016// Fetch Unit Controls
1017//----------------------------------------------------------------------
1018
1019   // reset buffer
1020   dffrl_async rstff(.din (grst_l),
1021                     .q   (fcl_reset_l),
1022                     .clk (clk), .se(se), .si(), .so(),
1023                     .rst_l (arst_l));
1024
1025   assign   fcl_reset = ~fcl_reset_l;
1026   assign   ifu_reset_l = fcl_reset_l;
1027   
1028
1029//-----------------------------------
1030// TLB Operations
1031//-----------------------------------
1032
1033   dff_s #(4) real_reg(.din (lsu_ifu_addr_real_l),
1034                     .q   (itlb_addr_real_l),
1035                     .clk (clk), .se(se), .si(), .so());
1036   assign   itlb_addr_real = ~itlb_addr_real_l;
1037
1038   // ITLB on signal
1039
1040//`ifdef SPARC_HPV_EN   
1041   assign   xlate_en = (~tlu_hpstate_enb & lsu_ifu_addr_real_l |
1042                        tlu_hpstate_enb & ~tlu_hpstate_priv) & 
1043                         ~tlu_lsu_redmode;
1044   
1045//`else
1046//   assign   xlate_en = lsu_ifu_addr_real_l;
1047//`endif
1048
1049   dff_s #(4) xlate_reg(.din (xlate_en),
1050                      .q   (xlate_en_d1),
1051                      .clk (clk), .se(se), .si(), .so());
1052   
1053//   assign sw_itlb_on = ((nextthr_bf_buf & xlate_en_d1) == 4'b0) ?
1054//                                   1'b0 : 1'b1;
1055//   assign this_itlb_on = ((thr_f & xlate_en_d1) == 4'b0) ?
1056//                                           1'b0 : 1'b1;
1057//   assign itlb_on = switch_bf ? sw_itlb_on : this_itlb_on;
1058   assign itlb_on = (nextthr_final_bf[0] & xlate_en_d1[0] |
1059                     nextthr_final_bf[1] & xlate_en_d1[1] |
1060                     nextthr_final_bf[2] & xlate_en_d1[2] |
1061                     nextthr_final_bf[3] & xlate_en_d1[3]);
1062   
1063
1064   // flop xlate_en (done) addr_real and icache_en if timing is
1065   // not cutting it
1066
1067   // Hypervisor signals
1068   assign sw_itlb_real = ((nextthr_bf_buf & itlb_addr_real) == 4'b0) ?
1069                                     1'b0 : 1'b1;
1070   assign this_itlb_real = ((thr_f & itlb_addr_real) == 4'b0) ?
1071                                             1'b0 : 1'b1;
1072
1073//   assign fcl_itlb_cam_real_bf = switch_bf ? sw_itlb_real : this_itlb_real;
1074
1075   mux3ds  creal_mx(.dout (fcl_itlb_cam_real_bf),
1076                    .in0  (sw_itlb_real),
1077                    .in1  (this_itlb_real),
1078                    .in2  (tlu_fcl_dmp_real_bf),
1079                    .sel0 (pid_sel_sw),
1080                    .sel1 (pid_sel_curr),
1081                    .sel2 (pid_sel_dmp));
1082
1083   // Partition ID
1084   mux4ds #(3) swpid_mux (.dout (sw_pid_bf[2:0]),
1085                          .in0  (lsu_pid_state0[2:0]),
1086                          .in1  (lsu_pid_state1[2:0]),
1087                          .in2  (lsu_pid_state2[2:0]),
1088                          .in3  (lsu_pid_state3[2:0]),
1089                          .sel0 (nextthr_bf_buf[0]),
1090                          .sel1 (nextthr_bf_buf[1]),
1091                          .sel2 (nextthr_bf_buf[2]),
1092                          .sel3 (nextthr_bf_buf[3]));
1093
1094   mux4ds #(3) currpid_mux (.dout (curr_pid_bf[2:0]),
1095                            .in0  (lsu_pid_state0[2:0]),
1096                            .in1  (lsu_pid_state1[2:0]),
1097                            .in2  (lsu_pid_state2[2:0]),
1098                            .in3  (lsu_pid_state3[2:0]),
1099                            .sel0 (thr_f[0]),
1100                            .sel1 (thr_f[1]),
1101                            .sel2 (thr_f[2]),
1102                            .sel3 (thr_f[3]));
1103
1104//   assign fcl_itlb_cam_pid_bf[2:0] = switch_bf ? 
1105//                                       sw_pid_bf[2:0] :
1106//                                       curr_pid_bf[2:0];
1107
1108//   assign pid_sel_dmp = tlu_itlb_dmp_actxt_g & ctxt_sel_dmp;
1109   assign pid_sel_dmp = ctxt_sel_dmp;   
1110   assign pid_sel_curr = ~pid_sel_dmp & ~switch_bf;
1111   assign pid_sel_sw = ~pid_sel_dmp & switch_bf;
1112   mux3ds #(3) ipid_mx(.dout (fcl_itlb_cam_pid_bf[2:0]),
1113                       .in0  (sw_pid_bf[2:0]),
1114                       .in1  (curr_pid_bf[2:0]),
1115                       .in2  (tlu_fcl_dmp_pid_bf[2:0]),
1116                       .sel0 (pid_sel_sw),
1117                       .sel1 (pid_sel_curr),
1118                       .sel2 (pid_sel_dmp));
1119   
1120   // ITLB address mask
1121   dff_s #(4) am_reg(.din (tlu_lsu_pstate_am),
1122                   .q   (pstate_am_d1),
1123                   .clk (clk), .se(se), .si(), .so());
1124   
1125   assign sw_itlb_am = ((nextthr_bf_buf & pstate_am_d1) == 4'b0) ?
1126                                     1'b0 : 1'b1;
1127   assign fcl_itlb_addr_mask_l = switch_bf ? 
1128                                 ~sw_itlb_am : ~fcl_fdp_mask32b_f;
1129
1130   dff_s #(4) tlz_reg(.din ({lsu_ifu_t3_tlz,
1131                           lsu_ifu_t2_tlz,
1132                           lsu_ifu_t1_tlz,
1133                           lsu_ifu_t0_tlz}),
1134                    .q   (tlzero_vec_d1[3:0]),
1135                    .clk (clk), .se (se), .si(), .so());
1136                           
1137
1138   // TLB context select
1139   assign fcl_fdp_tctxt_sel_prim = tlzero_vec_d1 & itlb_addr_real_l;
1140//   assign fcl_fdp_tctxt_sel_prim[1] = lsu_ifu_t1_tlz & itlb_addr_real_l[1];
1141//   assign fcl_fdp_tctxt_sel_prim[2] = lsu_ifu_t2_tlz & itlb_addr_real_l[2];
1142//   assign fcl_fdp_tctxt_sel_prim[3] = lsu_ifu_t3_tlz & itlb_addr_real_l[3];
1143   
1144
1145   // Access to TLB
1146   // ITLB may be accessed even when icache is off
1147   assign cam_vld_bf = itlb_on & inst_access_bf;
1148                       
1149   assign fcl_itlb_cam_vld_bf = cam_vld_bf;
1150   assign fcl_itlb_cam_bypass_bf = ~cam_vld_bf;
1151   
1152   dff_s #(1) itlb_onf_ff(.din (cam_vld_bf),
1153                                    .q   (cam_vld_f),
1154                                    .clk (clk),
1155                                    .se  (se), .si(), .so());
1156
1157   dff_s #(1) itlb_ons1_ff(.din (cam_vld_f),
1158                                     .q   (cam_vld_s1),
1159                                     .clk (clk),
1160                                     .se  (se), .si(), .so());
1161
1162   // allow rd/wr/demap access to tlb
1163   // itlb access is granted only every other cycle
1164   // (not enough time to turn the request from mmu around)
1165//   assign itlb_access_en = ~cam_vld_bf & ~ifq_fcl_asird_bf &
1166//                           ~itlb_access_done;
1167//
1168//   assign itlb_write_en = ~cam_vld_bf & ~ifq_fcl_asird_bf &
1169//                           ~itlb_write_done &
1170//                           (~tlu_itlb_dmp_vld_g | itlb_access_done);
1171
1172// Save some timing   
1173//   assign itlb_write_en = (~itlb_on | no_instacc_bf) & ~ifq_fcl_asird_bf &
1174//                          ~itlb_write_done &
1175//                          (~tlu_itlb_dmp_vld_g | itlb_access_done);
1176
1177   assign itlb_write_en = no_instacc_bf & ~ifq_fcl_asird_bf & 
1178                          ~itlb_write_done & 
1179                          (~tlu_itlb_dmp_vld_g | itlb_access_done);
1180   assign itlb_access_en = no_instacc_bf & ~ifq_fcl_asird_bf &
1181                           ~itlb_access_done;
1182
1183   // reset tlb
1184//   dff #(1) itlbrst_ff(.din (tlu_itlb_invalidate_all_g),
1185//                                 .q   (tlb_invall_req_bf),
1186//                                 .clk (clk), .se(se), .si(), .so());
1187//   assign tlb_invall_bf = tlb_invall_req_bf & ~itlb_access_done;
1188   assign tlb_invall_bf = sehold ? tlb_invall_f :
1189                           (tlu_itlb_invalidate_all_g & itlb_access_en);
1190   dff_s #(1) itlbrstf_ff(.din (tlb_invall_bf),
1191                                    .q   (tlb_invall_f),
1192                                    .clk (clk), .se(se), .si(), .so());
1193
1194   assign fcl_itlb_wr_vld_bf = tlu_itlb_wr_vld_g & itlb_write_en;
1195   assign fcl_itlb_dmp_vld_bf = tlu_itlb_dmp_vld_g & itlb_access_en;
1196   assign fcl_itlb_dmp_all_bf = tlu_itlb_dmp_all_g & tlu_itlb_dmp_vld_g & 
1197                                itlb_access_en;
1198
1199//   assign fcl_itlb_invall_bf = tlb_invall_bf & itlb_access_en | fcl_reset;
1200   assign fcl_itlb_invall_f_l = ~tlb_invall_f;
1201
1202   assign fcl_itlb_data_rd_vld_bf = tlu_itlb_data_rd_g & itlb_access_en & 
1203                                          ~itlb_rd_access_done_d2 &
1204                                    ~itlb_rd_access_done_d1;
1205 
1206   assign fcl_itlb_tag_rd_vld_bf = tlu_itlb_tag_rd_g & itlb_access_en &
1207                                         ~itlb_rd_access_done_d2 &
1208                                   ~itlb_rd_access_done_d1;
1209
1210   assign rst_itlb_stv_l = ((tlu_itlb_invalidate_all_g |
1211                             tlu_itlb_dmp_vld_g |
1212                             tlu_itlb_data_rd_g |
1213                             tlu_itlb_tag_rd_g) & ~itlb_access_done |
1214                            tlu_itlb_wr_vld_g & ~itlb_write_done) &
1215                             ~fcl_reset;
1216
1217   sparc_ifu_ctr5 starv_ctr(
1218                                              // Outputs
1219                                              .limit    (itlb_starv_alert),
1220                                              .so       (so),
1221                                              // Inputs
1222                                              .clk      (clk),
1223                                              .se       (se),
1224                                              .si       (si),
1225                                              .rst_ctr_l (rst_itlb_stv_l));
1226
1227   assign itlb_rd_req_bf = fcl_itlb_data_rd_vld_bf | fcl_itlb_tag_rd_vld_bf;
1228
1229   // tlb access request
1230   assign itlb_access_gnt = (fcl_itlb_data_rd_vld_bf |
1231                                               fcl_itlb_tag_rd_vld_bf  |
1232//                             tlb_invall_bf & itlb_access_en |
1233                             tlb_invall_bf |
1234                             fcl_itlb_dmp_vld_bf);
1235
1236   dff_s #(1) tlb_gnt1_ff(.din (itlb_access_gnt),
1237                                  .q   (itlb_access_done),
1238                                  .clk (clk), .se  (se), .si(), .so());
1239
1240   dff_s #(1) tlb_rd_ff(.din (itlb_rd_req_bf),
1241                                .q   (itlb_rd_req_f),
1242                                .clk (clk), .se  (se), .si(), .so());
1243
1244   dff_s #(1) tlb_wrt1_ff(.din (fcl_itlb_wr_vld_bf),
1245                                    .q   (itlb_write_done),
1246                                    .clk (clk), .se  (se), .si(), .so());
1247   
1248
1249   // TBD:
1250   // reads need to wait one more cycle.  Others can ack without this
1251   // second delay.
1252   assign itlb_rd_access_done = itlb_rd_req_f & itlb_access_done;
1253   
1254   dff_s #(1) tlb_rd1_ff(.din (itlb_rd_access_done),
1255                                  .q   (itlb_rd_access_done_d1),
1256                                  .clk (clk), .se  (se), .si(), .so());
1257   dff_s #(1) tlb_rd2_ff(.din (itlb_rd_access_done_d1),
1258                                   .q   (itlb_rd_access_done_d2),
1259                                  .clk (clk), .se  (se), .si(), .so());
1260   assign ifu_tlu_itlb_done = ~itlb_rd_req_f & itlb_access_done |
1261                               itlb_write_done | 
1262                                     itlb_rd_access_done_d2;
1263
1264   assign fcl_erb_itlbrd_vld_s = itlb_rd_access_done_d1;
1265   
1266   assign asi_tid_bf = ifq_fcl_asird_bf ? ifq_fcl_asi_tid_bf :
1267                                                tlu_idtlb_dmp_thrid_g;
1268   
1269   dff_s #(2) asi_tid_reg(.din (asi_tid_bf),
1270                                  .q   (fcl_erb_asi_tid_f),
1271                                  .clk (clk), .se(se), .si(), .so());
1272   
1273                   
1274   // Remember if we read tag or data
1275   dff_s #(1) tlb_rddf_ff(.din (fcl_itlb_data_rd_vld_bf),
1276                                  .q   (itlb_data_rd_f),
1277                                  .clk (clk), .se  (se), .si(), .so());
1278
1279   dff_s #(1) tlb_rdds_ff(.din (itlb_data_rd_f),
1280                                  .q   (itlb_data_rd_s),
1281                                  .clk (clk), .se  (se), .si(), .so());
1282
1283   // pick itlb ldxa data
1284   assign fcl_erb_itlbrd_data_s =  itlb_data_rd_s;
1285
1286   // Demap thread
1287   assign fcl_fdp_dmpthr_l[0] = ~(~tlu_idtlb_dmp_thrid_g[1] & ~tlu_idtlb_dmp_thrid_g[0]);
1288   assign fcl_fdp_dmpthr_l[1] = ~(~tlu_idtlb_dmp_thrid_g[1] & tlu_idtlb_dmp_thrid_g[0]);
1289   assign fcl_fdp_dmpthr_l[2] = ~(tlu_idtlb_dmp_thrid_g[1] & ~tlu_idtlb_dmp_thrid_g[0]);
1290   assign fcl_fdp_dmpthr_l[3] = ~(tlu_idtlb_dmp_thrid_g[1] & tlu_idtlb_dmp_thrid_g[0]);
1291
1292   // Select appropriate context for TLB
1293   // ctxt_sel_dmp is itlb_access_en without the asird signal
1294   assign ctxt_sel_dmp = no_instacc_bf & ~itlb_access_done;
1295   assign fcl_fdp_ctxt_sel_dmp_bf_l = ~ctxt_sel_dmp;   
1296   assign fcl_fdp_ctxt_sel_sw_bf_l = ctxt_sel_dmp | ~switch_bf;
1297   assign fcl_fdp_ctxt_sel_curr_bf_l = ctxt_sel_dmp | switch_bf;
1298   
1299   
1300//--------------------------
1301// Fetch Request and Stall
1302//--------------------------
1303   
1304   // Determine if we need can continue fetching next cycle
1305//   assign fetch_bf = (~all_stallreq & ~fcl_reset & ~rst_stallreq) &
1306//                   (switch_bf |
1307//                    ~(part_stall_thisthr_f | fdp_fcl_swc_s2));
1308//                    ~(stall_thisthr_f | fdp_fcl_swc_s2 | immu_fault_f));
1309
1310   assign fetch_bf = (~all_stallreq & ~fcl_reset & ~rst_stallreq) &
1311                       (switch_bf |  // replace with ntr_s?
1312                        ~(part_stall_thisthr_f 
1313                          | fdp_fcl_swc_s2
1314                          )
1315                        );
1316
1317   // dtu_fcl_running_s should be a part of this eqn, since it is assumed
1318   // by the ifill completion prediction logic in the swl
1319//   assign inst_access_bf = (~all_stallreq & ~fcl_reset & ~rst_stallreq &
1320//                            (switch_bf & ~usen_iso_bf |
1321//                             ~switch_bf & ~ely_stall_thisthr_f &
1322//                             dtu_fcl_running_s &
1323//                             ~ely_kill_thread_s2 &
1324//                             //~fdp_fcl_swc_s2 & // take out for tim reasons
1325//                             ~usep_bf));
1326
1327   assign ia0_bf = (~all_stallreq & ~fcl_reset & ~rst_stallreq & 
1328                    (switch_bf |
1329                     ~ely_stall_thisthr_f &
1330                     dtu_fcl_running_s & 
1331                     ~ely_kill_thread_s2 &
1332                     ~usep_bf));
1333
1334   assign ia1_bf = (~all_stallreq & ~fcl_reset & ~rst_stallreq & 
1335                    (~switch_bf & ~ely_stall_thisthr_f &
1336                     dtu_fcl_running_s & 
1337                     ~ely_kill_thread_s2 &
1338                     ~usep_bf));
1339   
1340
1341   assign inst_access_bf = usen_iso_bf ? ia1_bf : ia0_bf;
1342   // needs to work even if usen_iso_bf is X - not nec. 11/06/03
1343//   dp_mux2es #(1) ia_mx(.dout (inst_access_bf),
1344//                        .in0  (ia0_bf),
1345//                        .in1  (ia1_bf),
1346//                        .sel  (usen_iso_bf));
1347   
1348   
1349
1350//   assign allow_ifq_access_icd_bf = (all_stallreq | rs
1351//                                     ~switch_bf &
1352//                                     (usep_bf | stall_f) |
1353//                                     switch_bf & usen_bf);
1354   assign allow_ifq_access_icd_bf = ~inst_access_bf;
1355   
1356   // earlier version for critical stuff
1357   assign no_instacc_bf = all_stallreq | fcl_reset | rst_stallreq |
1358                          ~dtu_fcl_ntr_s & (ely_stall_thisthr_f | usep_bf);
1359   
1360   // check if icache is on
1361   dff_s #(4) ic_en_reg(.din (lsu_ifu_icache_en),
1362                      .q   (icache_en_d1),
1363                      .clk (clk), .se(se), .si(), .so());
1364   
1365//   assign sw_icache_on = (nextthr_bf_buf[0] & icache_en_d1[0] |
1366//                          nextthr_bf_buf[1] & icache_en_d1[1] |
1367//                          nextthr_bf_buf[2] & icache_en_d1[2] |
1368//                          nextthr_bf_buf[3] & icache_en_d1[3]);
1369//   assign this_icache_on = (thr_f[0] & icache_en_d1[0] |
1370//                            thr_f[1] & icache_en_d1[1] |
1371//                            thr_f[2] & icache_en_d1[2] |
1372//                            thr_f[3] & icache_en_d1[3]);
1373//   assign icache_on_bf = switch_bf ? sw_icache_on : this_icache_on;
1374
1375   assign icache_on_bf = (nextthr_final_bf[0] & icache_en_d1[0] |
1376                          nextthr_final_bf[1] & icache_en_d1[1] |
1377                          nextthr_final_bf[2] & icache_en_d1[2] |
1378                          nextthr_final_bf[3] & icache_en_d1[3]);
1379
1380   // remember if icache was turned on
1381   dff_s #(1) icef_ff(.din (icache_on_bf),
1382                              .q   (icache_on_f),
1383                              .clk (clk), .se(se), .si(), .so());
1384   dff_s #(1) ices_ff(.din (icache_on_f),
1385                              .q   (icache_on_s1),
1386                              .clk (clk), .se(se), .si(), .so());
1387
1388   // check if cp is set
1389   assign uncached_page_s1 = ~itlb_fcl_cp_s1 & cam_vld_s1;
1390   assign fcl_ifq_icache_en_s_l = ~icache_on_s1 | uncached_page_s1;
1391   
1392   // Read from the icache only if
1393   //   we need to fetch AND
1394   //   the icache is on AND
1395   //   we are not using the NIR
1396   assign rdreq_bf = icache_on_bf & inst_access_bf;
1397
1398   assign fcl_icd_rdreq_bf = rdreq_bf | ifq_fcl_rdreq_bf;
1399
1400   // split off driver to icv to reduce load
1401   assign fcl_icv_rdreq_bf = rdreq_bf | ifq_fcl_rdreq_bf;
1402   
1403   // Read req pipe
1404   dffr_s #(1)  rdreq_ff(.din  (rdreq_bf),
1405                                 .clk  (clk),
1406                                 .rst  (fcl_reset),
1407                                 .q    (rdreq_f),
1408                                 .se   (se), .si(), .so());
1409   // Remember if we fetched in the last cycle
1410   dff_s #(1)  rdreqs1_ff (.din  (rdreq_f),
1411                                   .clk  (clk),
1412                                   .q    (rdreq_s1),
1413                                   .se   (se), .si(), .so());
1414   assign fcl_ifq_rdreq_s1 = ~stall_s1;
1415
1416   // Use NIR pipe
1417   assign usenir_bf = switch_bf ? usen_bf : usep_bf;
1418   
1419   dffr_s #(1)  unf_ff(.din  (usenir_bf),
1420                                 .clk  (clk),
1421                                 .rst  (fcl_reset),
1422                                 .q    (usenir_f),
1423                                 .se   (se), .si(), .so());
1424   // Remember if we fetched in the last cycle
1425   dff_s #(1)  uns1_ff (.din  (usenir_f),
1426                                  .clk  (clk),
1427                                  .q    (usenir_s1),
1428                                  .se   (se), .si(), .so());
1429
1430
1431   // Write signal to icache if no access from pipe
1432   assign ic_wrreq_bf = allow_ifq_access_icd_bf & ifq_fcl_wrreq_bf;
1433
1434   assign fcl_icd_wrreq_bf = ic_wrreq_bf | ifq_fcl_icd_wrreq_bf;
1435   assign fcl_ict_wrreq_bf = ic_wrreq_bf | ifq_fcl_ictv_wrreq_bf;
1436   assign fcl_icv_wrreq_bf = ic_wrreq_bf | ifq_fcl_ictv_wrreq_bf |
1437                             ifq_fcl_invreq_bf;
1438
1439   // synopsys translate_off
1440   always @ (posedge clk)
1441   begin
1442            if (fcl_icd_rdreq_bf & fcl_icd_wrreq_bf)
1443              begin
1444                 // 0in <fire -message "ERROR: sparc_ifu_fcl: rd and wr req to I$ at the same time"
1445`ifdef DEFINE_0IN
1446`else           
1447                `ifdef MODELSIM
1448                         $display( "CACHE_CONTENTION", "ERROR: sparc_ifu_fcl: rd and wr req to I$ at the same time");
1449                `else
1450                 $error("CACHE_CONTENTION", "ERROR: sparc_ifu_fcl: rd and wr req to I$ at the same time");
1451                `endif   
1452`endif
1453              end
1454   end
1455   // synopsys translate_on
1456   
1457
1458   //-------------------------
1459   // Valid Instruction Pipe
1460   //-------------------------
1461   // F stage
1462   assign inst_vld_bf = fetch_bf;
1463   dff_s #(1) inst_vld_ff(.din (inst_vld_bf),
1464                                  .clk (clk),
1465                                  .q   (inst_vld_f),
1466                                  .se  (se), .si(), .so());
1467
1468   assign stall_f = ~inst_vld_f | kill_curr_f;
1469   assign stall_thisthr_f = stall_f | imsto_thisthr_s1 | // intrto_thisthr_d |
1470                                  kill_thread_s2 | rb_stg_s | ~dtu_fcl_running_s | 
1471                            iferrto_thisthr_d1;
1472
1473   assign part_stall_thisthr_f = stall_f | 
1474                                 imsto_thisthr_s1 |
1475                                 ~dtu_fcl_running_s | 
1476                                 ely_kill_thread_s2 |
1477                                       rb_stg_s;
1478   
1479   assign ely_stall_thisthr_f = stall_f | rb_stg_s;   
1480
1481//   assign stall_s1_nxt = stall_thisthr_f | intr_vld_s | tmsto_thisthr_f;
1482   assign stall_s1_nxt = stall_thisthr_f; //| intr_vld_s;
1483   
1484   // S1 stage
1485   dff_s #(1) stalld_ff(.din (stall_s1_nxt),
1486                                  .clk (clk),
1487                                  .q   (stall_s1),
1488                                  .se  (se), .si(), .so());
1489
1490   assign inst_vld_s1 = ~stall_s1 & ~ic_miss_s1 & ~kill_curr_d;
1491   assign val_thr_s1 = thr_s1 & {4{inst_vld_s1}}; // 4b
1492
1493   // S2 stage
1494   assign val_thr_f = thr_f & {4{~stall_f & ~rb_stg_s & dtu_fcl_running_s}};
1495
1496   // Tag the S stage thr inst register as containing a valid inst or not
1497   assign tinst_vld_nxt = (ifq_fcl_fill_thr | 
1498                           (rb_w2 & ~rb_for_iferr_e) | // set
1499                                             val_thr_s1 & ~val_thr_f |
1500                           //                      val_thr_s1 |
1501                                             tinst_vld_s & ~val_thr_f) &
1502                                              ~(clear_s_d1 |
1503                              {4{erb_dtu_ifeterr_d1 & inst_vld_d1 & 
1504                                 ~rb_stg_e}} & thr_e);   // reset
1505
1506   dffr_s #(4) tinst_reg(.din  (tinst_vld_nxt),
1507                                 .clk  (clk),
1508                                 .rst  (fcl_reset),
1509                                 .q    (tinst_vld_s),
1510                                 .se   (se), .si(), .so());
1511
1512   // Does current thread have valid inst in s2
1513   assign inst_vld_s2 = ((thr_f_crit & tinst_vld_s) == 4'b0000) ?
1514                                            {1'b0} :  {1'b1};         
1515
1516   assign inst_vld_s = ~switch_s2 & inst_vld_s1 | 
1517                              switch_s2 & inst_vld_s2;
1518   assign inst_vld_s_crit = ~switch_s2 & ~stall_s1 & ~kill_curr_d | 
1519                              switch_s2 & inst_vld_s2;
1520
1521   assign valid_s = inst_vld_s & ~stall_f &  // f and s2 have same thread
1522                       dtu_fcl_running_s &
1523                             ~(ely_kill_thread_s2 | rb_stg_s);
1524
1525   assign running_s2 = inst_vld_s & ~stall_thisthr_f;// f and s2 have
1526                                                     // same thread
1527   // D stage
1528   dff_s #(1) rund_ff(.din (running_s2),
1529                              .clk (clk),
1530                              .q   (inst_vld_d),
1531                              .se  (se), .si(), .so());
1532   dff_s #(1) eivd_ff(.din (running_s2),
1533                                .clk (clk),
1534                                .q   (inst_vld_d_crit),
1535                                .se  (se), .si(), .so());
1536   assign fcl_erb_inst_issue_d = inst_vld_d & ~intr_vld_d;
1537   assign running_d = inst_vld_d & ~kill_thread_d & ~rb_stg_d & 
1538                            ~intr_vld_d;
1539
1540   // E stage
1541   dff_s #(1) rune_ff(.din (running_d),
1542                              .clk (clk),
1543                              .q   (inst_vld_e),
1544                              .se  (se), .si(), .so());
1545
1546   assign running_e = inst_vld_e & ~dtu_inst_anull_e & 
1547                            ~kill_curr_e & ~rb_stg_e &
1548                      ~(thr_match_em & ifu_tlu_flush_m);
1549   assign inst_vld_qual_e = inst_vld_e & ~rb_stg_e;
1550   assign val_thr_e = thr_e_v2 & {4{inst_vld_qual_e}} & ~late_flush_w2 &
1551                      ~(thr_w & {4{utrap_flush_w}});
1552   
1553   
1554   // M stage
1555   dff_s #(1) runm_ff(.din (running_e),
1556                              .clk (clk),
1557                              .q   (inst_vld_m),
1558                              .se  (se), .si(), .so());
1559   assign running_m = (inst_vld_m | intr_vld_m) & ~kill_thread_m;
1560   
1561   assign ifu_tlu_inst_vld_m = (inst_vld_m | intr_vld_m) & ~kill_curr_m;
1562   // less critical
1563   // assign ifu_lsu_inst_vld_m = ifu_tlu_inst_vld_m;
1564   
1565   // W stage
1566   dff_s #(1) runw_ff(.din (running_m),
1567                              .q   (inst_vld_w),
1568                              .clk (clk), .se  (se), .si(), .so());   
1569
1570   dff_s #(1) iw_ff(.din (running_m),
1571                              .q   (inst_vld_w_crit),
1572                              .clk (clk), .se  (se), .si(), .so());   
1573   
1574   // synopsys translate_off
1575//   wire         sas_m,
1576//                          inst_done_w_for_sas;
1577   
1578//   assign sas_m = inst_vld_m & ~kill_thread_m &
1579//                      ~(exu_ifu_ecc_ce_m & inst_vld_m & ~trap_m);
1580
1581//   dff #(1) sasw_ff(.din (sas_m),
1582//                            .clk (clk),
1583//                            .q   (inst_done_w_for_sas),
1584//                            .se  (se), .si(), .so());   
1585   // synopsys translate_on
1586
1587   // need to kill branch by E stage, so qual with rb_stg_X
1588   assign fcl_dtu_inst_vld_e = inst_vld_e & ~rb_stg_e & ~kill_curr_e;
1589   assign fcl_dtu_intr_vld_e = intr_vld_e & ~rb_stg_e & ~kill_curr_e;
1590   assign fcl_dtu_inst_vld_d = inst_vld_d & ~kill_curr_d &
1591                                     ~rb_stg_d_crit & ~immu_miss_crit_d;
1592   assign fcl_dtu_ely_inst_vld_d = inst_vld_d_crit;
1593   assign ifu_tlu_inst_vld_w = inst_vld_w;
1594   assign ifu_exu_inst_vld_w = inst_vld_w_crit;
1595   assign ifu_spu_inst_vld_w = inst_vld_w;
1596   assign ifu_exu_inst_vld_e = fcl_dtu_inst_vld_e;
1597   
1598   assign flush_sonly_qual_e = dtu_fcl_flush_sonly_e & inst_vld_e &
1599//                               ~dec_fcl_kill4sta_e &
1600                               ~rb_stg_e & ~dtu_inst_anull_e & ~kill_curr_e;
1601   
1602
1603   dff_s #(1) flshm_ff(.din (flush_sonly_qual_e),
1604                     .q   (flush_sonly_m),
1605                     .clk (clk),
1606                     .se  (se), .si(), .so());
1607
1608   dff_s #(1) imflshm_ff(.din (ifq_fcl_flush_sonly_e),
1609                       .q   (ims_flush_sonly_m),
1610                       .clk (clk),
1611                       .se  (se), .si(), .so());
1612   // detect collision between two different types of retractions
1613   assign ims_flush_coll_m = ims_flush_sonly_m & ~canthr_sm & 
1614                             retract_iferr_e;
1615   dff_s #(1) imflshw_ff(.din (ims_flush_coll_m),
1616                       .q   (ims_flush_sonly_w),
1617                       .clk (clk),
1618                       .se  (se), .si(), .so());
1619   assign ims_flush_coll_w = ims_flush_sonly_w & ~canthr_sw;
1620   assign flush_sonly_qual_m = (ims_flush_sonly_m & ~canthr_sm & 
1621                                ~retract_iferr_e |
1622                                flush_sonly_m & inst_vld_m & ~kill_local_m &
1623                                ~kill_curr_m);
1624   assign flush_sonly_all_m = (ims_flush_sonly_m & ~canthr_sm | 
1625                               flush_sonly_m & inst_vld_m);
1626
1627//   assign flush_sonly_qual_m = flush_sonly_m & ~canthr_sm;
1628//   assign qtrap_flush_e = dtu_fcl_qtrap_e & inst_vld_e & ~dtu_inst_anull_e &
1629//                        ~rb_stg_e;
1630   
1631//------------------------------   
1632// Instruction Kill Logic
1633//------------------------------
1634   
1635   // kill_s2 is the same as kill_f
1636   assign kill_thread_s2 = thr_match_fw & rb_stg_w |
1637//                               thr_match_ft & trappc_vld_w2 |
1638                                 thr_match_fm & (flush_sonly_all_m) |
1639                           kill_curr_f;
1640   
1641   assign ely_kill_thread_s2 = thr_match_fw & utrap_flush_w |
1642//                                   thr_match_ft & trappc_vld_w2 |
1643                                     thr_match_fm & (flush_sonly_all_m) |
1644                               kill_curr_f;
1645   
1646   assign kill_thread_d = thr_match_dw & rb_stg_w |
1647                                thr_match_dm & (flush_sonly_all_m) |
1648                          kill_curr_d;
1649
1650   // M and E still need full qualification with flush pipe   
1651//   assign kill_thread_e = thr_match_ew & utrap_flush_w |
1652//                          thr_match_ew & tlu_ifu_flush_pipe_w |
1653//                          kill_curr_e ;
1654   assign ely_kill_thread_m = thr_match_mw & utrap_flush_w |
1655//                              mark4rb_m |
1656                              kill_curr_m;
1657   assign kill_thread_m = ely_kill_thread_m | 
1658                          thr_match_mw & tlu_ifu_flush_pipe_w;
1659   
1660   assign kill_local_m = thr_match_mw & (utrap_flush_w | intr_vld_w);
1661
1662   assign flush_pipe_w = rb_stg_w | tlu_ifu_flush_pipe_w;
1663//   assign part_flush_w = ifu_tlu_flush_w | tlu_ifu_flush_pipe_w;
1664//   assign kill_nextthr_w = thr_match_nw & flush_pipe_w;
1665   assign flush_thr_w = thr_w & {4{flush_pipe_w}};
1666   dff_s #(1) fp_ff(.din (flush_pipe_w),
1667                  .q   (flush_pipe_w2),
1668                  .clk (clk), .se(se), .si(), .so());
1669
1670//   assign clear_s_stage =  thr_e & {4{flush_sonly_qual_e}};
1671//   assign clear_s_stage =  trap_thr & {4{trappc_vld_w2}} |
1672//                               {4{dummy_flush_ireg}} |
1673//                               thr_e & {4{flush_sonly_qual_e}};
1674                           //  | flush_thr_w
1675
1676   assign canthr_f = thr_e & {4{flush_sonly_qual_e}} | 
1677                     (rb_w2 & ~rb_for_iferr_e) | rb_froms;
1678
1679//   dff #(4) cls_reg(.din (clear_s_stage),
1680//                              .q   (clear_s_early),
1681//                              .clk (clk), .se(se), .si(), .so());
1682
1683   // ***NOTE***
1684   // Don't use clear_s_d1 to generate fcl_ifq_canthr, since clear_s_d1
1685   // includes ifeterr!
1686   // first term could be just flush_sonly_m & inst_vld_m & thr_m
1687   assign clear_s_d1 = thr_m & {4{flush_sonly_all_m}} |
1688                       late_flush_w2 | 
1689                       trap_thr & {4{trappc_vld_w2}};
1690
1691   assign fcl_erb_clear_iferr = thr_m & {4{ims_flush_sonly_m | 
1692                                           flush_sonly_m}} |
1693                                late_flush_w2 | 
1694                                trap_thr & {4{trappc_vld_w2}};
1695
1696
1697   dff_s #(4) cm_reg(.din (canthr_f),
1698                               .q   (canthr_s_early),
1699                               .clk (clk),
1700                               .se  (se), .si(), .so());
1701
1702   assign canthr_s = canthr_s_early | late_flush_w2 | 
1703                     trap_thr & {4{trappc_vld_w2}};         
1704   
1705//   assign fcl_ifq_canthr = clear_s_stage | rb_w2 | rb_froms |
1706//                               canthr_s;
1707   assign fcl_ifq_canthr = canthr_s;
1708
1709   assign canthr_sm = (canthr_s[0] & thr_m[0] | 
1710                       canthr_s[1] & thr_m[1] | 
1711                       canthr_s[2] & thr_m[2] | 
1712                       canthr_s[3] & thr_m[3]);
1713
1714   assign canthr_sw = (canthr_s[0] & thr_w[0] | 
1715                       canthr_s[1] & thr_w[1] | 
1716                       canthr_s[2] & thr_w[2] | 
1717                       canthr_s[3] & thr_w[3]);
1718
1719   assign canthr_sd = (canthr_s[0] & thr_d[0] | 
1720                       canthr_s[1] & thr_d[1] | 
1721                       canthr_s[2] & thr_d[2] | 
1722                       canthr_s[3] & thr_d[3]) |
1723                        thr_match_dw & utrap_flush_w;
1724
1725   dff_s #(4) fpw2_reg(.din (flush_thr_w),
1726                     .q   (late_flush_w2),
1727                     .clk (clk), .se(se), .si(), .so());
1728
1729//   assign late_flush_w2 = thr_w2 & {4{flush_pipe_w2}};
1730   
1731   assign kill_curr_f = (thr_f_crit[0] & late_flush_w2[0] |
1732                         thr_f_crit[1] & late_flush_w2[1] |
1733                         thr_f_crit[2] & late_flush_w2[2] |
1734                         thr_f_crit[3] & late_flush_w2[3]);
1735   assign kill_curr_d = (thr_d[0] & late_flush_w2[0] |
1736                         thr_d[1] & late_flush_w2[1] |
1737                         thr_d[2] & late_flush_w2[2] |
1738                         thr_d[3] & late_flush_w2[3]);
1739   assign kill_curr_e = (thr_e_v2[0] & late_flush_w2[0] |
1740                         thr_e_v2[1] & late_flush_w2[1] |
1741                         thr_e_v2[2] & late_flush_w2[2] |
1742                         thr_e_v2[3] & late_flush_w2[3]) |
1743                          thr_match_ew & utrap_flush_w;
1744   
1745//   assign kill_curr_m = (thr_m[0] & late_flush_w2[0] |
1746//                         thr_m[1] & late_flush_w2[1] |
1747//                         thr_m[2] & late_flush_w2[2] |
1748//                         thr_m[3] & late_flush_w2[3]);
1749   assign kill_curr_m = same_thr_mw2 & flush_pipe_w2;
1750   
1751   //------------------------------
1752   // track I$ misses
1753   //------------------------------
1754   
1755   // force a miss if a fetch and icache is off
1756   // forcemiss triggers a fill vld_grequest to L2, so set to zero by default
1757   assign forcemiss_f = inst_vld_f & ~icache_on_f;
1758   dffr_s #(1)  miss_ff(.din (forcemiss_f),
1759                                  .clk (clk),
1760                                  .rst (fcl_reset),
1761                                  .q   (forcemiss_s1),
1762                                  .se  (se), .si(), .so());
1763
1764   //ooooooooooooooooooooooooooooooooooooooooooooooooooooooo
1765   // removed imiss_s_l from this signal for timing fix 
1766   // Perf Hit: 0.2% TPCC, 0.4% JBB
1767//   assign ic_miss_sw_s1 = (~itlb_fcl_imiss_s_l & rdreq_s1 |
1768//                             tlb_cam_miss_s1 |
1769//                             forcemiss_s1);
1770//   assign ic_miss_sw_s1 =   tlb_cam_miss_s1 |
1771//                            forcemiss_s1;
1772   //ooooooooooooooooooooooooooooooooooooooooooooooooooooooo
1773   
1774   assign ic_miss_s1 =  (~itlb_fcl_imiss_s_l & rdreq_s1 |
1775                                           forcemiss_s1) & 
1776                        ~stall_s1 & ~tlbmiss_s1_crit & ~pc_oor_s1 & 
1777                        ~rb_stg_d_crit & ~canthr_sd;
1778
1779   assign icmiss_for_perf =  (~itlb_fcl_imiss_s_l & rdreq_s1) & 
1780                        ~stall_s1 & ~tlbmiss_s1_crit & ~pc_oor_s1 & 
1781                        ~rb_stg_d & ~canthr_sd;
1782
1783//   assign fcl_ifq_icmiss_s1 = ic_miss_s1 & ~ely_kill_thread_d;  // use buffer
1784   assign fcl_ifq_icmiss_s1 = ic_miss_s1;  // use buffer   
1785
1786   // for perf counters (d1=e)
1787   dff_s #(1) icmd1_ff(.din (icmiss_for_perf),
1788                     .q   (ifu_tlu_icmiss_e),
1789                     .clk (clk), .se(se), .si(), .so());
1790   
1791   // I$ miss is always to thr_s1.  Below we check to see if this is
1792   // the same as thr_f (=thr_s2) which is the "current thread"
1793//   assign imsto_thisthr_s1 = thr_match_fd & ic_miss_s1;
1794//   assign imsto_nextthr_s1 = thr_match_nd & (ic_miss_s1 | tlbmiss_s1);
1795
1796   assign imsto_thisthr_s1 = thr_match_fd & ic_miss_s1;
1797//   assign imsto_nextthr_s1 = thr_match_nd & (ic_miss_sw_s1);
1798//   assign intrto_thisthr_d = thr_match_fd & fcl_dtu_sync_intr_d;
1799
1800   assign iferrto_thisthr_d1 = thr_match_fe & erb_dtu_ifeterr_d1 & 
1801                               inst_vld_d1;
1802   
1803
1804//------------------------------
1805// track itlb misses
1806//------------------------------
1807
1808   // default to hit when camming is turned off
1809   assign tlb_cam_miss_f = ~itlb_fcl_tlbmiss_f_l & cam_vld_f;
1810   dff_s #(1) tlbmsf_ff(.din (tlb_cam_miss_f),
1811                                  .clk (clk),
1812                                  .q   (tlb_cam_miss_s1),
1813                                  .se  (se), .si(), .so());
1814   
1815   // tlb miss logic
1816   // va hole has higher priority than immu miss
1817   assign tlbmiss_s2 = (({4{tlbmiss_s1 & ~pc_oor_s1 & ~rb_stg_d}} & thr_s1) |
1818                                          ({4{erb_fcl_itlb_ce_d1 & inst_vld_d1 & 
1819                            ~rb_stg_e}} & thr_e &
1820                                           (~thr_d | {4{~inst_vld_d | ~thr_match_de}})) |
1821                                          ({4{immu_miss_e}} & rb_frome) |
1822                                          ({4{immu_miss_d}} & rb_fromd & ~rb_frome) |  // set
1823                                          tlbmiss_d & (~thr_d | {4{~inst_vld_d}}) & ~rb_w2) & 
1824                                         ~(clear_s_d1); // reset
1825
1826//   assign tlbmiss_s2 = (({4{tlbmiss_s1 & ~pc_oor_s1 & ~rb_stg_d}} & thr_s1) |
1827//                      ({4{erb_fcl_itlb_ce_d1 & inst_vld_qual_d1}} & thr_e |
1828//                       tlbmiss_d & (~thr_e | {4{~inst_vld_qual_e}}) &
1829//                       ~rb_w2) & ~(clear_s_stage); // reset
1830
1831   dffr_s #(4) tlbmiss_reg(.din (tlbmiss_s2),
1832                                     .q   (tlbmiss_d),
1833                                     .clk (clk),
1834                                     .rst (fcl_reset),
1835                                     .se  (se), .si(), .so());
1836
1837   assign immu_fault_f = (thr_f_crit[0] & (tlbmiss_d[0] | inst_acc_vec_d[0]) |
1838                                            thr_f_crit[1] & (tlbmiss_d[1] | inst_acc_vec_d[1]) |
1839                                            thr_f_crit[2] & (tlbmiss_d[2] | inst_acc_vec_d[2]) |
1840                                            thr_f_crit[3] & (tlbmiss_d[3] | inst_acc_vec_d[3])) &
1841                           switch_s2| 
1842                                             // D stage miss
1843                                             (tlbmiss_s1 | pc_oor_s1) & thr_match_fs1;
1844                                 // S stage miss
1845
1846   assign immu_miss_crit_d = (thr_d[0] & tlbmiss_d[0] |
1847                                                thr_d[1] & tlbmiss_d[1] |
1848                                                thr_d[2] & tlbmiss_d[2] |
1849                                                thr_d[3] & tlbmiss_d[3]);
1850   
1851   // TBD: move this to the E stage, post RB
1852   assign immu_miss_d = immu_miss_crit_d & inst_vld_d | 
1853                                          thr_match_de & erb_fcl_itlb_ce_d1 & inst_vld_d1;
1854
1855   // don't need to do this, once everyone switches to immu_miss_m
1856   assign immu_miss_qual_d = immu_miss_d & ~kill_thread_d &
1857                                    ~(immu_miss_e & thr_match_de & 
1858                                inst_vld_e & ~dtu_inst_anull_e & ~rb_stg_e &
1859                                ~kill_curr_e);
1860   
1861   dff_s immu_misse_ff(.din (immu_miss_qual_d),
1862                                 .clk (clk),
1863                                 .q   (immu_miss_e),
1864                                 .se  (se), .si(), .so());
1865
1866   
1867   // flop this and send in M
1868//   assign ifu_tlu_immu_miss_e = immu_miss_e & ~addr_real_e &
1869//                                inst_vld_e & ~dtu_inst_anull_e & ~rb_stg_e;
1870//   assign ifu_tlu_immu_miss_e = 1'b0;
1871   
1872//   assign immu_miss_qual_e = immu_miss_e & //~addr_real_e &
1873// //                             ~(immu_miss_m & thr_match_em) &
1874//                             inst_vld_e & ~dtu_inst_anull_e & ~rb_stg_e;
1875
1876//   dff #(1) immu_msm_ff(.din (immu_miss_qual_e),
1877   dff_s #(1) immu_msm_ff(.din (immu_miss_e),
1878                        .q   (immu_miss_m),
1879                        .clk (clk), .se(se), .si(), .so());
1880
1881   assign ifu_tlu_immu_miss_m = immu_miss_m & inst_vld_m & ~kill_curr_m;
1882
1883   assign addr_real_e = (itlb_addr_real[0] & thr_e[0] |
1884                         itlb_addr_real[1] & thr_e[1] |
1885                         itlb_addr_real[2] & thr_e[2] |
1886                         itlb_addr_real[3] & thr_e[3]);
1887
1888   // store tlbmiss state for NIR
1889   assign nir_tlbmiss_next = ({4{tlb_cam_miss_s1 & ~stall_s1}} & thr_s1 |
1890                                                nir_tlbmiss_vec & (~thr_s1 | {4{stall_s1}}));
1891
1892   dffr_s #(4) nirtlbm_reg(.din (nir_tlbmiss_next),
1893                                   .clk (clk),
1894                                   .q   (nir_tlbmiss_vec),
1895                                   .rst (fcl_reset),
1896                                   .se  (se), .si(), .so());
1897
1898   assign nir_tlbmiss_s1 = (nir_tlbmiss_vec[0] & thr_s1[0] |
1899                                              nir_tlbmiss_vec[1] & thr_s1[1] |
1900                                              nir_tlbmiss_vec[2] & thr_s1[2] |
1901                                              nir_tlbmiss_vec[3] & thr_s1[3]);
1902
1903   assign tlbmiss_s1_crit = ~usenir_s1 ? tlb_cam_miss_s1 :
1904                                               nir_tlbmiss_s1;
1905
1906   assign tlbmiss_s1 = tlbmiss_s1_crit & ~stall_s1;
1907
1908//---------------------------------
1909//  Privilege Mode and VA Hole
1910//---------------------------------
1911   assign addr_mask_32b_m = (thr_m[0] & pstate_am_d1[0] |
1912                                               thr_m[1] & pstate_am_d1[1] |
1913                                               thr_m[2] & pstate_am_d1[2] |
1914                                               thr_m[3] & pstate_am_d1[3]);
1915   
1916   assign fcl_fdp_mask32b_f = (thr_f[0] & pstate_am_d1[0] |
1917                                                 thr_f[1] & pstate_am_d1[1] |
1918                                                 thr_f[2] & pstate_am_d1[2] |
1919                                                 thr_f[3] & pstate_am_d1[3]);
1920
1921   dff_s #(1) amd_ff(.din (fcl_fdp_mask32b_f),
1922                               .q   (fcl_fdp_addr_mask_d),
1923                               .clk (clk), .se(se), .si(), .so());
1924
1925   // keep track of whether pc is outside va hole
1926   assign set_oor_m = exu_ifu_va_oor_m & brtaken_m & ~addr_mask_32b_m;
1927   assign fcl_fdp_pcoor_vec_f = fdp_fcl_pc_oor_vec_f | {4{set_oor_m}} & thr_m;
1928   
1929   assign fcl_fdp_pcoor_f =  (thr_f[0] & fcl_fdp_pcoor_vec_f[0] |
1930                                                thr_f[1] & fcl_fdp_pcoor_vec_f[1] |
1931                                                thr_f[2] & fcl_fdp_pcoor_vec_f[2] |
1932                                                thr_f[3] & fcl_fdp_pcoor_vec_f[3]);
1933   
1934   assign pc_oor_f = fcl_fdp_pcoor_f  & ~part_stall_thisthr_f;
1935   dff_s oors1_ff(.din (pc_oor_f),
1936                            .q   (pc_oor_s1),
1937                            .clk (clk), .se(se), .si(), .so());
1938
1939   // track privilege mode of current page
1940   assign priv_mode_f = (thr_f[0] & tlu_lsu_pstate_priv[0] |
1941                                           thr_f[1] & tlu_lsu_pstate_priv[1] |
1942                                           thr_f[2] & tlu_lsu_pstate_priv[2] |
1943                                           thr_f[3] & tlu_lsu_pstate_priv[3]);
1944
1945   dff_s #(1) priv_ff(.din (priv_mode_f),
1946                    .q   (priv_mode_s1),
1947                    .clk (clk), .se(se), .si(), .so());
1948   
1949   // s1 and d are the same thread
1950   assign fcl_dtu_privmode_d = priv_mode_s1;
1951
1952   // hyper privilege
1953   assign hpriv_mode_f = (thr_f[0] & tlu_hpstate_priv[0] |
1954                                            thr_f[1] & tlu_hpstate_priv[1] |
1955                                            thr_f[2] & tlu_hpstate_priv[2] |
1956                                            thr_f[3] & tlu_hpstate_priv[3]);
1957
1958   assign hpriv_mode_w = (thr_w[0] & tlu_hpstate_priv[0] |
1959                                            thr_w[1] & tlu_hpstate_priv[1] |
1960                                            thr_w[2] & tlu_hpstate_priv[2] |
1961                                            thr_w[3] & tlu_hpstate_priv[3]);
1962   
1963   dff_s #(1) hprivd_ff(.din (hpriv_mode_f),
1964                     .q   (hpriv_mode_s1),
1965                     .clk (clk), .se(se), .si(), .so());
1966
1967   assign fcl_dtu_hprivmode_d = hpriv_mode_s1;
1968
1969   dff_s #(1) hprivw2_ff(.din (hpriv_mode_w),
1970                     .q   (hpriv_mode_w2),
1971                     .clk (clk), .se(se), .si(), .so());
1972   assign fcl_dtu_hprivmode_w2 = hpriv_mode_w2;
1973
1974   // determine if priv page has been accessed in non priv mode
1975   // or if we have fallen into the VA hole
1976   assign inst_acc_exc_s1 = (priv_inst_s1 & ~(priv_mode_s1 | hpriv_mode_s1) & 
1977                                               ~tlbmiss_s1_crit & cam_vld_s1 | 
1978                                               pc_oor_s1) & ~stall_s1 & ~rb_stg_d;
1979   assign pc_oor_s2 = (thr_f[0] & inst_acc_vec_d[0] |
1980                       thr_f[1] & inst_acc_vec_d[1] |
1981                       thr_f[2] & inst_acc_vec_d[2] |
1982                       thr_f[3] & inst_acc_vec_d[3]);
1983   assign pc_oor_s = (tm_fd_l) ? pc_oor_s2 : pc_oor_s1;
1984     
1985   assign inst_acc_vec_s2 = (({4{inst_acc_exc_s1}} & thr_s1) |
1986                                               ({4{inst_acc_exc_e}} & rb_frome) |
1987                                               ({4{inst_acc_exc_d}} & rb_fromd & ~rb_frome) |
1988                                   inst_acc_vec_d & (~thr_d | {4{~inst_vld_d}}) & 
1989                                               ~rb_w2) &
1990                                                ~(clear_s_d1);
1991         
1992   dffr_s #(4) instaccd_reg(.din (inst_acc_vec_s2),
1993                                          .q   (inst_acc_vec_d),
1994                                          .rst (fcl_reset),
1995                                          .clk (clk), .se (se), .si(), .so());
1996
1997   assign inst_acc_exc_d = (thr_d[0] & inst_acc_vec_d[0] |
1998                                              thr_d[1] & inst_acc_vec_d[1] |
1999                                              thr_d[2] & inst_acc_vec_d[2] |
2000                                              thr_d[3] & inst_acc_vec_d[3]);
2001
2002   dff_s #(1) instacce_ff(.din (inst_acc_exc_d),
2003                                  .q   (inst_acc_exc_e),
2004                                  .clk (clk), .se(se), .si(), .so());
2005
2006   // TLU needs to know if this is a priv violtn
2007   assign priv_violtn_e = inst_acc_exc_e & ~fdp_fcl_pc_oor_e;
2008   dff_s #(1) privm_ff(.din (priv_violtn_e),
2009                               .q   (priv_violtn_m),
2010                               .clk (clk),  .se  (se), .si(), .so());
2011
2012   assign ifu_tlu_priv_violtn_m = priv_violtn_m & inst_vld_m & ~kill_curr_m;
2013   
2014   // NIR privilege bit
2015   assign next_nir_privvec = {4{itlb_fcl_priv_s1 & ~stall_s1 & 
2016                                cam_vld_s1}} & thr_s1 |
2017                                   nir_privvec & (~thr_s1 | {4{stall_s1}});
2018
2019   dffr_s #(4) nir_priv_reg(.din (next_nir_privvec),
2020                                          .q   (nir_privvec),
2021                                          .rst (fcl_reset),
2022                                          .clk (clk), .se(se), .si(), .so());
2023   
2024   assign nir_priv_s1 = (nir_privvec[0] & thr_s1[0] |
2025                                           nir_privvec[1] & thr_s1[1] |
2026                                           nir_privvec[2] & thr_s1[2] |
2027                                           nir_privvec[3] & thr_s1[3]);
2028   
2029   assign priv_inst_s1 = ~usenir_s1 ? (itlb_fcl_priv_s1 & cam_vld_s1) : 
2030                                        nir_priv_s1;
2031
2032//-------------------------
2033// Errors
2034//-------------------------
2035
2036   // decide when the errors are valid
2037   assign running_s1 = ~stall_s1 & ~kill_thread_d & ~rb_stg_d & ~pc_oor_s1 &
2038                             ~tlb_cam_miss_s1 & ~retract_inst_d;
2039//   assign ely_running_s1 = ~stall_s1 & ~rb_stg_d & ~pc_oor_s1 &
2040//                           ~tlb_cam_miss_s1 & ~retract_inst_d & ~kill_curr_d;
2041   assign ely_running_s1 = ~stall_s1 & ~rb_stg_d_crit & ~pc_oor_s1 & 
2042                           ~tlb_cam_miss_s1 & ~kill_curr_d;
2043   assign fcl_erb_ievld_s1 = ely_running_s1 & rdreq_s1 & itlb_fcl_imiss_s_l;
2044   assign fcl_erb_tevld_s1 = ely_running_s1 & rdreq_s1;
2045
2046   assign fcl_erb_immuevld_s1 = ely_running_s1 & cam_vld_s1;
2047
2048//   assign fcl_erb_ttevld_s1 = asird_s & rdtag_s;
2049//   assign fcl_erb_tdevld_s1 = asird_s & ~rdtag_s;
2050   
2051   dff_s #(1) d1vld_ff(.din (running_s1),
2052                                 .q   (inst_vld_d1),
2053                                 .clk (clk), .se(se), .si(), .so());
2054//   assign inst_vld_qual_d1 = inst_vld_d1 & ~kill_thread_e &
2055//                                 ~flush_sonly_qual_e & ~rb_stg_e;
2056   assign fcl_erb_inst_vld_d1 = inst_vld_d1;
2057   
2058
2059   // ifetch unc. error
2060   assign ifet_ue_vec_d1 = (erb_fcl_ifet_uevec_d1 |
2061                                  ifet_ue_vec_e & ~val_thr_e) &   // reset
2062                                               ~(clear_s_d1);                 // wins
2063
2064   dffr_s #(4) ifuerr_reg(.din (ifet_ue_vec_d1),
2065                                  .q   (ifet_ue_vec_e),
2066                                  .rst (fcl_reset),
2067                                  .clk (clk), .se(se), .si(), .so());
2068
2069   assign ifet_ue_e = (ifet_ue_vec_e[0] & thr_e[0] | 
2070                                   ifet_ue_vec_e[1] & thr_e[1] | 
2071                                   ifet_ue_vec_e[2] & thr_e[2] | 
2072                                   ifet_ue_vec_e[3] & thr_e[3]);
2073
2074
2075//----------------------
2076// Other I side traps
2077//----------------------
2078   // Determine if we are in Trap Level 0
2079   assign tlzero_s2 = (thr_f[0] & tlzero_vec_d1[0] |
2080                                   thr_f[1] & tlzero_vec_d1[1] |
2081                                   thr_f[2] & tlzero_vec_d1[2] |
2082                                   thr_f[3] & tlzero_vec_d1[3]);
2083   dff_s #(1) tlzd_ff(.din (tlzero_s2),
2084                              .q   (fcl_dtu_tlzero_d),
2085                              .clk (clk), .se(se), .si(), .so());
2086
2087   // Collect all IFU traps
2088   assign trap_e = (immu_miss_e | inst_acc_exc_e | dtu_fcl_illinst_e |
2089                                dtu_fcl_fpdis_e | dtu_fcl_privop_e | ifet_ue_e |
2090                                dtu_fcl_imask_hit_e | dtu_fcl_sir_inst_e) & 
2091                     inst_vld_e;
2092
2093   dff_s trapm_ff(.din (trap_e),
2094                            .q   (trap_m),
2095                            .clk (clk),
2096                            .se  (se), .si(), .so());
2097
2098   assign no_iftrap_m = ~ifu_tlu_ttype_vld_m;
2099   dff_s trapw_ff(.din (no_iftrap_m),
2100                            .q   (no_iftrap_w),
2101                            .clk (clk),
2102                            .se  (se), .si(), .so());
2103   
2104   // south is very critical
2105   assign ifu_tlu_ttype_vld_m = (trap_m & inst_vld_m | 
2106                                 disr_trap_m) & ~kill_curr_m & ~kill_local_m;
2107   // less critical going east
2108   assign ifu_exu_ttype_vld_m = trap_m & inst_vld_m;
2109
2110   // less critical going southwest
2111   assign ifu_mmu_trap_m = trap_m;
2112
2113   // less critical going south   
2114   assign ifu_tlu_trap_m = trap_m;
2115   
2116   // trap type priority encode
2117   // Decreasing priority is
2118   //   pc out of range           i_acc_exc
2119   //   immu parity error         i_acc_err
2120   //   immu miss                 i_acc_mmu_ms
2121   //   icache/tag parity error   i_acc_err
2122   //   privilege page            i_acc_exc
2123   //   privilege opcode          priv_opc
2124   //   illegal non-fp inst       ill_inst
2125   //   soft reset                sir
2126   //   fp disabled               fp_disabled
2127   //   illegal fp instruction    ill_inst
2128
2129   // Clean this up!!
2130   assign ttype_sel_spuma_e = spuint1_qual_e;
2131   assign ttype_sel_spuenc_e = spuint0_qual_e;
2132   assign ttype_sel_corr_err_e = ceint_qual_e;
2133   assign ttype_sel_unc_err_e = ueint_qual_e;
2134   assign ttype_sel_res_err_e = rerr_qual_e;
2135   assign ttype_sel_hstk_cmp_e = hintp_qual_e;
2136   
2137   assign ttype_sel_pcoor_e = fdp_fcl_pc_oor_e & inst_acc_exc_e;
2138   assign ttype_sel_icache_err_e = ifet_ue_e; 
2139   assign ttype_sel_immu_miss_e = ~fdp_fcl_pc_oor_e & immu_miss_e & 
2140                                  ~addr_real_e;
2141   assign ttype_sel_real_trans_e = ~fdp_fcl_pc_oor_e & immu_miss_e & 
2142                                   addr_real_e;   
2143   assign ttype_sel_priv_viol_e = ~fdp_fcl_pc_oor_e & ~immu_miss_e & 
2144                                   inst_acc_exc_e;
2145   assign ttype_sel_ibe_e = ~fdp_fcl_pc_oor_e & ~immu_miss_e & 
2146                                ~inst_acc_exc_e & dtu_fcl_imask_hit_e;
2147   assign ttype_sel_privop_e = ~fdp_fcl_pc_oor_e & ~immu_miss_e & 
2148                               ~inst_acc_exc_e & dtu_fcl_privop_e;
2149   assign ttype_sel_illinst_e = ~fdp_fcl_pc_oor_e & ~immu_miss_e & 
2150                                ~inst_acc_exc_e & dtu_fcl_illinst_e;
2151   assign ttype_sel_sir_e = ~fdp_fcl_pc_oor_e & ~immu_miss_e & 
2152                            ~inst_acc_exc_e & ~dtu_fcl_illinst_e &
2153                             dtu_fcl_sir_inst_e;
2154   
2155   assign ttype_sel_fpdis_e = ~fdp_fcl_pc_oor_e & ~immu_miss_e & 
2156                              ~inst_acc_exc_e & ~dtu_fcl_illinst_e &
2157                               dtu_fcl_fpdis_e;
2158
2159   // mux in the trap type
2160   assign ttype_e[8:0] = ttype_sel_unc_err_e    ? `DATA_ERR  :
2161                   ttype_sel_hstk_cmp_e   ? `HSTICK_CMP    :
2162                         ttype_sel_spuma_e      ? `SPU_MAINT     :
2163                         ttype_sel_spuenc_e     ? `SPU_ENCINT    :
2164                         ttype_sel_corr_err_e   ? `CORR_ECC_ERR  :
2165                   ttype_sel_res_err_e    ? `RESUMABLE_ERR :
2166         
2167                         ttype_sel_pcoor_e      ? `INST_ACC_EXC  :
2168                         ttype_sel_immu_miss_e  ? `FAST_MMU_MS   :
2169                         ttype_sel_real_trans_e ? `REAL_TRANS_MS :
2170                         ttype_sel_icache_err_e ? `INST_ACC_ERR  :
2171                         ttype_sel_priv_viol_e  ? `INST_ACC_EXC  :
2172                         ttype_sel_ibe_e        ? `INST_BRK_PT   :
2173                         ttype_sel_privop_e     ? `PRIV_OPC :
2174                         ttype_sel_illinst_e    ? `ILL_INST :
2175                         ttype_sel_sir_e        ? `SIR      :
2176                         ttype_sel_fpdis_e      ? `FP_DISABLED :
2177                                                   9'h1ff;
2178
2179   dff_s #(9) ttype_reg(.din (ttype_e[8:0]),
2180                                .q   (ifu_tlu_ttype_m[8:0]),
2181                                .clk (clk), .se(se), .si(), .so());
2182         
2183//------------------------------
2184// Interrupts and Resets
2185//------------------------------
2186   // Process resets to see if they are sync or async
2187   assign intr_in_pipe = ({4{intr_vld_d}} & thr_d |
2188                          {4{intr_vld_e}} & thr_e |
2189                          {4{intr_vld_m}} & thr_m |
2190                          {4{intr_vld_w}} & thr_w);
2191
2192//   assign async_rst_i2 = tlu_ifu_rstthr_i2  & {4{tlu_ifu_rstint_i2}} &
2193   assign async_rst_i3 = (rstint_i3 | nuke_thr_i3 | resumint_i3) & 
2194                           ~dtu_fcl_thr_active & ~intr_in_pipe;
2195
2196   dff_s #(4) asyrst4_reg(.din (async_rst_i3),
2197                        .q   (async_rst_i4),
2198                        .clk (clk), .se(se), .si(), .so());
2199   
2200   // stall pipe before switching in rst thread
2201   assign rst_stallreq_d0 = (|async_rst_i4[3:0]);
2202   assign rst_stallreq = rst_stallreq_d0 | rst_stallreq_d1 | rst_stallreq_d2;
2203
2204   dff_s #(2) stlreq_reg(.din ({lsu_ifu_stallreq,
2205                              ffu_ifu_stallreq}),
2206                       .q   ({lsu_stallreq_d1,
2207                              ffu_stallreq_d1}),
2208                       .clk (clk), .se(se), .si(), .so());
2209   
2210   assign all_stallreq = ifq_fcl_stallreq | lsu_stallreq_d1 | 
2211                         ffu_stallreq_d1 | itlb_starv_alert;
2212
2213   // leave out stall from ifq which goes directly to swl
2214   assign fcl_dtu_stall_bf = lsu_stallreq_d1 | ffu_stallreq_d1 | 
2215                             itlb_starv_alert | rst_stallreq;
2216
2217   // priority encode rst interrupts
2218   // this could lead to obvious starvation of thr3, the assumption is that
2219   // idle/resume/reset interrupts do not occur very frequently
2220   assign rstint_penc[0] = async_rst_i4[0];
2221   assign rstint_penc[1] = ~async_rst_i4[0] & async_rst_i4[1];
2222   assign rstint_penc[2] = ~async_rst_i4[0] & ~async_rst_i4[1]  & 
2223                                  async_rst_i4[2];
2224   assign rstint_penc[3] = ~async_rst_i4[0] & ~async_rst_i4[1]  & 
2225                                 ~async_rst_i4[2];
2226
2227   // BF - switch in rst thread
2228   dff_s #(1) asyncr1_ff(.din (rst_stallreq_d0),
2229                                   .q   (rst_stallreq_d1),
2230                                   .clk (clk), .se(se), .si(), .so());
2231   assign arst_vld_f_l = ~arst_vld_f;
2232   assign arst_vld_s_l = ~arst_vld_s;
2233   bw_u1_nand3_4x UZsize_rstsw_n3(.z (rst_sw_bf_l),
2234                                  .a (arst_vld_f_l),
2235                                  .b (arst_vld_s_l),
2236                                  .c (rst_stallreq_d1));
2237   assign rst_sw_bf = ~rst_sw_bf_l;
2238
2239   // double check if asyn intrs are still valid
2240   assign sw_for_real_rst_bf = rst_sw_bf & rst_stallreq_d0;
2241   
2242   // F
2243   dff_s #(1) asyncr2_ff(.din (sw_for_real_rst_bf),
2244                                   .q   (rst_stallreq_d2),
2245                                   .clk (clk), .se(se), .si(), .so());
2246//   assign arst_vld_f = rst_stallreq_d2 & any_rstnuke_f;
2247   assign arst_vld_f = rst_stallreq_d2;   
2248
2249   // hold thread till reset of curr thread is processed
2250//   assign rst_thr_bf = arst_vld_f ? thr_f : rstint_penc;
2251   
2252   // S issue to pipe
2253   dff_s #(1) rstvlds_ff(.din (arst_vld_f),
2254                                   .q   (arst_vld_s),
2255                                   .clk (clk), .se(se), .si(), .so());
2256   assign async_intr_vld_s = arst_vld_s & ~kill_intr_f; // & any_rstnuke_f
2257
2258
2259   //
2260   // thread wise interrupts
2261   //
2262   assign rstint_i2 = {4{tlu_ifu_rstint_i2}} & tlu_ifu_rstthr_i2;
2263   assign resumint_i2 = {4{tlu_ifu_resumint_i2}} & tlu_ifu_rstthr_i2;
2264   assign nuke_thr_i2 =  {4{tlu_ifu_nukeint_i2}} & tlu_ifu_rstthr_i2;
2265
2266   assign next_rst_i2 = rstint_i2 | 
2267                              rstint_i3 & (~(thr_w & {4{fcl_dtu_rst_thr_w}}));
2268   assign next_resum_i2 = resumint_i2 | 
2269                                resumint_i3 & (~(thr_w & {4{fcl_dtu_resum_thr_w}})) 
2270                          & ~rstint_i2;
2271
2272   assign next_nuke_i2  = (nuke_thr_i2 | nuke_thr_i3) & 
2273                            (~(thr_w & {4{fcl_dtu_nuke_thr_w}})) & 
2274                               ~(rstint_i2 | resumint_i2);
2275
2276   assign next_sftint_i2 = tlu_ifu_sftint_vld;
2277   assign next_hwint_i3 = tlu_ifu_hwint_i3;
2278   assign next_hintp_i2 = tlu_ifu_hintp_vld;
2279   assign next_rerr_i2 = tlu_ifu_rerr_vld;
2280   
2281   assign next_ceint_i2 = erb_fcl_ce_trapvec |
2282                                ceint_i3 & (~(thr_w & {4{ceint_qual_w}}));
2283
2284   assign next_ueint_i2 = erb_fcl_ue_trapvec |
2285                                ueint_i3 & (~(thr_w & {4{ueint_qual_w}}));
2286
2287   // From Farnad: tid is ready several cycles before everything else
2288   // I will assume 1 cycle before in the ifu
2289   dff_s #(2) sptid_reg(.din (spu_ifu_ttype_tid_w2),
2290                      .q   (spu_tid_w2),
2291                      .clk (clk), .se(se), .so(), .si());
2292   
2293   assign spu_thr[0] = ~spu_tid_w2[1] & ~spu_tid_w2[0];
2294   assign spu_thr[1] = ~spu_tid_w2[1] &  spu_tid_w2[0];
2295   assign spu_thr[2] =  spu_tid_w2[1] & ~spu_tid_w2[0];
2296   assign spu_thr[3] =  spu_tid_w2[1] &  spu_tid_w2[0];
2297
2298   assign next_spuint1_i2 = {4{spu_ifu_ttype_vld_w2 & spu_ifu_ttype_w2}} & 
2299                                  spu_thr & ~erb_fcl_spu_uetrap |
2300                                  spuint1_i3 & ~({4{spuint1_w}} & thr_w);
2301
2302   assign next_spuint0_i2 = {4{spu_ifu_ttype_vld_w2 & ~spu_ifu_ttype_w2}} & 
2303                                  spu_thr & ~erb_fcl_spu_uetrap |
2304                                  spuint0_i3 & ~({4{spuint0_w}} & thr_w);
2305
2306
2307   dffr_s #(4) rst_reg(.din  (next_rst_i2),
2308                                 .q    (rstint_i3),
2309                                 .clk  (clk),
2310                                 .rst  (fcl_reset),
2311                                 .se   (se), .si(), .so());
2312
2313   dffr_s #(4) resum_reg(.din  (next_resum_i2),
2314                                   .q    (resumint_i3),
2315                                   .clk  (clk),
2316                                   .rst  (fcl_reset),
2317                                   .se   (se), .si(), .so());
2318
2319   dffr_s #(4) nuke_reg(.din  (next_nuke_i2),
2320                                  .q    (nuke_thr_i3),
2321                                  .rst  (fcl_reset),
2322                                  .clk  (clk),
2323                                  .se   (se), .si(), .so());
2324
2325   dffr_s #(4) sfti_reg(.din  (next_sftint_i2),
2326                                  .q    (sftint_i3),
2327                                  .rst  (fcl_reset),
2328                                  .clk  (clk), .se   (se), .si(), .so());
2329   dffr_s #(4) hstki_reg(.din  (next_hintp_i2),
2330                                  .q    (hintp_i3),
2331                                  .rst  (fcl_reset),
2332                                  .clk  (clk), .se   (se), .si(), .so());
2333   dffr_s #(4) reri_reg(.din  (next_rerr_i2),
2334                                  .q    (rerr_i3),
2335                                  .rst  (fcl_reset),
2336                                  .clk  (clk), .se   (se), .si(), .so());
2337   dffr_s #(4) hwi_reg(.din  (next_hwint_i3),
2338                                 .q    (hwint_i4),
2339                                 .rst  (fcl_reset),
2340                                 .clk  (clk), .se   (se), .si(), .so());
2341
2342   dffr_s #(4) spui0_reg(.din  (next_spuint0_i2),
2343                                   .q    (spuint0_i3),
2344                                   .rst  (fcl_reset),
2345                                   .clk  (clk), .se   (se), .si(), .so());
2346   
2347   dffr_s #(4) spui1_reg(.din  (next_spuint1_i2),
2348                                   .q    (spuint1_i3),
2349                                   .rst  (fcl_reset),
2350                                   .clk  (clk), .se   (se), .si(), .so());
2351
2352   dffr_s #(4) cei_reg(.din  (next_ceint_i2),
2353                                 .q    (ceint_i3),
2354                                 .rst  (fcl_reset),
2355                                 .clk  (clk), .se   (se), .si(), .so());
2356
2357   dffr_s #(4) uei_reg(.din  (next_ueint_i2),
2358                                 .q    (ueint_i3),
2359                                 .rst  (fcl_reset),
2360                                 .clk  (clk), .se   (se), .si(), .so());
2361
2362   assign supv_int_en = (~tlu_hpstate_priv | ~tlu_hpstate_enb) & 
2363                         tlu_ifu_pstate_ie & dtu_fcl_thr_active;
2364   assign hypv_int_en = ~tlu_hpstate_priv & tlu_hpstate_enb | 
2365                        tlu_ifu_pstate_ie & dtu_fcl_thr_active;
2366   
2367   dff_s #(4) spvie_ff(.din (supv_int_en),
2368                     .q   (supv_int_en_d1),
2369                     .clk (clk), .se(se), .si(), .so());
2370   dff_s #(4) hpvie_ff(.din (hypv_int_en),
2371                     .q   (hypv_int_en_d1),
2372                     .clk (clk), .se(se), .si(), .so());
2373
2374   // force an interrupt by putting nop on pipe
2375   // use this signal instead of hw_int_s to help with crit path
2376   assign supv_masked_intr_s = (sftint_i3        |
2377                                                  rerr_i3);
2378   assign hypv_masked_intr_s = (hwint_i4         |
2379                                                  hintp_i3         |
2380                                                  ceint_i3         |
2381                                                  ueint_i3         |
2382                                                  spuint0_i3       |
2383                                                  spuint1_i3);
2384
2385   assign fcl_swl_int_activate_i3 = hypv_masked_intr_s |
2386                                    supv_masked_intr_s;
2387
2388    // keep track of rolled back interrupts
2389   assign intr_pending_nxt =  (({4{intr_vld_e}} & rb_frome) |
2390                               ({4{intr_vld_d}} & rb_fromd & ~rb_frome) |
2391                                intr_pending_s) & ~clear_s_d1;
2392   
2393   dffr_s #(4) ipend_reg(.din (intr_pending_nxt),
2394                       .q   (intr_pending_s),
2395                       .rst (fcl_reset),
2396                       .clk (clk), .se(se), .si(), .so());
2397
2398   assign any_intr_vec_f = (supv_masked_intr_s & supv_int_en_d1 |
2399                            hypv_masked_intr_s & hypv_int_en_d1 |
2400                            intr_pending_s    |
2401                                              rstint_i3         |
2402                            resumint_i3       |
2403                                              nuke_thr_i3);
2404
2405   dff_s #(4) anyints_reg(.din (any_intr_vec_f),
2406                        .q   (any_intr_vec_s),
2407                        .clk (clk), .se(se), .si(), .so());
2408                       
2409   assign force_intr_s = (thr_f_crit[0] & any_intr_vec_s[0] |
2410                          thr_f_crit[1] & any_intr_vec_s[1] |
2411                          thr_f_crit[2] & any_intr_vec_s[2] |
2412                          thr_f_crit[3] & any_intr_vec_s[3]) &
2413                                 ~kill_intr_f;
2414
2415   // interrupt and reset signal pipe
2416   // VA hole trap has higher priority than interrupt
2417   //   - since the VA hole marker is lost once the intr is taken
2418   assign intr_vld_s = force_intr_s & (valid_s & ~pc_oor_s | 
2419                                       async_intr_vld_s);
2420
2421   assign intr_vld_qual_s = intr_vld_s & ~iferrto_thisthr_d1;
2422   dff_s #(1) any_intrd_ff(.din (intr_vld_qual_s),
2423                                     .q   (intr_vld_d), 
2424                                     .clk (clk),       
2425                                     .se  (se), .so(), .si());
2426   assign fcl_dec_intr_vld_d = intr_vld_d;
2427   assign intr_vld_qual_d = intr_vld_d & ~kill_intr_d & ~kill_thread_d & 
2428                                   ~rb_stg_d;
2429
2430   dff_s #(1) intr_vlde_ff(.din (intr_vld_qual_d),
2431                                   .q   (intr_vld_e),
2432                                   .clk (clk), .se  (se), .so(), .si());
2433
2434   assign intr_vld_qual_e = intr_vld_e & ~kill_curr_e & ~rb_stg_e & 
2435                            ~kill_intr_e & ~dtu_inst_anull_e &
2436                      ~(thr_match_em & ifu_tlu_flush_m);
2437   
2438   dff_s #(1) intr_vldm_ff(.din (intr_vld_qual_e),
2439                                   .q   (intr_vld_m),
2440                                   .clk (clk), .se  (se), .so(), .si());
2441
2442   assign intr_vld_qual_m = intr_vld_m & ~kill_thread_m & ~mark4rb_m;
2443
2444   dff_s #(1) intr_vldw_ff(.din (intr_vld_qual_m),
2445                                   .q   (intr_vld_w),
2446                                   .clk (clk), .se  (se), .so(), .si());
2447
2448   // Reset and Idle are prioritized in M.  All others in E
2449   // reset interrupt
2450   assign rstint_m = (rstint_i3[0] & thr_m[0] |
2451                                        rstint_i3[1] & thr_m[1] |
2452                                        rstint_i3[2] & thr_m[2] |
2453                                        rstint_i3[3] & thr_m[3]);
2454
2455   assign ifu_tlu_rstint_m = rstint_m & intr_vld_m & ~kill_local_m & 
2456                             ~kill_curr_m;
2457//   assign rstint_qual_m = rstint_m & ~ely_kill_thread_m & intr_vld_m;
2458   dff_s #(1) rstw_ff(.din (rstint_m),
2459                    .q   (rst_thr_w),
2460                    .clk (clk), .se(se), .si(), .so());
2461   assign fcl_dtu_rst_thr_w = rst_thr_w & intr_vld_w;
2462
2463   // resume interrupt
2464   assign resumint_m = (resumint_i3[0] & thr_m[0] |
2465                                          resumint_i3[1] & thr_m[1] |
2466                                          resumint_i3[2] & thr_m[2] |
2467                                          resumint_i3[3] & thr_m[3]);
2468   assign resumint_qual_m = resumint_m & ~rstint_m;
2469   
2470   dff_s #(1) resumw_ff(.din (resumint_qual_m),
2471                      .q   (resum_thr_w),
2472                      .clk (clk), .se(se), .si(), .so());
2473   assign fcl_dtu_resum_thr_w = resum_thr_w & intr_vld_w;
2474
2475   // idle interrupt
2476   assign nuke_thr_m = (nuke_thr_i3[0] & thr_m[0] |
2477                                                nuke_thr_i3[1] & thr_m[1] |
2478                                                nuke_thr_i3[2] & thr_m[2] |
2479                                                nuke_thr_i3[3] & thr_m[3]);
2480
2481   assign nuke_thr_qual_m = nuke_thr_m & ~rstint_m & ~resumint_m;
2482
2483   dff_s #(1) nukw_ff(.din (nuke_thr_qual_m),
2484                    .q   (nuke_thr_w),
2485                    .clk (clk),
2486                    .se  (se), .si(), .so());
2487   assign fcl_dtu_nuke_thr_w = nuke_thr_w & intr_vld_w;
2488   
2489   // uncorrected ecc
2490   assign ueint_e = (ueint_i3[0] & thr_e[0] & hypv_int_en_d1[0] |
2491                                 ueint_i3[1] & thr_e[1] & hypv_int_en_d1[1] |
2492                                 ueint_i3[2] & thr_e[2] & hypv_int_en_d1[2] |
2493                                 ueint_i3[3] & thr_e[3] & hypv_int_en_d1[3]);
2494   assign ueint_qual_e = ueint_e & intr_vld_e;
2495
2496   dff_s #(1) uem_ff (.din (ueint_qual_e),
2497                    .q   (ueint_m),
2498                    .clk (clk), .se (se), .si(), .so());
2499                   
2500//   assign ueint_m = (ueint_i3[0] & thr_m[0] |
2501//                               ueint_i3[1] & thr_m[1] |
2502//                               ueint_i3[2] & thr_m[2] |
2503//                               ueint_i3[3] & thr_m[3]);
2504   
2505   assign ueint_trap_m = ueint_m & intr_vld_m & 
2506                         ~(rstint_m | resumint_m | nuke_thr_m);
2507   
2508//   assign ueint_qual_m = ueint_trap_m & ~ely_kill_thread_m;
2509   dff_s #(1) ueintw_ff(.din (ueint_trap_m),
2510                      .q   (ueint_trap_w),
2511                      .clk (clk), .se(se), .si(), .so());
2512   assign ueint_qual_w = ueint_trap_w & intr_vld_w;
2513
2514   // hstk match interrupt
2515   assign hintp_e = (hintp_i3[0] & thr_e[0] & hypv_int_en_d1[0] |
2516                                       hintp_i3[1] & thr_e[1] & hypv_int_en_d1[1] |
2517                                       hintp_i3[2] & thr_e[2] & hypv_int_en_d1[2] |
2518                                       hintp_i3[3] & thr_e[3] & hypv_int_en_d1[3]);
2519   assign hintp_qual_e = hintp_e & intr_vld_e & ~ueint_e;
2520
2521   dff_s #(1) hintpm_ff (.din (hintp_qual_e),
2522                       .q   (hintp_m),
2523                       .clk (clk), .se (se), .si(), .so());
2524
2525//   assign ifu_tlu_hintp_m = hintp_m & ~kill_local_m & intr_vld_m &
2526//                          ~(rstint_m | nuke_thr_m | ueint_m);
2527   
2528   // hw int
2529   assign hwint_e = (hwint_i4[0] & thr_e[0] & hypv_int_en_d1[0] |
2530                                       hwint_i4[1] & thr_e[1] & hypv_int_en_d1[1] |
2531                                       hwint_i4[2] & thr_e[2] & hypv_int_en_d1[2] |
2532                                       hwint_i4[3] & thr_e[3] & hypv_int_en_d1[3]);
2533   dff_s #(1) hwe_ff(.din (hwint_e),
2534                   .q   (hwint_m),
2535                   .clk (clk), .se(se), .si(), .so());
2536
2537   assign ifu_tlu_hwint_m = hwint_m & intr_vld_m & ~kill_local_m &
2538                     ~kill_curr_m & 
2539                           ~(rstint_m | resumint_m | nuke_thr_m | ueint_m | hintp_m);
2540   
2541
2542   // spu interrupt
2543   assign spuint1_e = (spuint1_i3[0] & thr_e[0] & hypv_int_en_d1[0] |
2544                                   spuint1_i3[1] & thr_e[1] & hypv_int_en_d1[1] |
2545                                   spuint1_i3[2] & thr_e[2] & hypv_int_en_d1[2] |
2546                                   spuint1_i3[3] & thr_e[3] & hypv_int_en_d1[3]);
2547   assign spuint1_qual_e = spuint1_e & intr_vld_e & ~ueint_e & ~hintp_e;
2548
2549//   assign spuint1_m = (spuint1_i3[0] & thr_m[0] |
2550//                                 spuint1_i3[1] & thr_m[1] |
2551//                                 spuint1_i3[2] & thr_m[2] |
2552//                                 spuint1_i3[3] & thr_m[3]);
2553
2554   dff_s #(1) spu1m_ff(.din (spuint1_qual_e),
2555                     .q   (spuint1_m),
2556                     .clk (clk), .se(se), .si(), .so());
2557
2558   assign spuint1_trap_m = spuint1_m & intr_vld_m & 
2559                            ~(rstint_m | resumint_m | nuke_thr_m | hwint_m);
2560
2561//   assign spuint1_qual_m = spuint1_trap_m & ~ely_kill_thread_m;
2562   
2563   dff_s #(1) spiw1_ff(.din (spuint1_trap_m),
2564                                 .q   (spuint1_trap_w),
2565                                 .clk (clk), .se(se), .si(), .so());
2566   assign spuint1_w = spuint1_trap_w & intr_vld_w;
2567   
2568   assign spuint0_e = (spuint0_i3[0] & thr_e[0] & hypv_int_en_d1[0] |
2569                                   spuint0_i3[1] & thr_e[1] & hypv_int_en_d1[1] |
2570                                   spuint0_i3[2] & thr_e[2] & hypv_int_en_d1[2] |
2571                                   spuint0_i3[3] & thr_e[3] & hypv_int_en_d1[3]);
2572   
2573   assign spuint0_qual_e = spuint0_e & intr_vld_e & ~ueint_e &
2574                                             ~spuint1_e & ~hintp_e;
2575
2576//   assign spuint0_m = (spuint0_i3[0] & thr_m[0] |
2577//                                 spuint0_i3[1] & thr_m[1] |
2578//                                 spuint0_i3[2] & thr_m[2] |
2579//                                 spuint0_i3[3] & thr_m[3]);
2580   dff_s #(1) spu0m_ff(.din (spuint0_qual_e),
2581                     .q   (spuint0_m),
2582                     .clk (clk), .se(se), .si(), .so());
2583
2584   assign spuint0_trap_m = spuint0_m & intr_vld_m &
2585                        ~(rstint_m | nuke_thr_m | resumint_m |
2586                                    hwint_m);
2587   
2588//   assign spuint0_qual_m = spuint0_trap_m & ~kill_thread_m;
2589
2590   dff_s #(1) spiw0_ff(.din (spuint0_trap_m),
2591                                 .q   (spuint0_trap_w),
2592                                 .clk (clk), .se(se), .si(), .so());
2593   assign spuint0_w = spuint0_trap_w & intr_vld_w;
2594   
2595//   assign ifu_spu_trap_ack = {spuint1_w, spuint0_w};
2596   assign ifu_spu_trap_ack = spuint1_w;   
2597   
2598   
2599   // software interrupts
2600   assign sftint_e = (sftint_i3[0] & thr_e[0] & supv_int_en_d1[0] |
2601                                        sftint_i3[1] & thr_e[1] & supv_int_en_d1[1] |
2602                                        sftint_i3[2] & thr_e[2] & supv_int_en_d1[2] |
2603                                        sftint_i3[3] & thr_e[3] & supv_int_en_d1[3]);
2604
2605   assign sftint_qual_e = sftint_e & ~spuint0_e & intr_vld_e & 
2606                          ~ueint_e & ~spuint1_e & ~hintp_e;
2607   
2608   dff_s #(1) swm_ff(.din (sftint_qual_e),
2609                   .q   (sftint_m),
2610                   .clk (clk), .se(se), .si(), .so());
2611
2612   // if nothing else, signal sftint!
2613//   assign ifu_tlu_sftint_m = (sftint_m &
2614//                                  ~(rstint_m | nuke_thr_m | hintp_m | resumint_m |
2615//                                                      hwint_m | spuint1_m | spuint0_m | ueint_m) |
2616//                              ~(ceint_m | rerr_m)) &
2617//                               ~kill_local_m & intr_vld_m;
2618
2619   assign ifu_tlu_sftint_m = (sftint_m & 
2620                                    ~(rstint_m | nuke_thr_m | hintp_m | resumint_m |
2621                                                        hwint_m | spuint1_m | spuint0_m | ueint_m)) & 
2622                               ~kill_local_m & ~kill_curr_m & intr_vld_m;
2623   
2624
2625   // corrected ecc interrupt
2626   assign ceint_e = (ceint_i3[0] & thr_e[0] & hypv_int_en_d1[0] |
2627                                 ceint_i3[1] & thr_e[1] & hypv_int_en_d1[1] |
2628                                 ceint_i3[2] & thr_e[2] & hypv_int_en_d1[2] |
2629                                 ceint_i3[3] & thr_e[3] & hypv_int_en_d1[3]);
2630   assign ceint_qual_e = ceint_e & intr_vld_e & ~ueint_e & 
2631                          ~spuint1_e & ~spuint0_e & ~hintp_e;
2632
2633//   assign ceint_m = (ceint_i3[0] & thr_m[0] |
2634//                               ceint_i3[1] & thr_m[1] |
2635//                               ceint_i3[2] & thr_m[2] |
2636//                               ceint_i3[3] & thr_m[3]);
2637   dff_s #(1) cem_ff(.din (ceint_qual_e),
2638                   .q   (ceint_m),
2639                   .clk (clk), .se(se), .si(), .so());
2640   
2641   assign ceint_trap_m = ceint_m & intr_vld_m & 
2642                         ~(rstint_m | nuke_thr_m | resumint_m |
2643                                 sftint_m | hwint_m);
2644   
2645//   assign ceint_qual_m = ceint_trap_m & ~ely_kill_thread_m;
2646   dff_s #(1) ceintw_ff(.din (ceint_trap_m),
2647                      .q   (ceint_trap_w),
2648                      .clk (clk), .se(se), .si(), .so());
2649   assign ceint_qual_w = ceint_trap_w & intr_vld_w;
2650
2651   // resumable error interrupt
2652   assign rerr_e = (rerr_i3[0] & thr_e[0] & supv_int_en_d1[0] |
2653                                 rerr_i3[1] & thr_e[1] & supv_int_en_d1[1] |
2654                                 rerr_i3[2] & thr_e[2] & supv_int_en_d1[2] |
2655                                 rerr_i3[3] & thr_e[3] & supv_int_en_d1[3]);
2656   assign rerr_qual_e = rerr_e & intr_vld_e & ~ueint_e & ~ceint_e &
2657                        ~spuint1_e & ~spuint0_e & ~hintp_e;
2658   
2659   dff_s #(1) rem_ff(.din (rerr_qual_e),
2660                   .q   (rerr_m),
2661                   .clk (clk), .se(se), .si(), .so());
2662   
2663//   assign rerr_m = (rerr_i3[0] & thr_m[0] |
2664//                                    rerr_i3[1] & thr_m[1] |
2665//                                    rerr_i3[2] & thr_m[2] |
2666//                                    rerr_i3[3] & thr_m[3]);
2667
2668//   assign ifu_tlu_rerr_m = rerr_m & ~kill_local_m & intr_vld_m &
2669//                          ~(rstint_m | nuke_thr_m | ueint_m | ceint_m);
2670
2671   assign disr_trap_m = (ueint_m | hintp_m | spuint0_m | spuint1_m |
2672                         ceint_m | rerr_m) & ~rstint_m & ~nuke_thr_m &
2673                          ~resumint_m & intr_vld_m;
2674
2675   // check if a scheduled interrupt evaporated...
2676   assign any_intr_m = (ueint_m | ceint_m | spuint0_m | spuint1_m |
2677                        hintp_m | rerr_m | sftint_m | hwint_m | 
2678                        rstint_m | nuke_thr_m | resumint_m);
2679   
2680   // ..and rollback if that is the case
2681   assign rb_intr_m = ~any_intr_m & intr_vld_m;
2682   dff_s #(1) rbint_ff(.din (rb_intr_m),
2683                     .q   (rb_intr_w),
2684                     .clk (clk), .se(se), .si(), .so());
2685
2686   // use synchronous interrupt signal to switch out thread in swl
2687//   assign fcl_dtu_sync_intr_d = (intr_vld_d | immu_miss_crit_d) & ~rb_stg_d;
2688   assign fcl_dtu_sync_intr_d = (intr_vld_d) & ~rb_stg_d_crit;   
2689   
2690   // kill the next three interrupts.  After that you are on your own.
2691//   assign kill_intr_m = ((thr_m & thr_w) == 4'b0) ?
2692//                                          1'b0 : (intr_vld_w);
2693   assign kill_intr_e = ((thr_e & thr_w) == 4'b0) ?
2694                                            1'b0 : (intr_vld_w);
2695   assign kill_intr_d = ((thr_d & thr_w) == 4'b0) ?
2696                                            1'b0 : (intr_vld_w);
2697   assign kill_intr_f = ((thr_f & thr_w) == 4'b0) ?
2698                                            1'b0 : (intr_vld_w);
2699
2700//--------------------------------
2701// check if we are in a delay slot
2702//--------------------------------
2703   // remember if the current instruction is a delay slot
2704   assign delay_slot_vec_nxt = ({4{dtu_fcl_br_inst_d & inst_vld_d & 
2705                                   ~rb_stg_d}} & thr_d | // set
2706                                delay_slot_vec &
2707                                ~(thr_d & {4{inst_vld_d &
2708                                             ~rb_stg_d &
2709                                             ~intr_vld_d}})) &
2710                                 ~(trap_thr & {4{trappc_vld_w2}});
2711                                // & ~late_flush_w2;
2712   // Need to be a little pessimitic: can't clear the delay slot vec
2713   // after a utrap, since we may still be in the delay slot when we
2714   // re-execute
2715
2716   dffr_s #(4) ds_reg(.din (delay_slot_vec_nxt),
2717                    .q   (delay_slot_vec),
2718                    .rst (fcl_reset),
2719                    .clk (clk), .se(se), .si(), .so());
2720   assign fcl_dec_dslot_s = (delay_slot_vec[0] & thr_f[0] |
2721                             delay_slot_vec[1] & thr_f[1] |
2722                             delay_slot_vec[2] & thr_f[2] |
2723                             delay_slot_vec[3] & thr_f[3]);
2724   
2725
2726//------------------------------
2727// NIR control
2728//------------------------------
2729   // use nir if va[2] of previous fetch is a zero (i.e lower word)
2730   dff_s #(1) va2_ff(.din (fdp_fcl_va2_bf),
2731                               .clk (clk),
2732                               .q   (va2_f),
2733                               .se  (se), .si(), .so());
2734   
2735   assign usep_bf = rdreq_f & ~va2_f & ~ntpc_thisthr & ~stall_f;
2736   assign set_usen_bf = usep_bf & ~ely_stall_thisthr_f & dtu_fcl_running_s;
2737   
2738   // need to kill usen if trap or interrupt or flush
2739   assign thr_usen_nxt = ({4{set_usen_bf}} &  thr_f  |    // set usen
2740                                            thr_usen_bf  & ~val_thr_f) &    // keep old value
2741                                             ~((thr_d & {4{dtu_fcl_br_inst_d}})  |
2742                                         (thr_s1 & {4{ic_miss_s1}})  |
2743                             (thr_e & {4{erb_dtu_ifeterr_d1 & inst_vld_d1}}) |
2744                                               (clear_s_d1) |
2745                                               (ntpc_vld)  |
2746                                               (rb_w2 | rb_froms));     // reset usen (wins)
2747                         // & ~dtu_fcl_flush_nir
2748   
2749   dffr_s #(4) thr_usen_reg(.din  (thr_usen_nxt),
2750                                          .clk  (clk),
2751                                          .q    (thr_usen_bf),
2752                                          .rst  (fcl_reset),
2753                                          .se   (se), .si(), .so());
2754   
2755   /*
2756   // Use hand instantiated mux
2757   bw_u1_ao2222_4x UZsize_usn_mx(.z   (usen_iso_bf)
2758                                            .a2  (thr_usen_bf[0]),
2759                                            .b2  (thr_usen_bf[1]),
2760                                            .c2  (thr_usen_bf[2]),
2761                                            .d2  (thr_usen_bf[3]),
2762                                            .a1  (nextthr_bf_buf[0]),
2763                                            .b1  (nextthr_bf_buf[1]),
2764                                            .c1  (nextthr_bf_buf[2]),
2765                                            .d1  (nextthr_bf_buf[3]));
2766
2767    // isolate from critical path
2768    bw_u1_buf_5x  UZsize_usn_iso(.z(usen_bf), .a(usen_iso_bf));
2769    */
2770                               
2771   assign usen_iso_bf = (thr_usen_bf[0] & nextthr_bf_buf[0] |
2772                         thr_usen_bf[1] & nextthr_bf_buf[1] |
2773                         thr_usen_bf[2] & nextthr_bf_buf[2] |
2774                         thr_usen_bf[3] & nextthr_bf_buf[3]);
2775   assign usen_bf = usen_iso_bf;
2776
2777   
2778   
2779//------------------------------
2780// Switch Control
2781//------------------------------   
2782   // Switch IF
2783   //   1. Another thread is ready OR
2784   //   2. We hit a switch condition or Imiss and another thread is
2785   //      speculatively ready
2786   //   3. No thread is running and another thread is speculatively ready
2787   //   4. The DTU calls for a thread switch and another thread is ready
2788   //   (NOTE: if we hit a switch condition or Imiss and no thread is
2789   //    speculatively or otherwise ready we stall the pipe).
2790   //
2791   //   New plan:  switch if another thread is ready or spec ready.
2792   //
2793
2794//   assign switch_bf = dtu_fcl_ntr_s;
2795   bw_u1_buf_20x UZsize_swbuf(.a (dtu_fcl_ntr_s),
2796                              .z (switch_bf));
2797   
2798//   assign switch_bf = dtu_fcl_ntr_s & ~imsto_nextthr_s1;
2799//   assign switch_bf = dtu_fcl_ntr_s & ~(imsto_nextthr_s1 | kill_nextthr_w |
2800//                                        intrto_nextthr_d);   
2801   
2802//   assign fcl_dtu_switch_s = switch_bf & ~all_stallreq & ~rst_stallreq;
2803//   assign fcl_dtu_switch_s = switch_bf & ~kill_nextthr_w;
2804
2805   // TBD: No need to send this anymore, since switch_bf = ntr_s
2806//   assign fcl_dtu_switch_s = switch_bf;  // sw out curr and sw in next
2807
2808   assign fcl_swl_swout_f = stall_f;     // sw out curr but don't sw in next
2809   // Note: need fcl_swl_swout_f and dtu_fcl_running_s to sync swl and
2810   // fcl at all times. 
2811
2812   assign switch_qual_bf = switch_bf & ~rst_stallreq;
2813   dff_s #(1) sw_ff (.din  (switch_qual_bf),
2814                               .clk  (clk),
2815                               .q    (switch_s2),
2816                               .se   (se), .si(), .so());
2817
2818   dff_s #(1) tmfn_ff (.din  (switch_bf),
2819                                 .clk  (clk),
2820                                 .q    (tm_fd_l),
2821                                 .se   (se), .si(), .so());
2822
2823   // need to qual with immu_fault to avoid X's
2824//   assign fcl_dtu_swc_s = fdp_fcl_swc_s2 & inst_vld_s_crit &
2825//                          ~immu_fault_f & ~part_stall_thisthr_f;
2826//   assign fcl_dtu_swc_s = fdp_fcl_swc_s2 & inst_vld_s_crit &
2827//                          ~immu_fault_f & ~imsto_thisthr_s1 & ~rb_stg_s;
2828   assign fcl_swl_swcvld_s = inst_vld_s_crit & ~immu_fault_f & 
2829                             ~imsto_thisthr_s1 & ~rb_stg_s;
2830     
2831
2832//------------------------------   
2833// Thread pipe
2834//------------------------------
2835
2836//`ifdef VERPLEX
2837//   $constraint nthr_1h4 ($one_hot(dtu_fcl_nextthr_bf[3:0]));
2838//   $constraint thrf_1h4 ($one_hot(thr_f[3:0]));
2839//`endif
2840   
2841   // Keep track the thread in each pipe stage
2842   assign rstt = (~fcl_reset & (rst_stallreq_d1 & ~arst_vld_f)) | rst_tri_en;
2843   assign swt =  (~rst_stallreq_d1 & ~arst_vld_f & switch_bf | fcl_reset) & 
2844                   ~rst_tri_en;
2845   assign samet = (~rst_stallreq_d1 & ~switch_bf | arst_vld_f) & 
2846                    ~fcl_reset & ~rst_tri_en;
2847   
2848   mux3ds #(4)  nxttthr_mux(.dout  (thr_bf[3:0]),     
2849                                              .in0   (thr_f[3:0]),       
2850                                              .in1   (nextthr_bf_buf[3:0]),
2851                                              .in2   (rstint_penc[3:0]), 
2852                                              .sel0  (samet),
2853                                              .sel1  (swt),
2854                                              .sel2  (rstt));
2855
2856   assign thr_match_nw = (thr_w[0] & nextthr_bf_buf[0] | 
2857                                            thr_w[1] & nextthr_bf_buf[1] | 
2858                                            thr_w[2] & nextthr_bf_buf[2] | 
2859                                            thr_w[3] & nextthr_bf_buf[3]);
2860
2861   assign thr_match_nd = (thr_d[0] & nextthr_bf_buf[0] | 
2862                                            thr_d[1] & nextthr_bf_buf[1] | 
2863                                            thr_d[2] & nextthr_bf_buf[2] | 
2864                                            thr_d[3] & nextthr_bf_buf[3]);
2865
2866//   assign thr_match_ne = (thr_e[0] & dtu_fcl_nextthr_bf[0] |
2867//                                          thr_e[1] & dtu_fcl_nextthr_bf[1] |
2868//                                          thr_e[2] & dtu_fcl_nextthr_bf[2] |
2869//                                          thr_e[3] & dtu_fcl_nextthr_bf[3]);
2870   // qualify inst_vld_e in fcl itself
2871
2872//   bw_u1_ao2222_4x UZsize_tmne(.z  (thr_match_ne),
2873//                               .a1 (val_thr_e[0]),
2874//                               .b1 (val_thr_e[1]),
2875//                               .c1 (val_thr_e[2]),
2876//                               .d1 (val_thr_e[3]),
2877//                               .a2 (dtu_fcl_nextthr_bf[0]),
2878//                               .b2 (dtu_fcl_nextthr_bf[1]),
2879//                               .c2 (dtu_fcl_nextthr_bf[2]),
2880//                               .d2 (dtu_fcl_nextthr_bf[3]));
2881
2882   wire   tmne_10,
2883          tmne_32;
2884   bw_u1_aoi22_2x UZsize_tmne10(.z (tmne_10),
2885                                .a1 (dtu_fcl_nextthr_bf[0]),
2886                                .b1 (dtu_fcl_nextthr_bf[1]),
2887                                .a2 (val_thr_e[0]),
2888                                .b2 (val_thr_e[1]));
2889   bw_u1_aoi22_2x UZsize_tmne32(.z (tmne_32),
2890                                .a1 (dtu_fcl_nextthr_bf[2]),
2891                                .b1 (dtu_fcl_nextthr_bf[3]),
2892                                .a2 (val_thr_e[2]),
2893                                .b2 (val_thr_e[3]));
2894   bw_u1_nand2_4x UZsize_tmne30(.z (thr_match_ne),
2895                                .a (tmne_10),
2896                                .b (tmne_32));
2897   
2898
2899   dff_s #(4) thrf_reg(.din   (thr_bf),     // thr_f may be 4'b0000 but it has
2900                                 .clk   (clk),        // to reset to 4'b0001
2901                                 .q     (thr_f_flop),
2902                                 .se    (se),  .si(), .so());
2903
2904   bw_u1_buf_10x UZsize_tfcrit0(.a (thr_f_flop[0]), .z(thr_f_crit[0]));
2905   bw_u1_buf_10x UZsize_tfcrit1(.a (thr_f_flop[1]), .z(thr_f_crit[1]));
2906   bw_u1_buf_10x UZsize_tfcrit2(.a (thr_f_flop[2]), .z(thr_f_crit[2]));
2907   bw_u1_buf_10x UZsize_tfcrit3(.a (thr_f_flop[3]), .z(thr_f_crit[3]));
2908
2909   bw_u1_buf_10x UZsize_tfncr0(.a (thr_f_flop[0]), .z(thr_f[0]));
2910   bw_u1_buf_10x UZsize_tfncr1(.a (thr_f_flop[1]), .z(thr_f[1]));
2911   bw_u1_buf_10x UZsize_tfncr2(.a (thr_f_flop[2]), .z(thr_f[2]));
2912   bw_u1_buf_10x UZsize_tfncr3(.a (thr_f_flop[3]), .z(thr_f[3]));
2913
2914   assign     ifu_exu_tid_s2[1] = thr_f[3] | thr_f[2];
2915   assign     ifu_exu_tid_s2[0] = thr_f[3] | thr_f[1];
2916   assign     ifu_lsu_thrid_s = ifu_exu_tid_s2;
2917   assign     fcl_dtu_thr_f = thr_f;
2918   
2919//   assign thr_s1_next = inst_vld_f ? thr_f : thr_s1;
2920   assign     thr_s1_next[0] = thr_f[0];
2921   assign     thr_s1_next[1] = ~thr_f[0] & thr_f[1];
2922   assign     thr_s1_next[2] = ~thr_f[0] & ~thr_f[1] & thr_f[2];
2923   assign     thr_s1_next[3] = ~thr_f[0] & ~thr_f[1] & ~thr_f[2];
2924   
2925//`ifdef VERPLEX
2926//   $constraint thr_s1_1h4 ($one_hot(thr_s1_next[3:0]));
2927//`endif
2928   
2929   dff_s #(4) thrs1_reg(.din   (thr_s1_next),
2930                    .clk   (clk),
2931                    .q     (thr_s1),
2932                    .se    (se), .si(), .so());
2933   
2934   dff_s #(4) thrd_reg(.din    (thr_s1_next), 
2935                     .clk   (clk),
2936                     .q     (thr_d),
2937                     .se    (se), .si(), .so());
2938   
2939   assign fcl_ifq_thr_s1[0] = thr_s1[3] | thr_s1[1];
2940   assign fcl_ifq_thr_s1[1] = thr_s1[3] | thr_s1[2];
2941
2942   assign ifu_tlu_thrid_d[1] = thr_d[3] | thr_d[2];
2943   assign ifu_tlu_thrid_d[0] = thr_d[3] | thr_d[1];
2944   
2945   assign thr_match_fs1 = (thr_d[0] & thr_f_crit[0] | 
2946                                             thr_d[1] & thr_f_crit[1] | 
2947                                             thr_d[2] & thr_f_crit[2] | 
2948                                             thr_d[3] & thr_f_crit[3]);
2949   assign thr_match_fd = thr_match_fs1;
2950   assign thr_match_fe = (thr_e[0] & thr_f[0] | 
2951                                            thr_e[1] & thr_f[1] | 
2952                                            thr_e[2] & thr_f[2] | 
2953                                            thr_e[3] & thr_f[3]);
2954   assign thr_match_fm = (thr_m[0] & thr_f[0] | 
2955                                            thr_m[1] & thr_f[1] | 
2956                                            thr_m[2] & thr_f[2] | 
2957                                            thr_m[3] & thr_f[3]);
2958//   assign thr_match_ft = (trap_thr[0] & thr_f[0] |
2959//                        trap_thr[1] & thr_f[1] |
2960//                        trap_thr[2] & thr_f[2] |
2961//                        trap_thr[3] & thr_f[3]);
2962   
2963   dffr_s #(4) thre_reg(.din   (thr_d),   
2964                    .clk   (clk),
2965                    .rst   (fcl_reset),
2966                    .q     (thr_e),
2967                    .se    (se), .si(), .so());
2968
2969   dffr_s #(4) thre2_reg(.din   (thr_d),   
2970                    .clk   (clk),
2971                    .rst   (fcl_reset),
2972                    .q     (thr_e_v2),
2973                    .se    (se), .si(), .so());
2974
2975   assign     ifu_tlu_thrid_e[1] = thr_e[3] | thr_e[2];
2976   assign     ifu_tlu_thrid_e[0] = thr_e[3] | thr_e[1];
2977
2978   assign thr_match_de = (thr_d[0] & thr_e[0] | 
2979                                            thr_d[1] & thr_e[1] | 
2980                                            thr_d[2] & thr_e[2] | 
2981                                            thr_d[3] & thr_e[3]);
2982                         
2983   assign thr_match_dm = (thr_d[0] & thr_m[0] | 
2984                                            thr_d[1] & thr_m[1] | 
2985                                            thr_d[2] & thr_m[2] | 
2986                                            thr_d[3] & thr_m[3]);
2987
2988   dff_s #(4) thrm_reg(.din   (thr_e),   
2989                   .clk   (clk),
2990                   .q     (thr_m),
2991                   .se    (se), .si(), .so());
2992
2993   dff_s #(4) thrw_reg(.din   (thr_m),   
2994                   .clk   (clk),
2995                   .q     (thr_w),
2996                   .se    (se), .si(), .so());
2997
2998   assign sas_thrid_w[1] = thr_w[3] | thr_w[2];
2999   assign sas_thrid_w[0] = thr_w[3] | thr_w[1];
3000   
3001   assign thr_match_fw = (thr_f[0] & thr_w[0] | 
3002                                            thr_f[1] & thr_w[1] | 
3003                                            thr_f[2] & thr_w[2] | 
3004                                            thr_f[3] & thr_w[3]);
3005         
3006   assign thr_match_fw2 = (thr_f[0] & thr_w2[0] | 
3007                                             thr_f[1] & thr_w2[1] | 
3008                                             thr_f[2] & thr_w2[2] | 
3009                                             thr_f[3] & thr_w2[3]);
3010
3011   assign thr_match_dw = (thr_d[0] & thr_w[0] | 
3012                                            thr_d[1] & thr_w[1] | 
3013                                            thr_d[2] & thr_w[2] | 
3014                                            thr_d[3] & thr_w[3]);
3015
3016   assign thr_match_dw2 = (thr_d[0] & thr_w2[0] | 
3017                                             thr_d[1] & thr_w2[1] | 
3018                                             thr_d[2] & thr_w2[2] | 
3019                                             thr_d[3] & thr_w2[3]);
3020         
3021   assign thr_match_em = (thr_e[0] & thr_m[0] | 
3022                                            thr_e[1] & thr_m[1] | 
3023                                            thr_e[2] & thr_m[2] | 
3024                                            thr_e[3] & thr_m[3]);
3025
3026   assign thr_match_ew = (thr_e_v2[0] & thr_w[0] | 
3027                                            thr_e_v2[1] & thr_w[1] | 
3028                                            thr_e_v2[2] & thr_w[2] | 
3029                                            thr_e_v2[3] & thr_w[3]);
3030
3031   dff_s #(1) stmw2_ff(.din (thr_match_ew),
3032                     .q   (same_thr_mw2),
3033                     .clk (clk), .se (se), .si(), .so());
3034   
3035   assign thr_match_ew2 = (thr_e[0] & thr_w2[0] | 
3036                                             thr_e[1] & thr_w2[1] | 
3037                                             thr_e[2] & thr_w2[2] | 
3038                                             thr_e[3] & thr_w2[3]);
3039         
3040   assign thr_match_mw = (thr_m[0] & thr_w[0] | 
3041                                            thr_m[1] & thr_w[1] | 
3042                                            thr_m[2] & thr_w[2] | 
3043                                            thr_m[3] & thr_w[3]);
3044                         
3045   dff_s #(4) thrw2_reg(.din   (thr_w),   
3046                    .clk   (clk),
3047                    .q     (thr_w2),
3048                    .se    (se), .si(), .so());
3049   
3050
3051//-------------------------
3052// Rollback
3053//-------------------------
3054
3055   // 04/05/02
3056   // Looks like we made a mistake with rollback.  Should never
3057   // rollback to S.  In the event of a dmiss or mul contention, just
3058   // kill all the instructions and rollback to F.  This adds one
3059   // cycle to the dmiss penalty and to the mul latency if we have to
3060   // wait, both not a very high price to pay.  This would have saved
3061   // lots of hours of design and verif time.
3062   //   
3063   assign rb2_inst_d = thr_match_dw & inst_vld_d & dtu_fcl_rollback_g;
3064   assign rb1_inst_s = thr_match_fw & inst_vld_s & dtu_fcl_rollback_g;
3065   assign rb0_inst_bf = thr_match_nw & switch_bf & dtu_fcl_rollback_g;
3066
3067//   assign rt1_inst_s = thr_match_fd & inst_vld_s & retract_inst_d;
3068//   assign rt0_inst_bf = thr_match_nd & dtu_fcl_ntr_s & retract_inst_d;
3069
3070//   assign retract_iferr_d = thr_match_de & erb_dtu_ifeterr_d1 & inst_vld_d1 &
3071//                            ~kill_curr_e & fcl_dtu_inst_vld_d;
3072   assign retract_iferr_d1 = erb_dtu_ifeterr_d1 & inst_vld_d1;
3073
3074   assign retract_inst_d = retract_iferr_d1 & thr_match_de & 
3075                           fcl_dtu_inst_vld_d |
3076                           mark4rb_d | 
3077                           dtu_fcl_retract_d;
3078
3079   assign rt1_inst_s = thr_match_fd & inst_vld_s & dtu_fcl_retract_d | 
3080                       mark4rb_s;
3081//                     | thr_match_fe & inst_vld_s & retract_iferr_d1;
3082
3083   // TBD:  This is not necessary since the thread will switch out and
3084   // stall whatever makes its way to the S stage.
3085   // NOTE: rb0_inst *is needed* however.
3086   assign rt0_inst_bf = thr_match_nd & switch_bf & dtu_fcl_retract_d;
3087//                      | thr_match_ne & dtu_fcl_ntr_s & retract_iferr_d1;
3088
3089   assign retract_iferr_qual_d1 = retract_iferr_d1 & thr_match_de &
3090                                  fcl_dtu_inst_vld_d &
3091                                  ~(dtu_fcl_rollback_g & thr_match_ew);
3092
3093   dff_s rbe_ff(.din (rb2_inst_d),
3094              .q   (rb2_inst_e),
3095              .clk (clk),
3096              .se  (se), .si(), .so());
3097
3098   dff_s rte_ff(.din (retract_inst_d),
3099              .q   (rt2_inst_e),
3100              .clk (clk),
3101              .se  (se), .si(), .so());
3102
3103   dff_s rbd_ff(.din (rb1_inst_s),
3104              .q   (rb1_inst_d),
3105              .clk (clk),
3106              .se  (se), .si(), .so());
3107
3108   dff_s rtd_ff(.din (rt1_inst_s),
3109              .q   (rt1_inst_d),
3110              .clk (clk),
3111              .se  (se), .si(), .so());
3112   
3113   dff_s rbs_ff(.din (rb0_inst_bf),
3114              .q   (rb0_inst_s),
3115              .clk (clk),
3116              .se  (se), .si(), .so());
3117
3118   // TBD: is this necessary?
3119   dff_s rts_ff(.din (rt0_inst_bf),
3120              .q   (rt0_inst_s),
3121              .clk (clk),
3122              .se  (se), .si(), .so());
3123
3124   dff_s rtiferr_ff(.din (retract_iferr_qual_d1),
3125                  .q   (retract_iferr_e),
3126                  .clk (clk),
3127                  .se  (se), .si(), .so());
3128   
3129   assign rb_stg_s = (rb0_inst_s | rt0_inst_s) & tm_fd_l |
3130                           (rb1_inst_d | rt1_inst_d) & ~tm_fd_l;
3131   assign rb_stg_d_crit = rb1_inst_d | rt1_inst_d;
3132   assign rb_stg_e = rb2_inst_e | rt2_inst_e;
3133
3134   bw_u1_buf_5x UZsize_rbd_buf(.a (rb_stg_d_crit),
3135                               .z (rb_stg_d));
3136   
3137   // determine rollback amount
3138   assign rb_frome = {4{(rb2_inst_e | rt2_inst_e) & 
3139                        (inst_vld_e | intr_vld_e)}} & thr_e;
3140   assign rb_fromd = {4{(rb1_inst_d | rt1_inst_d) & 
3141                        (inst_vld_d | intr_vld_d)}} & thr_d;
3142   assign rb_froms = {4{rb_stg_s & inst_vld_s_crit}} & thr_f;   
3143   assign rb_w2 = rb_frome | rb_fromd;
3144   assign rb_for_iferr_e = {4{retract_iferr_e}} & thr_e;
3145
3146//------------------------------   
3147// Branch Control
3148//------------------------------
3149   // final portion of branch evaluation
3150   wire brtaken_e_l;   
3151   bw_u1_buf_20x UZsize_bcbf(.z(fcl_dcl_regz_e), 
3152                             .a(exu_ifu_regz_e));
3153     
3154   bw_u1_muxi21_6x UZsize_bcmux(.z(brtaken_e_l), 
3155                                .d0(dcl_fcl_bcregz0_e), 
3156                                .d1(dcl_fcl_bcregz1_e), 
3157                                .s(exu_ifu_regz_e));
3158
3159   bw_u1_inv_15x UZsize_bcinv(.z(brtaken_e), 
3160                              .a(brtaken_e_l));
3161
3162   // Branch is taken in the E stage to thr_e.  Below we check to see
3163   // if this is the same as the next thread we will switch to
3164
3165   // isolate non critical section
3166   bw_u1_buf_5x UZsize_btbuf(.z (brtaken_unq_e),
3167                             .a (brtaken_e));
3168   assign brtaken_buf_e = brtaken_unq_e & inst_vld_qual_e & ~kill_curr_e;
3169
3170//   assign thr_match_ne_norst = thr_match_ne & ~rst_sw_bf;
3171//   assign brto_nxtthr_bf  = thr_match_ne & brtaken_e;
3172   bw_u1_nand2_4x UZsize_btkn_ntl(.a (brtaken_e),
3173                                  .b (thr_match_ne),
3174                                  .z (brto_nxtthr_bf_l));
3175
3176//   bw_u1_inv_8x UZsize_btkn_bf(.a (brto_nxtthr_bf_l),
3177//                               .z (brto_nxtthr_bf));
3178
3179   dff_s #(1) br_ff(.din (brtaken_buf_e),
3180                              .q   (brtaken_m),
3181                              .clk (clk),
3182                              .se  (se), .si(), .so());
3183   
3184
3185//----------------------------------------------------------------------
3186// PC related control
3187//----------------------------------------------------------------------
3188
3189   // Choose next IC address
3190   // IC address is chosen from
3191   //    1. Next PC assuming no switch
3192   //    2. Branch PC if E stage branch is to next thread
3193   //    3. Saved F stage Thread PC if we switch threads
3194
3195   assign fcl_icd_index_sel_ifq_bf = allow_ifq_access_icd_bf;
3196   assign fcl_ifq_grant_bf = allow_ifq_access_icd_bf;
3197
3198   // Select branch PC
3199//   assign fcl_fdp_icaddr_sel_br_bf_l = ~(~all_stallreq &
3200//                                                                     brto_nxtthr_bf    &
3201//                                                                     switch_bf);
3202//
3203//   // Select the switch PC from thread PC register
3204//   assign fcl_fdp_icaddr_sel_swpc_bf_l = ~(~all_stallreq &
3205//                                                                       ~usen_bf &
3206//                                                                       ~brto_nxtthr_bf &
3207//                                                                       switch_bf);
3208//
3209//   // Select current thread's next PC or IC write addr (PC/PC+4/I$ wraddr)
3210//   assign fcl_fdp_icaddr_sel_curr_bf_l = ~(~all_stallreq &
3211//                                                                       ~(stall_f | usep_bf) &
3212//                                                                       ~switch_bf);
3213//   
3214//   assign fcl_fdp_icaddr_sel_ifq_bf_l = ~(all_stallreq |
3215//                                                                      (stall_f | usep_bf) & ~switch_bf |
3216//                                                                      ~brto_nxtthr_bf & usen_bf &
3217//                                                                      (switch_bf | stall_f | usep_bf));
3218   
3219   
3220
3221//   assign sw_or_async_stall = (switch_bf & ~rst_stallreq | rst_sw_bf);
3222   wire   sw_or_async_stall_l;
3223   assign rst_stallreq_l = ~rst_stallreq;
3224   bw_u1_aoi21_4x UZsize_swstl_aoi(.(sw_or_async_stall_l),
3225                                   .(rst_sw_bf),
3226                                   .b1 (switch_bf),
3227                                   .b2 (rst_stallreq_l));
3228   assign sw_or_async_stall = ~sw_or_async_stall_l;
3229
3230//   assign icadr_selbr = sw_or_async_stall & brto_nxtthr_bf;
3231   assign sw_match_ne_norst = sw_or_async_stall & thr_match_ne;
3232   bw_u1_nand2_10x UZfix_icad_br(.a (brtaken_e),
3233                                 .b (sw_match_ne_norst),
3234                                 .z (icadr_selbr_l));
3235
3236//   assign icadr_selsw = sw_or_async_stall & ~brto_nxtthr_bf;
3237   bw_u1_nand2_15x UZfix_icad_sw(.a (brto_nxtthr_bf_l),
3238                                 .b (sw_or_async_stall),
3239                                 .z (icadr_selsw_l));
3240   
3241
3242   // select next PC
3243   assign fcl_fdp_pcbf_sel_br_bf_l = icadr_selbr_l;
3244   assign fcl_fdp_pcbf_sel_swpc_bf_l = icadr_selsw_l ;
3245   assign fcl_fdp_pcbf_sel_nosw_bf_l = ~sw_or_async_stall_l;
3246
3247   // Select PC to switch to in the event of a switch
3248   // No need to protect during scan
3249   // NOTE: SWL guarantees nextthr_bf is one hot
3250//   assign fcl_fdp_next_thr_bf_l = rst_stallreq_d1 ? ~rstint_penc :
3251//                                                    ~dtu_fcl_nextthr_bf;
3252
3253   wire [3:0] next_thr_bf_l;
3254   wire       nt_sel_rst;
3255   assign     nt_sel_rst = rst_stallreq_d1 | rst_tri_en;
3256   
3257   bw_u1_muxi21_2x UZfix_nthr_mx0(.z (next_thr_bf_l[0]),
3258                                  .d0 (dtu_fcl_nextthr_bf[0]),
3259                                  .d1 (rstint_penc[0]),
3260                                  .(nt_sel_rst));
3261   bw_u1_muxi21_2x UZfix_nthr_mx1(.z (next_thr_bf_l[1]),
3262                                  .d0 (dtu_fcl_nextthr_bf[1]),
3263                                  .d1 (rstint_penc[1]),
3264                                  .(nt_sel_rst));
3265   bw_u1_muxi21_2x UZfix_nthr_mx2(.z (next_thr_bf_l[2]),
3266                                  .d0 (dtu_fcl_nextthr_bf[2]),
3267                                  .d1 (rstint_penc[2]),
3268                                  .(nt_sel_rst));
3269   bw_u1_muxi21_2x UZfix_nthr_mx3(.z (next_thr_bf_l[3]),
3270                                  .d0 (dtu_fcl_nextthr_bf[3]),
3271                                  .d1 (rstint_penc[3]),
3272                                  .(nt_sel_rst));
3273   assign     fcl_fdp_next_thr_bf_l = next_thr_bf_l;
3274   
3275
3276//   assign nextthr_bf_buf = dtu_fcl_nextthr_bf;
3277   bw_u1_buf_20x UZsize_ntbf0(.a (dtu_fcl_nextthr_bf[0]),
3278                              .z (nextthr_bf_buf[0]));
3279   bw_u1_buf_20x UZsize_ntbf1(.a (dtu_fcl_nextthr_bf[1]),
3280                              .z (nextthr_bf_buf[1]));
3281   bw_u1_buf_20x UZsize_ntbf2(.a (dtu_fcl_nextthr_bf[2]),
3282                              .z (nextthr_bf_buf[2]));
3283   bw_u1_buf_20x UZsize_ntbf3(.a (dtu_fcl_nextthr_bf[3]),
3284                              .z (nextthr_bf_buf[3]));
3285   // use 6x
3286   assign fcl_fdp_next_ctxt_bf_l[2:0] = ~nextthr_bf_buf[2:0] | {3{rst_tri_en}};
3287   assign fcl_fdp_next_ctxt_bf_l[3] = ~nextthr_bf_buf[3] & ~rst_tri_en;
3288
3289//   assign nextthr_final_bf = switch_bf ? dtu_fcl_nextthr_bf : thr_f;
3290   wire [3:0] nextthr_final_bf_l;
3291   bw_u1_muxi21_2x UZfix_ntfmux0(.(nextthr_final_bf_l[0]),
3292                                .d0 (thr_f[0]),
3293                                .d1 (dtu_fcl_nextthr_bf[0]),
3294                                .(switch_bf));
3295   bw_u1_inv_8x UZsize_ntfin_buf0(.z (nextthr_final_bf[0]),
3296                                 .a (nextthr_final_bf_l[0]));
3297
3298   bw_u1_muxi21_2x UZfix_ntfmux1(.(nextthr_final_bf_l[1]),
3299                                .d0 (thr_f[1]),
3300                                .d1 (dtu_fcl_nextthr_bf[1]),
3301                                .(switch_bf));
3302   bw_u1_inv_8x UZsize_ntfin_buf1(.z (nextthr_final_bf[1]),
3303                                 .a (nextthr_final_bf_l[1]));
3304
3305   bw_u1_muxi21_2x UZfix_ntfmux2(.(nextthr_final_bf_l[2]),
3306                                .d0 (thr_f[2]),
3307                                .d1 (dtu_fcl_nextthr_bf[2]),
3308                                .(switch_bf));
3309   bw_u1_inv_8x UZsize_ntfin_buf2(.z (nextthr_final_bf[2]),
3310                                 .a (nextthr_final_bf_l[2]));
3311
3312   bw_u1_muxi21_2x UZfix_ntfmux3(.(nextthr_final_bf_l[3]),
3313                                .d0 (thr_f[3]),
3314                                .d1 (dtu_fcl_nextthr_bf[3]),
3315                                .(switch_bf));
3316   bw_u1_inv_8x UZsize_ntfin_buf3(.z (nextthr_final_bf[3]),
3317                                 .a (nextthr_final_bf_l[3]));
3318   
3319   
3320   // decode trap thread
3321   dff_s #(2) ld_trp_reg(.din ({tlu_ifu_trappc_vld_w1,
3322                              tlu_ifu_trapnpc_vld_w1}),
3323                       .q   ({trappc_vld_w2,
3324                              trapnpc_vld_w2}),
3325                       .clk (clk), .se(se), .si(), .so());
3326
3327   dff_s #(2) trp_tid_reg(.din (tlu_ifu_trap_tid_w1[1:0]),
3328                        .q   (trap_tid_w2[1:0]),
3329                        .clk (clk), .se(se), .si(), .so());
3330   
3331   assign trap_thr[0] = ~trap_tid_w2[1] & ~trap_tid_w2[0];
3332   assign trap_thr[1] = ~trap_tid_w2[1] &  trap_tid_w2[0];
3333   assign trap_thr[2] =  trap_tid_w2[1] & ~trap_tid_w2[0];
3334   assign trap_thr[3] =  trap_tid_w2[1] &  trap_tid_w2[0];
3335
3336   assign load_tpc[3:0] = {4{trappc_vld_w2}} & trap_thr |
3337                           rb_w2 |
3338                           {4{rb_stg_w | ims_flush_coll_w}} & thr_w |
3339//                     {4{dec_fcl_kill4sta_e}} & thr_e |
3340                           {4{flush_sonly_qual_m}} & thr_m;
3341   
3342   assign load_bpc[3:0] = {4{brtaken_buf_e}} & thr_e;
3343   assign load_pcp4[3:0] = {4{~part_stall_thisthr_f &
3344                              ~iferrto_thisthr_d1 |
3345                              arst_vld_f |
3346                              async_intr_vld_s}}     & thr_f;
3347
3348   always @ (/*AUTOSENSE*/load_bpc or load_pcp4 or load_tpc)
3349     begin
3350//            if (fcl_reset)
3351//              begin // RESET PC is loaded to T0
3352//                 fcl_fdp_tpcbf_sel_old_bf_l = 4'b0001;
3353//                 fcl_fdp_tpcbf_sel_pcp4_bf_l = 4'b1110;
3354//                 fcl_fdp_tpcbf_sel_trap_bf_l = 4'b1111;
3355//                 fcl_fdp_tpcbf_sel_brpc_bf_l = 4'b1111;
3356//              end // if (reset)
3357//            else
3358//              begin
3359              fcl_fdp_tpcbf_sel_old_bf_l = (load_bpc | load_tpc | load_pcp4);
3360              fcl_fdp_tpcbf_sel_brpc_bf_l = ~load_bpc | load_tpc | load_pcp4;
3361              fcl_fdp_tpcbf_sel_pcp4_bf_l = ~load_pcp4 | load_tpc;
3362              fcl_fdp_tpcbf_sel_trap_bf_l = ~load_tpc;
3363     end // always @ (...
3364
3365   // Track correctible errors
3366   assign irf_ce_m = exu_ifu_ecc_ce_m & ~trap_m & inst_vld_m & ~kill_curr_m;
3367   dff_s #(1) irfcew_ff(.din (irf_ce_m),
3368                                .q   (irf_ce_w),
3369                                .clk (clk), .se(se), .si(), .so());
3370
3371   // track if ldhit was actually a miss
3372   // D and S stage are rolled back through the normal D stage retract
3373   // process. 
3374   assign mark4rb_d = lsu_ifu_dc_parity_error_w2 & thr_match_dw2 & 
3375                      (inst_vld_d | intr_vld_d);
3376   assign mark4rb_s = lsu_ifu_dc_parity_error_w2 & thr_match_fw2 & 
3377                      (inst_vld_s | intr_vld_s);
3378
3379   assign mark4rb_e = lsu_ifu_dc_parity_error_w2 & thr_match_ew2 & 
3380                      (inst_vld_e | intr_vld_e) & 
3381                        ~dtu_inst_anull_e & ~kill_curr_e;
3382
3383   dff_s #(2) markrb_reg(.din ({mark4rb_m,
3384                              mark4rb_e}),
3385                       .q   ({mark4rb_w,
3386                              mark4rb_m}),
3387                       .clk (clk),
3388                       .se  (se), .si(), .so());
3389   
3390   // Rollback from W on irf/frf ce and on a dcache parity error
3391   assign rb_stg_w = irf_ce_w & inst_vld_w & no_iftrap_w | 
3392                           ffu_ifu_fst_ce_w & inst_vld_w & no_iftrap_w |
3393                     rb_intr_w & intr_vld_w |
3394                     mark4rb_w |
3395                     fcl_dtu_resum_thr_w | 
3396                                 fcl_dtu_nuke_thr_w;
3397
3398   // flush after hardware micro trap
3399//   assign ifu_tlu_flush_w = irf_ce_w | fcl_dtu_nuke_thr_w | mark4rb_w |
3400//                            fcl_dtu_resum_thr_w;
3401   // very critical
3402   assign ifu_tlu_flush_m = (exu_ifu_ecc_ce_m & inst_vld_m & ~trap_m |
3403                             (resumint_m | nuke_thr_m) & 
3404                             intr_vld_m & ~rstint_m |
3405                             rb_intr_m | 
3406                             mark4rb_m);
3407   assign utrap_flush_m =  ifu_tlu_flush_m & ~kill_local_m;
3408   dff_s #(1) flw_ff(.din (utrap_flush_m),
3409                   .q   (utrap_flush_w),
3410                   .clk (clk), .se(se), .si(), .so());
3411   assign ifu_tlu_flush_w = utrap_flush_w;
3412   assign fcl_swl_flush_w =  (irf_ce_w & inst_vld_w & no_iftrap_w | 
3413                              rb_intr_w & intr_vld_w |
3414                              mark4rb_w |
3415                              fcl_dtu_resum_thr_w | 
3416                                          fcl_dtu_nuke_thr_w);
3417
3418   // tells swl to flush and then wake up
3419   assign fcl_swl_flush_wake_w = fcl_swl_flush_w & ~mark4rb_w;
3420   
3421   // if the same instruction keeps hitting ce's disable ce detection
3422   // count how many ce's occur to a given thread
3423   assign any_ce_w = ffu_ifu_fst_ce_w | irf_ce_w;
3424   
3425   assign ce_cnt1_nxt = (({4{any_ce_w & inst_vld_w}} & thr_w & 
3426                          ce_cnt0) ^ ce_cnt1) & ~ce_cnt_rst;
3427   assign ce_cnt0_nxt = (({4{any_ce_w & inst_vld_w}} & thr_w) ^ 
3428                         ce_cnt0) & ~ce_cnt_rst;
3429
3430   assign ce_cnt_rst = thr_w & {4{inst_vld_w & ~any_ce_w}} | {4{fcl_reset}};
3431
3432   dff_s #(8) cecnt_reg(.din ({ce_cnt1_nxt, ce_cnt0_nxt}),
3433                      .q   ({ce_cnt1, ce_cnt0}),
3434                      .clk (clk),
3435                      .se(se), .si(), .so());
3436
3437   // find the count for the current d stage thread
3438   assign ce_val1_d = (thr_d[0] & ce_cnt1[0] | 
3439                       thr_d[1] & ce_cnt1[1] | 
3440                       thr_d[2] & ce_cnt1[2] | 
3441                       thr_d[3] & ce_cnt1[3]);
3442
3443   assign ce_val0_d = (thr_d[0] & ce_cnt0[0] | 
3444                       thr_d[1] & ce_cnt0[1] | 
3445                       thr_d[2] & ce_cnt0[2] | 
3446                       thr_d[3] & ce_cnt0[3]);
3447
3448   // if count hits 3 disable ce's
3449   assign disable_ce_d = ce_val1_d & ce_val0_d;
3450
3451   dff_s #(1) disce_ff(.din (disable_ce_d),
3452                     .q   (disable_ce_e),
3453                     .clk (clk), .se(se), .si(), .so());
3454   assign ifu_exu_disable_ce_e = disable_ce_e;
3455   
3456   // select error/trap/utrap rollback PC
3457   assign fcl_fdp_trrbpc_sel_trap_bf_l = 
3458                                ~({4{trappc_vld_w2}} & trap_thr);
3459
3460   assign fcl_fdp_trrbpc_sel_err_bf_l = 
3461                  ({4{trappc_vld_w2}} & trap_thr) |
3462                         ~({4{rb_stg_w}} & thr_w);
3463   
3464   assign fcl_fdp_trrbpc_sel_rb_bf_l = 
3465                  ({4{trappc_vld_w2}} & trap_thr) |
3466                               ({4{rb_stg_w}} & thr_w) |                   
3467                        ~(rb_frome & rb_fromd);
3468   
3469   assign fcl_fdp_trrbpc_sel_pcs_bf_l = 
3470                 ({4{trappc_vld_w2}} & trap_thr) | 
3471                               ({4{rb_stg_w}} & thr_w) |                   
3472                         (rb_frome & rb_fromd);
3473   
3474   // select next S stage Thr PC
3475   assign fcl_fdp_nextpcs_sel_pce_f_l = ~rb_frome;
3476   assign fcl_fdp_nextpcs_sel_pcd_f_l = rb_frome | ~rb_fromd;
3477   assign fcl_fdp_nextpcs_sel_pcf_f_l = rb_frome | rb_fromd |
3478                                        ~(thr_f & {4{~part_stall_thisthr_f &
3479                                               ~iferrto_thisthr_d1 |
3480                                               arst_vld_f |
3481                                               async_intr_vld_s}});
3482   assign fcl_fdp_nextpcs_sel_pcs_f_l = rb_frome | rb_fromd | 
3483                                        (thr_f & {4{~part_stall_thisthr_f &
3484                                              ~iferrto_thisthr_d1 |
3485                                              arst_vld_f |
3486                                              async_intr_vld_s}});
3487   
3488   // next S2 stage pc and npc select
3489   assign thr_f_dec[3:1] = thr_f_crit[3:1] & {3{~rst_tri_en}};
3490   assign thr_f_dec[0] = thr_f_crit[0] | rst_tri_en;
3491   assign fcl_fdp_thr_s2_l = ~thr_f_dec;     // thr_f = thr_s2
3492
3493
3494   // Select NextPC from
3495   //    1. Trap NextPC (if the tnpc is valid)
3496   //    2. reset PC
3497   //    3. incremented PC (PC+4)
3498   //    4. old PC (in the event of a stall)
3499
3500   // Load the trap PC to the BF stage NPC.  (The BF stage NPC is used
3501   // only for storing the next PC from the TLU
3502   assign fcl_fdp_thrtnpc_sel_tnpc_l = ~({4{trapnpc_vld_w2}} & trap_thr);
3503
3504   assign fcl_fdp_thrtnpc_sel_npcw_l = ({4{trapnpc_vld_w2}} & trap_thr) |
3505                                               ~({4{rb_stg_w}} & thr_w);
3506
3507   assign fcl_fdp_thrtnpc_sel_pcf_l = ({4{trapnpc_vld_w2}} & trap_thr) |
3508                                              ({4{rb_stg_w}} & thr_w) |
3509                                                (~({4{ims_flush_coll_w}} & thr_w) &
3510                                           ~({4{flush_sonly_qual_m}} & thr_m));
3511                                       //   {4{dec_fcl_kill4sta_e}} & thr_e);
3512   
3513   assign fcl_fdp_thrtnpc_sel_old_l = ({4{trapnpc_vld_w2}} & trap_thr) |
3514                                              ({4{rb_stg_w}} & thr_w) |
3515                                              ({4{ims_flush_coll_w}} & thr_w) |
3516                                        ({4{flush_sonly_qual_m}} & thr_m);
3517                                         // {4{dec_fcl_kill4sta_e}} & thr_e);
3518   
3519   assign ntpc_vld_nxt = fcl_fdp_thrtnpc_sel_old_l | 
3520                               ntpc_vld & ({4{(part_stall_thisthr_f |
3521                                         iferrto_thisthr_d1) & 
3522                                        ~arst_vld_f &
3523                                        ~async_intr_vld_s}} | ~thr_f) &
3524                                  ~({4{trappc_vld_w2}} & trap_thr);
3525   
3526   dffr_s #(4) ntpcv_reg(.din  (ntpc_vld_nxt),
3527                     .clk  (clk),
3528                     .q    (ntpc_vld),
3529                     .rst  (fcl_reset),
3530                     .se   (se), .si(), .so());
3531
3532   assign ntpc_thisthr = (thr_f[0] & ntpc_vld[0] |
3533                                            thr_f[1] & ntpc_vld[1] |
3534                                            thr_f[2] & ntpc_vld[2] |
3535                                            thr_f[3] & ntpc_vld[3]);
3536
3537//   assign fcl_fdp_noswpc_sel_rst_l_bf = 1'b1;
3538   assign fcl_fdp_noswpc_sel_tnpc_l_bf = ~ntpc_thisthr;
3539   assign fcl_fdp_noswpc_sel_old_l_bf = ntpc_thisthr | inst_vld_f | arst_vld_f;
3540   assign fcl_fdp_noswpc_sel_inc_l_bf = ntpc_thisthr | ~inst_vld_f & ~arst_vld_f;
3541   
3542   
3543   // Don't need noswpc_sel_old anymore (this is always 1)
3544//   always @(/*AUTOSENSE*/ntpc_vld or reset or thr_f)
3545//     begin
3546//            if (reset)
3547//              begin
3548//                 fcl_fdp_noswpc_sel_tnpc_l_bf = 1'b1;
3549//                 fcl_fdp_noswpc_sel_rst_l_bf = 1'b0; 
3550//                 fcl_fdp_noswpc_sel_inc_l_bf = 1'b1;
3551//                 fcl_fdp_noswpc_sel_old_l_bf = 1'b1;
3552//              end
3553//            else if ((ntpc_vld & thr_f) != 4'b0000)
3554//              begin
3555//                 fcl_fdp_noswpc_sel_tnpc_l_bf = 1'b0;
3556//                 fcl_fdp_noswpc_sel_rst_l_bf = 1'b1; 
3557//                 fcl_fdp_noswpc_sel_inc_l_bf = 1'b1;
3558//                 fcl_fdp_noswpc_sel_old_l_bf = 1'b1; 
3559//              end // if ((ntpc_vld & thr_f) != 4'b0000)
3560////    else if (ely_stall_thisthr_f)
3561////      begin
3562////         fcl_fdp_noswpc_sel_tnpc_l_bf = 1'b1;
3563////         fcl_fdp_noswpc_sel_rst_l_bf = 1'b1;       
3564////         fcl_fdp_noswpc_sel_inc_l_bf = 1'b1;
3565////         fcl_fdp_noswpc_sel_old_l_bf = 1'b0;             
3566////      end // if (ely_stall_thisthr_f)
3567//            else
3568//              begin
3569//                 fcl_fdp_noswpc_sel_tnpc_l_bf = 1'b1;
3570//                 fcl_fdp_noswpc_sel_rst_l_bf = 1'b1; 
3571//                 fcl_fdp_noswpc_sel_inc_l_bf = 1'b0;
3572//                 fcl_fdp_noswpc_sel_old_l_bf = 1'b1; 
3573//              end // else:
3574//           
3575//     end // always @ (...
3576
3577   // NOTE: direct branch vs indirect branch select goes from dtu to fdp
3578
3579//----------------------------------------------------------------------
3580// Instruction Register Related Control
3581//----------------------------------------------------------------------
3582
3583   // use NIR if no read previously
3584   assign fcl_fdp_usenir_sel_nir_s1 = usenir_s1;
3585
3586
3587   assign  fcl_fdp_inst_sel_nop_s_l = ~(ely_stall_thisthr_f | 
3588                                        ~inst_vld_s_crit | 
3589                                        force_intr_s | 
3590                                        immu_fault_f);
3591   
3592   assign  fcl_fdp_inst_sel_switch_s_l = ~switch_s2 |
3593                                        (ely_stall_thisthr_f | 
3594                                         ~inst_vld_s_crit | 
3595                                         force_intr_s | 
3596                                         immu_fault_f);
3597
3598   assign  fcl_fdp_inst_sel_nir_s_l = ~usenir_s1 |
3599                                        (switch_s2 |
3600                                         ely_stall_thisthr_f | 
3601                                         ~inst_vld_s_crit | 
3602                                         force_intr_s | 
3603                                         immu_fault_f);
3604   
3605   assign  fcl_fdp_inst_sel_curr_s_l = (usenir_s1 |
3606                                        switch_s2 |
3607                                        ely_stall_thisthr_f | 
3608                                        ~inst_vld_s_crit | 
3609                                        force_intr_s | 
3610                                        immu_fault_f);
3611   
3612   
3613   // Instruction Output Mux
3614//   always @ (/*AUTOSENSE*/ely_stall_thisthr_f or force_intr_s
3615//             or immu_fault_f or inst_vld_s_crit or switch_s2
3616//             or usenir_s1)
3617//     begin
3618//            if (ely_stall_thisthr_f | ~inst_vld_s_crit | force_intr_s |
3619//            immu_fault_f)
3620//              begin // stalled or imiss
3621//                 fcl_fdp_inst_sel_nop_s_l = 1'b0;
3622//                 fcl_fdp_inst_sel_switch_s_l = 1'b1;
3623//                 fcl_fdp_inst_sel_nir_s_l = 1'b1;
3624//                 fcl_fdp_inst_sel_curr_s_l = 1'b1;
3625//              end
3626//            else if (switch_s2)
3627//              begin
3628//                 fcl_fdp_inst_sel_nop_s_l = 1'b1;
3629//                 fcl_fdp_inst_sel_switch_s_l = 1'b0;
3630//                 fcl_fdp_inst_sel_nir_s_l = 1'b1;
3631//                 fcl_fdp_inst_sel_curr_s_l = 1'b1;
3632//              end
3633//            else if (usenir_s1)
3634//              begin
3635//                 fcl_fdp_inst_sel_nop_s_l = 1'b1;
3636//                 fcl_fdp_inst_sel_switch_s_l = 1'b1;
3637//                 fcl_fdp_inst_sel_nir_s_l = 1'b0;
3638//                 fcl_fdp_inst_sel_curr_s_l = 1'b1;
3639//              end
3640//            else
3641//              begin
3642//                 fcl_fdp_inst_sel_nop_s_l = 1'b1;
3643//                 fcl_fdp_inst_sel_switch_s_l = 1'b1;
3644//                 fcl_fdp_inst_sel_nir_s_l = 1'b1;
3645//                 fcl_fdp_inst_sel_curr_s_l = 1'b0;
3646//              end // else: !if(switch_s2 | stall_s1)
3647//     end // always @ (...
3648
3649   // thread IR input muxes
3650   assign fcl_fdp_tinst_sel_rb_s_l   = ~rb_w2;
3651   assign fcl_fdp_tinst_sel_ifq_s_l  = rb_w2 | ~ifq_fcl_fill_thr;
3652   assign fcl_fdp_tinst_sel_curr_s_l = ~val_thr_s1 | rb_w2 | ifq_fcl_fill_thr; 
3653   assign fcl_fdp_tinst_sel_old_s_l  = val_thr_s1 | rb_w2 | ifq_fcl_fill_thr; 
3654
3655   // Select rollback instruction
3656   assign fcl_fdp_rbinst_sel_inste_s = {4{rb2_inst_e | rt2_inst_e}} & 
3657                                       thr_e;
3658
3659   // thread NIR input muxes  (2:1 no need to protect)
3660   assign fcl_fdp_thr_s1_l = ~thr_s1 | {4{stall_s1}};
3661
3662   // select appropriate NIR
3663   assign dec_thr_s1_l[0] = ~(thr_s1[0] | rst_tri_en);
3664   assign dec_thr_s1_l[3:1] = ~(thr_s1[3:1] & {3{~rst_tri_en}});
3665   
3666   assign fcl_fdp_nirthr_s1_l = dec_thr_s1_l; 
3667   
3668
3669//--------------------
3670// rdsr data to exu
3671//--------------------   
3672
3673   dff_s #(1) pcrsr_ff(.din  (dec_fcl_rdsr_sel_pc_d),
3674                               .clk  (clk),
3675                               .q    (rdsr_sel_pc_e),
3676                               .se   (se), .si(), .so());
3677   dff_s #(1) thrrsr_ff(.din  (dec_fcl_rdsr_sel_thr_d),
3678                                .clk  (clk),
3679                                .q    (rdsr_sel_thr_e),
3680                                .se   (se), .si(), .so());
3681   // make sure they are exclusive
3682   assign fcl_fdp_rdsr_sel_pc_e_l = ~rdsr_sel_pc_e;
3683   assign fcl_fdp_rdsr_sel_thr_e_l = ~(~rdsr_sel_pc_e & rdsr_sel_thr_e);
3684   assign fcl_fdp_rdsr_sel_ver_e_l = ~(~rdsr_sel_pc_e & ~rdsr_sel_thr_e);
3685
3686//--------------------------------------------------------------
3687// Reg file control
3688//--------------------------------------------------------------
3689
3690// Some decode is done here since these signals are in the crit path
3691
3692   // Regfile enables are only power saving features.  So they don't
3693   // have to be exact, as long as they are on, a super set of when
3694   // they need to be on.
3695
3696   // Enable rs3 if store or atomic or mov
3697   assign ifu_exu_ren3_s =  inst_vld_f & fdp_fcl_op_s[1] & fdp_fcl_op3_s[2] &
3698                            (fdp_fcl_op_s[0] | fdp_fcl_op3_s[5]);
3699
3700   // enable rs2 if i=0 and !branch or CAS
3701   // cas not fully decoded;  i=inst[13];
3702   assign ifu_exu_ren2_s = inst_vld_f & fdp_fcl_op_s[1] &
3703                            (~fdp_fcl_ibit_s | 
3704                             fdp_fcl_op_s[0] & fdp_fcl_op3_s[5]);
3705
3706   // rs1 is read if this is not (a branch on cc or no-op/sethi)
3707   assign ifu_exu_ren1_s = inst_vld_f & (fdp_fcl_op_s[1] |     // not br/call
3708                           fdp_fcl_op3_s[4] & fdp_fcl_op3_s[3]);  // BPR
3709
3710   //-------------------------------------
3711   // Generate oddwin signal for rs and rd
3712   //-------------------------------------
3713   assign fcl_fdp_oddwin_s = (exu_ifu_oddwin_s[0] & thr_f[0] |
3714                              exu_ifu_oddwin_s[1] & thr_f[1] |
3715                              exu_ifu_oddwin_s[2] & thr_f[2] |
3716                              exu_ifu_oddwin_s[3] & thr_f[3]);
3717
3718   dff_s #(1) oddwin_ff(.din (fcl_fdp_oddwin_s),
3719                                  .clk (clk),
3720                                  .q   (fcl_imd_oddwin_d),
3721                                  .se  (se), .si(), .so());
3722   
3723
3724   sink #(2) s0(.in (sas_thrid_w));
3725endmodule // sparc_ifu_fcl
Note: See TracBrowser for help on using the repository browser.