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

Subversion Repositories sparc64soc

[/] [sparc64soc/] [trunk/] [T1-CPU/] [ifu/] [sparc_ifu_fcl.v] - Rev 5

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

// ========== Copyright Header Begin ==========================================
// 
// OpenSPARC T1 Processor File: sparc_ifu_fcl.v
// Copyright (c) 2006 Sun Microsystems, Inc.  All Rights Reserved.
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
// 
// The above named program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public
// License version 2 as published by the Free Software Foundation.
// 
// The above named program is distributed in the hope that it will be 
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Public License for more details.
// 
// You should have received a copy of the GNU General Public
// License along with this work; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
// 
// ========== Copyright Header End ============================================
//////////////////////////////////////////////////////////////////////
/*
//  Module Name: sparc_ifu_fcl
//  Description:	
//  The FCL is the fetch control logic.  It controls the PC datapath
//  and the fetch/next instruction datapath.  It also manages access
//  to the icache data, tags, vbits and to the tlb.
//  The FCL starts fetching from the reset PC upon reset.  It is up to
//  the DTU to specify which thread to fetch from.  Only T0 is set to
//  the reset PC.  If the decode unit specifies any other thread, it
//  will fetch from an indeterminate address.
//  The fetch block automatically stalls the machine when an Imiss is
//  detected and there is no thread to switch to.  
// 
*/
////////////////////////////////////////////////////////////////////////
// Global header file includes
////////////////////////////////////////////////////////////////////////
 
`include "ifu.h"
 
 
module sparc_ifu_fcl(/*AUTOARG*/
   // Outputs
   fcl_icd_rdreq_bf, fcl_icv_rdreq_bf, fcl_icd_wrreq_bf, 
   fcl_ict_wrreq_bf, fcl_icv_wrreq_bf, fcl_icd_index_sel_ifq_bf, 
   fcl_ifq_grant_bf, fcl_ifq_icmiss_s1, fcl_ifq_rdreq_s1, 
   fcl_ifq_icache_en_s_l, fcl_ifq_thr_s1, fcl_ifq_canthr, 
   fcl_itlb_cam_vld_bf, fcl_itlb_cam_bypass_bf, fcl_itlb_addr_mask_l, 
   fcl_itlb_cam_real_bf, fcl_itlb_cam_pid_bf, fcl_itlb_wr_vld_bf, 
   fcl_itlb_dmp_vld_bf, fcl_itlb_dmp_all_bf, fcl_itlb_tag_rd_vld_bf, 
   fcl_itlb_invall_f_l, fcl_itlb_data_rd_vld_bf, fcl_erb_ievld_s1, 
   fcl_erb_tevld_s1, fcl_erb_immuevld_s1, ifu_lsu_thrid_s, 
   fcl_erb_asi_tid_f, fcl_erb_clear_iferr, fcl_erb_itlbrd_vld_s, 
   fcl_erb_itlbrd_data_s, fcl_dec_dslot_s, fcl_dtu_inst_vld_e, 
   fcl_dtu_intr_vld_e, fcl_dtu_inst_vld_d, fcl_dtu_ely_inst_vld_d, 
   fcl_dec_intr_vld_d, fcl_erb_inst_issue_d, fcl_erb_inst_vld_d1, 
   ifu_tlu_inst_vld_m, ifu_exu_inst_vld_e, ifu_exu_inst_vld_w, 
   ifu_spu_inst_vld_w, ifu_tlu_inst_vld_w, ifu_tlu_flush_w, 
   ifu_tlu_flush_m, fcl_swl_int_activate_i3, fcl_swl_flush_wake_w, 
   fcl_swl_flush_w, fcl_dcl_regz_e, ifu_tlu_thrid_e, ifu_tlu_thrid_d, 
   ifu_tlu_immu_miss_m, ifu_tlu_priv_violtn_m, ifu_tlu_icmiss_e, 
   ifu_tlu_ttype_vld_m, ifu_exu_ttype_vld_m, ifu_mmu_trap_m, 
   ifu_tlu_trap_m, ifu_tlu_ttype_m, ifu_tlu_hwint_m, 
   ifu_tlu_sftint_m, ifu_tlu_rstint_m, fcl_dtu_rst_thr_w, 
   fcl_dtu_resum_thr_w, ifu_tlu_itlb_done, ifu_spu_trap_ack, 
   ifu_exu_tid_s2, ifu_exu_ren1_s, ifu_exu_ren2_s, ifu_exu_ren3_s, 
   ifu_exu_disable_ce_e, fcl_dtu_sync_intr_d, fcl_dtu_tlzero_d, 
   fcl_dtu_privmode_d, fcl_dtu_hprivmode_d, fcl_dtu_hprivmode_w2, 
   fcl_dtu_nuke_thr_w, fcl_swl_swout_f, fcl_dtu_stall_bf, 
   fcl_swl_swcvld_s, fcl_dtu_thr_f, fcl_imd_oddwin_d, 
   fcl_fdp_oddwin_s, fcl_fdp_pcoor_vec_f, fcl_fdp_pcoor_f, 
   fcl_fdp_mask32b_f, fcl_fdp_addr_mask_d, fcl_fdp_tctxt_sel_prim, 
   fcl_fdp_usenir_sel_nir_s1, fcl_fdp_rbinst_sel_inste_s, 
   fcl_fdp_thrtnpc_sel_tnpc_l, fcl_fdp_thrtnpc_sel_npcw_l, 
   fcl_fdp_thrtnpc_sel_pcf_l, fcl_fdp_thrtnpc_sel_old_l, 
   fcl_fdp_thr_s1_l, fcl_fdp_next_thr_bf_l, fcl_fdp_next_ctxt_bf_l, 
   fcl_fdp_nirthr_s1_l, fcl_fdp_thr_s2_l, 
   fcl_fdp_tpcbf_sel_pcp4_bf_l, fcl_fdp_tpcbf_sel_brpc_bf_l, 
   fcl_fdp_tpcbf_sel_trap_bf_l, fcl_fdp_tpcbf_sel_old_bf_l, 
   fcl_fdp_pcbf_sel_nosw_bf_l, fcl_fdp_pcbf_sel_swpc_bf_l, 
   fcl_fdp_pcbf_sel_br_bf_l, fcl_fdp_trrbpc_sel_trap_bf_l, 
   fcl_fdp_trrbpc_sel_rb_bf_l, fcl_fdp_trrbpc_sel_err_bf_l, 
   fcl_fdp_trrbpc_sel_pcs_bf_l, fcl_fdp_noswpc_sel_tnpc_l_bf, 
   fcl_fdp_noswpc_sel_old_l_bf, fcl_fdp_noswpc_sel_inc_l_bf, 
   fcl_fdp_nextpcs_sel_pce_f_l, fcl_fdp_nextpcs_sel_pcd_f_l, 
   fcl_fdp_nextpcs_sel_pcs_f_l, fcl_fdp_nextpcs_sel_pcf_f_l, 
   fcl_fdp_inst_sel_curr_s_l, fcl_fdp_inst_sel_switch_s_l, 
   fcl_fdp_inst_sel_nir_s_l, fcl_fdp_inst_sel_nop_s_l, 
   fcl_fdp_tinst_sel_curr_s_l, fcl_fdp_tinst_sel_rb_s_l, 
   fcl_fdp_tinst_sel_old_s_l, fcl_fdp_tinst_sel_ifq_s_l, 
   fcl_fdp_dmpthr_l, fcl_fdp_ctxt_sel_dmp_bf_l, 
   fcl_fdp_ctxt_sel_sw_bf_l, fcl_fdp_ctxt_sel_curr_bf_l, 
   fcl_fdp_rdsr_sel_pc_e_l, fcl_fdp_rdsr_sel_thr_e_l, 
   fcl_fdp_rdsr_sel_ver_e_l, so, ifu_reset_l, 
   // Inputs
   rclk, grst_l, arst_l, se, sehold, si, rst_tri_en, 
   tlu_ifu_flush_pipe_w, exu_ifu_va_oor_m, exu_ifu_oddwin_s, 
   spu_ifu_ttype_tid_w2, spu_ifu_ttype_vld_w2, spu_ifu_ttype_w2, 
   erb_fcl_spu_uetrap, exu_ifu_regz_e, dcl_fcl_bcregz0_e, 
   dcl_fcl_bcregz1_e, dtu_fcl_rollback_g, dtu_fcl_retract_d, 
   dtu_fcl_br_inst_d, dtu_fcl_sir_inst_e, dtu_fcl_privop_e, 
   dtu_fcl_fpdis_e, dtu_fcl_imask_hit_e, dtu_fcl_illinst_e, 
   dtu_fcl_thr_active, dec_fcl_rdsr_sel_pc_d, dec_fcl_rdsr_sel_thr_d, 
   ifq_fcl_wrreq_bf, ifq_fcl_icd_wrreq_bf, ifq_fcl_ictv_wrreq_bf, 
   ifq_fcl_rdreq_bf, ifq_fcl_asi_tid_bf, ifq_fcl_asird_bf, 
   ifq_fcl_invreq_bf, erb_fcl_itlb_ce_d1, erb_dtu_ifeterr_d1, 
   erb_fcl_ifet_uevec_d1, erb_fcl_ue_trapvec, erb_fcl_ce_trapvec, 
   dtu_fcl_nextthr_bf, dtu_fcl_ntr_s, dtu_fcl_running_s, 
   dtu_fcl_flush_sonly_e, fdp_fcl_swc_s2, fdp_fcl_va2_bf, 
   itlb_fcl_tlbmiss_f_l, itlb_fcl_priv_s1, itlb_fcl_cp_s1, 
   itlb_fcl_imiss_s_l, fdp_fcl_pc_oor_vec_f, fdp_fcl_pc_oor_e, 
   fdp_fcl_op_s, fdp_fcl_op3_s, fdp_fcl_ibit_s, lsu_ifu_stallreq, 
   ffu_ifu_stallreq, ifq_fcl_stallreq, dtu_inst_anull_e, 
   ifq_fcl_fill_thr, ifq_fcl_flush_sonly_e, tlu_ifu_trap_tid_w1, 
   tlu_ifu_trappc_vld_w1, tlu_ifu_trapnpc_vld_w1, 
   tlu_lsu_pstate_priv, tlu_lsu_pstate_am, tlu_hpstate_priv, 
   tlu_lsu_redmode, tlu_hpstate_enb, lsu_ifu_addr_real_l, 
   lsu_pid_state0, lsu_pid_state1, lsu_pid_state2, lsu_pid_state3, 
   lsu_ifu_icache_en, lsu_ifu_dc_parity_error_w2, lsu_ifu_t0_tlz, 
   lsu_ifu_t1_tlz, lsu_ifu_t2_tlz, lsu_ifu_t3_tlz, tlu_ifu_hwint_i3, 
   tlu_ifu_pstate_ie, tlu_ifu_sftint_vld, tlu_ifu_hintp_vld, 
   tlu_ifu_rerr_vld, tlu_ifu_rstthr_i2, tlu_ifu_rstint_i2, 
   tlu_ifu_resumint_i2, tlu_ifu_nukeint_i2, tlu_itlb_wr_vld_g, 
   tlu_itlb_dmp_vld_g, tlu_itlb_dmp_all_g, tlu_itlb_data_rd_g, 
   tlu_itlb_tag_rd_g, tlu_itlb_invalidate_all_g, tlu_fcl_dmp_pid_bf, 
   tlu_fcl_dmp_real_bf, tlu_idtlb_dmp_thrid_g, exu_ifu_ecc_ce_m, 
   ffu_ifu_fst_ce_w
   );
 
   input  rclk,
	        grst_l,
          arst_l,
	        se,
          sehold,
	        si;
 
   input  rst_tri_en;
 
 
   input  tlu_ifu_flush_pipe_w;	// flush pipe on a trap
   input  exu_ifu_va_oor_m;
   input [3:0] exu_ifu_oddwin_s;
 
   input [1:0] spu_ifu_ttype_tid_w2;
   input       spu_ifu_ttype_vld_w2;
   input       spu_ifu_ttype_w2;
 
   input [3:0] erb_fcl_spu_uetrap;  // use m3
 
//   input       dtu_fcl_brtaken_e;    // branch taken
   input       exu_ifu_regz_e;
   input       dcl_fcl_bcregz0_e,
               dcl_fcl_bcregz1_e;
 
   input       dtu_fcl_rollback_g;
   input       dtu_fcl_retract_d;
   input       dtu_fcl_br_inst_d;
   input       dtu_fcl_sir_inst_e;
   input       dtu_fcl_privop_e,
		           dtu_fcl_fpdis_e,
               dtu_fcl_imask_hit_e,
		           dtu_fcl_illinst_e;
   input [3:0] dtu_fcl_thr_active;
 
   input       dec_fcl_rdsr_sel_pc_d,
		           dec_fcl_rdsr_sel_thr_d;
 
   input       ifq_fcl_wrreq_bf;
   input       ifq_fcl_icd_wrreq_bf,
		           ifq_fcl_ictv_wrreq_bf,
		           ifq_fcl_rdreq_bf;
 
   input [1:0] ifq_fcl_asi_tid_bf;
   input       ifq_fcl_asird_bf;
 
   input       ifq_fcl_invreq_bf;
 
   input       erb_fcl_itlb_ce_d1;
   input       erb_dtu_ifeterr_d1;
   input [3:0] erb_fcl_ifet_uevec_d1,
		           erb_fcl_ue_trapvec,
		           erb_fcl_ce_trapvec;   
 
   input [3:0] dtu_fcl_nextthr_bf;   // thread to switch to
   input       dtu_fcl_ntr_s,        // next thread ready for ex
               dtu_fcl_running_s;
 
   input       dtu_fcl_flush_sonly_e;
//               dec_fcl_kill4sta_e;
 
   input       fdp_fcl_swc_s2,       // instruction switch condition
		           fdp_fcl_va2_bf,       // bit 2 of vaddr
		           itlb_fcl_tlbmiss_f_l,  // itlb miss
		           itlb_fcl_priv_s1,     // privileged access page
		           itlb_fcl_cp_s1,       // uncached access page
		           itlb_fcl_imiss_s_l;     // icache miss in s1
 
   input [3:0] fdp_fcl_pc_oor_vec_f;
   input       fdp_fcl_pc_oor_e;
 
   input [1:0] fdp_fcl_op_s;
   input [5:2] fdp_fcl_op3_s;
   input       fdp_fcl_ibit_s;
 
   input       lsu_ifu_stallreq,
	             ffu_ifu_stallreq,
               ifq_fcl_stallreq;
 
   input       dtu_inst_anull_e;
 
   input [3:0] ifq_fcl_fill_thr;     // fill inst goes to this
                                   	 // thread instruction register
   input       ifq_fcl_flush_sonly_e;
 
   input [1:0] tlu_ifu_trap_tid_w1;     // thr for which trappc is sent
   input       tlu_ifu_trappc_vld_w1,   // ld pc on trap or done/retry
		           tlu_ifu_trapnpc_vld_w1;  // ld Npc for a retry
 
   input [3:0] tlu_lsu_pstate_priv;     // may need to flop these three
   input [3:0] tlu_lsu_pstate_am;
   input [3:0] tlu_hpstate_priv;
   input [3:0] tlu_lsu_redmode;
   input [3:0] tlu_hpstate_enb;
 
   input [3:0] lsu_ifu_addr_real_l;
   input [2:0] lsu_pid_state0,
               lsu_pid_state1,
               lsu_pid_state2,
               lsu_pid_state3;
   input [3:0] lsu_ifu_icache_en;
 
   input       lsu_ifu_dc_parity_error_w2;
 
 
//   input       lsu_ifu_flush_ireg;  // not needed any more
   input       lsu_ifu_t0_tlz,
 		           lsu_ifu_t1_tlz,
 		           lsu_ifu_t2_tlz,
 		           lsu_ifu_t3_tlz;
 
   input [3:0] tlu_ifu_hwint_i3,        // normal interrupt
		           tlu_ifu_pstate_ie,
		           tlu_ifu_sftint_vld,
		           tlu_ifu_hintp_vld,
		           tlu_ifu_rerr_vld,
		           tlu_ifu_rstthr_i2;       // reset or idle interrupt
 
   input       tlu_ifu_rstint_i2,       // reset to a dead thread
		           tlu_ifu_resumint_i2,
		           tlu_ifu_nukeint_i2;
 
   input       tlu_itlb_wr_vld_g,
		           tlu_itlb_dmp_vld_g,
               tlu_itlb_dmp_all_g,
		           tlu_itlb_data_rd_g,
		           tlu_itlb_tag_rd_g;
   input       tlu_itlb_invalidate_all_g;
 
   input [2:0] tlu_fcl_dmp_pid_bf;
   input       tlu_fcl_dmp_real_bf;
   input [1:0] tlu_idtlb_dmp_thrid_g;
 
   input       exu_ifu_ecc_ce_m;
   input       ffu_ifu_fst_ce_w;
 
   // to icd
   output      fcl_icd_rdreq_bf,
               fcl_icv_rdreq_bf,
		           fcl_icd_wrreq_bf,
		           fcl_ict_wrreq_bf,
		           fcl_icv_wrreq_bf;
 
   output      fcl_icd_index_sel_ifq_bf;
   output      fcl_ifq_grant_bf;
 
   // to ifq
   output      fcl_ifq_icmiss_s1;  // if icache turned off
   output      fcl_ifq_rdreq_s1;
   output      fcl_ifq_icache_en_s_l;
 
   output [1:0] fcl_ifq_thr_s1;
   output [3:0] fcl_ifq_canthr;     // cancel ifetch to this thread
 
   // to itlb
   output       fcl_itlb_cam_vld_bf,
                fcl_itlb_cam_bypass_bf,
		            fcl_itlb_addr_mask_l,
                fcl_itlb_cam_real_bf;
 
   output [2:0] fcl_itlb_cam_pid_bf;
 
   output       fcl_itlb_wr_vld_bf,
		            fcl_itlb_dmp_vld_bf,
                fcl_itlb_dmp_all_bf,
		            fcl_itlb_tag_rd_vld_bf,
		            fcl_itlb_invall_f_l,
		            fcl_itlb_data_rd_vld_bf;
 
   // to erb
   output       fcl_erb_ievld_s1,
		            fcl_erb_tevld_s1,
		            fcl_erb_immuevld_s1;
 
   output [1:0] ifu_lsu_thrid_s,
		            fcl_erb_asi_tid_f;
 
   output [3:0] fcl_erb_clear_iferr;
 
 
   output       fcl_erb_itlbrd_vld_s,
		            fcl_erb_itlbrd_data_s;
 
   output       fcl_dec_dslot_s;
   output       fcl_dtu_inst_vld_e,
                fcl_dtu_intr_vld_e,
		            fcl_dtu_inst_vld_d,
                fcl_dtu_ely_inst_vld_d,
                fcl_dec_intr_vld_d,
		            fcl_erb_inst_issue_d,
		            fcl_erb_inst_vld_d1,
		            ifu_tlu_inst_vld_m,
//		            ifu_lsu_inst_vld_m,
		            ifu_exu_inst_vld_e,
		            ifu_exu_inst_vld_w,
		            ifu_spu_inst_vld_w,
		            ifu_tlu_inst_vld_w;
 
   output       ifu_tlu_flush_w;
   output       ifu_tlu_flush_m;
 
   output [3:0] fcl_swl_int_activate_i3;
   output       fcl_swl_flush_wake_w;
   output       fcl_swl_flush_w;
 
   output       fcl_dcl_regz_e;
 
   // to tlu
   output [1:0] ifu_tlu_thrid_e;
   output [1:0] ifu_tlu_thrid_d;
 
   output       ifu_tlu_immu_miss_m,
		            ifu_tlu_priv_violtn_m;
 
   output       ifu_tlu_icmiss_e;
   output       ifu_tlu_ttype_vld_m;
   output       ifu_exu_ttype_vld_m;
   output       ifu_mmu_trap_m;
   output       ifu_tlu_trap_m;
   output [8:0] ifu_tlu_ttype_m;
 
   output       ifu_tlu_hwint_m;
   output       ifu_tlu_sftint_m;
//   output       ifu_tlu_hintp_m;
//   output       ifu_tlu_rerr_m;
   output       ifu_tlu_rstint_m;
   output       fcl_dtu_rst_thr_w;
   output       fcl_dtu_resum_thr_w;
 
   output       ifu_tlu_itlb_done;
 
   output       ifu_spu_trap_ack;
 
   // to exu
   output [1:0] ifu_exu_tid_s2;
   output       ifu_exu_ren1_s,
		            ifu_exu_ren2_s,
		            ifu_exu_ren3_s;
 
   output       ifu_exu_disable_ce_e;  // to exu and ffu
 
 
   // to dtu
   output       fcl_dtu_sync_intr_d;
   output       fcl_dtu_tlzero_d;
   output       fcl_dtu_privmode_d;
   output       fcl_dtu_hprivmode_d;
   output       fcl_dtu_hprivmode_w2;
   output       fcl_dtu_nuke_thr_w;
   output       fcl_swl_swout_f;
   output       fcl_dtu_stall_bf;
//   output       fcl_dtu_switch_s;     // indicates to the DTU that a
                                      // switch took place to next_thr
   output       fcl_swl_swcvld_s;
   output [3:0] fcl_dtu_thr_f;
   output       fcl_imd_oddwin_d;
 
   // to fdp
   output       fcl_fdp_oddwin_s;
   output [3:0] fcl_fdp_pcoor_vec_f;
   output       fcl_fdp_pcoor_f;
   output       fcl_fdp_mask32b_f;
   output       fcl_fdp_addr_mask_d;
 
   output [3:0] fcl_fdp_tctxt_sel_prim;
 
 
   // 2:1 mux selects
   output       fcl_fdp_usenir_sel_nir_s1;   // same as usenir_d2
   output [3:0] fcl_fdp_rbinst_sel_inste_s;
 
   output [3:0] fcl_fdp_thrtnpc_sel_tnpc_l,  // load npc
		            fcl_fdp_thrtnpc_sel_npcw_l,
		            fcl_fdp_thrtnpc_sel_pcf_l,
		            fcl_fdp_thrtnpc_sel_old_l;
 
   output [3:0] fcl_fdp_thr_s1_l;            // s1 thr for thrNIR input mux
 
   // other mux selects   
   output [3:0] fcl_fdp_next_thr_bf_l,  // for thrpc output mux
                fcl_fdp_next_ctxt_bf_l, // for ctxt output mux
		            fcl_fdp_nirthr_s1_l,    // select NIR in s1 stage
		            fcl_fdp_thr_s2_l;       // s2 thr for thr_inst_reg
 
   output [3:0] fcl_fdp_tpcbf_sel_pcp4_bf_l, // selects for thread PC muxes
		            fcl_fdp_tpcbf_sel_brpc_bf_l,
		            fcl_fdp_tpcbf_sel_trap_bf_l,
		            fcl_fdp_tpcbf_sel_old_bf_l;
 
   output       fcl_fdp_pcbf_sel_nosw_bf_l,      // F stage pc mux selects
		            fcl_fdp_pcbf_sel_swpc_bf_l,
		            fcl_fdp_pcbf_sel_br_bf_l;
 
   output [3:0] fcl_fdp_trrbpc_sel_trap_bf_l, 
		            fcl_fdp_trrbpc_sel_rb_bf_l,
		            fcl_fdp_trrbpc_sel_err_bf_l,
		            fcl_fdp_trrbpc_sel_pcs_bf_l;
 
   output       fcl_fdp_noswpc_sel_tnpc_l_bf,    // next pc select,
		            fcl_fdp_noswpc_sel_old_l_bf,		 // dont need anymore
		            fcl_fdp_noswpc_sel_inc_l_bf;
 
   output [3:0] fcl_fdp_nextpcs_sel_pce_f_l,  
		            fcl_fdp_nextpcs_sel_pcd_f_l,
		            fcl_fdp_nextpcs_sel_pcs_f_l,  
		            fcl_fdp_nextpcs_sel_pcf_f_l;
 
   output       fcl_fdp_inst_sel_curr_s_l,   // selects for inst_s2
		            fcl_fdp_inst_sel_switch_s_l,
		            fcl_fdp_inst_sel_nir_s_l,
		            fcl_fdp_inst_sel_nop_s_l;
 
   output [3:0] fcl_fdp_tinst_sel_curr_s_l,  // selects for tinst regs
		            fcl_fdp_tinst_sel_rb_s_l,		
		            fcl_fdp_tinst_sel_old_s_l,
		            fcl_fdp_tinst_sel_ifq_s_l;
 
   output [3:0] fcl_fdp_dmpthr_l;
 
   output       fcl_fdp_ctxt_sel_dmp_bf_l,
		            fcl_fdp_ctxt_sel_sw_bf_l,
		            fcl_fdp_ctxt_sel_curr_bf_l;
 
   output       fcl_fdp_rdsr_sel_pc_e_l,
                fcl_fdp_rdsr_sel_thr_e_l,
                fcl_fdp_rdsr_sel_ver_e_l;
 
   output       so,
                ifu_reset_l;
 
 
   //----------------------------------------------------------------------
   // Declarations
   //----------------------------------------------------------------------
   reg [3:0]    fcl_fdp_tpcbf_sel_old_bf_l,
		            fcl_fdp_tpcbf_sel_pcp4_bf_l,
		            fcl_fdp_tpcbf_sel_trap_bf_l,
		            fcl_fdp_tpcbf_sel_brpc_bf_l;
 
   wire         fcl_fdp_inst_sel_nop_s_l,
                fcl_fdp_inst_sel_nir_s_l,
		            fcl_fdp_inst_sel_curr_s_l,
		            fcl_fdp_inst_sel_switch_s_l;
 
 
   // local signals
   wire         //sw_itlb_on,
                sw_itlb_real,
		            sw_itlb_am,
		            //this_itlb_on,
                this_itlb_real,
		            itlb_on;
 
   wire [3:0]   xlate_en,
                xlate_en_d1;
 
   wire [2:0]   sw_pid_bf,
                curr_pid_bf;
 
   wire         pid_sel_sw,
                pid_sel_curr,
                pid_sel_dmp;
 
   wire         itlb_access_gnt,
		            itlb_access_en,
                itlb_write_en,
                ctxt_sel_dmp,
		            itlb_access_done,
                itlb_write_done,
		            itlb_rd_access_done,
		            itlb_rd_access_done_d1,
		            itlb_rd_access_done_d2,
		            itlb_rd_req_bf,
		            itlb_rd_req_f,
		            itlb_data_rd_f,
                itlb_data_rd_s;
 
   wire [1:0]   asi_tid_bf;
   wire [1:0]   spu_tid_w2;
 
   wire         fetch_bf,	// fetch an instruction next cycle
                allow_ifq_access_icd_bf,
                inst_access_bf,
                ia1_bf,
                ia0_bf,
                no_instacc_bf;
 
   wire         cam_vld_bf,
                tlb_invall_bf,
                tlb_invall_f,
//                tlb_invall_req_bf,
                inst_vld_bf;
 
   wire         rdreq_bf,     // read from I$ next cycle
		            rdreq_f;
 
   wire         ic_wrreq_bf;
 
   wire         running_s2,
                valid_s,
		            running_s1,
                ely_running_s1,
		            running_d,
		            running_e,
		            running_m,
    		        inst_vld_f,
		            inst_vld_s,
                inst_vld_s_crit,
		            inst_vld_s1,
		            inst_vld_s2,    // valid bit of S stage
	 	                            // instruction.  If this is 0,
		                            // convert inst to no-op
		            inst_vld_d,
                inst_vld_d_crit,
		            inst_vld_d1,
		            inst_vld_e,
		            inst_vld_qual_e,
		            inst_vld_m,
		            inst_vld_w;
 
   wire         inst_vld_w_crit;
 
   wire         no_iftrap_m,
                no_iftrap_w;
 
   wire         stall_f,
		            stall_s1,
		            stall_s1_nxt,
                ely_stall_thisthr_f,
                part_stall_thisthr_f,
		            stall_thisthr_f;
   wire         rdreq_s1;
 
   wire         usenir_bf,
		            usenir_f,
		            usenir_s1;
 
   wire [3:0]   tinst_vld_s,    // valid bit of thr instr register
		                            // in s stage
		            tinst_vld_nxt;
 
   wire [3:0]   val_thr_s1,
		            val_thr_f,
                thr_e_v2,
		            val_thr_e;
 
   wire         flush_sonly_qual_e,
                flush_sonly_all_m,
                flush_sonly_qual_m,
                ims_flush_sonly_m,
                ims_flush_sonly_w,
                ims_flush_coll_m,
                ims_flush_coll_w,
                flush_sonly_m;
 
   wire         flush_pipe_w;
 
   wire         kill_thread_d,
//		            kill_thread_e,
		            kill_thread_m,
                kill_local_m,
                ely_kill_thread_s2,
                ely_kill_thread_m,
		            kill_thread_s2;
 
   wire [3:0]   clear_s_d1,
                flush_thr_w,
                late_flush_w2;
 
   wire         utrap_flush_w,
                utrap_flush_m,
                flush_pipe_w2;
 
   wire         kill_curr_f,
                kill_curr_d,
                kill_curr_e,
                kill_curr_m;
 
   wire [3:0]   canthr_f,
                canthr_s_early,
		            canthr_s;
   wire         canthr_sw;
   wire         canthr_sm,
                canthr_sd;
 
   wire         forcemiss_f,   // force an icache miss (if icache is off)
		            forcemiss_s1,
                icmiss_for_perf,
//                ic_miss_sw_s1,
		            ic_miss_s1;    // icache miss (forced or not)
 
   wire [3:0]   icache_en_d1;
 
   wire         icache_on_bf,
		            icache_on_f,
		            icache_on_s1,
                uncached_page_s1;
//		            sw_icache_on,
//		            this_icache_on;
 
   wire         imsto_thisthr_s1,
                iferrto_thisthr_d1,
                retract_iferr_d1,
                retract_iferr_qual_d1,
                retract_inst_d,
                retract_iferr_e;
//   wire         intrto_thisthr_d;
//   wire         imsto_nextthr_s1;
 
   wire         mark4rb_w,
                mark4rb_m,
                mark4rb_e,
                mark4rb_d,
                mark4rb_s;
 
   wire [3:0]   tlbmiss_s2,
		            tlbmiss_d,
		            nir_tlbmiss_vec,
		            nir_tlbmiss_next;
 
   wire [3:0]   delay_slot_vec,
                delay_slot_vec_nxt;
 
   wire         tlb_cam_miss_f,
                tlb_cam_miss_s1,
                nir_tlbmiss_s1,
		            tlbmiss_s1_crit,
		            tlbmiss_s1;
 
   wire         cam_vld_f,
		            cam_vld_s1;
 
   wire         immu_fault_f,
		            immu_miss_d,
		            immu_miss_crit_d,
		            immu_miss_qual_d,
		            immu_miss_e,
//                immu_miss_qual_e,
                immu_miss_m,
                addr_real_e;
   wire [3:0]   itlb_addr_real_l,
                itlb_addr_real;
   wire [3:0]   pstate_am_d1;
 
   wire         pc_oor_s1,
                pc_oor_s2,
                pc_oor_s,
		            pc_oor_f;
   wire         set_oor_m;
   wire         addr_mask_32b_m;
 
   wire         priv_mode_s1,
                priv_mode_f,
                hpriv_mode_s1,
                hpriv_mode_w,
                hpriv_mode_w2,
                hpriv_mode_f;
 
   wire         inst_acc_exc_s1,
		            inst_acc_exc_d,
		            inst_acc_exc_e;
   wire [3:0]   inst_acc_vec_s2,
		            inst_acc_vec_d;
 
   wire         priv_violtn_e,
                priv_violtn_m;
 
   wire         trap_e,
		            trap_m;
 
   wire         ttype_sel_spuma_e,
 		            ttype_sel_spuenc_e,
		            ttype_sel_corr_err_e,
		            ttype_sel_unc_err_e,		
		            ttype_sel_res_err_e,		
		            ttype_sel_hstk_cmp_e,		
		            ttype_sel_pcoor_e,
		            ttype_sel_immu_miss_e, 
		            ttype_sel_real_trans_e, 
		            ttype_sel_icache_err_e,
		            ttype_sel_priv_viol_e, 
		            ttype_sel_privop_e,    
		            ttype_sel_illinst_e,
		            ttype_sel_ibe_e,
		            ttype_sel_sir_e,
		            ttype_sel_fpdis_e;
 
   wire [8:0]   ttype_e;
 
   wire [3:0]   next_nir_privvec,
		            nir_privvec;
   wire         nir_priv_s1,
		            priv_inst_s1;
 
   wire         tlzero_s2;
   wire [3:0]   tlzero_vec_d1;
 
   wire         nuke_thr_w,
                resum_thr_w,
                rst_thr_w;
 
   wire [3:0]   spu_thr;
//   wire [3:0]   rst_thr_bf;
 
   wire [3:0]   async_rst_i3,
                async_rst_i4,
		            next_rst_i2,
		            rstint_i2,
		            rstint_i3,
		            resumint_i2,
		            resumint_i3,
                next_resum_i2,
		            nuke_thr_i2,
		            next_nuke_i2,
		            nuke_thr_i3,
		            next_sftint_i2,
                next_hintp_i2,
                next_rerr_i2,
		            next_hwint_i3,
		            sftint_i3,
                hintp_i3,
                rerr_i3,
		            hwint_i4,
		            next_ceint_i2,
		            ceint_i3,
		            next_ueint_i2,
		            ueint_i3,
		            next_spuint0_i2,
		            spuint0_i3,
		            next_spuint1_i2,
		            spuint1_i3;
 
   wire [3:0]   intr_in_pipe;
 
   wire [3:0]   hypv_int_en,
                hypv_int_en_d1;
   wire [3:0]   supv_int_en,
                supv_int_en_d1;
 
   wire [3:0]   ifet_ue_vec_d1,
		            ifet_ue_vec_e;
   wire         ifet_ue_e;
 
   wire [3:0]   any_intr_vec_f,
                any_intr_vec_s,
                intr_pending_nxt,
                intr_pending_s,
                supv_masked_intr_s,
                hypv_masked_intr_s;
 
   wire         spuint0_m,
                spuint0_trap_m,
//                spuint0_qual_m,
		            spuint0_e,
		            spuint0_qual_e,
                spuint0_w,
                spuint0_trap_w,
 		            spuint1_m,
                spuint1_trap_m,
//                spuint1_qual_m,
		            spuint1_e,
		            spuint1_qual_e,
                spuint1_w,
                spuint1_trap_w,
                hwint_m,
                hwint_e,
                rstint_m,
//                rstint_qual_m,
                resumint_m,
                resumint_qual_m,
                sftint_m,
                sftint_e,
                sftint_qual_e,
                hintp_e,
                hintp_qual_e,
                hintp_m,
                rerr_e,
                rerr_qual_e,
                rerr_m,
                nuke_thr_m,
                nuke_thr_qual_m,
		            ceint_m,
                ceint_trap_m,
                ceint_trap_w,
//                ceint_qual_m,
                ceint_qual_w,
		            ceint_e,
		            ceint_qual_e,
		            ueint_m,
                ueint_trap_m,
                ueint_trap_w,
//                ueint_qual_m,
                ueint_qual_w,
                ueint_qual_e,
		            ueint_e;
 
   wire         disr_trap_m,
                rb_intr_m,
                rb_intr_w,
                any_intr_m;
 
   wire         force_intr_s;
   wire         intr_vld_s,
		            intr_vld_d,
		            intr_vld_e,
		            intr_vld_m,
		            intr_vld_w,
                intr_vld_qual_s,
		            intr_vld_qual_d,
		            intr_vld_qual_e,
		            intr_vld_qual_m;
 
   wire         kill_intr_f,
		            kill_intr_d,
		            kill_intr_e;
 
//	 wire         kill_intr_m;
 
   wire         rst_stallreq,
                rst_stallreq_l,
                all_stallreq,
                rst_itlb_stv_l,
                arst_vld_f,
                arst_vld_f_l,
                arst_vld_s,
                arst_vld_s_l,
                async_intr_vld_s,
                itlb_starv_alert,
                rst_sw_bf,
                rst_sw_bf_l,
                sw_for_real_rst_bf,
                rst_stallreq_d0,
		            rst_stallreq_d1,
		            rst_stallreq_d2;
 
   wire         lsu_stallreq_d1,
                ffu_stallreq_d1;
 
   wire [3:0]   rstint_penc;
 
   wire         usep_bf,
                set_usen_bf,
                usen_iso_bf,
		            usen_bf;
   wire         va2_f;
   wire         ntpc_thisthr;
 
   wire [3:0]   thr_usen_nxt,
 		            thr_usen_bf;
 
   wire         brto_nxtthr_bf_l,  // intermediate signal for icadr sel
//                brto_nxtthr_bf,
//                thr_match_ne_norst,
                sw_match_ne_norst,
                brtaken_buf_e,
                brtaken_unq_e,
                brtaken_e,
                brtaken_m;
 
   wire         switch_bf,   // switch in next cycle unless stall
                switch_qual_bf,
		            switch_s2;  // switch in this cycle
 
   wire         rstt,       // set thr_f to the reset pkt thread
		            swt,        // switch to nextthr_bf
		            samet;      // don't change thread
 
   wire [3:0]   thr_f_crit,
                thr_f_dec,
                thr_f_flop;
 
   wire [3:0]   thr_f,      // = thr_s2
		            thr_bf,
		            thr_s1,     // = thr_d
		            thr_s1_next,
                dec_thr_s1_l,
		            thr_d,
		            thr_e,
		            thr_m,
		            thr_w2,
		            thr_w;
 
   wire         tm_fd_l;
 
   wire         thr_match_fw,
		            thr_match_fw2,
		            thr_match_dw,
		            thr_match_dw2,
		            thr_match_em,
		            thr_match_ew,
		            thr_match_ew2,
		            same_thr_mw2,
		            thr_match_mw,
		            thr_match_fm,
		            thr_match_de,
		            thr_match_dm,
		            thr_match_fe,
		            thr_match_fd,
		            thr_match_fs1,
		            thr_match_nw,
		            thr_match_nd,
		            thr_match_ne;
//		            thr_match_ft;
 
   wire         rb2_inst_d,
		            rb2_inst_e,
		            rb1_inst_s,
		            rb1_inst_d,
		            rb0_inst_bf,
		            rb0_inst_s,
		            rt2_inst_e,
		            rt1_inst_s,
		            rt1_inst_d,
		            rt0_inst_bf,
		            rt0_inst_s;
 
   wire [3:0]   rb_w2,
                rb_for_iferr_e,
		            rb_froms,
		            rb_frome,
		            rb_fromd;
 
   wire         rb_stg_s,
		            rb_stg_d,
                rb_stg_d_crit,
		            rb_stg_e;
 
   wire         icadr_selbr_l,
//		            icadr_selsw,
//                icadr_selbr,
                icadr_selsw_l;
 
   wire         sw_or_async_stall;
 
   wire [3:0]   trap_thr;
 
   wire [3:0]   load_tpc,     // thread pc reg input select
		            load_bpc,     // these should be exclusive in normal mode
		            load_pcp4;    // but not during scan shift or reset
 
   wire         irf_ce_w,
		            irf_ce_m,
                any_ce_w,
		            rb_stg_w;
 
   wire [3:0]   ce_cnt0,
                ce_cnt0_nxt,
                ce_cnt1,
                ce_cnt1_nxt,
                ce_cnt_rst;
 
   wire         ce_val0_d,
                ce_val1_d,
                disable_ce_e,
                disable_ce_d;
 
   wire [3:0]   ntpc_vld,     // use thr_nextpc_f
		            ntpc_vld_nxt;
 
   wire [1:0]   sas_thrid_w;
 
   wire         rdsr_sel_pc_e,
		    		    rdsr_sel_thr_e;
 
   wire [1:0]   trap_tid_w2;
   wire         trappc_vld_w2, 
                trapnpc_vld_w2;
 
   wire         fcl_reset,
                fcl_reset_l;
 
   // some monitor is looking for this signal
//   wire         fcl_swl_flush_wait_w=1'b0;
   wire         clk;
 
   wire [3:0]   nextthr_bf_buf,
                nextthr_final_bf;
 
 
//
// Code start here 
//
   assign       clk = rclk;
 
//----------------------------------------------------------------------
// Fetch Unit Controls
//----------------------------------------------------------------------
 
   // reset buffer
   dffrl_async rstff(.din (grst_l),
                     .q   (fcl_reset_l),
                     .clk (clk), .se(se), .si(), .so(),
                     .rst_l (arst_l));
 
   assign   fcl_reset = ~fcl_reset_l;
   assign   ifu_reset_l = fcl_reset_l;
 
 
//-----------------------------------
// TLB Operations
//-----------------------------------
 
   dff_s #(4) real_reg(.din (lsu_ifu_addr_real_l),
                     .q   (itlb_addr_real_l),
                     .clk (clk), .se(se), .si(), .so());
   assign   itlb_addr_real = ~itlb_addr_real_l;
 
   // ITLB on signal
 
//`ifdef SPARC_HPV_EN   
   assign   xlate_en = (~tlu_hpstate_enb & lsu_ifu_addr_real_l |
                        tlu_hpstate_enb & ~tlu_hpstate_priv) & 
                         ~tlu_lsu_redmode;
 
