// ========== 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