//`else
//   assign   xlate_en = lsu_ifu_addr_real_l;
//`endif
 
   dff_s #(4) xlate_reg(.din (xlate_en),
                      .q   (xlate_en_d1),
                      .clk (clk), .se(se), .si(), .so());
 
//   assign sw_itlb_on = ((nextthr_bf_buf & xlate_en_d1) == 4'b0) ?
//		                     1'b0 : 1'b1;
//   assign this_itlb_on = ((thr_f & xlate_en_d1) == 4'b0) ?
//			                     1'b0 : 1'b1;
//   assign itlb_on = switch_bf ? sw_itlb_on : this_itlb_on;
   assign itlb_on = (nextthr_final_bf[0] & xlate_en_d1[0] |
                     nextthr_final_bf[1] & xlate_en_d1[1] |
                     nextthr_final_bf[2] & xlate_en_d1[2] |
                     nextthr_final_bf[3] & xlate_en_d1[3]);
 
 
   // flop xlate_en (done) addr_real and icache_en if timing is 
   // not cutting it
 
   // Hypervisor signals
   assign sw_itlb_real = ((nextthr_bf_buf & itlb_addr_real) == 4'b0) ?
		                     1'b0 : 1'b1;
   assign this_itlb_real = ((thr_f & itlb_addr_real) == 4'b0) ?
			                     1'b0 : 1'b1;
 
//   assign fcl_itlb_cam_real_bf = switch_bf ? sw_itlb_real : this_itlb_real;
 
   mux3ds  creal_mx(.dout (fcl_itlb_cam_real_bf),
                    .in0  (sw_itlb_real),
                    .in1  (this_itlb_real),
                    .in2  (tlu_fcl_dmp_real_bf),
                    .sel0 (pid_sel_sw),
                    .sel1 (pid_sel_curr),
                    .sel2 (pid_sel_dmp));
 
   // Partition ID
   mux4ds #(3) swpid_mux (.dout (sw_pid_bf[2:0]),
                          .in0  (lsu_pid_state0[2:0]),
                          .in1  (lsu_pid_state1[2:0]),
                          .in2  (lsu_pid_state2[2:0]),
                          .in3  (lsu_pid_state3[2:0]),
                          .sel0 (nextthr_bf_buf[0]),
                          .sel1 (nextthr_bf_buf[1]),
                          .sel2 (nextthr_bf_buf[2]),
                          .sel3 (nextthr_bf_buf[3]));
 
   mux4ds #(3) currpid_mux (.dout (curr_pid_bf[2:0]),
                            .in0  (lsu_pid_state0[2:0]),
                            .in1  (lsu_pid_state1[2:0]),
                            .in2  (lsu_pid_state2[2:0]),
                            .in3  (lsu_pid_state3[2:0]),
                            .sel0 (thr_f[0]),
                            .sel1 (thr_f[1]),
                            .sel2 (thr_f[2]),
                            .sel3 (thr_f[3]));
 
//   assign fcl_itlb_cam_pid_bf[2:0] = switch_bf ?  
//                                       sw_pid_bf[2:0] : 
//                                       curr_pid_bf[2:0];
 
//   assign pid_sel_dmp = tlu_itlb_dmp_actxt_g & ctxt_sel_dmp;
   assign pid_sel_dmp = ctxt_sel_dmp;   
   assign pid_sel_curr = ~pid_sel_dmp & ~switch_bf;
   assign pid_sel_sw = ~pid_sel_dmp & switch_bf;
   mux3ds #(3) ipid_mx(.dout (fcl_itlb_cam_pid_bf[2:0]),
                       .in0  (sw_pid_bf[2:0]),
                       .in1  (curr_pid_bf[2:0]),
                       .in2  (tlu_fcl_dmp_pid_bf[2:0]),
                       .sel0 (pid_sel_sw),
                       .sel1 (pid_sel_curr),
                       .sel2 (pid_sel_dmp));
 
   // ITLB address mask
   dff_s #(4) am_reg(.din (tlu_lsu_pstate_am),
                   .q   (pstate_am_d1),
                   .clk (clk), .se(se), .si(), .so());
 
   assign sw_itlb_am = ((nextthr_bf_buf & pstate_am_d1) == 4'b0) ?
		                     1'b0 : 1'b1;
   assign fcl_itlb_addr_mask_l = switch_bf ? 
                                 ~sw_itlb_am : ~fcl_fdp_mask32b_f;
 
   dff_s #(4) tlz_reg(.din ({lsu_ifu_t3_tlz,
                           lsu_ifu_t2_tlz,
                           lsu_ifu_t1_tlz,
                           lsu_ifu_t0_tlz}),
                    .q   (tlzero_vec_d1[3:0]),
                    .clk (clk), .se (se), .si(), .so());
 
 
   // TLB context select
   assign fcl_fdp_tctxt_sel_prim = tlzero_vec_d1 & itlb_addr_real_l;
//   assign fcl_fdp_tctxt_sel_prim[1] = lsu_ifu_t1_tlz & itlb_addr_real_l[1];
//   assign fcl_fdp_tctxt_sel_prim[2] = lsu_ifu_t2_tlz & itlb_addr_real_l[2];
//   assign fcl_fdp_tctxt_sel_prim[3] = lsu_ifu_t3_tlz & itlb_addr_real_l[3];
 
 
   // Access to TLB
   // ITLB may be accessed even when icache is off
   assign cam_vld_bf = itlb_on & inst_access_bf;
 
   assign fcl_itlb_cam_vld_bf = cam_vld_bf;
   assign fcl_itlb_cam_bypass_bf = ~cam_vld_bf;
 
   dff_s #(1) itlb_onf_ff(.din (cam_vld_bf),
		                    .q   (cam_vld_f),
		                    .clk (clk),
		                    .se  (se), .si(), .so());
 
   dff_s #(1) itlb_ons1_ff(.din (cam_vld_f),
		                     .q   (cam_vld_s1),
		                     .clk (clk),
		                     .se  (se), .si(), .so());
 
   // allow rd/wr/demap access to tlb
   // itlb access is granted only every other cycle
   // (not enough time to turn the request from mmu around)
//   assign itlb_access_en = ~cam_vld_bf & ~ifq_fcl_asird_bf & 
//                           ~itlb_access_done;
//
//   assign itlb_write_en = ~cam_vld_bf & ~ifq_fcl_asird_bf & 
//                           ~itlb_write_done & 
//                           (~tlu_itlb_dmp_vld_g | itlb_access_done);
 
// Save some timing   
//   assign itlb_write_en = (~itlb_on | no_instacc_bf) & ~ifq_fcl_asird_bf &
//                          ~itlb_write_done & 
//                          (~tlu_itlb_dmp_vld_g | itlb_access_done);
 
   assign itlb_write_en = no_instacc_bf & ~ifq_fcl_asird_bf & 
                          ~itlb_write_done &  
                          (~tlu_itlb_dmp_vld_g | itlb_access_done);
   assign itlb_access_en = no_instacc_bf & ~ifq_fcl_asird_bf &
                           ~itlb_access_done;
 
   // reset tlb
//   dff #(1) itlbrst_ff(.din (tlu_itlb_invalidate_all_g),
//		                   .q   (tlb_invall_req_bf),
//		                   .clk (clk), .se(se), .si(), .so());
//   assign tlb_invall_bf = tlb_invall_req_bf & ~itlb_access_done;
   assign tlb_invall_bf = sehold ? tlb_invall_f :
                           (tlu_itlb_invalidate_all_g & itlb_access_en);
   dff_s #(1) itlbrstf_ff(.din (tlb_invall_bf),
		                    .q   (tlb_invall_f),
		                    .clk (clk), .se(se), .si(), .so());
 
   assign fcl_itlb_wr_vld_bf = tlu_itlb_wr_vld_g & itlb_write_en;
   assign fcl_itlb_dmp_vld_bf = tlu_itlb_dmp_vld_g & itlb_access_en;
   assign fcl_itlb_dmp_all_bf = tlu_itlb_dmp_all_g & tlu_itlb_dmp_vld_g & 
                                itlb_access_en;
 
//   assign fcl_itlb_invall_bf = tlb_invall_bf & itlb_access_en | fcl_reset;
   assign fcl_itlb_invall_f_l = ~tlb_invall_f;
 
   assign fcl_itlb_data_rd_vld_bf = tlu_itlb_data_rd_g & itlb_access_en & 
	                                  ~itlb_rd_access_done_d2 &
                                    ~itlb_rd_access_done_d1;
 
   assign fcl_itlb_tag_rd_vld_bf = tlu_itlb_tag_rd_g & itlb_access_en &
	                                 ~itlb_rd_access_done_d2 &
                                   ~itlb_rd_access_done_d1;
 
   assign rst_itlb_stv_l = ((tlu_itlb_invalidate_all_g |
                             tlu_itlb_dmp_vld_g |
                             tlu_itlb_data_rd_g |
                             tlu_itlb_tag_rd_g) & ~itlb_access_done |
                            tlu_itlb_wr_vld_g & ~itlb_write_done) &
                             ~fcl_reset;
 
   sparc_ifu_ctr5 starv_ctr(
			                      // Outputs
			                      .limit	(itlb_starv_alert),
			                      .so	(so),
			                      // Inputs
			                      .clk	(clk),
			                      .se	(se),
			                      .si	(si),
			                      .rst_ctr_l (rst_itlb_stv_l));
 
   assign itlb_rd_req_bf = fcl_itlb_data_rd_vld_bf | fcl_itlb_tag_rd_vld_bf;
 
   // tlb access request
   assign itlb_access_gnt = (fcl_itlb_data_rd_vld_bf |
			                       fcl_itlb_tag_rd_vld_bf  |
//                             tlb_invall_bf & itlb_access_en |
                             tlb_invall_bf |
                             fcl_itlb_dmp_vld_bf);
 
   dff_s #(1) tlb_gnt1_ff(.din (itlb_access_gnt),
		                  .q   (itlb_access_done),
		                  .clk (clk), .se  (se), .si(), .so());
 
   dff_s #(1) tlb_rd_ff(.din (itlb_rd_req_bf),
		                .q   (itlb_rd_req_f),
		                .clk (clk), .se  (se), .si(), .so());
 
   dff_s #(1) tlb_wrt1_ff(.din (fcl_itlb_wr_vld_bf),
		                    .q   (itlb_write_done),
		                    .clk (clk), .se  (se), .si(), .so());
 
 
   // TBD:
   // reads need to wait one more cycle.  Others can ack without this
   // second delay.
   assign itlb_rd_access_done = itlb_rd_req_f & itlb_access_done;
 
   dff_s #(1) tlb_rd1_ff(.din (itlb_rd_access_done),
		                  .q   (itlb_rd_access_done_d1),
		                  .clk (clk), .se  (se), .si(), .so());
   dff_s #(1) tlb_rd2_ff(.din (itlb_rd_access_done_d1),
		                   .q   (itlb_rd_access_done_d2),
		                  .clk (clk), .se  (se), .si(), .so());
   assign ifu_tlu_itlb_done = ~itlb_rd_req_f & itlb_access_done |
                               itlb_write_done | 
	                             itlb_rd_access_done_d2;
 
   assign fcl_erb_itlbrd_vld_s = itlb_rd_access_done_d1;
 
   assign asi_tid_bf = ifq_fcl_asird_bf ? ifq_fcl_asi_tid_bf :
	                                        tlu_idtlb_dmp_thrid_g;
 
   dff_s #(2) asi_tid_reg(.din (asi_tid_bf),
		                  .q   (fcl_erb_asi_tid_f),
		                  .clk (clk), .se(se), .si(), .so());
 
 
   // Remember if we read tag or data
   dff_s #(1) tlb_rddf_ff(.din (fcl_itlb_data_rd_vld_bf),
		                  .q   (itlb_data_rd_f),
		                  .clk (clk), .se  (se), .si(), .so());
 
   dff_s #(1) tlb_rdds_ff(.din (itlb_data_rd_f),
		                  .q   (itlb_data_rd_s),
		                  .clk (clk), .se  (se), .si(), .so());
 
   // pick itlb ldxa data
   assign fcl_erb_itlbrd_data_s =  itlb_data_rd_s;
 
   // Demap thread
   assign fcl_fdp_dmpthr_l[0] = ~(~tlu_idtlb_dmp_thrid_g[1] & ~tlu_idtlb_dmp_thrid_g[0]);
   assign fcl_fdp_dmpthr_l[1] = ~(~tlu_idtlb_dmp_thrid_g[1] & tlu_idtlb_dmp_thrid_g[0]);
   assign fcl_fdp_dmpthr_l[2] = ~(tlu_idtlb_dmp_thrid_g[1] & ~tlu_idtlb_dmp_thrid_g[0]);
   assign fcl_fdp_dmpthr_l[3] = ~(tlu_idtlb_dmp_thrid_g[1] & tlu_idtlb_dmp_thrid_g[0]);
 
   // Select appropriate context for TLB
   // ctxt_sel_dmp is itlb_access_en without the asird signal
   assign ctxt_sel_dmp = no_instacc_bf & ~itlb_access_done;
   assign fcl_fdp_ctxt_sel_dmp_bf_l = ~ctxt_sel_dmp;   
   assign fcl_fdp_ctxt_sel_sw_bf_l = ctxt_sel_dmp | ~switch_bf;
   assign fcl_fdp_ctxt_sel_curr_bf_l = ctxt_sel_dmp | switch_bf;
 
 
//--------------------------
// Fetch Request and Stall
//--------------------------
 
   // Determine if we need can continue fetching next cycle
//   assign fetch_bf = (~all_stallreq & ~fcl_reset & ~rst_stallreq) &
//                   (switch_bf |
//                    ~(part_stall_thisthr_f | fdp_fcl_swc_s2));
//                    ~(stall_thisthr_f | fdp_fcl_swc_s2 | immu_fault_f));
 
   assign fetch_bf = (~all_stallreq & ~fcl_reset & ~rst_stallreq) &
                       (switch_bf |  // replace with ntr_s?
                        ~(part_stall_thisthr_f  
                          | fdp_fcl_swc_s2
                          )
                        );
 
   // dtu_fcl_running_s should be a part of this eqn, since it is assumed
   // by the ifill completion prediction logic in the swl
//   assign inst_access_bf = (~all_stallreq & ~fcl_reset & ~rst_stallreq & 
//                            (switch_bf & ~usen_iso_bf |
//                             ~switch_bf & ~ely_stall_thisthr_f &
//                             dtu_fcl_running_s & 
//                             ~ely_kill_thread_s2 &
//                             //~fdp_fcl_swc_s2 & // take out for tim reasons
//                             ~usep_bf));
 
   assign ia0_bf = (~all_stallreq & ~fcl_reset & ~rst_stallreq & 
                    (switch_bf |
                     ~ely_stall_thisthr_f &
                     dtu_fcl_running_s & 
                     ~ely_kill_thread_s2 &
                     ~usep_bf));
 
   assign ia1_bf = (~all_stallreq & ~fcl_reset & ~rst_stallreq & 
                    (~switch_bf & ~ely_stall_thisthr_f &
                     dtu_fcl_running_s & 
                     ~ely_kill_thread_s2 &
                     ~usep_bf));
 
 
   assign inst_access_bf = usen_iso_bf ? ia1_bf : ia0_bf;
   // needs to work even if usen_iso_bf is X - not nec. 11/06/03
//   dp_mux2es #(1) ia_mx(.dout (inst_access_bf),
//                        .in0  (ia0_bf),
//                        .in1  (ia1_bf),
//                        .sel  (usen_iso_bf));
 
 
 
//   assign allow_ifq_access_icd_bf = (all_stallreq | rs
//                                     ~switch_bf & 
//                                     (usep_bf | stall_f) |
//                                     switch_bf & usen_bf);
   assign allow_ifq_access_icd_bf = ~inst_access_bf;
 
   // earlier version for critical stuff
   assign no_instacc_bf = all_stallreq | fcl_reset | rst_stallreq |
                          ~dtu_fcl_ntr_s & (ely_stall_thisthr_f | usep_bf);
 
   // check if icache is on
   dff_s #(4) ic_en_reg(.din (lsu_ifu_icache_en),
                      .q   (icache_en_d1),
                      .clk (clk), .se(se), .si(), .so());
 
//   assign sw_icache_on = (nextthr_bf_buf[0] & icache_en_d1[0] |
//                          nextthr_bf_buf[1] & icache_en_d1[1] |
//                          nextthr_bf_buf[2] & icache_en_d1[2] |
//                          nextthr_bf_buf[3] & icache_en_d1[3]);
//   assign this_icache_on = (thr_f[0] & icache_en_d1[0] |
//                            thr_f[1] & icache_en_d1[1] |
//                            thr_f[2] & icache_en_d1[2] |
//                            thr_f[3] & icache_en_d1[3]);
//   assign icache_on_bf = switch_bf ? sw_icache_on : this_icache_on;
 
   assign icache_on_bf = (nextthr_final_bf[0] & icache_en_d1[0] |
                          nextthr_final_bf[1] & icache_en_d1[1] |
                          nextthr_final_bf[2] & icache_en_d1[2] |
                          nextthr_final_bf[3] & icache_en_d1[3]);
 
   // remember if icache was turned on
   dff_s #(1) icef_ff(.din (icache_on_bf),
		              .q   (icache_on_f),
		              .clk (clk), .se(se), .si(), .so());
   dff_s #(1) ices_ff(.din (icache_on_f),
		              .q   (icache_on_s1),
		              .clk (clk), .se(se), .si(), .so());
 
   // check if cp is set
   assign uncached_page_s1 = ~itlb_fcl_cp_s1 & cam_vld_s1;
   assign fcl_ifq_icache_en_s_l = ~icache_on_s1 | uncached_page_s1;
 
   // Read from the icache only if 
   //   we need to fetch AND 
   //   the icache is on AND 
   //   we are not using the NIR 
   assign rdreq_bf = icache_on_bf & inst_access_bf;
 
   assign fcl_icd_rdreq_bf = rdreq_bf | ifq_fcl_rdreq_bf;
 
   // split off driver to icv to reduce load
   assign fcl_icv_rdreq_bf = rdreq_bf | ifq_fcl_rdreq_bf;
 
   // Read req pipe
   dffr_s #(1)  rdreq_ff(.din  (rdreq_bf),
		                 .clk  (clk),
		                 .rst  (fcl_reset),
		                 .q    (rdreq_f),
		                 .se   (se), .si(), .so());
   // Remember if we fetched in the last cycle
   dff_s #(1)  rdreqs1_ff (.din  (rdreq_f),
		                   .clk  (clk),
		                   .q    (rdreq_s1),
		                   .se   (se), .si(), .so());
   assign fcl_ifq_rdreq_s1 = ~stall_s1;
 
   // Use NIR pipe
   assign usenir_bf = switch_bf ? usen_bf : usep_bf;
 
   dffr_s #(1)  unf_ff(.din  (usenir_bf),
		                 .clk  (clk),
		                 .rst  (fcl_reset),
		                 .q    (usenir_f),
		                 .se   (se), .si(), .so());
   // Remember if we fetched in the last cycle
   dff_s #(1)  uns1_ff (.din  (usenir_f),
		                  .clk  (clk),
		                  .q    (usenir_s1),
		                  .se   (se), .si(), .so());
 
 
   // Write signal to icache if no access from pipe
   assign ic_wrreq_bf = allow_ifq_access_icd_bf & ifq_fcl_wrreq_bf;
 
   assign fcl_icd_wrreq_bf = ic_wrreq_bf | ifq_fcl_icd_wrreq_bf;
   assign fcl_ict_wrreq_bf = ic_wrreq_bf | ifq_fcl_ictv_wrreq_bf;
   assign fcl_icv_wrreq_bf = ic_wrreq_bf | ifq_fcl_ictv_wrreq_bf |
                             ifq_fcl_invreq_bf;
 
   // synopsys translate_off
   always @ (posedge clk)
   begin
	    if (fcl_icd_rdreq_bf & fcl_icd_wrreq_bf)
	      begin
		 // 0in <fire -message "ERROR: sparc_ifu_fcl: rd and wr req to I$ at the same time"
`ifdef DEFINE_0IN
`else           
		`ifdef MODELSIM
			 $display( "CACHE_CONTENTION", "ERROR: sparc_ifu_fcl: rd and wr req to I$ at the same time");
		`else
	         $error("CACHE_CONTENTION", "ERROR: sparc_ifu_fcl: rd and wr req to I$ at the same time");
		`endif	 
`endif
	      end
   end
   // synopsys translate_on
 
 
   //-------------------------
   // Valid Instruction Pipe
   //-------------------------
   // F stage
   assign inst_vld_bf = fetch_bf;
   dff_s #(1) inst_vld_ff(.din (inst_vld_bf),
		                  .clk (clk),
		                  .q   (inst_vld_f),
		                  .se  (se), .si(), .so());
 
   assign stall_f = ~inst_vld_f | kill_curr_f;
   assign stall_thisthr_f = stall_f | imsto_thisthr_s1 | // intrto_thisthr_d |
	                          kill_thread_s2 | rb_stg_s | ~dtu_fcl_running_s | 
                            iferrto_thisthr_d1;
 
   assign part_stall_thisthr_f = stall_f | 
                                 imsto_thisthr_s1 |
                                 ~dtu_fcl_running_s | 
                                 ely_kill_thread_s2 |
	                               rb_stg_s;
 
   assign ely_stall_thisthr_f = stall_f | rb_stg_s;   
 
//   assign stall_s1_nxt = stall_thisthr_f | intr_vld_s | tmsto_thisthr_f;
   assign stall_s1_nxt = stall_thisthr_f; //| intr_vld_s;
 
   // S1 stage
   dff_s #(1) stalld_ff(.din (stall_s1_nxt),
		                  .clk (clk),
		                  .q   (stall_s1),
		                  .se  (se), .si(), .so());
 
   assign inst_vld_s1 = ~stall_s1 & ~ic_miss_s1 & ~kill_curr_d;
   assign val_thr_s1 = thr_s1 & {4{inst_vld_s1}}; // 4b
 
   // S2 stage
   assign val_thr_f = thr_f & {4{~stall_f & ~rb_stg_s & dtu_fcl_running_s}};
 
   // Tag the S stage thr inst register as containing a valid inst or not
   assign tinst_vld_nxt = (ifq_fcl_fill_thr |  
                           (rb_w2 & ~rb_for_iferr_e) | // set
			                     val_thr_s1 & ~val_thr_f |
                           //			   val_thr_s1 |
			                     tinst_vld_s & ~val_thr_f) &
			                      ~(clear_s_d1 |
                              {4{erb_dtu_ifeterr_d1 & inst_vld_d1 & 
                                 ~rb_stg_e}} & thr_e);   // reset
 
   dffr_s #(4) tinst_reg(.din  (tinst_vld_nxt),
		                 .clk  (clk),
		                 .rst  (fcl_reset),
		                 .q    (tinst_vld_s),
		                 .se   (se), .si(), .so());
 
   // Does current thread have valid inst in s2
   assign inst_vld_s2 = ((thr_f_crit & tinst_vld_s) == 4'b0000) ?
			                    {1'b0} :  {1'b1};          
 
   assign inst_vld_s = ~switch_s2 & inst_vld_s1 | 
	                      switch_s2 & inst_vld_s2;
   assign inst_vld_s_crit = ~switch_s2 & ~stall_s1 & ~kill_curr_d | 
	                      switch_s2 & inst_vld_s2;
 
   assign valid_s = inst_vld_s & ~stall_f &  // f and s2 have same thread
                       dtu_fcl_running_s &
	                     ~(ely_kill_thread_s2 | rb_stg_s);
 
   assign running_s2 = inst_vld_s & ~stall_thisthr_f;// f and s2 have 
                                                     // same thread
   // D stage
   dff_s #(1) rund_ff(.din (running_s2),
		              .clk (clk),
		              .q   (inst_vld_d),
		              .se  (se), .si(), .so());
   dff_s #(1) eivd_ff(.din (running_s2),
		                .clk (clk),
		                .q   (inst_vld_d_crit),
		                .se  (se), .si(), .so());
   assign fcl_erb_inst_issue_d = inst_vld_d & ~intr_vld_d;
   assign running_d = inst_vld_d & ~kill_thread_d & ~rb_stg_d & 
	                    ~intr_vld_d;
 
   // E stage
   dff_s #(1) rune_ff(.din (running_d),
		              .clk (clk),
		              .q   (inst_vld_e),
		              .se  (se), .si(), .so());
 
   assign running_e = inst_vld_e & ~dtu_inst_anull_e & 
	                    ~kill_curr_e & ~rb_stg_e &
                      ~(thr_match_em & ifu_tlu_flush_m);
   assign inst_vld_qual_e = inst_vld_e & ~rb_stg_e;
   assign val_thr_e = thr_e_v2 & {4{inst_vld_qual_e}} & ~late_flush_w2 &
                      ~(thr_w & {4{utrap_flush_w}});
 
 
   // M stage
   dff_s #(1) runm_ff(.din (running_e),
		              .clk (clk),
		              .q   (inst_vld_m),
		              .se  (se), .si(), .so());
   assign running_m = (inst_vld_m | intr_vld_m) & ~kill_thread_m;
 
   assign ifu_tlu_inst_vld_m = (inst_vld_m | intr_vld_m) & ~kill_curr_m;
   // less critical
   // assign ifu_lsu_inst_vld_m = ifu_tlu_inst_vld_m;
 
   // W stage
   dff_s #(1) runw_ff(.din (running_m),
		              .q   (inst_vld_w),
		              .clk (clk), .se  (se), .si(), .so());   
 
   dff_s #(1) iw_ff(.din (running_m),
		              .q   (inst_vld_w_crit),
		              .clk (clk), .se  (se), .si(), .so());   
 
   // synopsys translate_off
//   wire         sas_m,
//		            inst_done_w_for_sas;
 
//   assign sas_m = inst_vld_m & ~kill_thread_m & 
//	                ~(exu_ifu_ecc_ce_m & inst_vld_m & ~trap_m);
 
//   dff #(1) sasw_ff(.din (sas_m),
//		              .clk (clk),
//		              .q   (inst_done_w_for_sas),
//		              .se  (se), .si(), .so());   
   // synopsys translate_on
 
   // need to kill branch by E stage, so qual with rb_stg_X
   assign fcl_dtu_inst_vld_e = inst_vld_e & ~rb_stg_e & ~kill_curr_e;
   assign fcl_dtu_intr_vld_e = intr_vld_e & ~rb_stg_e & ~kill_curr_e;
   assign fcl_dtu_inst_vld_d = inst_vld_d & ~kill_curr_d &
	                             ~rb_stg_d_crit & ~immu_miss_crit_d;
   assign fcl_dtu_ely_inst_vld_d = inst_vld_d_crit;
   assign ifu_tlu_inst_vld_w = inst_vld_w;
   assign ifu_exu_inst_vld_w = inst_vld_w_crit;
   assign ifu_spu_inst_vld_w = inst_vld_w;
   assign ifu_exu_inst_vld_e = fcl_dtu_inst_vld_e;
 
   assign flush_sonly_qual_e = dtu_fcl_flush_sonly_e & inst_vld_e &
//                               ~dec_fcl_kill4sta_e &
                               ~rb_stg_e & ~dtu_inst_anull_e & ~kill_curr_e;
 
 
   dff_s #(1) flshm_ff(.din (flush_sonly_qual_e),
                     .q   (flush_sonly_m),
                     .clk (clk),
                     .se  (se), .si(), .so());
 
   dff_s #(1) imflshm_ff(.din (ifq_fcl_flush_sonly_e),
                       .q   (ims_flush_sonly_m),
                       .clk (clk),
                       .se  (se), .si(), .so());
   // detect collision between two different types of retractions
   assign ims_flush_coll_m = ims_flush_sonly_m & ~canthr_sm & 
                             retract_iferr_e;
   dff_s #(1) imflshw_ff(.din (ims_flush_coll_m),
                       .q   (ims_flush_sonly_w),
                       .clk (clk),
                       .se  (se), .si(), .so());
   assign ims_flush_coll_w = ims_flush_sonly_w & ~canthr_sw;
   assign flush_sonly_qual_m = (ims_flush_sonly_m & ~canthr_sm & 
                                ~retract_iferr_e |
                                flush_sonly_m & inst_vld_m & ~kill_local_m &
                                ~kill_curr_m);
   assign flush_sonly_all_m = (ims_flush_sonly_m & ~canthr_sm | 
                               flush_sonly_m & inst_vld_m);
 
//   assign flush_sonly_qual_m = flush_sonly_m & ~canthr_sm;
//   assign qtrap_flush_e = dtu_fcl_qtrap_e & inst_vld_e & ~dtu_inst_anull_e & 
//	                  ~rb_stg_e;
 
//------------------------------   
// Instruction Kill Logic
//------------------------------
 
   // kill_s2 is the same as kill_f
   assign kill_thread_s2 = thr_match_fw & rb_stg_w |
//	                         thr_match_ft & trappc_vld_w2 |
	                         thr_match_fm & (flush_sonly_all_m) |
                           kill_curr_f;
 
   assign ely_kill_thread_s2 = thr_match_fw & utrap_flush_w |
//	                             thr_match_ft & trappc_vld_w2 |
	                             thr_match_fm & (flush_sonly_all_m) |
                               kill_curr_f;
 
   assign kill_thread_d = thr_match_dw & rb_stg_w |
	                        thr_match_dm & (flush_sonly_all_m) |
                          kill_curr_d;
 
   // M and E still need full qualification with flush pipe   
//   assign kill_thread_e = thr_match_ew & utrap_flush_w | 
//                          thr_match_ew & tlu_ifu_flush_pipe_w | 
//                          kill_curr_e ;
   assign ely_kill_thread_m = thr_match_mw & utrap_flush_w |
//                              mark4rb_m |
                              kill_curr_m;
   assign kill_thread_m = ely_kill_thread_m | 
                          thr_match_mw & tlu_ifu_flush_pipe_w;
 
   assign kill_local_m = thr_match_mw & (utrap_flush_w | intr_vld_w);
 
   assign flush_pipe_w = rb_stg_w | tlu_ifu_flush_pipe_w;
//   assign part_flush_w = ifu_tlu_flush_w | tlu_ifu_flush_pipe_w;
//   assign kill_nextthr_w = thr_match_nw & flush_pipe_w;
   assign flush_thr_w = thr_w & {4{flush_pipe_w}};
   dff_s #(1) fp_ff(.din (flush_pipe_w),
                  .q   (flush_pipe_w2),
                  .clk (clk), .se(se), .si(), .so());
 
//   assign clear_s_stage =  thr_e & {4{flush_sonly_qual_e}};
//   assign clear_s_stage =  trap_thr & {4{trappc_vld_w2}} |
//	                         {4{dummy_flush_ireg}} | 
//	                         thr_e & {4{flush_sonly_qual_e}};
                           //  | flush_thr_w 
 
   assign canthr_f = thr_e & {4{flush_sonly_qual_e}} | 
                     (rb_w2 & ~rb_for_iferr_e) | rb_froms;
 
//   dff #(4) cls_reg(.din (clear_s_stage),
//		                .q   (clear_s_early),
//		                .clk (clk), .se(se), .si(), .so());
 
   // ***NOTE***
   // Don't use clear_s_d1 to generate fcl_ifq_canthr, since clear_s_d1 
   // includes ifeterr!
   // first term could be just flush_sonly_m & inst_vld_m & thr_m
   assign clear_s_d1 = thr_m & {4{flush_sonly_all_m}} |
                       late_flush_w2 | 
                       trap_thr & {4{trappc_vld_w2}};
 
   assign fcl_erb_clear_iferr = thr_m & {4{ims_flush_sonly_m | 
                                           flush_sonly_m}} |
                                late_flush_w2 | 
                                trap_thr & {4{trappc_vld_w2}};
 
 
   dff_s #(4) cm_reg(.din (canthr_f),
		               .q   (canthr_s_early),
		               .clk (clk),
		               .se  (se), .si(), .so());
 
   assign canthr_s = canthr_s_early | late_flush_w2 | 
                     trap_thr & {4{trappc_vld_w2}};          
 
//   assign fcl_ifq_canthr = clear_s_stage | rb_w2 | rb_froms | 
//	                         canthr_s;
   assign fcl_ifq_canthr = canthr_s;
 
   assign canthr_sm = (canthr_s[0] & thr_m[0] | 
                       canthr_s[1] & thr_m[1] | 
                       canthr_s[2] & thr_m[2] | 
                       canthr_s[3] & thr_m[3]);
 
   assign canthr_sw = (canthr_s[0] & thr_w[0] | 
                       canthr_s[1] & thr_w[1] | 
                       canthr_s[2] & thr_w[2] | 
                       canthr_s[3] & thr_w[3]);
 
   assign canthr_sd = (canthr_s[0] & thr_d[0] | 
                       canthr_s[1] & thr_d[1] | 
                       canthr_s[2] & thr_d[2] | 
                       canthr_s[3] & thr_d[3]) |
                        thr_match_dw & utrap_flush_w;
 
   dff_s #(4) fpw2_reg(.din (flush_thr_w),
                     .q   (late_flush_w2),
                     .clk (clk), .se(se), .si(), .so());
 
//   assign late_flush_w2 = thr_w2 & {4{flush_pipe_w2}};
 
   assign kill_curr_f = (thr_f_crit[0] & late_flush_w2[0] |
                         thr_f_crit[1] & late_flush_w2[1] |
                         thr_f_crit[2] & late_flush_w2[2] |
                         thr_f_crit[3] & late_flush_w2[3]);
   assign kill_curr_d = (thr_d[0] & late_flush_w2[0] |
                         thr_d[1] & late_flush_w2[1] |
                         thr_d[2] & late_flush_w2[2] |
                         thr_d[3] & late_flush_w2[3]);
   assign kill_curr_e = (thr_e_v2[0] & late_flush_w2[0] |
                         thr_e_v2[1] & late_flush_w2[1] |
                         thr_e_v2[2] & late_flush_w2[2] |
                         thr_e_v2[3] & late_flush_w2[3]) |
                          thr_match_ew & utrap_flush_w;
 
//   assign kill_curr_m = (thr_m[0] & late_flush_w2[0] |
//                         thr_m[1] & late_flush_w2[1] |
//                         thr_m[2] & late_flush_w2[2] |
//                         thr_m[3] & late_flush_w2[3]);
   assign kill_curr_m = same_thr_mw2 & flush_pipe_w2;
 
   //------------------------------
   // track I$ misses
   //------------------------------
 
   // force a miss if a fetch and icache is off
   // forcemiss triggers a fill vld_grequest to L2, so set to zero by default
   assign forcemiss_f = inst_vld_f & ~icache_on_f;
   dffr_s #(1)  miss_ff(.din (forcemiss_f),
		                  .clk (clk),
		                  .rst (fcl_reset),
		                  .q   (forcemiss_s1),
		                  .se  (se), .si(), .so());
 
   //ooooooooooooooooooooooooooooooooooooooooooooooooooooooo
   // removed imiss_s_l from this signal for timing fix  
   // Perf Hit: 0.2% TPCC, 0.4% JBB
//   assign ic_miss_sw_s1 = (~itlb_fcl_imiss_s_l & rdreq_s1 |
//                             tlb_cam_miss_s1 | 
//                             forcemiss_s1);
//   assign ic_miss_sw_s1 =   tlb_cam_miss_s1 | 
//                            forcemiss_s1;
   //ooooooooooooooooooooooooooooooooooooooooooooooooooooooo
 
   assign ic_miss_s1 =  (~itlb_fcl_imiss_s_l & rdreq_s1 |
			                   forcemiss_s1) & 
                        ~stall_s1 & ~tlbmiss_s1_crit & ~pc_oor_s1 & 
                        ~rb_stg_d_crit & ~canthr_sd;
 
   assign icmiss_for_perf =  (~itlb_fcl_imiss_s_l & rdreq_s1) & 
                        ~stall_s1 & ~tlbmiss_s1_crit & ~pc_oor_s1 & 
                        ~rb_stg_d & ~canthr_sd;
 
//   assign fcl_ifq_icmiss_s1 = ic_miss_s1 & ~ely_kill_thread_d;  // use buffer
   assign fcl_ifq_icmiss_s1 = ic_miss_s1;  // use buffer   
 
   // for perf counters (d1=e)
   dff_s #(1) icmd1_ff(.din (icmiss_for_perf),
                     .q   (ifu_tlu_icmiss_e),
                     .clk (clk), .se(se), .si(), .so());
 
   // I$ miss is always to thr_s1.  Below we check to see if this is
   // the same as thr_f (=thr_s2) which is the "current thread"
//   assign imsto_thisthr_s1 = thr_match_fd & ic_miss_s1;
//   assign imsto_nextthr_s1 = thr_match_nd & (ic_miss_s1 | tlbmiss_s1);
 
   assign imsto_thisthr_s1 = thr_match_fd & ic_miss_s1;
//   assign imsto_nextthr_s1 = thr_match_nd & (ic_miss_sw_s1);
//   assign intrto_thisthr_d = thr_match_fd & fcl_dtu_sync_intr_d;
 
   assign iferrto_thisthr_d1 = thr_match_fe & erb_dtu_ifeterr_d1 & 
                               inst_vld_d1;
 
 
//------------------------------
// track itlb misses
//------------------------------
 
   // default to hit when camming is turned off
   assign tlb_cam_miss_f = ~itlb_fcl_tlbmiss_f_l & cam_vld_f;
   dff_s #(1) tlbmsf_ff(.din (tlb_cam_miss_f),
		                  .clk (clk),
		                  .q   (tlb_cam_miss_s1),
		                  .se  (se), .si(), .so());
 
   // tlb miss logic
   // va hole has higher priority than immu miss
   assign tlbmiss_s2 = (({4{tlbmiss_s1 & ~pc_oor_s1 & ~rb_stg_d}} & thr_s1) |
			                  ({4{erb_fcl_itlb_ce_d1 & inst_vld_d1 & 
                            ~rb_stg_e}} & thr_e &
			                   (~thr_d | {4{~inst_vld_d | ~thr_match_de}})) |
			                  ({4{immu_miss_e}} & rb_frome) |
			                  ({4{immu_miss_d}} & rb_fromd & ~rb_frome) |  // set
			                  tlbmiss_d & (~thr_d | {4{~inst_vld_d}}) & ~rb_w2) & 
			                 ~(clear_s_d1); // reset
 
//   assign tlbmiss_s2 = (({4{tlbmiss_s1 & ~pc_oor_s1 & ~rb_stg_d}} & thr_s1) |
//			({4{erb_fcl_itlb_ce_d1 & inst_vld_qual_d1}} & thr_e |
//			 tlbmiss_d & (~thr_e | {4{~inst_vld_qual_e}}) & 
//			 ~rb_w2) & ~(clear_s_stage); // reset
 
   dffr_s #(4) tlbmiss_reg(.din (tlbmiss_s2),
		                     .q   (tlbmiss_d),
		                     .clk (clk),
		                     .rst (fcl_reset),
		                     .se  (se), .si(), .so());
 
   assign immu_fault_f = (thr_f_crit[0] & (tlbmiss_d[0] | inst_acc_vec_d[0]) |
			                    thr_f_crit[1] & (tlbmiss_d[1] | inst_acc_vec_d[1]) |
			                    thr_f_crit[2] & (tlbmiss_d[2] | inst_acc_vec_d[2]) |
			                    thr_f_crit[3] & (tlbmiss_d[3] | inst_acc_vec_d[3])) &
                           switch_s2|  
			                     // D stage miss
			                     (tlbmiss_s1 | pc_oor_s1) & thr_match_fs1;
	                         // S stage miss
 
   assign immu_miss_crit_d = (thr_d[0] & tlbmiss_d[0] |
			                        thr_d[1] & tlbmiss_d[1] |
			                        thr_d[2] & tlbmiss_d[2] |
			                        thr_d[3] & tlbmiss_d[3]);
 
   // TBD: move this to the E stage, post RB
   assign immu_miss_d = immu_miss_crit_d & inst_vld_d | 
			                  thr_match_de & erb_fcl_itlb_ce_d1 & inst_vld_d1;
 
   // don't need to do this, once everyone switches to immu_miss_m
   assign immu_miss_qual_d = immu_miss_d & ~kill_thread_d &
	                            ~(immu_miss_e & thr_match_de & 
                                inst_vld_e & ~dtu_inst_anull_e & ~rb_stg_e &
                                ~kill_curr_e);
 
   dff_s immu_misse_ff(.din (immu_miss_qual_d),
		                 .clk (clk),
		                 .q   (immu_miss_e),
		                 .se  (se), .si(), .so());
 
 
   // flop this and send in M
//   assign ifu_tlu_immu_miss_e = immu_miss_e & ~addr_real_e & 
//                                inst_vld_e & ~dtu_inst_anull_e & ~rb_stg_e;
//   assign ifu_tlu_immu_miss_e = 1'b0;
 
//   assign immu_miss_qual_e = immu_miss_e & //~addr_real_e & 
// //                             ~(immu_miss_m & thr_match_em) &
//                             inst_vld_e & ~dtu_inst_anull_e & ~rb_stg_e;
 
//   dff #(1) immu_msm_ff(.din (immu_miss_qual_e),
   dff_s #(1) immu_msm_ff(.din (immu_miss_e),
                        .q   (immu_miss_m),
                        .clk (clk), .se(se), .si(), .so());
 
   assign ifu_tlu_immu_miss_m = immu_miss_m & inst_vld_m & ~kill_curr_m;
 
   assign addr_real_e = (itlb_addr_real[0] & thr_e[0] |
                         itlb_addr_real[1] & thr_e[1] |
                         itlb_addr_real[2] & thr_e[2] |
                         itlb_addr_real[3] & thr_e[3]);
 
   // store tlbmiss state for NIR
   assign nir_tlbmiss_next = ({4{tlb_cam_miss_s1 & ~stall_s1}} & thr_s1 |
			                        nir_tlbmiss_vec & (~thr_s1 | {4{stall_s1}}));
 
   dffr_s #(4) nirtlbm_reg(.din (nir_tlbmiss_next),
		                   .clk (clk),
		                   .q   (nir_tlbmiss_vec),
		                   .rst (fcl_reset),
		                   .se  (se), .si(), .so());
 
   assign nir_tlbmiss_s1 = (nir_tlbmiss_vec[0] & thr_s1[0] |
			                      nir_tlbmiss_vec[1] & thr_s1[1] |
			                      nir_tlbmiss_vec[2] & thr_s1[2] |
			                      nir_tlbmiss_vec[3] & thr_s1[3]);
 
   assign tlbmiss_s1_crit = ~usenir_s1 ? tlb_cam_miss_s1 :
	                                       nir_tlbmiss_s1;
 
   assign tlbmiss_s1 = tlbmiss_s1_crit & ~stall_s1;
 
//---------------------------------
//  Privilege Mode and VA Hole
//---------------------------------
   assign addr_mask_32b_m = (thr_m[0] & pstate_am_d1[0] |
			                       thr_m[1] & pstate_am_d1[1] |
			                       thr_m[2] & pstate_am_d1[2] |
			                       thr_m[3] & pstate_am_d1[3]);
 
   assign fcl_fdp_mask32b_f = (thr_f[0] & pstate_am_d1[0] |
			                         thr_f[1] & pstate_am_d1[1] |
			                         thr_f[2] & pstate_am_d1[2] |
			                         thr_f[3] & pstate_am_d1[3]);
 
   dff_s #(1) amd_ff(.din (fcl_fdp_mask32b_f),
		               .q   (fcl_fdp_addr_mask_d),
		               .clk (clk), .se(se), .si(), .so());
 
   // keep track of whether pc is outside va hole
   assign set_oor_m = exu_ifu_va_oor_m & brtaken_m & ~addr_mask_32b_m;
   assign fcl_fdp_pcoor_vec_f = fdp_fcl_pc_oor_vec_f | {4{set_oor_m}} & thr_m;
 
   assign fcl_fdp_pcoor_f =  (thr_f[0] & fcl_fdp_pcoor_vec_f[0] |
			                        thr_f[1] & fcl_fdp_pcoor_vec_f[1] |
			                        thr_f[2] & fcl_fdp_pcoor_vec_f[2] |
			                        thr_f[3] & fcl_fdp_pcoor_vec_f[3]);
 
   assign pc_oor_f = fcl_fdp_pcoor_f  & ~part_stall_thisthr_f;
   dff_s oors1_ff(.din (pc_oor_f),
		            .q   (pc_oor_s1),
		            .clk (clk), .se(se), .si(), .so());
 
   // track privilege mode of current page
   assign priv_mode_f = (thr_f[0] & tlu_lsu_pstate_priv[0] |
			                   thr_f[1] & tlu_lsu_pstate_priv[1] |
			                   thr_f[2] & tlu_lsu_pstate_priv[2] |
			                   thr_f[3] & tlu_lsu_pstate_priv[3]);
 
   dff_s #(1) priv_ff(.din (priv_mode_f),
                    .q   (priv_mode_s1),
                    .clk (clk), .se(se), .si(), .so());
 
   // s1 and d are the same thread
   assign fcl_dtu_privmode_d = priv_mode_s1;
 
   // hyper privilege
   assign hpriv_mode_f = (thr_f[0] & tlu_hpstate_priv[0] |
			                    thr_f[1] & tlu_hpstate_priv[1] |
			                    thr_f[2] & tlu_hpstate_priv[2] |
			                    thr_f[3] & tlu_hpstate_priv[3]);
 
   assign hpriv_mode_w = (thr_w[0] & tlu_hpstate_priv[0] |
			                    thr_w[1] & tlu_hpstate_priv[1] |
			                    thr_w[2] & tlu_hpstate_priv[2] |
			                    thr_w[3] & tlu_hpstate_priv[3]);
 
   dff_s #(1) hprivd_ff(.din (hpriv_mode_f),
                     .q   (hpriv_mode_s1),
                     .clk (clk), .se(se), .si(), .so());
 
   assign fcl_dtu_hprivmode_d = hpriv_mode_s1;
 
   dff_s #(1) hprivw2_ff(.din (hpriv_mode_w),
                     .q   (hpriv_mode_w2),
                     .clk (clk), .se(se), .si(), .so());
   assign fcl_dtu_hprivmode_w2 = hpriv_mode_w2;
 
   // determine if priv page has been accessed in non priv mode
   // or if we have fallen into the VA hole
   assign inst_acc_exc_s1 = (priv_inst_s1 & ~(priv_mode_s1 | hpriv_mode_s1) & 
			                       ~tlbmiss_s1_crit & cam_vld_s1 | 
			                       pc_oor_s1) & ~stall_s1 & ~rb_stg_d;
   assign pc_oor_s2 = (thr_f[0] & inst_acc_vec_d[0] |
                       thr_f[1] & inst_acc_vec_d[1] |
                       thr_f[2] & inst_acc_vec_d[2] |
                       thr_f[3] & inst_acc_vec_d[3]);
   assign pc_oor_s = (tm_fd_l) ? pc_oor_s2 : pc_oor_s1;
 
   assign inst_acc_vec_s2 = (({4{inst_acc_exc_s1}} & thr_s1) |
			                       ({4{inst_acc_exc_e}} & rb_frome) |
			                       ({4{inst_acc_exc_d}} & rb_fromd & ~rb_frome) |
	                           inst_acc_vec_d & (~thr_d | {4{~inst_vld_d}}) & 
			                       ~rb_w2) &
			                        ~(clear_s_d1);
 
   dffr_s #(4) instaccd_reg(.din (inst_acc_vec_s2),
			                  .q   (inst_acc_vec_d),
			                  .rst (fcl_reset),
			                  .clk (clk), .se (se), .si(), .so());
 
   assign inst_acc_exc_d = (thr_d[0] & inst_acc_vec_d[0] |
			                      thr_d[1] & inst_acc_vec_d[1] |
			                      thr_d[2] & inst_acc_vec_d[2] |
			                      thr_d[3] & inst_acc_vec_d[3]);
 
   dff_s #(1) instacce_ff(.din (inst_acc_exc_d),
		                  .q   (inst_acc_exc_e),
		                  .clk (clk), .se(se), .si(), .so());
 
   // TLU needs to know if this is a priv violtn
   assign priv_violtn_e = inst_acc_exc_e & ~fdp_fcl_pc_oor_e;
   dff_s #(1) privm_ff(.din (priv_violtn_e),
		               .q   (priv_violtn_m),
		               .clk (clk),  .se  (se), .si(), .so());
 
   assign ifu_tlu_priv_violtn_m = priv_violtn_m & inst_vld_m & ~kill_curr_m;
 
   // NIR privilege bit
   assign next_nir_privvec = {4{itlb_fcl_priv_s1 & ~stall_s1 & 
                                cam_vld_s1}} & thr_s1 |
	                           nir_privvec & (~thr_s1 | {4{stall_s1}});
 
   dffr_s #(4) nir_priv_reg(.din (next_nir_privvec),
			                  .q   (nir_privvec),
			                  .rst (fcl_reset),
			                  .clk (clk), .se(se), .si(), .so());
 
   assign nir_priv_s1 = (nir_privvec[0] & thr_s1[0] |
			                   nir_privvec[1] & thr_s1[1] |
			                   nir_privvec[2] & thr_s1[2] |
			                   nir_privvec[3] & thr_s1[3]);
 
   assign priv_inst_s1 = ~usenir_s1 ? (itlb_fcl_priv_s1 & cam_vld_s1) : 
                                        nir_priv_s1;
 
//-------------------------
// Errors
//-------------------------
 
   // decide when the errors are valid
   assign running_s1 = ~stall_s1 & ~kill_thread_d & ~rb_stg_d & ~pc_oor_s1 &
	                     ~tlb_cam_miss_s1 & ~retract_inst_d;
//   assign ely_running_s1 = ~stall_s1 & ~rb_stg_d & ~pc_oor_s1 & 
//                           ~tlb_cam_miss_s1 & ~retract_inst_d & ~kill_curr_d;
   assign ely_running_s1 = ~stall_s1 & ~rb_stg_d_crit & ~pc_oor_s1 & 
                           ~tlb_cam_miss_s1 & ~kill_curr_d;
   assign fcl_erb_ievld_s1 = ely_running_s1 & rdreq_s1 & itlb_fcl_imiss_s_l;
   assign fcl_erb_tevld_s1 = ely_running_s1 & rdreq_s1;
 
   assign fcl_erb_immuevld_s1 = ely_running_s1 & cam_vld_s1;
 
//   assign fcl_erb_ttevld_s1 = asird_s & rdtag_s;
//   assign fcl_erb_tdevld_s1 = asird_s & ~rdtag_s;
 
   dff_s #(1) d1vld_ff(.din (running_s1),
		                 .q   (inst_vld_d1),
		                 .clk (clk), .se(se), .si(), .so());
//   assign inst_vld_qual_d1 = inst_vld_d1 & ~kill_thread_e & 
//	                           ~flush_sonly_qual_e & ~rb_stg_e;
   assign fcl_erb_inst_vld_d1 = inst_vld_d1;
 
 
   // ifetch unc. error
   assign ifet_ue_vec_d1 = (erb_fcl_ifet_uevec_d1 |
	                          ifet_ue_vec_e & ~val_thr_e) &   // reset
			                       ~(clear_s_d1);                 // wins
 
   dffr_s #(4) ifuerr_reg(.din (ifet_ue_vec_d1),
		                  .q   (ifet_ue_vec_e),
		                  .rst (fcl_reset),
		                  .clk (clk), .se(se), .si(), .so());
 
   assign ifet_ue_e = (ifet_ue_vec_e[0] & thr_e[0] | 
		                   ifet_ue_vec_e[1] & thr_e[1] | 
		                   ifet_ue_vec_e[2] & thr_e[2] | 
		                   ifet_ue_vec_e[3] & thr_e[3]);
 
 
//----------------------
// Other I side traps
//----------------------
   // Determine if we are in Trap Level 0
   assign tlzero_s2 = (thr_f[0] & tlzero_vec_d1[0] |
		                   thr_f[1] & tlzero_vec_d1[1] |
		                   thr_f[2] & tlzero_vec_d1[2] |
		                   thr_f[3] & tlzero_vec_d1[3]);
   dff_s #(1) tlzd_ff(.din (tlzero_s2),
		              .q   (fcl_dtu_tlzero_d),
		              .clk (clk), .se(se), .si(), .so());
 
   // Collect all IFU traps
   assign trap_e = (immu_miss_e | inst_acc_exc_e | dtu_fcl_illinst_e |
		                dtu_fcl_fpdis_e | dtu_fcl_privop_e | ifet_ue_e |
		                dtu_fcl_imask_hit_e | dtu_fcl_sir_inst_e) & 
                     inst_vld_e;
 
   dff_s trapm_ff(.din (trap_e),
		            .q   (trap_m),
		            .clk (clk),
		            .se  (se), .si(), .so());
 
   assign no_iftrap_m = ~ifu_tlu_ttype_vld_m;
   dff_s trapw_ff(.din (no_iftrap_m),
		            .q   (no_iftrap_w),
		            .clk (clk),
		            .se  (se), .si(), .so());
 
   // south is very critical
   assign ifu_tlu_ttype_vld_m = (trap_m & inst_vld_m | 
                                 disr_trap_m) & ~kill_curr_m & ~kill_local_m;
   // less critical going east
   assign ifu_exu_ttype_vld_m = trap_m & inst_vld_m;
 
   // less critical going southwest
   assign ifu_mmu_trap_m = trap_m;
 
   // less critical going south   
   assign ifu_tlu_trap_m = trap_m;
 
   // trap type priority encode
   // Decreasing priority is
   //   pc out of range           i_acc_exc
   //   immu parity error         i_acc_err
   //   immu miss                 i_acc_mmu_ms
   //   icache/tag parity error   i_acc_err
   //   privilege page            i_acc_exc
   //   privilege opcode          priv_opc
   //   illegal non-fp inst       ill_inst
   //   soft reset                sir
   //   fp disabled               fp_disabled
   //   illegal fp instruction    ill_inst
 
   // Clean this up!!
   assign ttype_sel_spuma_e = spuint1_qual_e;
   assign ttype_sel_spuenc_e = spuint0_qual_e;
   assign ttype_sel_corr_err_e = ceint_qual_e;
   assign ttype_sel_unc_err_e = ueint_qual_e;
   assign ttype_sel_res_err_e = rerr_qual_e;
   assign ttype_sel_hstk_cmp_e = hintp_qual_e;
 
   assign ttype_sel_pcoor_e = fdp_fcl_pc_oor_e & inst_acc_exc_e;
   assign ttype_sel_icache_err_e = ifet_ue_e; 
   assign ttype_sel_immu_miss_e = ~fdp_fcl_pc_oor_e & immu_miss_e & 
                                  ~addr_real_e;
   assign ttype_sel_real_trans_e = ~fdp_fcl_pc_oor_e & immu_miss_e & 
                                   addr_real_e;    
   assign ttype_sel_priv_viol_e = ~fdp_fcl_pc_oor_e & ~immu_miss_e & 
	                           inst_acc_exc_e;
   assign ttype_sel_ibe_e = ~fdp_fcl_pc_oor_e & ~immu_miss_e & 
	                        ~inst_acc_exc_e & dtu_fcl_imask_hit_e;
   assign ttype_sel_privop_e = ~fdp_fcl_pc_oor_e & ~immu_miss_e & 
	                       ~inst_acc_exc_e & dtu_fcl_privop_e;
   assign ttype_sel_illinst_e = ~fdp_fcl_pc_oor_e & ~immu_miss_e & 
	                        ~inst_acc_exc_e & dtu_fcl_illinst_e;
   assign ttype_sel_sir_e = ~fdp_fcl_pc_oor_e & ~immu_miss_e & 
	                    ~inst_acc_exc_e & ~dtu_fcl_illinst_e &
	                     dtu_fcl_sir_inst_e;
 
   assign ttype_sel_fpdis_e = ~fdp_fcl_pc_oor_e & ~immu_miss_e & 
	                      ~inst_acc_exc_e & ~dtu_fcl_illinst_e &
	                       dtu_fcl_fpdis_e;
 
   // mux in the trap type
   assign ttype_e[8:0] = ttype_sel_unc_err_e    ? `DATA_ERR  :
                   ttype_sel_hstk_cmp_e   ? `HSTICK_CMP    :
	                 ttype_sel_spuma_e      ? `SPU_MAINT     :
	                 ttype_sel_spuenc_e     ? `SPU_ENCINT    :
	                 ttype_sel_corr_err_e   ? `CORR_ECC_ERR  :
                   ttype_sel_res_err_e    ? `RESUMABLE_ERR :
 
	                 ttype_sel_pcoor_e      ? `INST_ACC_EXC  :
	                 ttype_sel_immu_miss_e  ? `FAST_MMU_MS   :
	                 ttype_sel_real_trans_e ? `REAL_TRANS_MS :
	                 ttype_sel_icache_err_e ? `INST_ACC_ERR  :
	                 ttype_sel_priv_viol_e  ? `INST_ACC_EXC  :
	                 ttype_sel_ibe_e        ? `INST_BRK_PT   :
	                 ttype_sel_privop_e     ? `PRIV_OPC :
	                 ttype_sel_illinst_e    ? `ILL_INST :
	                 ttype_sel_sir_e        ? `SIR      :
	                 ttype_sel_fpdis_e      ? `FP_DISABLED :
	                                           9'h1ff;
 
   dff_s #(9) ttype_reg(.din (ttype_e[8:0]),
		                .q   (ifu_tlu_ttype_m[8:0]),
		                .clk (clk), .se(se), .si(), .so());
 
//------------------------------
// Interrupts and Resets
//------------------------------
   // Process resets to see if they are sync or async
   assign intr_in_pipe = ({4{intr_vld_d}} & thr_d |
                          {4{intr_vld_e}} & thr_e |
                          {4{intr_vld_m}} & thr_m |
                          {4{intr_vld_w}} & thr_w);
 
//   assign async_rst_i2 = tlu_ifu_rstthr_i2  & {4{tlu_ifu_rstint_i2}} &
   assign async_rst_i3 = (rstint_i3 | nuke_thr_i3 | resumint_i3) & 
                           ~dtu_fcl_thr_active & ~intr_in_pipe;
 
   dff_s #(4) asyrst4_reg(.din (async_rst_i3),
                        .q   (async_rst_i4),
                        .clk (clk), .se(se), .si(), .so());
 
   // stall pipe before switching in rst thread
   assign rst_stallreq_d0 = (|async_rst_i4[3:0]);
   assign rst_stallreq = rst_stallreq_d0 | rst_stallreq_d1 | rst_stallreq_d2;
 
   dff_s #(2) stlreq_reg(.din ({lsu_ifu_stallreq,
                              ffu_ifu_stallreq}),
                       .q   ({lsu_stallreq_d1,
                              ffu_stallreq_d1}),
                       .clk (clk), .se(se), .si(), .so());
 
   assign all_stallreq = ifq_fcl_stallreq | lsu_stallreq_d1 | 
                         ffu_stallreq_d1 | itlb_starv_alert;
 
   // leave out stall from ifq which goes directly to swl
   assign fcl_dtu_stall_bf = lsu_stallreq_d1 | ffu_stallreq_d1 | 
                             itlb_starv_alert | rst_stallreq;
 
   // priority encode rst interrupts
   // this could lead to obvious starvation of thr3, the assumption is that
   // idle/resume/reset interrupts do not occur very frequently
   assign rstint_penc[0] = async_rst_i4[0];
   assign rstint_penc[1] = ~async_rst_i4[0] & async_rst_i4[1];
   assign rstint_penc[2] = ~async_rst_i4[0] & ~async_rst_i4[1]  & 
	                          async_rst_i4[2];
   assign rstint_penc[3] = ~async_rst_i4[0] & ~async_rst_i4[1]  & 
	                         ~async_rst_i4[2];
 
   // BF - switch in rst thread
   dff_s #(1) asyncr1_ff(.din (rst_stallreq_d0),
		                   .q   (rst_stallreq_d1),
		                   .clk (clk), .se(se), .si(), .so());
   assign arst_vld_f_l = ~arst_vld_f;
   assign arst_vld_s_l = ~arst_vld_s;
   bw_u1_nand3_4x UZsize_rstsw_n3(.z (rst_sw_bf_l),
                                  .a (arst_vld_f_l),
                                  .b (arst_vld_s_l),
                                  .c (rst_stallreq_d1));
   assign rst_sw_bf = ~rst_sw_bf_l;
 
   // double check if asyn intrs are still valid
   assign sw_for_real_rst_bf = rst_sw_bf & rst_stallreq_d0;
 
   // F
   dff_s #(1) asyncr2_ff(.din (sw_for_real_rst_bf),
		                   .q   (rst_stallreq_d2),
		                   .clk (clk), .se(se), .si(), .so());
//   assign arst_vld_f = rst_stallreq_d2 & any_rstnuke_f;
   assign arst_vld_f = rst_stallreq_d2;   
 
   // hold thread till reset of curr thread is processed
//   assign rst_thr_bf = arst_vld_f ? thr_f : rstint_penc;
 
   // S issue to pipe
   dff_s #(1) rstvlds_ff(.din (arst_vld_f),
		                   .q   (arst_vld_s),
		                   .clk (clk), .se(se), .si(), .so());
   assign async_intr_vld_s = arst_vld_s & ~kill_intr_f; // & any_rstnuke_f 
 
 
   //
   // thread wise interrupts
   //
   assign rstint_i2 = {4{tlu_ifu_rstint_i2}} & tlu_ifu_rstthr_i2;
   assign resumint_i2 = {4{tlu_ifu_resumint_i2}} & tlu_ifu_rstthr_i2;
   assign nuke_thr_i2 =  {4{tlu_ifu_nukeint_i2}} & tlu_ifu_rstthr_i2;
 
   assign next_rst_i2 = rstint_i2 | 
	                      rstint_i3 & (~(thr_w & {4{fcl_dtu_rst_thr_w}}));
   assign next_resum_i2 = resumint_i2 | 
	                        resumint_i3 & (~(thr_w & {4{fcl_dtu_resum_thr_w}})) 
                          & ~rstint_i2;
 
   assign next_nuke_i2  = (nuke_thr_i2 | nuke_thr_i3) & 
                            (~(thr_w & {4{fcl_dtu_nuke_thr_w}})) & 
	                       ~(rstint_i2 | resumint_i2);
 
   assign next_sftint_i2 = tlu_ifu_sftint_vld;
   assign next_hwint_i3 = tlu_ifu_hwint_i3;
   assign next_hintp_i2 = tlu_ifu_hintp_vld;
   assign next_rerr_i2 = tlu_ifu_rerr_vld;
 
   assign next_ceint_i2 = erb_fcl_ce_trapvec |
	                        ceint_i3 & (~(thr_w & {4{ceint_qual_w}}));
 
   assign next_ueint_i2 = erb_fcl_ue_trapvec |
	                        ueint_i3 & (~(thr_w & {4{ueint_qual_w}}));
 
   // From Farnad: tid is ready several cycles before everything else
   // I will assume 1 cycle before in the ifu
   dff_s #(2) sptid_reg(.din (spu_ifu_ttype_tid_w2),
                      .q   (spu_tid_w2),
                      .clk (clk), .se(se), .so(), .si());
 
   assign spu_thr[0] = ~spu_tid_w2[1] & ~spu_tid_w2[0];
   assign spu_thr[1] = ~spu_tid_w2[1] &  spu_tid_w2[0];
   assign spu_thr[2] =  spu_tid_w2[1] & ~spu_tid_w2[0];
   assign spu_thr[3] =  spu_tid_w2[1] &  spu_tid_w2[0];
 
   assign next_spuint1_i2 = {4{spu_ifu_ttype_vld_w2 & spu_ifu_ttype_w2}} & 
	                          spu_thr & ~erb_fcl_spu_uetrap |
	                          spuint1_i3 & ~({4{spuint1_w}} & thr_w);
 
   assign next_spuint0_i2 = {4{spu_ifu_ttype_vld_w2 & ~spu_ifu_ttype_w2}} & 
	                          spu_thr & ~erb_fcl_spu_uetrap |
	                          spuint0_i3 & ~({4{spuint0_w}} & thr_w);
 
 
   dffr_s #(4) rst_reg(.din  (next_rst_i2),
		                 .q    (rstint_i3),
		                 .clk  (clk),
		                 .rst  (fcl_reset),
		                 .se   (se), .si(), .so());
 
   dffr_s #(4) resum_reg(.din  (next_resum_i2),
		                   .q    (resumint_i3),
		                   .clk  (clk),
		                   .rst  (fcl_reset),
		                   .se   (se), .si(), .so());
 
   dffr_s #(4) nuke_reg(.din  (next_nuke_i2),
		                  .q    (nuke_thr_i3),
		                  .rst  (fcl_reset),
		                  .clk  (clk),
		                  .se   (se), .si(), .so());
 
   dffr_s #(4) sfti_reg(.din  (next_sftint_i2),
		                  .q    (sftint_i3),
		                  .rst  (fcl_reset),
		                  .clk  (clk), .se   (se), .si(), .so());
   dffr_s #(4) hstki_reg(.din  (next_hintp_i2),
		                  .q    (hintp_i3),
		                  .rst  (fcl_reset),
		                  .clk  (clk), .se   (se), .si(), .so());
   dffr_s #(4) reri_reg(.din  (next_rerr_i2),
		                  .q    (rerr_i3),
		                  .rst  (fcl_reset),
		                  .clk  (clk), .se   (se), .si(), .so());
   dffr_s #(4) hwi_reg(.din  (next_hwint_i3),
		                 .q    (hwint_i4),
		                 .rst  (fcl_reset),
		                 .clk  (clk), .se   (se), .si(), .so());
 
   dffr_s #(4) spui0_reg(.din  (next_spuint0_i2),
		                   .q    (spuint0_i3),
		                   .rst  (fcl_reset),
		                   .clk  (clk), .se   (se), .si(), .so());
 
   dffr_s #(4) spui1_reg(.din  (next_spuint1_i2),
		                   .q    (spuint1_i3),
		                   .rst  (fcl_reset),
		                   .clk  (clk), .se   (se), .si(), .so());
 
   dffr_s #(4) cei_reg(.din  (next_ceint_i2),
		                 .q    (ceint_i3),
		                 .rst  (fcl_reset),
		                 .clk  (clk), .se   (se), .si(), .so());
 
   dffr_s #(4) uei_reg(.din  (next_ueint_i2),
		                 .q    (ueint_i3),
		                 .rst  (fcl_reset),
		                 .clk  (clk), .se   (se), .si(), .so());
 
   assign supv_int_en = (~tlu_hpstate_priv | ~tlu_hpstate_enb) & 
                         tlu_ifu_pstate_ie & dtu_fcl_thr_active;
   assign hypv_int_en = ~tlu_hpstate_priv & tlu_hpstate_enb | 
                        tlu_ifu_pstate_ie & dtu_fcl_thr_active;
 
   dff_s #(4) spvie_ff(.din (supv_int_en),
                     .q   (supv_int_en_d1),
                     .clk (clk), .se(se), .si(), .so());
   dff_s #(4) hpvie_ff(.din (hypv_int_en),
                     .q   (hypv_int_en_d1),
                     .clk (clk), .se(se), .si(), .so());
 
   // force an interrupt by putting nop on pipe
   // use this signal instead of hw_int_s to help with crit path
   assign supv_masked_intr_s = (sftint_i3        |
			                          rerr_i3);
   assign hypv_masked_intr_s = (hwint_i4         |
			                          hintp_i3         |
			                          ceint_i3         |
			                          ueint_i3         |
			                          spuint0_i3       |
			                          spuint1_i3);
 
   assign fcl_swl_int_activate_i3 = hypv_masked_intr_s |
                                    supv_masked_intr_s;
 
    // keep track of rolled back interrupts
   assign intr_pending_nxt =  (({4{intr_vld_e}} & rb_frome) |
                               ({4{intr_vld_d}} & rb_fromd & ~rb_frome) |
                                intr_pending_s) & ~clear_s_d1;
 
   dffr_s #(4) ipend_reg(.din (intr_pending_nxt),
                       .q   (intr_pending_s),
                       .rst (fcl_reset),
                       .clk (clk), .se(se), .si(), .so());
 
   assign any_intr_vec_f = (supv_masked_intr_s & supv_int_en_d1 |
                            hypv_masked_intr_s & hypv_int_en_d1 |
                            intr_pending_s    |
			                      rstint_i3         |
                            resumint_i3       |
			                      nuke_thr_i3);
 
   dff_s #(4) anyints_reg(.din (any_intr_vec_f),
                        .q   (any_intr_vec_s),
                        .clk (clk), .se(se), .si(), .so());
 
   assign force_intr_s = (thr_f_crit[0] & any_intr_vec_s[0] |
                          thr_f_crit[1] & any_intr_vec_s[1] |
                          thr_f_crit[2] & any_intr_vec_s[2] |
                          thr_f_crit[3] & any_intr_vec_s[3]) &
	                         ~kill_intr_f;
 
   // interrupt and reset signal pipe
   // VA hole trap has higher priority than interrupt
   //   - since the VA hole marker is lost once the intr is taken
   assign intr_vld_s = force_intr_s & (valid_s & ~pc_oor_s | 
                                       async_intr_vld_s);
 
   assign intr_vld_qual_s = intr_vld_s & ~iferrto_thisthr_d1;
   dff_s #(1) any_intrd_ff(.din (intr_vld_qual_s),
		                     .q   (intr_vld_d),	
		                     .clk (clk),	
		                     .se  (se), .so(), .si());
   assign fcl_dec_intr_vld_d = intr_vld_d;
   assign intr_vld_qual_d = intr_vld_d & ~kill_intr_d & ~kill_thread_d & 
	                           ~rb_stg_d;
 
   dff_s #(1) intr_vlde_ff(.din (intr_vld_qual_d),
		                   .q   (intr_vld_e),
		                   .clk (clk), .se  (se), .so(), .si());
 
   assign intr_vld_qual_e = intr_vld_e & ~kill_curr_e & ~rb_stg_e & 
	                    ~kill_intr_e & ~dtu_inst_anull_e &
                      ~(thr_match_em & ifu_tlu_flush_m);
 
   dff_s #(1) intr_vldm_ff(.din (intr_vld_qual_e),
		                   .q   (intr_vld_m),
		                   .clk (clk), .se  (se), .so(), .si());
 
   assign intr_vld_qual_m = intr_vld_m & ~kill_thread_m & ~mark4rb_m;
 
   dff_s #(1) intr_vldw_ff(.din (intr_vld_qual_m),
		                   .q   (intr_vld_w),
		                   .clk (clk), .se  (se), .so(), .si());
 
   // Reset and Idle are prioritized in M.  All others in E
   // reset interrupt
   assign rstint_m = (rstint_i3[0] & thr_m[0] |
			                rstint_i3[1] & thr_m[1] |
			                rstint_i3[2] & thr_m[2] |
			                rstint_i3[3] & thr_m[3]);
 
   assign ifu_tlu_rstint_m = rstint_m & intr_vld_m & ~kill_local_m & 
                             ~kill_curr_m;
//   assign rstint_qual_m = rstint_m & ~ely_kill_thread_m & intr_vld_m;
   dff_s #(1) rstw_ff(.din (rstint_m),
                    .q   (rst_thr_w),
                    .clk (clk), .se(se), .si(), .so());
   assign fcl_dtu_rst_thr_w = rst_thr_w & intr_vld_w;
 
   // resume interrupt
   assign resumint_m = (resumint_i3[0] & thr_m[0] |
			                  resumint_i3[1] & thr_m[1] |
			                  resumint_i3[2] & thr_m[2] |
			                  resumint_i3[3] & thr_m[3]);
   assign resumint_qual_m = resumint_m & ~rstint_m;
 
   dff_s #(1) resumw_ff(.din (resumint_qual_m),
                      .q   (resum_thr_w),
                      .clk (clk), .se(se), .si(), .so());
   assign fcl_dtu_resum_thr_w = resum_thr_w & intr_vld_w;
 
   // idle interrupt
   assign nuke_thr_m = (nuke_thr_i3[0] & thr_m[0] |
				                nuke_thr_i3[1] & thr_m[1] |
				                nuke_thr_i3[2] & thr_m[2] |
				                nuke_thr_i3[3] & thr_m[3]);
 
   assign nuke_thr_qual_m = nuke_thr_m & ~rstint_m & ~resumint_m;
 
   dff_s #(1) nukw_ff(.din (nuke_thr_qual_m),
                    .q   (nuke_thr_w),
                    .clk (clk),
                    .se  (se), .si(), .so());
   assign fcl_dtu_nuke_thr_w = nuke_thr_w & intr_vld_w;
 
   // uncorrected ecc
   assign ueint_e = (ueint_i3[0] & thr_e[0] & hypv_int_en_d1[0] |
		                 ueint_i3[1] & thr_e[1] & hypv_int_en_d1[1] |
		                 ueint_i3[2] & thr_e[2] & hypv_int_en_d1[2] |
		                 ueint_i3[3] & thr_e[3] & hypv_int_en_d1[3]);
   assign ueint_qual_e = ueint_e & intr_vld_e;
 
   dff_s #(1) uem_ff (.din (ueint_qual_e),
                    .q   (ueint_m),
                    .clk (clk), .se (se), .si(), .so());
 
//   assign ueint_m = (ueint_i3[0] & thr_m[0] |
//		                 ueint_i3[1] & thr_m[1] |
//		                 ueint_i3[2] & thr_m[2] |
//		                 ueint_i3[3] & thr_m[3]);
 
   assign ueint_trap_m = ueint_m & intr_vld_m & 
                         ~(rstint_m | resumint_m | nuke_thr_m);
 
//   assign ueint_qual_m = ueint_trap_m & ~ely_kill_thread_m;
   dff_s #(1) ueintw_ff(.din (ueint_trap_m),
                      .q   (ueint_trap_w),
                      .clk (clk), .se(se), .si(), .so());
   assign ueint_qual_w = ueint_trap_w & intr_vld_w;
 
   // hstk match interrupt
   assign hintp_e = (hintp_i3[0] & thr_e[0] & hypv_int_en_d1[0] |
			               hintp_i3[1] & thr_e[1] & hypv_int_en_d1[1] |
			               hintp_i3[2] & thr_e[2] & hypv_int_en_d1[2] |
			               hintp_i3[3] & thr_e[3] & hypv_int_en_d1[3]);
   assign hintp_qual_e = hintp_e & intr_vld_e & ~ueint_e;
 
   dff_s #(1) hintpm_ff (.din (hintp_qual_e),
                       .q   (hintp_m),
                       .clk (clk), .se (se), .si(), .so());
 
//   assign ifu_tlu_hintp_m = hintp_m & ~kill_local_m & intr_vld_m & 
//	                    ~(rstint_m | nuke_thr_m | ueint_m);
 
   // hw int
   assign hwint_e = (hwint_i4[0] & thr_e[0] & hypv_int_en_d1[0] |
			               hwint_i4[1] & thr_e[1] & hypv_int_en_d1[1] |
			               hwint_i4[2] & thr_e[2] & hypv_int_en_d1[2] |
			               hwint_i4[3] & thr_e[3] & hypv_int_en_d1[3]);
   dff_s #(1) hwe_ff(.din (hwint_e),
                   .q   (hwint_m),
                   .clk (clk), .se(se), .si(), .so());
 
   assign ifu_tlu_hwint_m = hwint_m & intr_vld_m & ~kill_local_m &
                     ~kill_curr_m & 
	                   ~(rstint_m | resumint_m | nuke_thr_m | ueint_m | hintp_m);
 
 
   // spu interrupt
   assign spuint1_e = (spuint1_i3[0] & thr_e[0] & hypv_int_en_d1[0] |
		                   spuint1_i3[1] & thr_e[1] & hypv_int_en_d1[1] |
		                   spuint1_i3[2] & thr_e[2] & hypv_int_en_d1[2] |
		                   spuint1_i3[3] & thr_e[3] & hypv_int_en_d1[3]);
   assign spuint1_qual_e = spuint1_e & intr_vld_e & ~ueint_e & ~hintp_e;
 
//   assign spuint1_m = (spuint1_i3[0] & thr_m[0] |
//		                   spuint1_i3[1] & thr_m[1] |
//		                   spuint1_i3[2] & thr_m[2] |
//		                   spuint1_i3[3] & thr_m[3]);
 
   dff_s #(1) spu1m_ff(.din (spuint1_qual_e),
                     .q   (spuint1_m),
                     .clk (clk), .se(se), .si(), .so());
 
   assign spuint1_trap_m = spuint1_m & intr_vld_m & 
	                    ~(rstint_m | resumint_m | nuke_thr_m | hwint_m);
 
//   assign spuint1_qual_m = spuint1_trap_m & ~ely_kill_thread_m;
 
   dff_s #(1) spiw1_ff(.din (spuint1_trap_m),
		                 .q   (spuint1_trap_w),
		                 .clk (clk), .se(se), .si(), .so());
   assign spuint1_w = spuint1_trap_w & intr_vld_w;
 
   assign spuint0_e = (spuint0_i3[0] & thr_e[0] & hypv_int_en_d1[0] |
		                   spuint0_i3[1] & thr_e[1] & hypv_int_en_d1[1] |
		                   spuint0_i3[2] & thr_e[2] & hypv_int_en_d1[2] |
		                   spuint0_i3[3] & thr_e[3] & hypv_int_en_d1[3]);
 
   assign spuint0_qual_e = spuint0_e & intr_vld_e & ~ueint_e &
			                     ~spuint1_e & ~hintp_e;
 
//   assign spuint0_m = (spuint0_i3[0] & thr_m[0] |
//		                   spuint0_i3[1] & thr_m[1] |
//		                   spuint0_i3[2] & thr_m[2] |
//		                   spuint0_i3[3] & thr_m[3]);
   dff_s #(1) spu0m_ff(.din (spuint0_qual_e),
                     .q   (spuint0_m),
                     .clk (clk), .se(se), .si(), .so());
 
   assign spuint0_trap_m = spuint0_m & intr_vld_m &
             	        ~(rstint_m | nuke_thr_m | resumint_m |
		                    hwint_m);
 
//   assign spuint0_qual_m = spuint0_trap_m & ~kill_thread_m;
 
   dff_s #(1) spiw0_ff(.din (spuint0_trap_m),
		                 .q   (spuint0_trap_w),
		                 .clk (clk), .se(se), .si(), .so());
   assign spuint0_w = spuint0_trap_w & intr_vld_w;
 
//   assign ifu_spu_trap_ack = {spuint1_w, spuint0_w};
   assign ifu_spu_trap_ack = spuint1_w;   
 
 
   // software interrupts
   assign sftint_e = (sftint_i3[0] & thr_e[0] & supv_int_en_d1[0] |
			                sftint_i3[1] & thr_e[1] & supv_int_en_d1[1] |
			                sftint_i3[2] & thr_e[2] & supv_int_en_d1[2] |
			                sftint_i3[3] & thr_e[3] & supv_int_en_d1[3]);
 
   assign sftint_qual_e = sftint_e & ~spuint0_e & intr_vld_e & 
                          ~ueint_e & ~spuint1_e & ~hintp_e;
 
   dff_s #(1) swm_ff(.din (sftint_qual_e),
                   .q   (sftint_m),
                   .clk (clk), .se(se), .si(), .so());
 
   // if nothing else, signal sftint!
//   assign ifu_tlu_sftint_m = (sftint_m & 
//	                            ~(rstint_m | nuke_thr_m | hintp_m | resumint_m |
//				                        hwint_m | spuint1_m | spuint0_m | ueint_m) |
//                              ~(ceint_m | rerr_m)) & 
//                               ~kill_local_m & intr_vld_m;
 
   assign ifu_tlu_sftint_m = (sftint_m & 
	                            ~(rstint_m | nuke_thr_m | hintp_m | resumint_m |
				                        hwint_m | spuint1_m | spuint0_m | ueint_m)) & 
                               ~kill_local_m & ~kill_curr_m & intr_vld_m;
 
 
   // corrected ecc interrupt
   assign ceint_e = (ceint_i3[0] & thr_e[0] & hypv_int_en_d1[0] |
		                 ceint_i3[1] & thr_e[1] & hypv_int_en_d1[1] |
		                 ceint_i3[2] & thr_e[2] & hypv_int_en_d1[2] |
		                 ceint_i3[3] & thr_e[3] & hypv_int_en_d1[3]);
   assign ceint_qual_e = ceint_e & intr_vld_e & ~ueint_e & 
                          ~spuint1_e & ~spuint0_e & ~hintp_e;
 
//   assign ceint_m = (ceint_i3[0] & thr_m[0] |
//		                 ceint_i3[1] & thr_m[1] |
//		                 ceint_i3[2] & thr_m[2] |
//		                 ceint_i3[3] & thr_m[3]);
   dff_s #(1) cem_ff(.din (ceint_qual_e),
                   .q   (ceint_m),
                   .clk (clk), .se(se), .si(), .so());
 
   assign ceint_trap_m = ceint_m & intr_vld_m & 
	                 ~(rstint_m | nuke_thr_m | resumint_m |
		                 sftint_m | hwint_m);
 
//   assign ceint_qual_m = ceint_trap_m & ~ely_kill_thread_m;
   dff_s #(1) ceintw_ff(.din (ceint_trap_m),
                      .q   (ceint_trap_w),
                      .clk (clk), .se(se), .si(), .so());
   assign ceint_qual_w = ceint_trap_w & intr_vld_w;
 
   // resumable error interrupt
   assign rerr_e = (rerr_i3[0] & thr_e[0] & supv_int_en_d1[0] |
		                 rerr_i3[1] & thr_e[1] & supv_int_en_d1[1] |
		                 rerr_i3[2] & thr_e[2] & supv_int_en_d1[2] |
		                 rerr_i3[3] & thr_e[3] & supv_int_en_d1[3]);
   assign rerr_qual_e = rerr_e & intr_vld_e & ~ueint_e & ~ceint_e &
                        ~spuint1_e & ~spuint0_e & ~hintp_e;
 
   dff_s #(1) rem_ff(.din (rerr_qual_e),
                   .q   (rerr_m),
                   .clk (clk), .se(se), .si(), .so());
 
//   assign rerr_m = (rerr_i3[0] & thr_m[0] |
//			              rerr_i3[1] & thr_m[1] |
//			              rerr_i3[2] & thr_m[2] |
//			              rerr_i3[3] & thr_m[3]);
 
//   assign ifu_tlu_rerr_m = rerr_m & ~kill_local_m & intr_vld_m & 
//	                    ~(rstint_m | nuke_thr_m | ueint_m | ceint_m);
 
   assign disr_trap_m = (ueint_m | hintp_m | spuint0_m | spuint1_m |
                         ceint_m | rerr_m) & ~rstint_m & ~nuke_thr_m &
                          ~resumint_m & intr_vld_m;
 
   // check if a scheduled interrupt evaporated...
   assign any_intr_m = (ueint_m | ceint_m | spuint0_m | spuint1_m |
                        hintp_m | rerr_m | sftint_m | hwint_m | 
                        rstint_m | nuke_thr_m | resumint_m);
 
   // ..and rollback if that is the case
   assign rb_intr_m = ~any_intr_m & intr_vld_m;
   dff_s #(1) rbint_ff(.din (rb_intr_m),
                     .q   (rb_intr_w),
                     .clk (clk), .se(se), .si(), .so());
 
   // use synchronous interrupt signal to switch out thread in swl
//   assign fcl_dtu_sync_intr_d = (intr_vld_d | immu_miss_crit_d) & ~rb_stg_d;
   assign fcl_dtu_sync_intr_d = (intr_vld_d) & ~rb_stg_d_crit;   
 
   // kill the next three interrupts.  After that you are on your own.
//   assign kill_intr_m = ((thr_m & thr_w) == 4'b0) ?
//			                    1'b0 : (intr_vld_w);
   assign kill_intr_e = ((thr_e & thr_w) == 4'b0) ?
			                    1'b0 : (intr_vld_w);
   assign kill_intr_d = ((thr_d & thr_w) == 4'b0) ?
			                    1'b0 : (intr_vld_w);
   assign kill_intr_f = ((thr_f & thr_w) == 4'b0) ?
			                    1'b0 : (intr_vld_w);
 
//--------------------------------
// check if we are in a delay slot
//--------------------------------
   // remember if the current instruction is a delay slot
   assign delay_slot_vec_nxt = ({4{dtu_fcl_br_inst_d & inst_vld_d & 
                                   ~rb_stg_d}} & thr_d | // set
                                delay_slot_vec &
                                ~(thr_d & {4{inst_vld_d &
                                             ~rb_stg_d &
                                             ~intr_vld_d}})) &
                                 ~(trap_thr & {4{trappc_vld_w2}});
                                // & ~late_flush_w2;
   // Need to be a little pessimitic: can't clear the delay slot vec
   // after a utrap, since we may still be in the delay slot when we
   // re-execute
 
   dffr_s #(4) ds_reg(.din (delay_slot_vec_nxt),
                    .q   (delay_slot_vec),
                    .rst (fcl_reset),
                    .clk (clk), .se(se), .si(), .so());
   assign fcl_dec_dslot_s = (delay_slot_vec[0] & thr_f[0] |
                             delay_slot_vec[1] & thr_f[1] |
                             delay_slot_vec[2] & thr_f[2] |
                             delay_slot_vec[3] & thr_f[3]);
 
 
//------------------------------
// NIR control
//------------------------------
   // use nir if va[2] of previous fetch is a zero (i.e lower word)
   dff_s #(1) va2_ff(.din (fdp_fcl_va2_bf),
		               .clk (clk),
		               .q   (va2_f),
		               .se  (se), .si(), .so());
 
   assign usep_bf = rdreq_f & ~va2_f & ~ntpc_thisthr & ~stall_f;
   assign set_usen_bf = usep_bf & ~ely_stall_thisthr_f & dtu_fcl_running_s;
 
   // need to kill usen if trap or interrupt or flush
   assign thr_usen_nxt = ({4{set_usen_bf}} &  thr_f  |    // set usen
			                    thr_usen_bf  & ~val_thr_f) &    // keep old value
			                     ~((thr_d & {4{dtu_fcl_br_inst_d}})  |
		                         (thr_s1 & {4{ic_miss_s1}})  |
                             (thr_e & {4{erb_dtu_ifeterr_d1 & inst_vld_d1}}) |
			                       (clear_s_d1) |
			                       (ntpc_vld)  |
			                       (rb_w2 | rb_froms));     // reset usen (wins)
                         // & ~dtu_fcl_flush_nir
 
   dffr_s #(4) thr_usen_reg(.din  (thr_usen_nxt),
			                  .clk  (clk),
			                  .q    (thr_usen_bf),
			                  .rst  (fcl_reset),
			                  .se   (se), .si(), .so());
 
   /*
   // Use hand instantiated mux
   bw_u1_ao2222_4x UZsize_usn_mx(.z   (usen_iso_bf)
		                            .a2  (thr_usen_bf[0]),
		                            .b2  (thr_usen_bf[1]),
		                            .c2  (thr_usen_bf[2]),
		                            .d2  (thr_usen_bf[3]),
		                            .a1  (nextthr_bf_buf[0]),
		                            .b1  (nextthr_bf_buf[1]),
		                            .c1  (nextthr_bf_buf[2]),
		                            .d1  (nextthr_bf_buf[3]));
 
    // isolate from critical path
    bw_u1_buf_5x  UZsize_usn_iso(.z(usen_bf), .a(usen_iso_bf));
    */
 
   assign usen_iso_bf = (thr_usen_bf[0] & nextthr_bf_buf[0] |
                         thr_usen_bf[1] & nextthr_bf_buf[1] |
                         thr_usen_bf[2] & nextthr_bf_buf[2] |
                         thr_usen_bf[3] & nextthr_bf_buf[3]);
   assign usen_bf = usen_iso_bf;
 
 
 
//------------------------------
// Switch Control
//------------------------------   
   // Switch IF
   //   1. Another thread is ready OR
   //   2. We hit a switch condition or Imiss and another thread is
   //      speculatively ready
   //   3. No thread is running and another thread is speculatively ready
   //   4. The DTU calls for a thread switch and another thread is ready
   //   (NOTE: if we hit a switch condition or Imiss and no thread is
   //    speculatively or otherwise ready we stall the pipe).
   //
   //   New plan:  switch if another thread is ready or spec ready.
   //
 
//   assign switch_bf = dtu_fcl_ntr_s;
   bw_u1_buf_20x UZsize_swbuf(.a (dtu_fcl_ntr_s),
                              .z (switch_bf));
 
//   assign switch_bf = dtu_fcl_ntr_s & ~imsto_nextthr_s1;
//   assign switch_bf = dtu_fcl_ntr_s & ~(imsto_nextthr_s1 | kill_nextthr_w | 
//                                        intrto_nextthr_d);   
 
//   assign fcl_dtu_switch_s = switch_bf & ~all_stallreq & ~rst_stallreq;
//   assign fcl_dtu_switch_s = switch_bf & ~kill_nextthr_w;
 
   // TBD: No need to send this anymore, since switch_bf = ntr_s
//   assign fcl_dtu_switch_s = switch_bf;  // sw out curr and sw in next
 
   assign fcl_swl_swout_f = stall_f;     // sw out curr but don't sw in next
   // Note: need fcl_swl_swout_f and dtu_fcl_running_s to sync swl and
   // fcl at all times.  
 
   assign switch_qual_bf = switch_bf & ~rst_stallreq;
   dff_s #(1) sw_ff (.din  (switch_qual_bf),
		               .clk  (clk),
		               .q    (switch_s2),
		               .se   (se), .si(), .so());
 
   dff_s #(1) tmfn_ff (.din  (switch_bf),
		                 .clk  (clk),
		                 .q    (tm_fd_l),
		                 .se   (se), .si(), .so());
 
   // need to qual with immu_fault to avoid X's
//   assign fcl_dtu_swc_s = fdp_fcl_swc_s2 & inst_vld_s_crit & 
//                          ~immu_fault_f & ~part_stall_thisthr_f;
//   assign fcl_dtu_swc_s = fdp_fcl_swc_s2 & inst_vld_s_crit & 
//                          ~immu_fault_f & ~imsto_thisthr_s1 & ~rb_stg_s;
   assign fcl_swl_swcvld_s = inst_vld_s_crit & ~immu_fault_f & 
                             ~imsto_thisthr_s1 & ~rb_stg_s;
 
 
//------------------------------   
// Thread pipe
//------------------------------
 
//`ifdef VERPLEX
//   $constraint nthr_1h4 ($one_hot(dtu_fcl_nextthr_bf[3:0]));
//   $constraint thrf_1h4 ($one_hot(thr_f[3:0]));
//`endif
 
   // Keep track the thread in each pipe stage
   assign rstt = (~fcl_reset & (rst_stallreq_d1 & ~arst_vld_f)) | rst_tri_en;
   assign swt =  (~rst_stallreq_d1 & ~arst_vld_f & switch_bf | fcl_reset) & 
                   ~rst_tri_en;
   assign samet = (~rst_stallreq_d1 & ~switch_bf | arst_vld_f) & 
                    ~fcl_reset & ~rst_tri_en;
 
   mux3ds #(4)  nxttthr_mux(.dout  (thr_bf[3:0]),      
			                      .in0   (thr_f[3:0]),       
			                      .in1   (nextthr_bf_buf[3:0]),
			                      .in2   (rstint_penc[3:0]), 
			                      .sel0  (samet),
			                      .sel1  (swt),
			                      .sel2  (rstt));
 
   assign thr_match_nw = (thr_w[0] & nextthr_bf_buf[0] | 
			                    thr_w[1] & nextthr_bf_buf[1] | 
			                    thr_w[2] & nextthr_bf_buf[2] | 
			                    thr_w[3] & nextthr_bf_buf[3]);
 
   assign thr_match_nd = (thr_d[0] & nextthr_bf_buf[0] | 
			                    thr_d[1] & nextthr_bf_buf[1] | 
			                    thr_d[2] & nextthr_bf_buf[2] | 
			                    thr_d[3] & nextthr_bf_buf[3]);
 
//   assign thr_match_ne = (thr_e[0] & dtu_fcl_nextthr_bf[0] | 
//			                    thr_e[1] & dtu_fcl_nextthr_bf[1] | 
//			                    thr_e[2] & dtu_fcl_nextthr_bf[2] | 
//			                    thr_e[3] & dtu_fcl_nextthr_bf[3]);
   // qualify inst_vld_e in fcl itself
 
//   bw_u1_ao2222_4x UZsize_tmne(.z  (thr_match_ne),
//                               .a1 (val_thr_e[0]),
//                               .b1 (val_thr_e[1]),
//                               .c1 (val_thr_e[2]),
//                               .d1 (val_thr_e[3]),
//                               .a2 (dtu_fcl_nextthr_bf[0]),
//                               .b2 (dtu_fcl_nextthr_bf[1]),
//                               .c2 (dtu_fcl_nextthr_bf[2]),
//                               .d2 (dtu_fcl_nextthr_bf[3]));
 
   wire   tmne_10,
          tmne_32;
   bw_u1_aoi22_2x UZsize_tmne10(.z (tmne_10),
                                .a1 (dtu_fcl_nextthr_bf[0]),
                                .b1 (dtu_fcl_nextthr_bf[1]),
                                .a2 (val_thr_e[0]),
                                .b2 (val_thr_e[1]));
   bw_u1_aoi22_2x UZsize_tmne32(.z (tmne_32),
                                .a1 (dtu_fcl_nextthr_bf[2]),
                                .b1 (dtu_fcl_nextthr_bf[3]),
                                .a2 (val_thr_e[2]),
                                .b2 (val_thr_e[3]));
   bw_u1_nand2_4x UZsize_tmne30(.z (thr_match_ne),
                                .a (tmne_10),
                                .b (tmne_32));
 
 
   dff_s #(4) thrf_reg(.din   (thr_bf),     // thr_f may be 4'b0000 but it has 
		                 .clk   (clk),        // to reset to 4'b0001
		                 .q     (thr_f_flop),
		                 .se    (se),  .si(), .so());
 
   bw_u1_buf_10x UZsize_tfcrit0(.a (thr_f_flop[0]), .z(thr_f_crit[0]));
   bw_u1_buf_10x UZsize_tfcrit1(.a (thr_f_flop[1]), .z(thr_f_crit[1]));
   bw_u1_buf_10x UZsize_tfcrit2(.a (thr_f_flop[2]), .z(thr_f_crit[2]));
   bw_u1_buf_10x UZsize_tfcrit3(.a (thr_f_flop[3]), .z(thr_f_crit[3]));
 
   bw_u1_buf_10x UZsize_tfncr0(.a (thr_f_flop[0]), .z(thr_f[0]));
   bw_u1_buf_10x UZsize_tfncr1(.a (thr_f_flop[1]), .z(thr_f[1]));
   bw_u1_buf_10x UZsize_tfncr2(.a (thr_f_flop[2]), .z(thr_f[2]));
   bw_u1_buf_10x UZsize_tfncr3(.a (thr_f_flop[3]), .z(thr_f[3]));
 
   assign     ifu_exu_tid_s2[1] = thr_f[3] | thr_f[2];
   assign     ifu_exu_tid_s2[0] = thr_f[3] | thr_f[1];
   assign     ifu_lsu_thrid_s = ifu_exu_tid_s2;
   assign     fcl_dtu_thr_f = thr_f;
 
//   assign thr_s1_next = inst_vld_f ? thr_f : thr_s1;
   assign     thr_s1_next[0] = thr_f[0];
   assign     thr_s1_next[1] = ~thr_f[0] & thr_f[1];
   assign     thr_s1_next[2] = ~thr_f[0] & ~thr_f[1] & thr_f[2];
   assign     thr_s1_next[3] = ~thr_f[0] & ~thr_f[1] & ~thr_f[2];
 
//`ifdef VERPLEX
//   $constraint thr_s1_1h4 ($one_hot(thr_s1_next[3:0]));
//`endif
 
   dff_s #(4) thrs1_reg(.din   (thr_s1_next),
		    .clk   (clk),
		    .q     (thr_s1),
		    .se    (se), .si(), .so());
 
   dff_s #(4) thrd_reg(.din    (thr_s1_next), 
		     .clk   (clk),
		     .q     (thr_d),
		     .se    (se), .si(), .so());
 
   assign fcl_ifq_thr_s1[0] = thr_s1[3] | thr_s1[1];
   assign fcl_ifq_thr_s1[1] = thr_s1[3] | thr_s1[2];
 
   assign ifu_tlu_thrid_d[1] = thr_d[3] | thr_d[2];
   assign ifu_tlu_thrid_d[0] = thr_d[3] | thr_d[1];
 
   assign thr_match_fs1 = (thr_d[0] & thr_f_crit[0] | 
			                     thr_d[1] & thr_f_crit[1] | 
			                     thr_d[2] & thr_f_crit[2] | 
			                     thr_d[3] & thr_f_crit[3]);
   assign thr_match_fd = thr_match_fs1;
   assign thr_match_fe = (thr_e[0] & thr_f[0] | 
			                    thr_e[1] & thr_f[1] | 
			                    thr_e[2] & thr_f[2] | 
			                    thr_e[3] & thr_f[3]);
   assign thr_match_fm = (thr_m[0] & thr_f[0] | 
			                    thr_m[1] & thr_f[1] | 
			                    thr_m[2] & thr_f[2] | 
			                    thr_m[3] & thr_f[3]);
//   assign thr_match_ft = (trap_thr[0] & thr_f[0] | 
//			  trap_thr[1] & thr_f[1] | 
//			  trap_thr[2] & thr_f[2] | 
//			  trap_thr[3] & thr_f[3]);
 
   dffr_s #(4) thre_reg(.din   (thr_d),    
		    .clk   (clk),
		    .rst   (fcl_reset),
		    .q     (thr_e),
		    .se    (se), .si(), .so());
 
   dffr_s #(4) thre2_reg(.din   (thr_d),    
		    .clk   (clk),
		    .rst   (fcl_reset),
		    .q     (thr_e_v2),
		    .se    (se), .si(), .so());
 
   assign     ifu_tlu_thrid_e[1] = thr_e[3] | thr_e[2];
   assign     ifu_tlu_thrid_e[0] = thr_e[3] | thr_e[1];
 
   assign thr_match_de = (thr_d[0] & thr_e[0] | 
			                    thr_d[1] & thr_e[1] | 
			                    thr_d[2] & thr_e[2] | 
			                    thr_d[3] & thr_e[3]);
 
   assign thr_match_dm = (thr_d[0] & thr_m[0] | 
			                    thr_d[1] & thr_m[1] | 
			                    thr_d[2] & thr_m[2] | 
			                    thr_d[3] & thr_m[3]);
 
   dff_s #(4) thrm_reg(.din   (thr_e),    
		   .clk   (clk),
		   .q     (thr_m),
		   .se    (se), .si(), .so());
 
   dff_s #(4) thrw_reg(.din   (thr_m),    
		   .clk   (clk),
		   .q     (thr_w),
		   .se    (se), .si(), .so());
 
   assign sas_thrid_w[1] = thr_w[3] | thr_w[2];
   assign sas_thrid_w[0] = thr_w[3] | thr_w[1];
 
   assign thr_match_fw = (thr_f[0] & thr_w[0] | 
			                    thr_f[1] & thr_w[1] | 
			                    thr_f[2] & thr_w[2] | 
			                    thr_f[3] & thr_w[3]);
 
   assign thr_match_fw2 = (thr_f[0] & thr_w2[0] | 
			                     thr_f[1] & thr_w2[1] | 
			                     thr_f[2] & thr_w2[2] | 
			                     thr_f[3] & thr_w2[3]);
 
   assign thr_match_dw = (thr_d[0] & thr_w[0] | 
			                    thr_d[1] & thr_w[1] | 
			                    thr_d[2] & thr_w[2] | 
			                    thr_d[3] & thr_w[3]);
 
   assign thr_match_dw2 = (thr_d[0] & thr_w2[0] | 
			                     thr_d[1] & thr_w2[1] | 
			                     thr_d[2] & thr_w2[2] | 
			                     thr_d[3] & thr_w2[3]);
 
   assign thr_match_em = (thr_e[0] & thr_m[0] | 
			                    thr_e[1] & thr_m[1] | 
			                    thr_e[2] & thr_m[2] | 
			                    thr_e[3] & thr_m[3]);
 
   assign thr_match_ew = (thr_e_v2[0] & thr_w[0] | 
			                    thr_e_v2[1] & thr_w[1] | 
			                    thr_e_v2[2] & thr_w[2] | 
			                    thr_e_v2[3] & thr_w[3]);
 
   dff_s #(1) stmw2_ff(.din (thr_match_ew),
                     .q   (same_thr_mw2),
                     .clk (clk), .se (se), .si(), .so());
 
   assign thr_match_ew2 = (thr_e[0] & thr_w2[0] | 
			                     thr_e[1] & thr_w2[1] | 
			                     thr_e[2] & thr_w2[2] | 
			                     thr_e[3] & thr_w2[3]);
 
   assign thr_match_mw = (thr_m[0] & thr_w[0] | 
			                    thr_m[1] & thr_w[1] | 
			                    thr_m[2] & thr_w[2] | 
			                    thr_m[3] & thr_w[3]);
 
   dff_s #(4) thrw2_reg(.din   (thr_w),    
		    .clk   (clk),
		    .q     (thr_w2),
		    .se    (se), .si(), .so());
 
 
//-------------------------
// Rollback
//-------------------------
 
   // 04/05/02
   // Looks like we made a mistake with rollback.  Should never
   // rollback to S.  In the event of a dmiss or mul contention, just
   // kill all the instructions and rollback to F.  This adds one
   // cycle to the dmiss penalty and to the mul latency if we have to
   // wait, both not a very high price to pay.  This would have saved
   // lots of hours of design and verif time.
   //    
   assign rb2_inst_d = thr_match_dw & inst_vld_d & dtu_fcl_rollback_g;
   assign rb1_inst_s = thr_match_fw & inst_vld_s & dtu_fcl_rollback_g;
   assign rb0_inst_bf = thr_match_nw & switch_bf & dtu_fcl_rollback_g;
 
//   assign rt1_inst_s = thr_match_fd & inst_vld_s & retract_inst_d;
//   assign rt0_inst_bf = thr_match_nd & dtu_fcl_ntr_s & retract_inst_d;
 
//   assign retract_iferr_d = thr_match_de & erb_dtu_ifeterr_d1 & inst_vld_d1 &
//                            ~kill_curr_e & fcl_dtu_inst_vld_d;
   assign retract_iferr_d1 = erb_dtu_ifeterr_d1 & inst_vld_d1;
 
   assign retract_inst_d = retract_iferr_d1 & thr_match_de & 
                           fcl_dtu_inst_vld_d |
                           mark4rb_d | 
                           dtu_fcl_retract_d;
 
   assign rt1_inst_s = thr_match_fd & inst_vld_s & dtu_fcl_retract_d | 
                       mark4rb_s;
//                     | thr_match_fe & inst_vld_s & retract_iferr_d1;
 
   // TBD:  This is not necessary since the thread will switch out and
   // stall whatever makes its way to the S stage.
   // NOTE: rb0_inst *is needed* however.
   assign rt0_inst_bf = thr_match_nd & switch_bf & dtu_fcl_retract_d;
//                      | thr_match_ne & dtu_fcl_ntr_s & retract_iferr_d1;
 
   assign retract_iferr_qual_d1 = retract_iferr_d1 & thr_match_de &
                                  fcl_dtu_inst_vld_d &
                                  ~(dtu_fcl_rollback_g & thr_match_ew);
 
   dff_s rbe_ff(.din (rb2_inst_d),
	      .q   (rb2_inst_e),
	      .clk (clk),
	      .se  (se), .si(), .so());
 
   dff_s rte_ff(.din (retract_inst_d),
	      .q   (rt2_inst_e),
	      .clk (clk),
	      .se  (se), .si(), .so());
 
   dff_s rbd_ff(.din (rb1_inst_s),
	      .q   (rb1_inst_d),
	      .clk (clk),
	      .se  (se), .si(), .so());
 
   dff_s rtd_ff(.din (rt1_inst_s),
	      .q   (rt1_inst_d),
	      .clk (clk),
	      .se  (se), .si(), .so());
 
   dff_s rbs_ff(.din (rb0_inst_bf),
	      .q   (rb0_inst_s),
	      .clk (clk),
	      .se  (se), .si(), .so());
 
   // TBD: is this necessary?
   dff_s rts_ff(.din (rt0_inst_bf),
	      .q   (rt0_inst_s),
	      .clk (clk),
	      .se  (se), .si(), .so());
 
   dff_s rtiferr_ff(.din (retract_iferr_qual_d1),
                  .q   (retract_iferr_e),
                  .clk (clk),
                  .se  (se), .si(), .so());
 
   assign rb_stg_s = (rb0_inst_s | rt0_inst_s) & tm_fd_l |
	                   (rb1_inst_d | rt1_inst_d) & ~tm_fd_l;
   assign rb_stg_d_crit = rb1_inst_d | rt1_inst_d;
   assign rb_stg_e = rb2_inst_e | rt2_inst_e;
 
   bw_u1_buf_5x UZsize_rbd_buf(.a (rb_stg_d_crit),
                               .z (rb_stg_d));
 
   // determine rollback amount
   assign rb_frome = {4{(rb2_inst_e | rt2_inst_e) & 
                        (inst_vld_e | intr_vld_e)}} & thr_e;
   assign rb_fromd = {4{(rb1_inst_d | rt1_inst_d) & 
                        (inst_vld_d | intr_vld_d)}} & thr_d;
   assign rb_froms = {4{rb_stg_s & inst_vld_s_crit}} & thr_f;   
   assign rb_w2 = rb_frome | rb_fromd;
   assign rb_for_iferr_e = {4{retract_iferr_e}} & thr_e;
 
//------------------------------   
// Branch Control
//------------------------------
   // final portion of branch evaluation
   wire brtaken_e_l;   
   bw_u1_buf_20x UZsize_bcbf(.z(fcl_dcl_regz_e), 
                             .a(exu_ifu_regz_e));
 
   bw_u1_muxi21_6x UZsize_bcmux(.z(brtaken_e_l), 
                                .d0(dcl_fcl_bcregz0_e), 
                                .d1(dcl_fcl_bcregz1_e), 
                                .s(exu_ifu_regz_e));
 
   bw_u1_inv_15x UZsize_bcinv(.z(brtaken_e), 
                              .a(brtaken_e_l));
 
   // Branch is taken in the E stage to thr_e.  Below we check to see
   // if this is the same as the next thread we will switch to
 
   // isolate non critical section
   bw_u1_buf_5x UZsize_btbuf(.z (brtaken_unq_e),
                             .a (brtaken_e));
   assign brtaken_buf_e = brtaken_unq_e & inst_vld_qual_e & ~kill_curr_e;
 
//   assign thr_match_ne_norst = thr_match_ne & ~rst_sw_bf;
//   assign brto_nxtthr_bf  = thr_match_ne & brtaken_e;
   bw_u1_nand2_4x UZsize_btkn_ntl(.a (brtaken_e),
                                  .b (thr_match_ne),
                                  .z (brto_nxtthr_bf_l));
 
//   bw_u1_inv_8x UZsize_btkn_bf(.a (brto_nxtthr_bf_l),
//                               .z (brto_nxtthr_bf));
 
   dff_s #(1) br_ff(.din (brtaken_buf_e),
		              .q   (brtaken_m),
		              .clk (clk),
		              .se  (se), .si(), .so());
 
 
//----------------------------------------------------------------------
// PC related control
//----------------------------------------------------------------------
 
   // Choose next IC address
   // IC address is chosen from
   //    1. Next PC assuming no switch 
   //    2. Branch PC if E stage branch is to next thread
   //    3. Saved F stage Thread PC if we switch threads
 
   assign fcl_icd_index_sel_ifq_bf = allow_ifq_access_icd_bf;
   assign fcl_ifq_grant_bf = allow_ifq_access_icd_bf;
 
   // Select branch PC
//   assign fcl_fdp_icaddr_sel_br_bf_l = ~(~all_stallreq &
//					                               brto_nxtthr_bf    &
//					                               switch_bf);
//
//   // Select the switch PC from thread PC register
//   assign fcl_fdp_icaddr_sel_swpc_bf_l = ~(~all_stallreq &
//					                                 ~usen_bf &
//					                                 ~brto_nxtthr_bf &
//					                                 switch_bf);
//
//   // Select current thread's next PC or IC write addr (PC/PC+4/I$ wraddr)
//   assign fcl_fdp_icaddr_sel_curr_bf_l = ~(~all_stallreq &
//					                                 ~(stall_f | usep_bf) & 
//					                                 ~switch_bf);
//   
//   assign fcl_fdp_icaddr_sel_ifq_bf_l = ~(all_stallreq |
//					                                (stall_f | usep_bf) & ~switch_bf |
//					                                ~brto_nxtthr_bf & usen_bf &
//					                                (switch_bf | stall_f | usep_bf));
 
 
 
//   assign sw_or_async_stall = (switch_bf & ~rst_stallreq | rst_sw_bf);
   wire   sw_or_async_stall_l;
   assign rst_stallreq_l = ~rst_stallreq;
   bw_u1_aoi21_4x UZsize_swstl_aoi(.z  (sw_or_async_stall_l),
                                   .a  (rst_sw_bf),
                                   .b1 (switch_bf),
                                   .b2 (rst_stallreq_l));
   assign sw_or_async_stall = ~sw_or_async_stall_l;
 
//   assign icadr_selbr = sw_or_async_stall & brto_nxtthr_bf;
   assign sw_match_ne_norst = sw_or_async_stall & thr_match_ne;
   bw_u1_nand2_10x UZfix_icad_br(.a (brtaken_e),
                                 .b (sw_match_ne_norst),
                                 .z (icadr_selbr_l));
 
//   assign icadr_selsw = sw_or_async_stall & ~brto_nxtthr_bf;
   bw_u1_nand2_15x UZfix_icad_sw(.a (brto_nxtthr_bf_l),
                                 .b (sw_or_async_stall),
                                 .z (icadr_selsw_l));
 
 
   // select next PC
   assign fcl_fdp_pcbf_sel_br_bf_l = icadr_selbr_l;
   assign fcl_fdp_pcbf_sel_swpc_bf_l = icadr_selsw_l ;
   assign fcl_fdp_pcbf_sel_nosw_bf_l = ~sw_or_async_stall_l;
 
   // Select PC to switch to in the event of a switch
   // No need to protect during scan
   // NOTE: SWL guarantees nextthr_bf is one hot
//   assign fcl_fdp_next_thr_bf_l = rst_stallreq_d1 ? ~rstint_penc :
//                                                    ~dtu_fcl_nextthr_bf;
 
   wire [3:0] next_thr_bf_l;
   wire       nt_sel_rst;
   assign     nt_sel_rst = rst_stallreq_d1 | rst_tri_en;
 
   bw_u1_muxi21_2x UZfix_nthr_mx0(.z (next_thr_bf_l[0]),
                                  .d0 (dtu_fcl_nextthr_bf[0]),
                                  .d1 (rstint_penc[0]),
                                  .s  (nt_sel_rst));
   bw_u1_muxi21_2x UZfix_nthr_mx1(.z (next_thr_bf_l[1]),
                                  .d0 (dtu_fcl_nextthr_bf[1]),
                                  .d1 (rstint_penc[1]),
                                  .s  (nt_sel_rst));
   bw_u1_muxi21_2x UZfix_nthr_mx2(.z (next_thr_bf_l[2]),
                                  .d0 (dtu_fcl_nextthr_bf[2]),
                                  .d1 (rstint_penc[2]),
                                  .s  (nt_sel_rst));
   bw_u1_muxi21_2x UZfix_nthr_mx3(.z (next_thr_bf_l[3]),
                                  .d0 (dtu_fcl_nextthr_bf[3]),
                                  .d1 (rstint_penc[3]),
                                  .s  (nt_sel_rst));
   assign     fcl_fdp_next_thr_bf_l = next_thr_bf_l;
 
 
//   assign nextthr_bf_buf = dtu_fcl_nextthr_bf;
   bw_u1_buf_20x UZsize_ntbf0(.a (dtu_fcl_nextthr_bf[0]),
                              .z (nextthr_bf_buf[0]));
   bw_u1_buf_20x UZsize_ntbf1(.a (dtu_fcl_nextthr_bf[1]),
                              .z (nextthr_bf_buf[1]));
   bw_u1_buf_20x UZsize_ntbf2(.a (dtu_fcl_nextthr_bf[2]),
                              .z (nextthr_bf_buf[2]));
   bw_u1_buf_20x UZsize_ntbf3(.a (dtu_fcl_nextthr_bf[3]),
                              .z (nextthr_bf_buf[3]));
   // use 6x
   assign fcl_fdp_next_ctxt_bf_l[2:0] = ~nextthr_bf_buf[2:0] | {3{rst_tri_en}};
   assign fcl_fdp_next_ctxt_bf_l[3] = ~nextthr_bf_buf[3] & ~rst_tri_en;
 
//   assign nextthr_final_bf = switch_bf ? dtu_fcl_nextthr_bf : thr_f;
   wire [3:0] nextthr_final_bf_l;
   bw_u1_muxi21_2x UZfix_ntfmux0(.z  (nextthr_final_bf_l[0]),
                                .d0 (thr_f[0]),
                                .d1 (dtu_fcl_nextthr_bf[0]),
                                .s  (switch_bf));
   bw_u1_inv_8x UZsize_ntfin_buf0(.z (nextthr_final_bf[0]),
                                 .a (nextthr_final_bf_l[0]));
 
   bw_u1_muxi21_2x UZfix_ntfmux1(.z  (nextthr_final_bf_l[1]),
                                .d0 (thr_f[1]),
                                .d1 (dtu_fcl_nextthr_bf[1]),
                                .s  (switch_bf));
   bw_u1_inv_8x UZsize_ntfin_buf1(.z (nextthr_final_bf[1]),
                                 .a (nextthr_final_bf_l[1]));
 
   bw_u1_muxi21_2x UZfix_ntfmux2(.z  (nextthr_final_bf_l[2]),
                                .d0 (thr_f[2]),
                                .d1 (dtu_fcl_nextthr_bf[2]),
                                .s  (switch_bf));
   bw_u1_inv_8x UZsize_ntfin_buf2(.z (nextthr_final_bf[2]),
                                 .a (nextthr_final_bf_l[2]));
 
   bw_u1_muxi21_2x UZfix_ntfmux3(.z  (nextthr_final_bf_l[3]),
                                .d0 (thr_f[3]),
                                .d1 (dtu_fcl_nextthr_bf[3]),
                                .s  (switch_bf));
   bw_u1_inv_8x UZsize_ntfin_buf3(.z (nextthr_final_bf[3]),
                                 .a (nextthr_final_bf_l[3]));
 
 
   // decode trap thread
   dff_s #(2) ld_trp_reg(.din ({tlu_ifu_trappc_vld_w1,
                              tlu_ifu_trapnpc_vld_w1}),
                       .q   ({trappc_vld_w2,
                              trapnpc_vld_w2}),
                       .clk (clk), .se(se), .si(), .so());
 
   dff_s #(2) trp_tid_reg(.din (tlu_ifu_trap_tid_w1[1:0]),
                        .q   (trap_tid_w2[1:0]),
                        .clk (clk), .se(se), .si(), .so());
 
   assign trap_thr[0] = ~trap_tid_w2[1] & ~trap_tid_w2[0];
   assign trap_thr[1] = ~trap_tid_w2[1] &  trap_tid_w2[0];
   assign trap_thr[2] =  trap_tid_w2[1] & ~trap_tid_w2[0];
   assign trap_thr[3] =  trap_tid_w2[1] &  trap_tid_w2[0];
 
   assign load_tpc[3:0] = {4{trappc_vld_w2}} & trap_thr |
	                   rb_w2 |
	                   {4{rb_stg_w | ims_flush_coll_w}} & thr_w |
//                     {4{dec_fcl_kill4sta_e}} & thr_e |
	                   {4{flush_sonly_qual_m}} & thr_m;
 
   assign load_bpc[3:0] = {4{brtaken_buf_e}} & thr_e;
   assign load_pcp4[3:0] = {4{~part_stall_thisthr_f &
                              ~iferrto_thisthr_d1 |
                              arst_vld_f |
                              async_intr_vld_s}}     & thr_f;
 
   always @ (/*AUTOSENSE*/load_bpc or load_pcp4 or load_tpc)
     begin
//	      if (fcl_reset)
//	        begin // RESET PC is loaded to T0
//	           fcl_fdp_tpcbf_sel_old_bf_l = 4'b0001;
//	           fcl_fdp_tpcbf_sel_pcp4_bf_l = 4'b1110;
//	           fcl_fdp_tpcbf_sel_trap_bf_l = 4'b1111;
//	           fcl_fdp_tpcbf_sel_brpc_bf_l = 4'b1111;
//	        end // if (reset)
//	      else 
//	        begin
	      fcl_fdp_tpcbf_sel_old_bf_l = (load_bpc | load_tpc | load_pcp4);
	      fcl_fdp_tpcbf_sel_brpc_bf_l = ~load_bpc | load_tpc | load_pcp4;
	      fcl_fdp_tpcbf_sel_pcp4_bf_l = ~load_pcp4 | load_tpc;
	      fcl_fdp_tpcbf_sel_trap_bf_l = ~load_tpc;
     end // always @ (...
 
   // Track correctible errors
   assign irf_ce_m = exu_ifu_ecc_ce_m & ~trap_m & inst_vld_m & ~kill_curr_m;
   dff_s #(1) irfcew_ff(.din (irf_ce_m),
		                .q   (irf_ce_w),
		                .clk (clk), .se(se), .si(), .so());
 
   // track if ldhit was actually a miss
   // D and S stage are rolled back through the normal D stage retract
   // process.  
   assign mark4rb_d = lsu_ifu_dc_parity_error_w2 & thr_match_dw2 & 
                      (inst_vld_d | intr_vld_d);
   assign mark4rb_s = lsu_ifu_dc_parity_error_w2 & thr_match_fw2 & 
                      (inst_vld_s | intr_vld_s);
 
   assign mark4rb_e = lsu_ifu_dc_parity_error_w2 & thr_match_ew2 & 
                      (inst_vld_e | intr_vld_e) & 
                        ~dtu_inst_anull_e & ~kill_curr_e;
 
   dff_s #(2) markrb_reg(.din ({mark4rb_m,
                              mark4rb_e}),
                       .q   ({mark4rb_w,
                              mark4rb_m}),
                       .clk (clk),
                       .se  (se), .si(), .so());
 
   // Rollback from W on irf/frf ce and on a dcache parity error
   assign rb_stg_w = irf_ce_w & inst_vld_w & no_iftrap_w | 
	                   ffu_ifu_fst_ce_w & inst_vld_w & no_iftrap_w |
                     rb_intr_w & intr_vld_w |
                     mark4rb_w |
                     fcl_dtu_resum_thr_w | 
		                 fcl_dtu_nuke_thr_w;
 
   // flush after hardware micro trap
//   assign ifu_tlu_flush_w = irf_ce_w | fcl_dtu_nuke_thr_w | mark4rb_w |
//                            fcl_dtu_resum_thr_w;
   // very critical
   assign ifu_tlu_flush_m = (exu_ifu_ecc_ce_m & inst_vld_m & ~trap_m |
                             (resumint_m | nuke_thr_m) & 
                             intr_vld_m & ~rstint_m |
                             rb_intr_m | 
                             mark4rb_m);
   assign utrap_flush_m =  ifu_tlu_flush_m & ~kill_local_m;
   dff_s #(1) flw_ff(.din (utrap_flush_m),
                   .q   (utrap_flush_w),
                   .clk (clk), .se(se), .si(), .so());
   assign ifu_tlu_flush_w = utrap_flush_w;
   assign fcl_swl_flush_w =  (irf_ce_w & inst_vld_w & no_iftrap_w | 
                              rb_intr_w & intr_vld_w |
                              mark4rb_w |
                              fcl_dtu_resum_thr_w | 
		                          fcl_dtu_nuke_thr_w);
 
   // tells swl to flush and then wake up
   assign fcl_swl_flush_wake_w = fcl_swl_flush_w & ~mark4rb_w;
 
   // if the same instruction keeps hitting ce's disable ce detection
   // count how many ce's occur to a given thread
   assign any_ce_w = ffu_ifu_fst_ce_w | irf_ce_w;
 
   assign ce_cnt1_nxt = (({4{any_ce_w & inst_vld_w}} & thr_w & 
                          ce_cnt0) ^ ce_cnt1) & ~ce_cnt_rst;
   assign ce_cnt0_nxt = (({4{any_ce_w & inst_vld_w}} & thr_w) ^ 
                         ce_cnt0) & ~ce_cnt_rst;
 
   assign ce_cnt_rst = thr_w & {4{inst_vld_w & ~any_ce_w}} | {4{fcl_reset}};
 
   dff_s #(8) cecnt_reg(.din ({ce_cnt1_nxt, ce_cnt0_nxt}),
                      .q   ({ce_cnt1, ce_cnt0}),
                      .clk (clk),
                      .se(se), .si(), .so());
 
   // find the count for the current d stage thread
   assign ce_val1_d = (thr_d[0] & ce_cnt1[0] | 
                       thr_d[1] & ce_cnt1[1] | 
                       thr_d[2] & ce_cnt1[2] | 
                       thr_d[3] & ce_cnt1[3]);
 
   assign ce_val0_d = (thr_d[0] & ce_cnt0[0] | 
                       thr_d[1] & ce_cnt0[1] | 
                       thr_d[2] & ce_cnt0[2] | 
                       thr_d[3] & ce_cnt0[3]);
 
   // if count hits 3 disable ce's
   assign disable_ce_d = ce_val1_d & ce_val0_d;
 
   dff_s #(1) disce_ff(.din (disable_ce_d),
                     .q   (disable_ce_e),
                     .clk (clk), .se(se), .si(), .so());
   assign ifu_exu_disable_ce_e = disable_ce_e;
 
   // select error/trap/utrap rollback PC
   assign fcl_fdp_trrbpc_sel_trap_bf_l = 
		                ~({4{trappc_vld_w2}} & trap_thr);
 
   assign fcl_fdp_trrbpc_sel_err_bf_l = 
                  ({4{trappc_vld_w2}} & trap_thr) |
	                 ~({4{rb_stg_w}} & thr_w);
 
   assign fcl_fdp_trrbpc_sel_rb_bf_l = 
                  ({4{trappc_vld_w2}} & trap_thr) |
		               ({4{rb_stg_w}} & thr_w) |		   
	                ~(rb_frome & rb_fromd);
 
   assign fcl_fdp_trrbpc_sel_pcs_bf_l = 
                 ({4{trappc_vld_w2}} & trap_thr) | 
		               ({4{rb_stg_w}} & thr_w) |		   
	                 (rb_frome & rb_fromd);
 
   // select next S stage Thr PC
   assign fcl_fdp_nextpcs_sel_pce_f_l = ~rb_frome;
   assign fcl_fdp_nextpcs_sel_pcd_f_l = rb_frome | ~rb_fromd;
   assign fcl_fdp_nextpcs_sel_pcf_f_l = rb_frome | rb_fromd |
	                                ~(thr_f & {4{~part_stall_thisthr_f &
                                               ~iferrto_thisthr_d1 |
                                               arst_vld_f |
                                               async_intr_vld_s}});
   assign fcl_fdp_nextpcs_sel_pcs_f_l = rb_frome | rb_fromd | 
	                                (thr_f & {4{~part_stall_thisthr_f &
                                              ~iferrto_thisthr_d1 |
                                              arst_vld_f |
                                              async_intr_vld_s}});
 
   // next S2 stage pc and npc select
   assign thr_f_dec[3:1] = thr_f_crit[3:1] & {3{~rst_tri_en}};
   assign thr_f_dec[0] = thr_f_crit[0] | rst_tri_en;
   assign fcl_fdp_thr_s2_l = ~thr_f_dec;     // thr_f = thr_s2
 
 
   // Select NextPC from
   //    1. Trap NextPC (if the tnpc is valid)
   //    2. reset PC
   //    3. incremented PC (PC+4)
   //    4. old PC (in the event of a stall)
 
   // Load the trap PC to the BF stage NPC.  (The BF stage NPC is used
   // only for storing the next PC from the TLU
   assign fcl_fdp_thrtnpc_sel_tnpc_l = ~({4{trapnpc_vld_w2}} & trap_thr);
 
   assign fcl_fdp_thrtnpc_sel_npcw_l = ({4{trapnpc_vld_w2}} & trap_thr) |
	                                       ~({4{rb_stg_w}} & thr_w);
 
   assign fcl_fdp_thrtnpc_sel_pcf_l = ({4{trapnpc_vld_w2}} & trap_thr) |
	                                      ({4{rb_stg_w}} & thr_w) |
	                                        (~({4{ims_flush_coll_w}} & thr_w) &
                                           ~({4{flush_sonly_qual_m}} & thr_m));
                                       //   {4{dec_fcl_kill4sta_e}} & thr_e);
 
   assign fcl_fdp_thrtnpc_sel_old_l = ({4{trapnpc_vld_w2}} & trap_thr) |
	                                      ({4{rb_stg_w}} & thr_w) |
	                                      ({4{ims_flush_coll_w}} & thr_w) |
                                        ({4{flush_sonly_qual_m}} & thr_m);
                                         // {4{dec_fcl_kill4sta_e}} & thr_e);
 
   assign ntpc_vld_nxt = fcl_fdp_thrtnpc_sel_old_l | 
	                       ntpc_vld & ({4{(part_stall_thisthr_f |
                                         iferrto_thisthr_d1) & 
                                        ~arst_vld_f &
                                        ~async_intr_vld_s}} | ~thr_f) &
                                  ~({4{trappc_vld_w2}} & trap_thr);
 
   dffr_s #(4) ntpcv_reg(.din  (ntpc_vld_nxt),
		     .clk  (clk),
		     .q    (ntpc_vld),
		     .rst  (fcl_reset),
		     .se   (se), .si(), .so());
 
   assign ntpc_thisthr = (thr_f[0] & ntpc_vld[0] |
			                    thr_f[1] & ntpc_vld[1] |
			                    thr_f[2] & ntpc_vld[2] |
			                    thr_f[3] & ntpc_vld[3]);
 
//   assign fcl_fdp_noswpc_sel_rst_l_bf = 1'b1; 
   assign fcl_fdp_noswpc_sel_tnpc_l_bf = ~ntpc_thisthr;
   assign fcl_fdp_noswpc_sel_old_l_bf = ntpc_thisthr | inst_vld_f | arst_vld_f;
   assign fcl_fdp_noswpc_sel_inc_l_bf = ntpc_thisthr | ~inst_vld_f & ~arst_vld_f;
 
 
   // Don't need noswpc_sel_old anymore (this is always 1)
//   always @(/*AUTOSENSE*/ntpc_vld or reset or thr_f)
//     begin
//	      if (reset)
//	        begin
//	           fcl_fdp_noswpc_sel_tnpc_l_bf = 1'b1;
//	           fcl_fdp_noswpc_sel_rst_l_bf = 1'b0;	
//	           fcl_fdp_noswpc_sel_inc_l_bf = 1'b1;
//	           fcl_fdp_noswpc_sel_old_l_bf = 1'b1;
//	        end
//	      else if ((ntpc_vld & thr_f) != 4'b0000)
//	        begin
//	           fcl_fdp_noswpc_sel_tnpc_l_bf = 1'b0;
//	           fcl_fdp_noswpc_sel_rst_l_bf = 1'b1;	
//	           fcl_fdp_noswpc_sel_inc_l_bf = 1'b1;
//	           fcl_fdp_noswpc_sel_old_l_bf = 1'b1;	
//	        end // if ((ntpc_vld & thr_f) != 4'b0000)
////	else if (ely_stall_thisthr_f)
////	  begin
////	     fcl_fdp_noswpc_sel_tnpc_l_bf = 1'b1;
////	     fcl_fdp_noswpc_sel_rst_l_bf = 1'b1;	
////	     fcl_fdp_noswpc_sel_inc_l_bf = 1'b1;
////	     fcl_fdp_noswpc_sel_old_l_bf = 1'b0;	     
////	  end // if (ely_stall_thisthr_f)
//	      else 
//	        begin
//	           fcl_fdp_noswpc_sel_tnpc_l_bf = 1'b1;
//	           fcl_fdp_noswpc_sel_rst_l_bf = 1'b1;	
//	           fcl_fdp_noswpc_sel_inc_l_bf = 1'b0;
//	           fcl_fdp_noswpc_sel_old_l_bf = 1'b1;	
//	        end // else: 
//	      
//     end // always @ (...
 
   // NOTE: direct branch vs indirect branch select goes from dtu to fdp
 
//----------------------------------------------------------------------
// Instruction Register Related Control
//----------------------------------------------------------------------
 
   // use NIR if no read previously
   assign fcl_fdp_usenir_sel_nir_s1 = usenir_s1;
 
 
   assign  fcl_fdp_inst_sel_nop_s_l = ~(ely_stall_thisthr_f | 
                                        ~inst_vld_s_crit | 
                                        force_intr_s | 
                                        immu_fault_f);
 
   assign  fcl_fdp_inst_sel_switch_s_l = ~switch_s2 |
                                        (ely_stall_thisthr_f | 
                                         ~inst_vld_s_crit | 
                                         force_intr_s | 
                                         immu_fault_f);
 
   assign  fcl_fdp_inst_sel_nir_s_l = ~usenir_s1 |
                                        (switch_s2 |
                                         ely_stall_thisthr_f | 
                                         ~inst_vld_s_crit | 
                                         force_intr_s | 
                                         immu_fault_f);
 
   assign  fcl_fdp_inst_sel_curr_s_l = (usenir_s1 |
                                        switch_s2 |
                                        ely_stall_thisthr_f | 
                                        ~inst_vld_s_crit | 
                                        force_intr_s | 
                                        immu_fault_f);
 
 
   // Instruction Output Mux
//   always @ (/*AUTOSENSE*/ely_stall_thisthr_f or force_intr_s
//             or immu_fault_f or inst_vld_s_crit or switch_s2
//             or usenir_s1)
//     begin
//	      if (ely_stall_thisthr_f | ~inst_vld_s_crit | force_intr_s | 
//            immu_fault_f) 
//	        begin // stalled or imiss
//	           fcl_fdp_inst_sel_nop_s_l = 1'b0;
//	           fcl_fdp_inst_sel_switch_s_l = 1'b1;
//	           fcl_fdp_inst_sel_nir_s_l = 1'b1;
//	           fcl_fdp_inst_sel_curr_s_l = 1'b1;
//	        end
//	      else if (switch_s2) 
//	        begin
//	           fcl_fdp_inst_sel_nop_s_l = 1'b1;
//	           fcl_fdp_inst_sel_switch_s_l = 1'b0;
//	           fcl_fdp_inst_sel_nir_s_l = 1'b1;
//	           fcl_fdp_inst_sel_curr_s_l = 1'b1;
//	        end
//	      else if (usenir_s1) 
//	        begin
//	           fcl_fdp_inst_sel_nop_s_l = 1'b1;
//	           fcl_fdp_inst_sel_switch_s_l = 1'b1;
//	           fcl_fdp_inst_sel_nir_s_l = 1'b0;
//	           fcl_fdp_inst_sel_curr_s_l = 1'b1;
//	        end
//	      else
//	        begin
//	           fcl_fdp_inst_sel_nop_s_l = 1'b1;
//	           fcl_fdp_inst_sel_switch_s_l = 1'b1;
//	           fcl_fdp_inst_sel_nir_s_l = 1'b1;
//	           fcl_fdp_inst_sel_curr_s_l = 1'b0;
//	        end // else: !if(switch_s2 | stall_s1)
//     end // always @ (...
 
   // thread IR input muxes
   assign fcl_fdp_tinst_sel_rb_s_l   = ~rb_w2;
   assign fcl_fdp_tinst_sel_ifq_s_l  = rb_w2 | ~ifq_fcl_fill_thr;
   assign fcl_fdp_tinst_sel_curr_s_l = ~val_thr_s1 | rb_w2 | ifq_fcl_fill_thr; 
   assign fcl_fdp_tinst_sel_old_s_l  = val_thr_s1 | rb_w2 | ifq_fcl_fill_thr; 
 
   // Select rollback instruction
   assign fcl_fdp_rbinst_sel_inste_s = {4{rb2_inst_e | rt2_inst_e}} & 
                                       thr_e;
 
   // thread NIR input muxes  (2:1 no need to protect)
   assign fcl_fdp_thr_s1_l = ~thr_s1 | {4{stall_s1}};
 
   // select appropriate NIR
   assign dec_thr_s1_l[0] = ~(thr_s1[0] | rst_tri_en);
   assign dec_thr_s1_l[3:1] = ~(thr_s1[3:1] & {3{~rst_tri_en}});
 
   assign fcl_fdp_nirthr_s1_l = dec_thr_s1_l; 
 
 
//--------------------
// rdsr data to exu
//--------------------   
 
   dff_s #(1) pcrsr_ff(.din  (dec_fcl_rdsr_sel_pc_d),
		               .clk  (clk),
		               .q    (rdsr_sel_pc_e),
		               .se   (se), .si(), .so());
   dff_s #(1) thrrsr_ff(.din  (dec_fcl_rdsr_sel_thr_d),
		                .clk  (clk),
		                .q    (rdsr_sel_thr_e),
		                .se   (se), .si(), .so());
   // make sure they are exclusive
   assign fcl_fdp_rdsr_sel_pc_e_l = ~rdsr_sel_pc_e;
   assign fcl_fdp_rdsr_sel_thr_e_l = ~(~rdsr_sel_pc_e & rdsr_sel_thr_e);
   assign fcl_fdp_rdsr_sel_ver_e_l = ~(~rdsr_sel_pc_e & ~rdsr_sel_thr_e);
 
//--------------------------------------------------------------
// Reg file control
//--------------------------------------------------------------
 
// Some decode is done here since these signals are in the crit path
 
   // Regfile enables are only power saving features.  So they don't
   // have to be exact, as long as they are on, a super set of when
   // they need to be on.
 
   // Enable rs3 if store or atomic or mov
   assign ifu_exu_ren3_s =  inst_vld_f & fdp_fcl_op_s[1] & fdp_fcl_op3_s[2] &
	                    (fdp_fcl_op_s[0] | fdp_fcl_op3_s[5]);
 
   // enable rs2 if i=0 and !branch or CAS
   // cas not fully decoded;  i=inst[13];
   assign ifu_exu_ren2_s = inst_vld_f & fdp_fcl_op_s[1] &
			    (~fdp_fcl_ibit_s | 
			     fdp_fcl_op_s[0] & fdp_fcl_op3_s[5]);
 
   // rs1 is read if this is not (a branch on cc or no-op/sethi)
   assign ifu_exu_ren1_s = inst_vld_f & (fdp_fcl_op_s[1] |     // not br/call
			   fdp_fcl_op3_s[4] & fdp_fcl_op3_s[3]);  // BPR
 
   //-------------------------------------
   // Generate oddwin signal for rs and rd
   //-------------------------------------
   assign fcl_fdp_oddwin_s = (exu_ifu_oddwin_s[0] & thr_f[0] |
                              exu_ifu_oddwin_s[1] & thr_f[1] |
                              exu_ifu_oddwin_s[2] & thr_f[2] |
                              exu_ifu_oddwin_s[3] & thr_f[3]);
 
   dff_s #(1) oddwin_ff(.din (fcl_fdp_oddwin_s),
		                  .clk (clk),
		                  .q   (fcl_imd_oddwin_d),
		                  .se  (se), .si(), .so());
 
 
   sink #(2) s0(.in (sas_thrid_w));
endmodule // sparc_ifu_fcl
 

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

powered by: WebSVN 2.1.0

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