// ========== Copyright Header Begin ========================================== // // OpenSPARC T2 Processor File: lsu_lmc_ctl.v // Copyright (C) 1995-2007 Sun Microsystems, Inc. All Rights Reserved // 4150 Network Circle, Santa Clara, California 95054, U.S.A. // // * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This 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 program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // For the avoidance of doubt, and except that if any non-GPL license // choice is available it will apply instead, Sun elects to use only // the General Public License version 2 (GPLv2) at this time for any // software where a choice of GPL license versions is made // available with the language indicating that GPLv2 or any later version // may be used, or where a choice of which version of the GPL is applied is // otherwise unspecified. // // Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, // CA 95054 USA or visit www.sun.com if you need additional information or // have any questions. // // ========== Copyright Header End ============================================ module lsu_lmc_ctl ( l2clk, scan_in, tcu_pce_ov, tcu_scan_en, spc_aclk, spc_bclk, scan_out, dcc_tid_m, dcc_ld_inst_vld_m, dcc_pref_inst_m, dcc_ld_miss_b, dcc_ld_miss_ldd, dcc_asi_load_b, dcc_asi_iomap_b, dcc_blk_inst_b, dcc_ldbl_b, dcc_ncache_b, dcc_ld_miss_ctl_b43, dcc_atomic_b, dcc_casa_inst_b, dcc_lsu_asi_rd_b, dcc_lsu_asi_sel_w, dcc_ceter_wr_w, dcc_stb_diag_sel_w3, dcc_exception_flush_b, dcc_perror_b, dcc_sync_pipe_w, dcc_cache_diag_wr_b, dcc_asi_rtn_vld, dcc_asi_rtn_excp, dcc_asi_rtn_rd, pic_casa_squash_req, pic_early_ld_b_sel_p3, pic_no_load_p3, pic_asi_busy, lmd_pcx_pref, lmd_asi_ld, lmd_asi_indet, lmd_sec_cmp_b, lmd_addrb2, lmd_sz_b1, lmd_sz_b0, lmd_ldbl, lmd_rd_e, lmd_dc_err_e, lmd_fill_addr_b3_e, lmd_fill_sz_b0_e, tlb_pgnum_b39, tlb_cam_mhit, tlu_flush_lsu_b, tlu_cerer_sbdlc, tlu_cerer_sbdlu, tlu_cerer_dcl2c, tlu_cerer_dcl2u, tlu_cerer_dcl2nd, tlu_cerer_l2c_socc, tlu_cerer_l2u_socu, dec_flush_lm, dec_flush_lb, dec_ld_inst_d, cic_l2fill_vld_e, cic_cpq_ld_rdy, cic_cpq_ld_rdy_, cic_div_stall_d, cic_oddrd_e, cic_xinval_e, cic_xinval, cic_set_inval, cic_rtn_cmplt, cic_cpq_stall, cic_ext_interrupt, cid_tid, cid_err, cid_dcsoc_err_e, cid_l2miss, stb_cam_hit, stb_cam_mhit, stb_ld_part_raw, stb_cecc_err, stb_uecc_err, sbd_st_data_b_62, sbs_all_commited, sbc_st_atom_p3, sbc_rawp_rst, sbc_st_sel_tid_p4, sbc_force_inv, sbc_kill_store_p4_, lsu_lsu_pmen, lmc_lmq_enable_b, lmc_pcx_sel_p4, lmc_pcx_rq_vld, lmc_asi_rq_vld, lmc_ld_rq_p3, lmc_ld_vld_p4, lmc_ld_no_req_p4, lmc_ld_inv_p4, lmc_ld_tid, lmc_byp_sel_e, lmc_cpq_tid_m, lmc_lmq_bypass_en, lmc_asi_bypass_m, lmc_bld_addr54, lmc_bld_req, lmc_bld_req_, lmc_bld_annul, lmc_bld_miss_e, lmc_bld_last_e, lmc_rd_update, lmc_pref_issued, lmc_ldd_vld, lmc_ld_unfilled, lmc_lmd_ncache_b, lmc_ld_sz, lmc_ld_inst_w, lmc_full_raw_w, lmc_ld_stall, lmc_l2_err_noup, lmc_l2_uerr, lmc_byp_data_hi, lmc_byp_data_enable, lmc_thrd_byp_sel_e, lmc_thrd_byp_sel_m, lmc_byp_tid_m, lmc_byp_vld_m, lmc_lmq0_byp_sel, lmc_lmq1_byp_sel, lmc_lmq2_byp_sel, lmc_lmq3_byp_sel, lmc_lmq4_byp_sel, lmc_lmq5_byp_sel, lmc_lmq6_byp_sel, lmc_lmq7_byp_sel, lmc_asi_indet_retire, lsu_ifu_no_miss, lsu_dcmh_err_g, lsu_dcvp_err_g, lsu_dctp_err_g, lsu_dcdp_err_g, lsu_dcerr_tid_g, lsu_dcl2c_err_g, lsu_dcl2u_err_g, lsu_dcl2nd_err_g, lsu_sbdlc_err_g, lsu_sbdlu_err_g, lsu_stberr_tid_g, lbist_run, mbi_run, lmc_mbi_run, lmc_bist_or_diag_e); wire se; wire pce_ov; wire stop; wire siclk; wire soclk; wire l1clk; wire rqpend_clken; wire l1clk_pm1; wire [7:0] cpq_mx_thread; wire [7:0] ceter_pscce_in; wire [7:0] thread_w; wire st_data_w_62; wire [7:0] ceter_pscce_reg; wire dff_ceter_scanin; wire dff_ceter_scanout; wire ceter_pscce_cpq; wire ceter_pscce_w3; wire [7:0] thread_w3; wire dff_cerer_scanin; wire dff_cerer_scanout; wire cerer_sbdlc; wire cerer_sbdlu; wire cerer_dcl2c; wire cerer_dcl2u; wire cerer_dcl2nd; wire cerer_socc; wire cerer_socu; wire [7:0] thread_b; wire [2:0] tid_b; wire dff_thread_w_scanin; wire dff_thread_w_scanout; wire dff_flush_b_scanin; wire dff_flush_b_scanout; wire local_flush_b; wire flush_b; wire excep_only_flush_b; wire dff_flush_w_scanin; wire dff_flush_w_scanout; wire flush_w; wire perror_w; wire dff_inst_b_scanin; wire dff_inst_b_scanout; wire ld_inst_vld_b; wire pref_inst_b; wire blk_inst_w; wire dff_inst_w_scanin; wire dff_inst_w_scanout; wire pref_inst_w; wire excep_only_flush_w; wire [7:0] load_lmq_entry; wire dff_l2fill_scanin; wire dff_l2fill_scanout; wire l2fill_vld_m; wire [7:0] ld_fill; wire [7:0] ld_unfilled_in; wire [7:0] ld_unfilled; wire dff_unfilled_scanin; wire dff_unfilled_scanout; wire [7:0] ld_unfilled_out; wire [7:0] ld_pcx_vld_set; wire ncache_w; wire ld_sec_hit_b; wire tlb_pgnum_b39_b; wire stb_cam_hit_b; wire stb_cam_mhit_b; wire stb_ld_part_raw_b; wire dff_stb_raw_scanin; wire dff_stb_raw_scanout; wire stb_cam_hit_w; wire stb_cam_mhit_w; wire stb_ld_part_raw_w; wire tlb_pgnum_b39_w; wire ldbl_w; wire ld_full_raw_w; wire ld_part_raw_w; wire ld_rawp_disabled_asi_b; wire [7:0] ld_rawp_disabled_in; wire [7:0] ld_rawp_disabled; wire dff_rawp_disable_scanin; wire dff_rawp_disable_scanout; wire ld_rawp_disabled_asi_w; wire [7:0] ld_rawp_disabled_out; wire [7:0] ld_rawp_disabled_set; wire [7:0] ldd_vld_in; wire dff_ldd_vld_scanin; wire dff_ldd_vld_scanout; wire lmq_vld_enable_b; wire lmq_vld_cancel_b; wire dff_ld_lmq_en_b_scanin; wire dff_ld_lmq_en_b_scanout; wire lmq_vld_enable_w_pre; wire lmq_vld_cancel_w_pre; wire lmq_vld_cancel_w; wire lmq_vld_enable_w; wire [7:0] ld_pcx_vld_rst; wire [7:0] ld_pcx_commit; wire [7:0] kill_pcx_ld_req; wire [7:0] bld_hold; wire [7:0] perr_inv; wire [7:0] ld_pcx_vld_in; wire [7:0] ld_pcx_vld; wire dff_ld_pcx_vld_scanin; wire dff_ld_pcx_vld_scanout; wire [7:0] ld_pcx_vld_out; wire ld_asi_vld_set_b; wire [7:0] ld_asi_vld_set; wire ld_asi_vld_set_w; wire [7:0] ld_asi_vld_in; wire [7:0] ld_asi_vld_rst; wire [7:0] ld_asi_vld; wire dff_ld_asi_vld_scanin; wire dff_ld_asi_vld_scanout; wire [7:0] ld_asi_vld_out; wire early_ld_cancel_w; wire [7:0] ld_pcx_rq_vld; wire early_ld_b_sel_p4; wire block_ldd_req; wire [7:0] ld_asi_rq_vld; wire asi_indet_block; wire [7:0] ld_rq_vld; wire [7:0] load_miss_w; wire ld_inst_unflushed_w; wire ld_inst_vld_w; wire lru8_scanin; wire lru8_scanout; wire [7:0] ld_rq_sel; wire [7:0] ld_pcx_rq_sel; wire [7:0] ld_asi_rq_sel; wire ld_pcx_sel_p3; wire ld_asi_sel_p3; wire [7:0] ld_early_rq_sel; wire [7:0] ld_all_rq_sel; wire [7:0] st_atom_p4_dec; wire dff_ld_sel_scanin; wire dff_ld_sel_scanout; wire [7:0] ld_all_sel_p4; wire ld_pcx_sel_p4; wire [3:0] ldd_count_p1; wire [3:0] ldd_count; wire [3:0] ldd_count_m1; wire inc_ldd_count_pre; wire dec_ldd_count; wire [3:0] ldd_count_in; wire inc_ldd_count; wire dff_ldd_out_scanin; wire dff_ldd_out_scanout; wire cpq_stall; wire casa_ld_to_pcx; wire [3:0] st_atom_p3; wire casa_bypass_d; wire dff_st_atom_p4_scanin; wire dff_st_atom_p4_scanout; wire [3:0] st_atom_p4; wire casa_bypass_e; wire [3:0] st_atom_p4_in; wire dff_st_atom_p5_scanin; wire dff_st_atom_p5_scanout; wire asi_indet_sel; wire asi_indet_retire; wire asi_indet_in; wire dff_asi_indet_scanin; wire dff_asi_indet_scanout; wire dff_cpq_tid_scanin; wire dff_cpq_tid_scanout; wire ld_inst_nopref_b; wire dff_ld_raw_w_scanin; wire dff_ld_raw_w_scanout; wire ld_inst_nopref_w; wire [2:0] tid_w; wire ld_raw_bypass_w; wire dff_ld_raw_w2_scanin; wire dff_ld_raw_w2_scanout; wire ld_raw_bypass_w2; wire [2:0] tid_w2; wire dff_ld_raw_w3_scanin; wire dff_ld_raw_w3_scanout; wire ld_raw_bypass_w3; wire [2:0] tid_w3; wire sbdlc_err; wire sbdlu_err; wire [7:0] lmq_bypass_vld; wire [7:0] ldbyp_vld_en; wire [7:0] ldbyp_rst; wire [7:0] ldbyp_vld; wire dff_ldbyp_vld_scanin; wire dff_ldbyp_vld_scanout; wire ld_bypass_ok_d; wire dff_ld_inst_e_scanin; wire dff_ld_inst_e_scanout; wire ld_bypass_ok_e; wire byp_cnt_rst; wire [2:0] byp_cnt_in; wire [2:0] byp_cnt; wire dff_byp_cnt_scanin; wire dff_byp_cnt_scanout; wire ld_bypass_e; wire byp_vld_e; wire [7:0] thrd_byp_sel_e; wire dff_thrd_byp_sel_m_scanin; wire dff_thrd_byp_sel_m_scanout; wire [7:0] thrd_byp_sel_m; wire [7:0] bld_inst_w; wire [7:0] bld_pending; wire [7:0] bld_pend_hold; wire [7:0] bld_pending_in; wire [7:0] bld_reset; wire dff_bld_pending_scanin; wire dff_bld_pending_scanout; wire [1:0] bld_addr54_p3; wire [1:0] bld_cnt0; wire [1:0] bld_cnt1; wire [1:0] bld_cnt2; wire [1:0] bld_cnt3; wire [1:0] bld_cnt4; wire [1:0] bld_cnt5; wire [1:0] bld_cnt6; wire [1:0] bld_cnt7; wire bld_req_p3; wire dff_bld_addr_scanin; wire dff_bld_addr_scanout; wire [1:0] bld_cnt0_in; wire inc_bld0_cnt; wire dff_bld_cnt0_scanin; wire dff_bld_cnt0_scanout; wire [1:0] bld_cnt1_in; wire inc_bld1_cnt; wire dff_bld_cnt1_scanin; wire dff_bld_cnt1_scanout; wire [1:0] bld_cnt2_in; wire inc_bld2_cnt; wire dff_bld_cnt2_scanin; wire dff_bld_cnt2_scanout; wire [1:0] bld_cnt3_in; wire inc_bld3_cnt; wire dff_bld_cnt3_scanin; wire dff_bld_cnt3_scanout; wire [1:0] bld_cnt4_in; wire inc_bld4_cnt; wire dff_bld_cnt4_scanin; wire dff_bld_cnt4_scanout; wire [1:0] bld_cnt5_in; wire inc_bld5_cnt; wire dff_bld_cnt5_scanin; wire dff_bld_cnt5_scanout; wire [1:0] bld_cnt6_in; wire inc_bld6_cnt; wire dff_bld_cnt6_scanin; wire dff_bld_cnt6_scanout; wire [1:0] bld_cnt7_in; wire inc_bld7_cnt; wire dff_bld_cnt7_scanin; wire dff_bld_cnt7_scanout; wire [7:0] bld_annul_rst; wire [7:0] bld_annul_in; wire [7:0] bld_annul; wire dff_bld_bypass_scanin; wire dff_bld_bypass_scanout; wire block_load_annul; wire [7:0] bld_miss_set; wire [7:0] bld_miss_in; wire [7:0] bld_miss; wire report_and_clear_error; wire [7:0] bld_miss_out; wire bld_pass7; wire dff_bld_miss_scanin; wire dff_bld_miss_scanout; wire bld_pass7_done; wire [7:0] pref_issued; wire dff_pref_issued_scanin; wire dff_pref_issued_scanout; wire [7:0] perr_set; wire [7:0] perr_inv_in; wire dff_perr_scanin; wire dff_perr_scanout; wire ld_inv_p3; wire [7:0] perr_inv_out; wire ld_inv_p4; wire lsu_dcvp_err_e2; wire lsu_dctp_err_e2; wire lsu_dcmh_err_e2; wire lsu_dcdp_err_e2; wire dff_dcerr_scanin; wire dff_dcerr_scanout; wire [1:0] l2_err; wire [1:0] l2_err0; wire [1:0] l2_err1; wire [1:0] l2_err2; wire [1:0] l2_err3; wire [1:0] l2_err4; wire [1:0] l2_err5; wire [1:0] l2_err6; wire [1:0] l2_err7; wire [1:0] l2_err_qual; wire [1:0] l2_err_new; wire [1:0] l2_err0_in; wire [1:0] l2_err1_in; wire [1:0] l2_err2_in; wire [1:0] l2_err3_in; wire [1:0] l2_err4_in; wire [1:0] l2_err5_in; wire [1:0] l2_err6_in; wire [1:0] l2_err7_in; wire dff_l2errcode_scanin; wire dff_l2errcode_scanout; wire dcl2c_err; wire dcl2u_err; wire dcl2nd_err; wire dff_l2err_scanin; wire dff_l2err_scanout; wire [2:0] stberr_tid; wire dff_stberr_scanin; wire dff_stberr_scanout; wire [7:0] xinval_pend_in; wire [7:0] xinval_pend; wire cpq_xinval_m; wire dff_xinval_pend_scanin; wire dff_xinval_pend_scanout; wire dff_bist_diag_scanin; wire dff_bist_diag_scanout; wire bist_or_diag_d; wire spares_scanin; wire spares_scanout; wire [4:0] unused; // Globals input l2clk; input scan_in; input tcu_pce_ov; // scan signals input tcu_scan_en; input spc_aclk; input spc_bclk; output scan_out; input [2:0] dcc_tid_m; input dcc_ld_inst_vld_m; input dcc_pref_inst_m; input dcc_ld_miss_b; // A load that needs to go to L2 input dcc_ld_miss_ldd; input dcc_asi_load_b; input dcc_asi_iomap_b; input dcc_blk_inst_b; // Block load instruction in B input dcc_ldbl_b; input dcc_ncache_b; // Non-cacheable ldst in B input dcc_ld_miss_ctl_b43; // Non-cacheable request to pcx input dcc_atomic_b; input dcc_casa_inst_b; input dcc_lsu_asi_rd_b; input dcc_lsu_asi_sel_w; input dcc_ceter_wr_w; input dcc_stb_diag_sel_w3; input dcc_exception_flush_b; input dcc_perror_b; input dcc_sync_pipe_w; input dcc_cache_diag_wr_b; input [7:0] dcc_asi_rtn_vld; input dcc_asi_rtn_excp; input dcc_asi_rtn_rd; input pic_casa_squash_req; // No loads can request this cycle input pic_early_ld_b_sel_p3; // The load in B is going to the pcx input pic_no_load_p3; // Load cannot issue in P3 input pic_asi_busy; // ASI ring cannot accept a request input lmd_pcx_pref; input [7:0] lmd_asi_ld; input [7:0] lmd_asi_indet; input [7:0] lmd_sec_cmp_b; // secondary hit compare results input lmd_addrb2; input lmd_sz_b1; input lmd_sz_b0; input lmd_ldbl; input [2:1] lmd_rd_e; input [1:0] lmd_dc_err_e; input lmd_fill_addr_b3_e; input lmd_fill_sz_b0_e; input tlb_pgnum_b39; input tlb_cam_mhit; input tlu_flush_lsu_b; // Flush the instruction in B input tlu_cerer_sbdlc; input tlu_cerer_sbdlu; input tlu_cerer_dcl2c; input tlu_cerer_dcl2u; input tlu_cerer_dcl2nd; input tlu_cerer_l2c_socc; input tlu_cerer_l2u_socu; input dec_flush_lm; // Flush the instruction in M input dec_flush_lb; // Flush the instruction in B input dec_ld_inst_d; input cic_l2fill_vld_e; input cic_cpq_ld_rdy; input cic_cpq_ld_rdy_; input cic_div_stall_d; input cic_oddrd_e; input cic_xinval_e; // xinval is being processed input [7:0] cic_xinval; // xinval arrived for a thread input cic_set_inval; input cic_rtn_cmplt; input cic_cpq_stall; input cic_ext_interrupt; input [2:0] cid_tid; input [1:0] cid_err; input cid_dcsoc_err_e; input cid_l2miss; input stb_cam_hit; input stb_cam_mhit; input stb_ld_part_raw; input stb_cecc_err; input stb_uecc_err; input sbd_st_data_b_62; input [7:0] sbs_all_commited; input [7:0] sbc_st_atom_p3; input [7:0] sbc_rawp_rst; input [2:0] sbc_st_sel_tid_p4; input sbc_force_inv; input sbc_kill_store_p4_; input lsu_lsu_pmen; output [7:0] lmc_lmq_enable_b; // Load enables for LMQ flops (threaded) output [7:0] lmc_pcx_sel_p4; // Which thread to send to pcx/asi output lmc_pcx_rq_vld; // At least one thread is ready to issue output lmc_asi_rq_vld; // At least one thread is ready to issue output lmc_ld_rq_p3; output lmc_ld_vld_p4; output lmc_ld_no_req_p4; // Cancel the pcx request of the load output lmc_ld_inv_p4; output [2:0] lmc_ld_tid; // Thread ID of load selected for issue output [7:0] lmc_byp_sel_e; // Thread select for fill/bypass data output [2:0] lmc_cpq_tid_m; // Thread ID of current cpq packet output [7:0] lmc_lmq_bypass_en; // Load enable for the LMQ bypass registers output lmc_asi_bypass_m; // ASI data is bypassing now output [1:0] lmc_bld_addr54; // Block load address modifier output lmc_bld_req; // Current pcx req is for block load output lmc_bld_req_; output lmc_bld_annul; output lmc_bld_miss_e; output lmc_bld_last_e; output [7:0] lmc_rd_update; output [7:0] lmc_pref_issued; // Prefetch issued to pcx output [7:0] lmc_ldd_vld; output [7:0] lmc_ld_unfilled; output lmc_lmd_ncache_b; output [4:0] lmc_ld_sz; output lmc_ld_inst_w; output lmc_full_raw_w; output lmc_ld_stall; // stall pipe so bypass can complete output lmc_l2_err_noup; output lmc_l2_uerr; output lmc_byp_data_hi; output lmc_byp_data_enable; output [7:0] lmc_thrd_byp_sel_e; // Thread is bypassing (or filling) output [7:0] lmc_thrd_byp_sel_m; // Which thread's bypass register is bypassing output [2:0] lmc_byp_tid_m; // Which thread's bypass register is bypassing output lmc_byp_vld_m; // A bypass is occuring output [4:0] lmc_lmq0_byp_sel; // source selects for load bypass registers output [4:0] lmc_lmq1_byp_sel; // source selects for load bypass registers output [4:0] lmc_lmq2_byp_sel; // source selects for load bypass registers output [4:0] lmc_lmq3_byp_sel; // source selects for load bypass registers output [4:0] lmc_lmq4_byp_sel; // source selects for load bypass registers output [4:0] lmc_lmq5_byp_sel; // source selects for load bypass registers output [4:0] lmc_lmq6_byp_sel; // source selects for load bypass registers output [4:0] lmc_lmq7_byp_sel; // source selects for load bypass registers output lmc_asi_indet_retire; // indeterminate ASI load back from ring output [7:0] lsu_ifu_no_miss; // xinval pending so do not allow I$ miss output lsu_dcmh_err_g; output lsu_dcvp_err_g; output lsu_dctp_err_g; output lsu_dcdp_err_g; output [2:0] lsu_dcerr_tid_g; output lsu_dcl2c_err_g; output lsu_dcl2u_err_g; output lsu_dcl2nd_err_g; output lsu_sbdlc_err_g; output lsu_sbdlu_err_g; output [2:0] lsu_stberr_tid_g; input lbist_run; input mbi_run; output lmc_mbi_run; output lmc_bist_or_diag_e; // scan renames assign se = tcu_scan_en; assign pce_ov = tcu_pce_ov; assign stop = 1'b0; assign siclk = spc_aclk; assign soclk = spc_bclk; // end scan ////////////////////////////// // Clock header ////////////////////////////// lsu_lmc_ctll1clkhdr_ctl_macro clkgen ( .l2clk (l2clk ), .l1en (1'b1 ), .l1clk (l1clk ), .pce_ov(pce_ov), .stop(stop), .se(se) ); lsu_lmc_ctll1clkhdr_ctl_macro rqpend_clkgen ( .l2clk (l2clk ), .l1en (rqpend_clken ), .l1clk (l1clk_pm1 ), .pce_ov(pce_ov), .stop(stop), .se(se) ); assign cpq_mx_thread[0] = (cid_tid[2:0] == 3'd0); assign cpq_mx_thread[1] = (cid_tid[2:0] == 3'd1); assign cpq_mx_thread[2] = (cid_tid[2:0] == 3'd2); assign cpq_mx_thread[3] = (cid_tid[2:0] == 3'd3); assign cpq_mx_thread[4] = (cid_tid[2:0] == 3'd4); assign cpq_mx_thread[5] = (cid_tid[2:0] == 3'd5); assign cpq_mx_thread[6] = (cid_tid[2:0] == 3'd6); assign cpq_mx_thread[7] = (cid_tid[2:0] == 3'd7); assign ceter_pscce_in[0] = (dcc_ceter_wr_w & thread_w[0]) ? st_data_w_62 : ceter_pscce_reg[0]; assign ceter_pscce_in[1] = (dcc_ceter_wr_w & thread_w[1]) ? st_data_w_62 : ceter_pscce_reg[1]; assign ceter_pscce_in[2] = (dcc_ceter_wr_w & thread_w[2]) ? st_data_w_62 : ceter_pscce_reg[2]; assign ceter_pscce_in[3] = (dcc_ceter_wr_w & thread_w[3]) ? st_data_w_62 : ceter_pscce_reg[3]; assign ceter_pscce_in[4] = (dcc_ceter_wr_w & thread_w[4]) ? st_data_w_62 : ceter_pscce_reg[4]; assign ceter_pscce_in[5] = (dcc_ceter_wr_w & thread_w[5]) ? st_data_w_62 : ceter_pscce_reg[5]; assign ceter_pscce_in[6] = (dcc_ceter_wr_w & thread_w[6]) ? st_data_w_62 : ceter_pscce_reg[6]; assign ceter_pscce_in[7] = (dcc_ceter_wr_w & thread_w[7]) ? st_data_w_62 : ceter_pscce_reg[7]; lsu_lmc_ctlmsff_ctl_macro__width_9 dff_ceter ( .scan_in(dff_ceter_scanin), .scan_out(dff_ceter_scanout), .din ({sbd_st_data_b_62,ceter_pscce_in[7:0]}), .dout ({st_data_w_62, ceter_pscce_reg[7:0]}), .l1clk(l1clk), .siclk(siclk), .soclk(soclk) ); assign ceter_pscce_cpq = (cpq_mx_thread[0] & ceter_pscce_reg[0]) | (cpq_mx_thread[1] & ceter_pscce_reg[1]) | (cpq_mx_thread[2] & ceter_pscce_reg[2]) | (cpq_mx_thread[3] & ceter_pscce_reg[3]) | (cpq_mx_thread[4] & ceter_pscce_reg[4]) | (cpq_mx_thread[5] & ceter_pscce_reg[5]) | (cpq_mx_thread[6] & ceter_pscce_reg[6]) | (cpq_mx_thread[7] & ceter_pscce_reg[7]) ; assign ceter_pscce_w3 = (thread_w3[0] & ceter_pscce_reg[0]) | (thread_w3[1] & ceter_pscce_reg[1]) | (thread_w3[2] & ceter_pscce_reg[2]) | (thread_w3[3] & ceter_pscce_reg[3]) | (thread_w3[4] & ceter_pscce_reg[4]) | (thread_w3[5] & ceter_pscce_reg[5]) | (thread_w3[6] & ceter_pscce_reg[6]) | (thread_w3[7] & ceter_pscce_reg[7]) ; lsu_lmc_ctlmsff_ctl_macro__width_7 dff_cerer ( .scan_in(dff_cerer_scanin), .scan_out(dff_cerer_scanout), .din ({tlu_cerer_sbdlc,tlu_cerer_sbdlu,tlu_cerer_dcl2c,tlu_cerer_dcl2u,tlu_cerer_dcl2nd, tlu_cerer_l2c_socc, tlu_cerer_l2u_socu}), .dout ({ cerer_sbdlc, cerer_sbdlu, cerer_dcl2c, cerer_dcl2u, cerer_dcl2nd, cerer_socc, cerer_socu}), .l1clk(l1clk), .siclk(siclk), .soclk(soclk) ); ////////////////////////////// // Thread decoding ////////////////////////////// assign thread_b[0] = ~tid_b[2] & ~tid_b[1] & ~tid_b[0]; assign thread_b[1] = ~tid_b[2] & ~tid_b[1] & tid_b[0]; assign thread_b[2] = ~tid_b[2] & tid_b[1] & ~tid_b[0]; assign thread_b[3] = ~tid_b[2] & tid_b[1] & tid_b[0]; assign thread_b[4] = tid_b[2] & ~tid_b[1] & ~tid_b[0]; assign thread_b[5] = tid_b[2] & ~tid_b[1] & tid_b[0]; assign thread_b[6] = tid_b[2] & tid_b[1] & ~tid_b[0]; assign thread_b[7] = tid_b[2] & tid_b[1] & tid_b[0]; lsu_lmc_ctlmsff_ctl_macro__width_8 dff_thread_w ( .scan_in(dff_thread_w_scanin), .scan_out(dff_thread_w_scanout), .l1clk (l1clk_pm1), .din (thread_b[7:0]), .dout (thread_w[7:0]), .siclk(siclk), .soclk(soclk) ); ////////////////////////////// // Instruction flushing ////////////////////////////// lsu_lmc_ctlmsff_ctl_macro__width_1 dff_flush_b ( .scan_in(dff_flush_b_scanin), .scan_out(dff_flush_b_scanout), .din (dec_flush_lm), .dout (local_flush_b), .l1clk(l1clk), .siclk(siclk), .soclk(soclk) ); assign flush_b = tlu_flush_lsu_b | dec_flush_lb | local_flush_b | dcc_exception_flush_b; assign excep_only_flush_b = dcc_exception_flush_b & ~(tlu_flush_lsu_b | dec_flush_lb | local_flush_b); lsu_lmc_ctlmsff_ctl_macro__width_2 dff_flush_w ( .scan_in(dff_flush_w_scanin), .scan_out(dff_flush_w_scanout), .din ({flush_b,dcc_perror_b}), .dout ({flush_w,perror_w}), .l1clk(l1clk), .siclk(siclk), .soclk(soclk) ); //////////////////////////////////////////////////////////////////////////////// // Enables to load miss information into the LMQ buffers // LMQ buffers are written in the W stage, so the enable must be valid in B. // ld_miss_b will be the critical signal. If it's too late, the LMQ can be loaded // on every miss and a separate signal used to track whether the load needs to go // to L2, but this will mess up the LRU mechanism below, so I'd like to avoid it // if possible. //////////////////////////////////////////////////////////////////////////////// lsu_lmc_ctlmsff_ctl_macro__width_6 dff_inst_b ( .scan_in(dff_inst_b_scanin), .scan_out(dff_inst_b_scanout), .din ({dcc_ld_inst_vld_m, dcc_pref_inst_m, dcc_blk_inst_b,dcc_tid_m[2:0]}), .dout ({ ld_inst_vld_b, pref_inst_b, blk_inst_w, tid_b[2:0]}), .l1clk(l1clk), .siclk(siclk), .soclk(soclk) ); lsu_lmc_ctlmsff_ctl_macro__width_2 dff_inst_w ( .scan_in(dff_inst_w_scanin), .scan_out(dff_inst_w_scanout), .l1clk (l1clk_pm1), .din ({pref_inst_b, excep_only_flush_b}), .dout ({pref_inst_w, excep_only_flush_w}), .siclk(siclk), .soclk(soclk) ); assign load_lmq_entry[7:0] = (({8{ld_inst_vld_b}} & thread_b[7:0]) & ~(({8{dcc_sync_pipe_w}} & thread_w[7:0]) | {8{local_flush_b}})); assign lmc_lmq_enable_b[7:0] = load_lmq_entry[7:0] | lmc_rd_update[7:0]; //////////////////////////////////////////////////////////////////////////////// // Fill state of each entry. An unfilled flag is set when the miss occurs // and cleared when the cache is filled (or when the data is bypassed in the // case of non-cacheable loads). //////////////////////////////////////////////////////////////////////////////// lsu_lmc_ctlmsff_ctl_macro__width_1 dff_l2fill ( .scan_in(dff_l2fill_scanin), .scan_out(dff_l2fill_scanout), .din (cic_l2fill_vld_e), .dout (l2fill_vld_m), .l1clk(l1clk), .siclk(siclk), .soclk(soclk) ); assign ld_fill[0] = l2fill_vld_m & (lmc_cpq_tid_m[2:0] == 3'b000); assign ld_fill[1] = l2fill_vld_m & (lmc_cpq_tid_m[2:0] == 3'b001); assign ld_fill[2] = l2fill_vld_m & (lmc_cpq_tid_m[2:0] == 3'b010); assign ld_fill[3] = l2fill_vld_m & (lmc_cpq_tid_m[2:0] == 3'b011); assign ld_fill[4] = l2fill_vld_m & (lmc_cpq_tid_m[2:0] == 3'b100); assign ld_fill[5] = l2fill_vld_m & (lmc_cpq_tid_m[2:0] == 3'b101); assign ld_fill[6] = l2fill_vld_m & (lmc_cpq_tid_m[2:0] == 3'b110); assign ld_fill[7] = l2fill_vld_m & (lmc_cpq_tid_m[2:0] == 3'b111); assign ld_unfilled_in[7:0] = ld_unfilled[7:0] & ~ld_fill[7:0]; lsu_lmc_ctlmsff_ctl_macro__width_8 dff_unfilled ( .scan_in(dff_unfilled_scanin), .scan_out(dff_unfilled_scanout), .din (ld_unfilled_in[7:0]), .dout (ld_unfilled_out[7:0]), .l1clk(l1clk), .siclk(siclk), .soclk(soclk) ); assign ld_unfilled[7:0] = (ld_pcx_vld_set[7:0] & {8{~ncache_w}}) | ld_unfilled_out[7:0]; //////////////////////////////////////////////////////////////////////////////// // Secondary miss processing // A load miss is considered secondary if it matches a load from another thread // that has a miss pending. In this case, the secondary load will be marked // as non-cacheable to avoid cache pollution. //////////////////////////////////////////////////////////////////////////////// assign lmc_ld_unfilled[7:0] = ld_unfilled[7:0]; assign ld_sec_hit_b = (|(lmd_sec_cmp_b[7:0]) & ~dcc_asi_load_b); assign lmc_lmd_ncache_b = dcc_ld_miss_ctl_b43 | ld_sec_hit_b; //////////////////////////////////////////////////////////////////////////////// // Partial RAW handling // Partial RAWs and loads treated like partial raws (full raw to multiple stb // entries) cannot issue to the pcx until dependent stores have been committed // to the pcx. The depedency tracking is done in lsu_sbc_ctl. //////////////////////////////////////////////////////////////////////////////// assign tlb_pgnum_b39_b = ld_inst_vld_b & tlb_pgnum_b39 & ~tlb_cam_mhit; assign stb_cam_hit_b = stb_cam_hit & ~(lbist_run | lmc_mbi_run); assign stb_cam_mhit_b = stb_cam_mhit & ~(lbist_run | lmc_mbi_run); assign stb_ld_part_raw_b = stb_ld_part_raw & ~(lbist_run | lmc_mbi_run); lsu_lmc_ctlmsff_ctl_macro__width_5 dff_stb_raw ( .scan_in(dff_stb_raw_scanin), .scan_out(dff_stb_raw_scanout), .l1clk (l1clk_pm1), .din ({stb_cam_hit_b,stb_cam_mhit_b,stb_ld_part_raw_b,tlb_pgnum_b39_b,dcc_ldbl_b}), .dout ({stb_cam_hit_w,stb_cam_mhit_w,stb_ld_part_raw_w,tlb_pgnum_b39_w,ldbl_w}), .siclk(siclk), .soclk(soclk) ); assign ld_full_raw_w = stb_cam_hit_w & ~ld_part_raw_w; assign ld_part_raw_w = stb_ld_part_raw_w | // a partial hit stb_cam_mhit_w | // multiple hits tlb_pgnum_b39_w | // IO load (ldbl_w & stb_cam_hit_w) ; // BLD/QUAD/LDD assign ld_rawp_disabled_asi_b = (dcc_asi_load_b & ~dcc_lsu_asi_rd_b) & ld_inst_vld_b; assign ld_rawp_disabled_in[7:0] = (ld_rawp_disabled[7:0] & ~sbc_rawp_rst[7:0]) & ~sbs_all_commited[7:0]; lsu_lmc_ctlmsff_ctl_macro__width_9 dff_rawp_disable ( .scan_in(dff_rawp_disable_scanin), .scan_out(dff_rawp_disable_scanout), .l1clk (l1clk_pm1), .din ({ld_rawp_disabled_asi_b,ld_rawp_disabled_in[7:0]}), .dout ({ld_rawp_disabled_asi_w,ld_rawp_disabled_out[7:0]}), .siclk(siclk), .soclk(soclk) ); // Don't change or remove this signal name. It's used by the bench. assign ld_rawp_disabled_set[7:0] = {8{ (ld_rawp_disabled_asi_w | ld_part_raw_w) & ~flush_w }} & thread_w[7:0]; assign ld_rawp_disabled[7:0] = ld_rawp_disabled_set[7:0] | ld_rawp_disabled_out[7:0]; //////////////////////////////////////////////////////////////////////////////// // Track ldd flags here. They used to be part of lmq entry in lsu_lmd_dp, but // they need to be here for timing. //////////////////////////////////////////////////////////////////////////////// assign ldd_vld_in[7:0] = ( load_lmq_entry[7:0] & {8{dcc_ld_miss_ldd}}) | (~load_lmq_entry[7:0] & lmc_ldd_vld[7:0]); lsu_lmc_ctlmsff_ctl_macro__width_8 dff_ldd_vld ( .scan_in(dff_ldd_vld_scanin), .scan_out(dff_ldd_vld_scanout), .l1clk (l1clk_pm1), .din (ldd_vld_in[7:0]), .dout (lmc_ldd_vld[7:0]), .siclk(siclk), .soclk(soclk) ); //////////////////////////////////////////////////////////////////////////////// // PCX and ASI Load Control // An LMQ entry is ready to issue to the pcx when it is loaded. // The request is cleared once the entry successfully issues to the pcx. // // B | W/P3 | P4 // | | // miss detected| LMQ loaded | packet to gasket // | request set | // | arb for pcx | // // Arbitration among threads with pending load requests happens here. Arbitration // between the pcx sources (loads and stores) happens in the pic control block. //////////////////////////////////////////////////////////////////////////////// // Load misses issue to the pcx with the following exceptions // - internal ASI's which aren't IO mapped (they go to the ASI ring instead) // - atomics (the STB arbitrates for these) // - prefetches always issue, regardless // - full raw assign lmq_vld_enable_b = dcc_ld_miss_b & ld_inst_vld_b; assign lmq_vld_cancel_b = (dcc_asi_load_b & ~dcc_asi_iomap_b) | dcc_atomic_b; lsu_lmc_ctlmsff_ctl_macro__width_3 dff_ld_lmq_en_b ( .scan_in(dff_ld_lmq_en_b_scanin), .scan_out(dff_ld_lmq_en_b_scanout), .l1clk (l1clk_pm1), .din ({lmq_vld_enable_b, lmq_vld_cancel_b, lmc_lmd_ncache_b}), .dout ({lmq_vld_enable_w_pre,lmq_vld_cancel_w_pre,ncache_w}), .siclk(siclk), .soclk(soclk) ); assign lmq_vld_cancel_w = lmq_vld_cancel_w_pre | ld_full_raw_w; assign lmq_vld_enable_w = (lmq_vld_enable_w_pre | ld_part_raw_w) & ~lmq_vld_cancel_w; // PCX requests pending assign ld_pcx_vld_set[0] = lmq_vld_enable_w & ~flush_w & thread_w[0]; assign ld_pcx_vld_set[1] = lmq_vld_enable_w & ~flush_w & thread_w[1]; assign ld_pcx_vld_set[2] = lmq_vld_enable_w & ~flush_w & thread_w[2]; assign ld_pcx_vld_set[3] = lmq_vld_enable_w & ~flush_w & thread_w[3]; assign ld_pcx_vld_set[4] = lmq_vld_enable_w & ~flush_w & thread_w[4]; assign ld_pcx_vld_set[5] = lmq_vld_enable_w & ~flush_w & thread_w[5]; assign ld_pcx_vld_set[6] = lmq_vld_enable_w & ~flush_w & thread_w[6]; assign ld_pcx_vld_set[7] = lmq_vld_enable_w & ~flush_w & thread_w[7]; assign ld_pcx_vld_rst[7:0] = (ld_pcx_commit[7:0] | kill_pcx_ld_req[7:0]) & ~(bld_hold[7:0] | perr_inv[7:0]); assign ld_pcx_vld_in[7:0] = ~ld_pcx_vld_rst[7:0] & ld_pcx_vld[7:0]; lsu_lmc_ctlmsff_ctl_macro__width_8 dff_ld_pcx_vld ( .scan_in(dff_ld_pcx_vld_scanin), .scan_out(dff_ld_pcx_vld_scanout), .l1clk (l1clk_pm1), .din (ld_pcx_vld_in[7:0]), .dout (ld_pcx_vld_out[7:0]), .siclk(siclk), .soclk(soclk) ); assign ld_pcx_vld[7:0] = ld_pcx_vld_set[7:0] | ld_pcx_vld_out[7:0]; // ASI requests pending assign ld_asi_vld_set_b = dcc_asi_load_b & ~dcc_asi_iomap_b & ~dcc_lsu_asi_rd_b; assign ld_asi_vld_set[0] = ld_asi_vld_set_w & ~flush_w & thread_w[0]; assign ld_asi_vld_set[1] = ld_asi_vld_set_w & ~flush_w & thread_w[1]; assign ld_asi_vld_set[2] = ld_asi_vld_set_w & ~flush_w & thread_w[2]; assign ld_asi_vld_set[3] = ld_asi_vld_set_w & ~flush_w & thread_w[3]; assign ld_asi_vld_set[4] = ld_asi_vld_set_w & ~flush_w & thread_w[4]; assign ld_asi_vld_set[5] = ld_asi_vld_set_w & ~flush_w & thread_w[5]; assign ld_asi_vld_set[6] = ld_asi_vld_set_w & ~flush_w & thread_w[6]; assign ld_asi_vld_set[7] = ld_asi_vld_set_w & ~flush_w & thread_w[7]; assign ld_asi_vld_in[7:0] = ~ld_asi_vld_rst[7:0] & ld_asi_vld[7:0]; lsu_lmc_ctlmsff_ctl_macro__width_9 dff_ld_asi_vld ( .scan_in(dff_ld_asi_vld_scanin), .scan_out(dff_ld_asi_vld_scanout), .l1clk (l1clk_pm1), .din ({ld_asi_vld_set_b,ld_asi_vld_in[7:0]}), .dout ({ld_asi_vld_set_w,ld_asi_vld_out[7:0]}), .siclk(siclk), .soclk(soclk) ); assign ld_asi_vld[7:0] = ld_asi_vld_set[7:0] | ld_asi_vld_out[7:0]; // Is the load which made an early request still valid? assign early_ld_cancel_w = ld_full_raw_w | ld_part_raw_w | flush_w | perror_w; // A thread should never have pcx and asi requests valid simultaneously // 0in bits_on -var {ld_pcx_vld[0],ld_asi_vld[0]} -max 1 -message "PCX and ASI load requests for thread 0" // 0in bits_on -var {ld_pcx_vld[1],ld_asi_vld[1]} -max 1 -message "PCX and ASI load requests for thread 1" // 0in bits_on -var {ld_pcx_vld[2],ld_asi_vld[2]} -max 1 -message "PCX and ASI load requests for thread 2" // 0in bits_on -var {ld_pcx_vld[3],ld_asi_vld[3]} -max 1 -message "PCX and ASI load requests for thread 3" // 0in bits_on -var {ld_pcx_vld[4],ld_asi_vld[4]} -max 1 -message "PCX and ASI load requests for thread 4" // 0in bits_on -var {ld_pcx_vld[5],ld_asi_vld[5]} -max 1 -message "PCX and ASI load requests for thread 5" // 0in bits_on -var {ld_pcx_vld[6],ld_asi_vld[6]} -max 1 -message "PCX and ASI load requests for thread 6" // 0in bits_on -var {ld_pcx_vld[7],ld_asi_vld[7]} -max 1 -message "PCX and ASI load requests for thread 7" ////////////////////// // P3 stage ////////////////////// // Generate valid pcx and asi requests. // PCX requests can be cancelled by rawp conditions // ASI requests can be cancelled by rawp conditions and by another outstanding indeterminate. assign ld_pcx_rq_vld[7:0] = ld_pcx_vld[7:0] & ~ld_rawp_disabled[7:0] & ~({8{early_ld_b_sel_p4}} & thread_w[7:0]) & ~({8{block_ldd_req}} & lmc_ldd_vld[7:0]); assign ld_asi_rq_vld[7:0] = ld_asi_vld[7:0] & ~ld_rawp_disabled[7:0] & ~(lmd_asi_ld[7:0] & lmd_asi_indet[7:0] & {8{asi_indet_block}}); assign ld_rq_vld[7:0] = ld_pcx_rq_vld[7:0] | ld_asi_rq_vld[7:0]; assign lmc_ld_rq_p3 = |(ld_rq_vld[7:0]); // Pseudo-LRU picker to choose the oldest thread for issuing to pcx. // LRU state is updated after a load is put into the miss queue assign load_miss_w[7:0] = {8{(ld_inst_unflushed_w | (ld_inst_vld_w & ~flush_w))}} & thread_w[7:0] & (ld_pcx_vld[7:0] | ld_asi_vld[7:0]); lsu_lru8_ctl lru8 ( .scan_in(lru8_scanin), .scan_out(lru8_scanout), .request (ld_rq_vld[7:0]), .enable (load_miss_w[7:0]), .select (ld_rq_sel[7:0]), .l1clk(l1clk), .spc_aclk(spc_aclk), .spc_bclk(spc_bclk) ); // Tell pic if request was pcx or asi assign lmc_pcx_rq_vld = |(ld_rq_sel[7:0] & ld_pcx_rq_vld[7:0]); assign lmc_asi_rq_vld = |(ld_rq_sel[7:0] & ld_asi_rq_vld[7:0]); // A request wins arbitration to the pcx if it's thread is selected AND // the load port wins source arbitration. // Loads will win over stores unless blocked by pic_no_load_p3 assign ld_pcx_rq_sel[7:0] = ld_rq_sel[7:0] & ld_pcx_rq_vld[7:0] & {8{~pic_no_load_p3}}; assign ld_asi_rq_sel[7:0] = ld_rq_sel[7:0] & ld_asi_rq_vld[7:0] & {8{~(pic_no_load_p3 | pic_asi_busy)}}; assign ld_pcx_sel_p3 = |(ld_pcx_rq_sel[7:0]); assign ld_asi_sel_p3 = |(ld_asi_rq_sel[7:0]); assign ld_early_rq_sel[7:0] = {8{~(ld_pcx_sel_p3 | ld_asi_sel_p3 | pic_casa_squash_req)}} & thread_b[7:0]; assign ld_all_rq_sel[7:0] = ld_pcx_rq_sel[7:0] | ld_asi_rq_sel[7:0] | ld_early_rq_sel[7:0] | st_atom_p4_dec[7:0]; assign ld_pcx_commit[7:0] = ld_pcx_rq_sel[7:0]; assign ld_asi_vld_rst[7:0] = ld_asi_rq_sel[7:0]; lsu_lmc_ctlmsff_ctl_macro__width_10 dff_ld_sel ( .scan_in(dff_ld_sel_scanin), .scan_out(dff_ld_sel_scanout), .l1clk (l1clk_pm1), .din ({ld_all_rq_sel[7:0],ld_pcx_sel_p3,pic_early_ld_b_sel_p3}), .dout ({ld_all_sel_p4[7:0],ld_pcx_sel_p4, early_ld_b_sel_p4}), .siclk(siclk), .soclk(soclk) ); // Need to throttle the number of outstanding LDD requests to avoid CPQ overflow. // No more LDD requests can be sent if // (i) Number of outstanding requests is 14 OR // (ii)cic is issuing a stall due to CPQ above high water mark // Counter is incremented one cycle late to ease timing. assign ldd_count_p1[3:0] = ldd_count[3:0] + 4'b0001; assign ldd_count_m1[3:0] = ldd_count[3:0] - 4'b0001; assign inc_ldd_count_pre = |(ld_pcx_rq_sel[7:0] & lmc_ldd_vld[7:0] & ~perr_inv[7:0]); assign dec_ldd_count = cic_oddrd_e; assign ldd_count_in[3:0] = ({4{inc_ldd_count & ~dec_ldd_count}} & ldd_count_p1[3:0]) | ({4{dec_ldd_count & ~inc_ldd_count}} & ldd_count_m1[3:0]) | ({4{inc_ldd_count ~^ dec_ldd_count}} & ldd_count[3:0]) ; lsu_lmc_ctlmsff_ctl_macro__width_6 dff_ldd_out ( .scan_in(dff_ldd_out_scanin), .scan_out(dff_ldd_out_scanout), .din ({cic_cpq_stall,inc_ldd_count_pre,ldd_count_in[3:0]}), .dout ({cpq_stall, inc_ldd_count ,ldd_count[3:0]}), .l1clk(l1clk), .siclk(siclk), .soclk(soclk) ); assign block_ldd_req = (ldd_count[3:2]==2'b11 & (ldd_count[1] | ldd_count[0] & inc_ldd_count)) | cpq_stall; ////////////////////// // P4 stage ////////////////////// assign lmc_ld_no_req_p4 = early_ld_b_sel_p4 & early_ld_cancel_w; assign kill_pcx_ld_req[7:0] = {8{(early_ld_b_sel_p4 & ~early_ld_cancel_w)}} & thread_w[7:0]; assign lmc_ld_vld_p4 = (casa_ld_to_pcx) | // CAS packet 2 (ld_pcx_sel_p4) | // queued miss request (early_ld_b_sel_p4 & ~early_ld_cancel_w);// early B/W request assign lmc_pcx_sel_p4[7:0] = ld_all_sel_p4[7:0]; assign lmc_ld_tid[2] = lmc_pcx_sel_p4[7] | lmc_pcx_sel_p4[6] | lmc_pcx_sel_p4[5] | lmc_pcx_sel_p4[4]; assign lmc_ld_tid[1] = lmc_pcx_sel_p4[7] | lmc_pcx_sel_p4[6] | lmc_pcx_sel_p4[3] | lmc_pcx_sel_p4[2]; assign lmc_ld_tid[0] = lmc_pcx_sel_p4[7] | lmc_pcx_sel_p4[5] | lmc_pcx_sel_p4[3] | lmc_pcx_sel_p4[1]; // Encode this info to save some flops. [3]=valid,[2:0]=tid assign st_atom_p3[3] = |(sbc_st_atom_p3[7:0]); assign st_atom_p3[2] = sbc_st_atom_p3[7] | sbc_st_atom_p3[6] | sbc_st_atom_p3[5] | sbc_st_atom_p3[4]; assign st_atom_p3[1] = sbc_st_atom_p3[7] | sbc_st_atom_p3[6] | sbc_st_atom_p3[3] | sbc_st_atom_p3[2]; assign st_atom_p3[0] = sbc_st_atom_p3[7] | sbc_st_atom_p3[5] | sbc_st_atom_p3[3] | sbc_st_atom_p3[1]; assign casa_bypass_d = st_atom_p3[3]; lsu_lmc_ctlmsff_ctl_macro__width_4 dff_st_atom_p4 ( .scan_in(dff_st_atom_p4_scanin), .scan_out(dff_st_atom_p4_scanout), .din (st_atom_p3[3:0]), .dout (st_atom_p4[3:0]), .l1clk(l1clk), .siclk(siclk), .soclk(soclk) ); // If casa is using the bypass register, other bypasses must be blocked. assign casa_bypass_e = st_atom_p4[3]; // If STB read of CAS1 had an error, kill the CAS2 and restart the thread assign st_atom_p4_in[3] = st_atom_p4[3] & sbc_kill_store_p4_; assign st_atom_p4_in[2:0] = st_atom_p4[2:0]; assign st_atom_p4_dec[0] = st_atom_p4[3] & ~st_atom_p4[2] & ~st_atom_p4[1] & ~st_atom_p4[0]; assign st_atom_p4_dec[1] = st_atom_p4[3] & ~st_atom_p4[2] & ~st_atom_p4[1] & st_atom_p4[0]; assign st_atom_p4_dec[2] = st_atom_p4[3] & ~st_atom_p4[2] & st_atom_p4[1] & ~st_atom_p4[0]; assign st_atom_p4_dec[3] = st_atom_p4[3] & ~st_atom_p4[2] & st_atom_p4[1] & st_atom_p4[0]; assign st_atom_p4_dec[4] = st_atom_p4[3] & st_atom_p4[2] & ~st_atom_p4[1] & ~st_atom_p4[0]; assign st_atom_p4_dec[5] = st_atom_p4[3] & st_atom_p4[2] & ~st_atom_p4[1] & st_atom_p4[0]; assign st_atom_p4_dec[6] = st_atom_p4[3] & st_atom_p4[2] & st_atom_p4[1] & ~st_atom_p4[0]; assign st_atom_p4_dec[7] = st_atom_p4[3] & st_atom_p4[2] & st_atom_p4[1] & st_atom_p4[0]; lsu_lmc_ctlmsff_ctl_macro__width_1 dff_st_atom_p5 ( .scan_in(dff_st_atom_p5_scanin), .scan_out(dff_st_atom_p5_scanout), .din (st_atom_p4_in[3]), .dout (casa_ld_to_pcx), .l1clk(l1clk), .siclk(siclk), .soclk(soclk) ); // Indeterminate ASI blocks assign asi_indet_sel = |(ld_asi_vld_rst[7:0] & lmd_asi_indet[7:0]); assign asi_indet_retire = (lmc_lmq0_byp_sel[1] & lmd_asi_indet[0]) | (lmc_lmq1_byp_sel[1] & lmd_asi_indet[1]) | (lmc_lmq2_byp_sel[1] & lmd_asi_indet[2]) | (lmc_lmq3_byp_sel[1] & lmd_asi_indet[3]) | (lmc_lmq4_byp_sel[1] & lmd_asi_indet[4]) | (lmc_lmq5_byp_sel[1] & lmd_asi_indet[5]) | (lmc_lmq6_byp_sel[1] & lmd_asi_indet[6]) | (lmc_lmq7_byp_sel[1] & lmd_asi_indet[7]) ; assign lmc_asi_indet_retire = asi_indet_retire; assign asi_indet_in = asi_indet_sel | (asi_indet_block & ~asi_indet_retire); lsu_lmc_ctlmsff_ctl_macro__width_1 dff_asi_indet ( .scan_in(dff_asi_indet_scanin), .scan_out(dff_asi_indet_scanout), .din (asi_indet_in), .dout (asi_indet_block), .l1clk(l1clk), .siclk(siclk), .soclk(soclk) ); //////////////////////////////////////////////////////////////////////////////// // Data return //////////////////////////////////////////////////////////////////////////////// // Select the correct thread's LMQ assign lmc_byp_sel_e[0] = cpq_mx_thread[0] & cic_cpq_ld_rdy | lmc_thrd_byp_sel_e[0]; assign lmc_byp_sel_e[1] = cpq_mx_thread[1] & cic_cpq_ld_rdy | lmc_thrd_byp_sel_e[1]; assign lmc_byp_sel_e[2] = cpq_mx_thread[2] & cic_cpq_ld_rdy | lmc_thrd_byp_sel_e[2]; assign lmc_byp_sel_e[3] = cpq_mx_thread[3] & cic_cpq_ld_rdy | lmc_thrd_byp_sel_e[3]; assign lmc_byp_sel_e[4] = cpq_mx_thread[4] & cic_cpq_ld_rdy | lmc_thrd_byp_sel_e[4]; assign lmc_byp_sel_e[5] = cpq_mx_thread[5] & cic_cpq_ld_rdy | lmc_thrd_byp_sel_e[5]; assign lmc_byp_sel_e[6] = cpq_mx_thread[6] & cic_cpq_ld_rdy | lmc_thrd_byp_sel_e[6]; assign lmc_byp_sel_e[7] = cpq_mx_thread[7] & cic_cpq_ld_rdy | lmc_thrd_byp_sel_e[7]; lsu_lmc_ctlmsff_ctl_macro__width_3 dff_cpq_tid ( .scan_in(dff_cpq_tid_scanin), .scan_out(dff_cpq_tid_scanout), .din (cid_tid[2:0]), .dout (lmc_cpq_tid_m[2:0]), .l1clk(l1clk), .siclk(siclk), .soclk(soclk) ); //////////////////////////////////////////////////////////////////////////////// // LMQ bypassing //////////////////////////////////////////////////////////////////////////////// assign ld_inst_nopref_b = ld_inst_vld_b & ~pref_inst_b; lsu_lmc_ctlmsff_ctl_macro__width_4 dff_ld_raw_w ( .scan_in(dff_ld_raw_w_scanin), .scan_out(dff_ld_raw_w_scanout), .l1clk (l1clk_pm1), .din ({ld_inst_nopref_b,tid_b[2:0]}), .dout ({ld_inst_nopref_w,tid_w[2:0]}), .siclk(siclk), .soclk(soclk) ); assign ld_inst_unflushed_w = ld_inst_nopref_w & ~flush_w; assign lmc_ld_inst_w = ld_inst_unflushed_w; assign ld_raw_bypass_w = ld_inst_unflushed_w & ld_full_raw_w & ~stb_cam_mhit_w & ~ldbl_w; assign lmc_full_raw_w = ld_raw_bypass_w; lsu_lmc_ctlmsff_ctl_macro__width_4 dff_ld_raw_w2 ( .scan_in(dff_ld_raw_w2_scanin), .scan_out(dff_ld_raw_w2_scanout), .din ({ld_raw_bypass_w, tid_w[2:0]}), .dout ({ld_raw_bypass_w2,tid_w2[2:0]}), .l1clk(l1clk), .siclk(siclk), .soclk(soclk) ); lsu_lmc_ctlmsff_ctl_macro__width_4 dff_ld_raw_w3 ( .scan_in(dff_ld_raw_w3_scanin), .scan_out(dff_ld_raw_w3_scanout), .din ({ld_raw_bypass_w2,tid_w2[2:0]}), .dout ({ld_raw_bypass_w3,tid_w3[2:0]}), .l1clk(l1clk), .siclk(siclk), .soclk(soclk) ); assign thread_w3[0] = ~tid_w3[2] & ~tid_w3[1] & ~tid_w3[0]; assign thread_w3[1] = ~tid_w3[2] & ~tid_w3[1] & tid_w3[0]; assign thread_w3[2] = ~tid_w3[2] & tid_w3[1] & ~tid_w3[0]; assign thread_w3[3] = ~tid_w3[2] & tid_w3[1] & tid_w3[0]; assign thread_w3[4] = tid_w3[2] & ~tid_w3[1] & ~tid_w3[0]; assign thread_w3[5] = tid_w3[2] & ~tid_w3[1] & tid_w3[0]; assign thread_w3[6] = tid_w3[2] & tid_w3[1] & ~tid_w3[0]; assign thread_w3[7] = tid_w3[2] & tid_w3[1] & tid_w3[0]; // Select the source to load into the bypass register // [0] - swap data for CAS operation // [1] - load return data from the ASI interface // [2] - raw bypass from stb // [3] - ldxa asi read data from registers internal to LSU (left side) // [4] - ldxa asi read data from registers internal to LSU (right side) // [5] - error code from L2 assign lmc_lmq0_byp_sel[0] = dcc_casa_inst_b & thread_b[0] & ~(dcc_sync_pipe_w & thread_w[0]) & ~local_flush_b; assign lmc_lmq1_byp_sel[0] = dcc_casa_inst_b & thread_b[1] & ~(dcc_sync_pipe_w & thread_w[1]) & ~local_flush_b; assign lmc_lmq2_byp_sel[0] = dcc_casa_inst_b & thread_b[2] & ~(dcc_sync_pipe_w & thread_w[2]) & ~local_flush_b; assign lmc_lmq3_byp_sel[0] = dcc_casa_inst_b & thread_b[3] & ~(dcc_sync_pipe_w & thread_w[3]) & ~local_flush_b; assign lmc_lmq4_byp_sel[0] = dcc_casa_inst_b & thread_b[4] & ~(dcc_sync_pipe_w & thread_w[4]) & ~local_flush_b; assign lmc_lmq5_byp_sel[0] = dcc_casa_inst_b & thread_b[5] & ~(dcc_sync_pipe_w & thread_w[5]) & ~local_flush_b; assign lmc_lmq6_byp_sel[0] = dcc_casa_inst_b & thread_b[6] & ~(dcc_sync_pipe_w & thread_w[6]) & ~local_flush_b; assign lmc_lmq7_byp_sel[0] = dcc_casa_inst_b & thread_b[7] & ~(dcc_sync_pipe_w & thread_w[7]) & ~local_flush_b; assign lmc_lmq0_byp_sel[1] = dcc_asi_rtn_vld[0] & dcc_asi_rtn_rd & ~dcc_asi_rtn_excp; assign lmc_lmq1_byp_sel[1] = dcc_asi_rtn_vld[1] & dcc_asi_rtn_rd & ~dcc_asi_rtn_excp; assign lmc_lmq2_byp_sel[1] = dcc_asi_rtn_vld[2] & dcc_asi_rtn_rd & ~dcc_asi_rtn_excp; assign lmc_lmq3_byp_sel[1] = dcc_asi_rtn_vld[3] & dcc_asi_rtn_rd & ~dcc_asi_rtn_excp; assign lmc_lmq4_byp_sel[1] = dcc_asi_rtn_vld[4] & dcc_asi_rtn_rd & ~dcc_asi_rtn_excp; assign lmc_lmq5_byp_sel[1] = dcc_asi_rtn_vld[5] & dcc_asi_rtn_rd & ~dcc_asi_rtn_excp; assign lmc_lmq6_byp_sel[1] = dcc_asi_rtn_vld[6] & dcc_asi_rtn_rd & ~dcc_asi_rtn_excp; assign lmc_lmq7_byp_sel[1] = dcc_asi_rtn_vld[7] & dcc_asi_rtn_rd & ~dcc_asi_rtn_excp; assign lmc_lmq0_byp_sel[2] = ld_raw_bypass_w3 & ~(sbdlc_err | sbdlu_err) & thread_w3[0]; assign lmc_lmq1_byp_sel[2] = ld_raw_bypass_w3 & ~(sbdlc_err | sbdlu_err) & thread_w3[1]; assign lmc_lmq2_byp_sel[2] = ld_raw_bypass_w3 & ~(sbdlc_err | sbdlu_err) & thread_w3[2]; assign lmc_lmq3_byp_sel[2] = ld_raw_bypass_w3 & ~(sbdlc_err | sbdlu_err) & thread_w3[3]; assign lmc_lmq4_byp_sel[2] = ld_raw_bypass_w3 & ~(sbdlc_err | sbdlu_err) & thread_w3[4]; assign lmc_lmq5_byp_sel[2] = ld_raw_bypass_w3 & ~(sbdlc_err | sbdlu_err) & thread_w3[5]; assign lmc_lmq6_byp_sel[2] = ld_raw_bypass_w3 & ~(sbdlc_err | sbdlu_err) & thread_w3[6]; assign lmc_lmq7_byp_sel[2] = ld_raw_bypass_w3 & ~(sbdlc_err | sbdlu_err) & thread_w3[7]; assign lmc_lmq0_byp_sel[3] = dcc_lsu_asi_sel_w & thread_w[0] & ~flush_w; assign lmc_lmq1_byp_sel[3] = dcc_lsu_asi_sel_w & thread_w[1] & ~flush_w; assign lmc_lmq2_byp_sel[3] = dcc_lsu_asi_sel_w & thread_w[2] & ~flush_w; assign lmc_lmq3_byp_sel[3] = dcc_lsu_asi_sel_w & thread_w[3] & ~flush_w; assign lmc_lmq4_byp_sel[3] = dcc_lsu_asi_sel_w & thread_w[4] & ~flush_w; assign lmc_lmq5_byp_sel[3] = dcc_lsu_asi_sel_w & thread_w[5] & ~flush_w; assign lmc_lmq6_byp_sel[3] = dcc_lsu_asi_sel_w & thread_w[6] & ~flush_w; assign lmc_lmq7_byp_sel[3] = dcc_lsu_asi_sel_w & thread_w[7] & ~flush_w; assign lmc_lmq0_byp_sel[4] = dcc_stb_diag_sel_w3 & thread_w3[0]; assign lmc_lmq1_byp_sel[4] = dcc_stb_diag_sel_w3 & thread_w3[1]; assign lmc_lmq2_byp_sel[4] = dcc_stb_diag_sel_w3 & thread_w3[2]; assign lmc_lmq3_byp_sel[4] = dcc_stb_diag_sel_w3 & thread_w3[3]; assign lmc_lmq4_byp_sel[4] = dcc_stb_diag_sel_w3 & thread_w3[4]; assign lmc_lmq5_byp_sel[4] = dcc_stb_diag_sel_w3 & thread_w3[5]; assign lmc_lmq6_byp_sel[4] = dcc_stb_diag_sel_w3 & thread_w3[6]; assign lmc_lmq7_byp_sel[4] = dcc_stb_diag_sel_w3 & thread_w3[7]; assign lmc_lmq_bypass_en[0] = |(lmc_lmq0_byp_sel[4:0]); assign lmc_lmq_bypass_en[1] = |(lmc_lmq1_byp_sel[4:0]); assign lmc_lmq_bypass_en[2] = |(lmc_lmq2_byp_sel[4:0]); assign lmc_lmq_bypass_en[3] = |(lmc_lmq3_byp_sel[4:0]); assign lmc_lmq_bypass_en[4] = |(lmc_lmq4_byp_sel[4:0]); assign lmc_lmq_bypass_en[5] = |(lmc_lmq5_byp_sel[4:0]); assign lmc_lmq_bypass_en[6] = |(lmc_lmq6_byp_sel[4:0]); assign lmc_lmq_bypass_en[7] = |(lmc_lmq7_byp_sel[4:0]); // This indicates bypass data ready to bypass back to the registers. // It should not be valid for CAS/DIAG storage assign lmq_bypass_vld[0] = |(lmc_lmq0_byp_sel[4:1]); assign lmq_bypass_vld[1] = |(lmc_lmq1_byp_sel[4:1]); assign lmq_bypass_vld[2] = |(lmc_lmq2_byp_sel[4:1]); assign lmq_bypass_vld[3] = |(lmc_lmq3_byp_sel[4:1]); assign lmq_bypass_vld[4] = |(lmc_lmq4_byp_sel[4:1]); assign lmq_bypass_vld[5] = |(lmc_lmq5_byp_sel[4:1]); assign lmq_bypass_vld[6] = |(lmc_lmq6_byp_sel[4:1]); assign lmq_bypass_vld[7] = |(lmc_lmq7_byp_sel[4:1]); // Valid tracking assign ldbyp_vld_en[7:0] = ~ldbyp_rst[7:0] & // Reset (lmq_bypass_vld[7:0] | ldbyp_vld[7:0]); // Set/hold lsu_lmc_ctlmsff_ctl_macro__width_8 dff_ldbyp_vld ( .scan_in(dff_ldbyp_vld_scanin), .scan_out(dff_ldbyp_vld_scanout), .din (ldbyp_vld_en[7:0]), .dout (ldbyp_vld[7:0]), .l1clk(l1clk), .siclk(siclk), .soclk(soclk) ); // A valid entry ready for bypass can only go when there are no loads // in the pipe and no data coming from the CPQ. assign ld_bypass_ok_d = ~dec_ld_inst_d & ~cic_div_stall_d & ~casa_bypass_d; lsu_lmc_ctlmsff_ctl_macro__width_1 dff_ld_inst_e ( .scan_in(dff_ld_inst_e_scanin), .scan_out(dff_ld_inst_e_scanout), .din (ld_bypass_ok_d), .dout (ld_bypass_ok_e), .l1clk(l1clk), .siclk(siclk), .soclk(soclk) ); // Because of the low priority of bypass, and because of the fixed thread priority, // there is a livelock concern. If a bypass has been ready for eight cycles without // proceeding, a decode block will be issued to free up the pipe. The block will // be removed once the bypass queue clears. assign byp_cnt_rst = &(~ldbyp_vld[7:0] | lmc_thrd_byp_sel_e[7:0]); assign byp_cnt_in[2:0] = {3{~byp_cnt_rst}} & (lmc_ld_stall ? byp_cnt[2:0] : (byp_cnt[2:0] + 3'b001)); lsu_lmc_ctlmsff_ctl_macro__width_3 dff_byp_cnt ( .scan_in(dff_byp_cnt_scanin), .scan_out(dff_byp_cnt_scanout), .din (byp_cnt_in[2:0]), .dout (byp_cnt[2:0]), .l1clk(l1clk), .siclk(siclk), .soclk(soclk) ); assign lmc_ld_stall = &(byp_cnt[2:0]); assign ld_bypass_e = ld_bypass_ok_e & cic_cpq_ld_rdy_; assign lmc_thrd_byp_sel_e[0] = ldbyp_vld[0] & ld_bypass_e; assign lmc_thrd_byp_sel_e[1] = ldbyp_vld[1] & ~ldbyp_vld[0] & ld_bypass_e; assign lmc_thrd_byp_sel_e[2] = ldbyp_vld[2] & ~(|ldbyp_vld[1:0]) & ld_bypass_e; assign lmc_thrd_byp_sel_e[3] = ldbyp_vld[3] & ~(|ldbyp_vld[2:0]) & ld_bypass_e; assign lmc_thrd_byp_sel_e[4] = ldbyp_vld[4] & ~(|ldbyp_vld[3:0]) & ld_bypass_e; assign lmc_thrd_byp_sel_e[5] = ldbyp_vld[5] & ~(|ldbyp_vld[4:0]) & ld_bypass_e; assign lmc_thrd_byp_sel_e[6] = ldbyp_vld[6] & ~(|ldbyp_vld[5:0]) & ld_bypass_e; assign lmc_thrd_byp_sel_e[7] = ldbyp_vld[7] & ~(|ldbyp_vld[6:0]) & ld_bypass_e; assign byp_vld_e = |(lmc_thrd_byp_sel_e[7:0]); assign ldbyp_rst[7:0] = lmc_thrd_byp_sel_e[7:0]; // Combine true bypass and a casa issue assign thrd_byp_sel_e[7:0] = lmc_thrd_byp_sel_e[7:0] | st_atom_p4_dec[7:0]; lsu_lmc_ctlmsff_ctl_macro__width_9 dff_thrd_byp_sel_m ( .scan_in(dff_thrd_byp_sel_m_scanin), .scan_out(dff_thrd_byp_sel_m_scanout), .din ({ byp_vld_e,thrd_byp_sel_e[7:0]}), .dout ({lmc_byp_vld_m,thrd_byp_sel_m[7:0]}), .l1clk(l1clk), .siclk(siclk), .soclk(soclk) ); assign lmc_thrd_byp_sel_m[7:0] = thrd_byp_sel_m[7:0]; assign lmc_asi_bypass_m = |(thrd_byp_sel_m[7:0] & lmd_asi_ld[7:0]); assign lmc_byp_tid_m[2] = thrd_byp_sel_m[7] | thrd_byp_sel_m[6] | thrd_byp_sel_m[5] | thrd_byp_sel_m[4]; assign lmc_byp_tid_m[1] = thrd_byp_sel_m[7] | thrd_byp_sel_m[6] | thrd_byp_sel_m[3] | thrd_byp_sel_m[2]; assign lmc_byp_tid_m[0] = thrd_byp_sel_m[7] | thrd_byp_sel_m[5] | thrd_byp_sel_m[3] | thrd_byp_sel_m[1]; //////////////////////////////////////////////////////////////////////////////// // Block load control // Each incoming block (64B) load instruction must cause four requests to the // L2 which return 16B each. //////////////////////////////////////////////////////////////////////////////// assign bld_inst_w[7:0] = {8{blk_inst_w & ld_inst_unflushed_w}} & thread_w[7:0]; assign bld_pending[7:0] = bld_inst_w[7:0] | bld_pend_hold[7:0]; assign bld_pending_in[7:0] = bld_pending[7:0] & ~bld_reset[7:0]; lsu_lmc_ctlmsff_ctl_macro__width_8 dff_bld_pending ( .scan_in(dff_bld_pending_scanin), .scan_out(dff_bld_pending_scanout), .l1clk (l1clk_pm1), .din (bld_pending_in[7:0]), .dout (bld_pend_hold[7:0]), .siclk(siclk), .soclk(soclk) ); assign bld_addr54_p3[1:0] = {2{ld_pcx_rq_sel[0]}} & bld_cnt0[1:0] | {2{ld_pcx_rq_sel[1]}} & bld_cnt1[1:0] | {2{ld_pcx_rq_sel[2]}} & bld_cnt2[1:0] | {2{ld_pcx_rq_sel[3]}} & bld_cnt3[1:0] | {2{ld_pcx_rq_sel[4]}} & bld_cnt4[1:0] | {2{ld_pcx_rq_sel[5]}} & bld_cnt5[1:0] | {2{ld_pcx_rq_sel[6]}} & bld_cnt6[1:0] | {2{ld_pcx_rq_sel[7]}} & bld_cnt7[1:0] ; assign bld_req_p3 = |(ld_pcx_rq_sel[7:0] & bld_pending[7:0]); lsu_lmc_ctlmsff_ctl_macro__width_3 dff_bld_addr ( .scan_in(dff_bld_addr_scanin), .scan_out(dff_bld_addr_scanout), .l1clk (l1clk_pm1), .din ({bld_addr54_p3[1:0], bld_req_p3}), .dout ({lmc_bld_addr54[1:0],lmc_bld_req}), .siclk(siclk), .soclk(soclk) ); assign lmc_bld_req_ = ~lmc_bld_req; // Thread 0 // Counter is incremented when the preceeding request was accepted. assign bld_cnt0_in[1:0] = bld_cnt0[1:0] + {1'b0,inc_bld0_cnt}; assign inc_bld0_cnt = ld_pcx_rq_sel[0] & ~perr_inv[0] & bld_pending[0]; // Reset the bld pending state when the final request is accepted. assign bld_reset[0] = ld_pcx_rq_sel[0] & (&(bld_cnt0[1:0])); // Requests 1-3 must prevent the ld_pcx_vld state from being reset so that // following requests still go to the pcx. assign bld_hold[0] = ~(&(bld_cnt0[1:0])) & bld_pending[0]; lsu_lmc_ctlmsff_ctl_macro__width_2 dff_bld_cnt0 ( .scan_in(dff_bld_cnt0_scanin), .scan_out(dff_bld_cnt0_scanout), .l1clk (l1clk_pm1), .din (bld_cnt0_in[1:0]), .dout (bld_cnt0[1:0]), .siclk(siclk), .soclk(soclk) ); // Thread 1 // Counter is incremented when the preceeding request was accepted. assign bld_cnt1_in[1:0] = bld_cnt1[1:0] + {1'b0,inc_bld1_cnt}; assign inc_bld1_cnt = ld_pcx_rq_sel[1] & ~perr_inv[1] & bld_pending[1]; // Reset the bld pending state when the final request is accepted. assign bld_reset[1] = ld_pcx_rq_sel[1] & (&(bld_cnt1[1:0])); // Requests 1-3 must prevent the ld_pcx_vld state from being reset so that // following requests still go to the pcx. assign bld_hold[1] = ~(&(bld_cnt1[1:0])) & bld_pending[1]; lsu_lmc_ctlmsff_ctl_macro__width_2 dff_bld_cnt1 ( .scan_in(dff_bld_cnt1_scanin), .scan_out(dff_bld_cnt1_scanout), .l1clk (l1clk_pm1), .din (bld_cnt1_in[1:0]), .dout (bld_cnt1[1:0]), .siclk(siclk), .soclk(soclk) ); // Thread 2 // Counter is incremented when the preceeding request was accepted. assign bld_cnt2_in[1:0] = bld_cnt2[1:0] + {1'b0,inc_bld2_cnt}; assign inc_bld2_cnt = ld_pcx_rq_sel[2] & ~perr_inv[2] & bld_pending[2]; // Reset the bld pending state when the final request is accepted. assign bld_reset[2] = ld_pcx_rq_sel[2] & (&(bld_cnt2[1:0])); // Requests 1-3 must prevent the ld_pcx_vld state from being reset so that // following requests still go to the pcx. assign bld_hold[2] = ~(&(bld_cnt2[1:0])) & bld_pending[2]; lsu_lmc_ctlmsff_ctl_macro__width_2 dff_bld_cnt2 ( .scan_in(dff_bld_cnt2_scanin), .scan_out(dff_bld_cnt2_scanout), .l1clk (l1clk_pm1), .din (bld_cnt2_in[1:0]), .dout (bld_cnt2[1:0]), .siclk(siclk), .soclk(soclk) ); // Thread 3 // Counter is incremented when the preceeding request was accepted. assign bld_cnt3_in[1:0] = bld_cnt3[1:0] + {1'b0,inc_bld3_cnt}; assign inc_bld3_cnt = ld_pcx_rq_sel[3] & ~perr_inv[3] & bld_pending[3]; // Reset the bld pending state when the final request is accepted. assign bld_reset[3] = ld_pcx_rq_sel[3] & (&(bld_cnt3[1:0])); // Requests 1-3 must prevent the ld_pcx_vld state from being reset so that // following requests still go to the pcx. assign bld_hold[3] = ~(&(bld_cnt3[1:0])) & bld_pending[3]; lsu_lmc_ctlmsff_ctl_macro__width_2 dff_bld_cnt3 ( .scan_in(dff_bld_cnt3_scanin), .scan_out(dff_bld_cnt3_scanout), .l1clk (l1clk_pm1), .din (bld_cnt3_in[1:0]), .dout (bld_cnt3[1:0]), .siclk(siclk), .soclk(soclk) ); // Thread 4 // Counter is incremented when the preceeding request was accepted. assign bld_cnt4_in[1:0] = bld_cnt4[1:0] + {1'b0,inc_bld4_cnt}; assign inc_bld4_cnt = ld_pcx_rq_sel[4] & ~perr_inv[4] & bld_pending[4]; // Reset the bld pending state when the final request is accepted. assign bld_reset[4] = ld_pcx_rq_sel[4] & (&(bld_cnt4[1:0])); // Requests 1-3 must prevent the ld_pcx_vld state from being reset so that // following requests still go to the pcx. assign bld_hold[4] = ~(&(bld_cnt4[1:0])) & bld_pending[4]; lsu_lmc_ctlmsff_ctl_macro__width_2 dff_bld_cnt4 ( .scan_in(dff_bld_cnt4_scanin), .scan_out(dff_bld_cnt4_scanout), .l1clk (l1clk_pm1), .din (bld_cnt4_in[1:0]), .dout (bld_cnt4[1:0]), .siclk(siclk), .soclk(soclk) ); // Thread 5 // Counter is incremented when the preceeding request was accepted. assign bld_cnt5_in[1:0] = bld_cnt5[1:0] + {1'b0,inc_bld5_cnt}; assign inc_bld5_cnt = ld_pcx_rq_sel[5] & ~perr_inv[5] & bld_pending[5]; // Reset the bld pending state when the final request is accepted. assign bld_reset[5] = ld_pcx_rq_sel[5] & (&(bld_cnt5[1:0])); // Requests 1-3 must prevent the ld_pcx_vld state from being reset so that // following requests still go to the pcx. assign bld_hold[5] = ~(&(bld_cnt5[1:0])) & bld_pending[5]; lsu_lmc_ctlmsff_ctl_macro__width_2 dff_bld_cnt5 ( .scan_in(dff_bld_cnt5_scanin), .scan_out(dff_bld_cnt5_scanout), .l1clk (l1clk_pm1), .din (bld_cnt5_in[1:0]), .dout (bld_cnt5[1:0]), .siclk(siclk), .soclk(soclk) ); // Thread 6 // Counter is incremented when the preceeding request was accepted. assign bld_cnt6_in[1:0] = bld_cnt6[1:0] + {1'b0,inc_bld6_cnt}; assign inc_bld6_cnt = ld_pcx_rq_sel[6] & ~perr_inv[6] & bld_pending[6]; // Reset the bld pending state when the final request is accepted. assign bld_reset[6] = ld_pcx_rq_sel[6] & (&(bld_cnt6[1:0])); // Requests 1-3 must prevent the ld_pcx_vld state from being reset so that // following requests still go to the pcx. assign bld_hold[6] = ~(&(bld_cnt6[1:0])) & bld_pending[6]; lsu_lmc_ctlmsff_ctl_macro__width_2 dff_bld_cnt6 ( .scan_in(dff_bld_cnt6_scanin), .scan_out(dff_bld_cnt6_scanout), .l1clk (l1clk_pm1), .din (bld_cnt6_in[1:0]), .dout (bld_cnt6[1:0]), .siclk(siclk), .soclk(soclk) ); // Thread 7 // Counter is incremented when the preceeding request was accepted. assign bld_cnt7_in[1:0] = bld_cnt7[1:0] + {1'b0,inc_bld7_cnt}; assign inc_bld7_cnt = ld_pcx_rq_sel[7] & ~perr_inv[7] & bld_pending[7]; // Reset the bld pending state when the final request is accepted. assign bld_reset[7] = ld_pcx_rq_sel[7] & (&(bld_cnt7[1:0])); // Requests 1-3 must prevent the ld_pcx_vld state from being reset so that // following requests still go to the pcx. assign bld_hold[7] = ~(&(bld_cnt7[1:0])) & bld_pending[7]; lsu_lmc_ctlmsff_ctl_macro__width_2 dff_bld_cnt7 ( .scan_in(dff_bld_cnt7_scanin), .scan_out(dff_bld_cnt7_scanout), .l1clk (l1clk_pm1), .din (bld_cnt7_in[1:0]), .dout (bld_cnt7[1:0]), .siclk(siclk), .soclk(soclk) ); // Increment Rd after a load returns (used for QUAD/LDD/BLD) // This path is also used to update the entry during a set invalidate to // clear the error code. assign lmc_rd_update[7:0] = {8{cic_l2fill_vld_e}} & lmc_byp_sel_e[7:0]; assign bld_annul_rst[7:0] = {8{(&lmd_rd_e[2:1] & cic_l2fill_vld_e)}} & lmc_byp_sel_e[7:0]; assign bld_annul_in[7:0] = ~bld_annul_rst[7:0] & (bld_annul[7:0] | bld_inst_w[7:0]); lsu_lmc_ctlmsff_ctl_macro__width_8 dff_bld_bypass ( .scan_in(dff_bld_bypass_scanin), .scan_out(dff_bld_bypass_scanout), .din (bld_annul_in[7:0]), .dout (bld_annul[7:0]), .l1clk(l1clk), .siclk(siclk), .soclk(soclk) ); assign block_load_annul = (cpq_mx_thread[0] & bld_annul[0]) | (cpq_mx_thread[1] & bld_annul[1]) | (cpq_mx_thread[2] & bld_annul[2]) | (cpq_mx_thread[3] & bld_annul[3]) | (cpq_mx_thread[4] & bld_annul[4]) | (cpq_mx_thread[5] & bld_annul[5]) | (cpq_mx_thread[6] & bld_annul[6]) | (cpq_mx_thread[7] & bld_annul[7]) ; assign lmc_bld_annul = block_load_annul; // Must track the l2miss behavior for block loads to properly trap & // write frf on perfmon events. Block loads will act based on the first // helper. If it misses, the entire instruction is considered a miss. assign bld_miss_set[7:0] = bld_annul[7:0] & cpq_mx_thread[7:0] & {8{lmd_rd_e[2:1] == 2'b00}} & {8{cid_l2miss}}; assign bld_miss_in[7:0] = (bld_miss_set[7:0] | bld_miss[7:0]) & ~({8{report_and_clear_error}} & cpq_mx_thread[7:0]); assign bld_miss[7:0] = bld_miss_set[7:0] | bld_miss_out[7:0]; assign bld_pass7 = |(bld_annul_rst[7:0]) & ~report_and_clear_error; lsu_lmc_ctlmsff_ctl_macro__width_9 dff_bld_miss ( .scan_in(dff_bld_miss_scanin), .scan_out(dff_bld_miss_scanout), .din ({bld_miss_in[7:0], bld_pass7}), .dout ({bld_miss_out[7:0],bld_pass7_done}), .l1clk(l1clk), .siclk(siclk), .soclk(soclk) ); assign lmc_bld_last_e = bld_pass7_done & report_and_clear_error; assign lmc_bld_miss_e = (cpq_mx_thread[0] & bld_miss[0]) | (cpq_mx_thread[1] & bld_miss[1]) | (cpq_mx_thread[2] & bld_miss[2]) | (cpq_mx_thread[3] & bld_miss[3]) | (cpq_mx_thread[4] & bld_miss[4]) | (cpq_mx_thread[5] & bld_miss[5]) | (cpq_mx_thread[6] & bld_miss[6]) | (cpq_mx_thread[7] & bld_miss[7]) ; //////////////////////////////////////////////////////////////////////////////// // Tracking issued prefetches //////////////////////////////////////////////////////////////////////////////// assign pref_issued[7:0] = (ld_all_sel_p4[7:0] & {8{ld_pcx_sel_p4 & lmd_pcx_pref & ~(early_ld_b_sel_p4 & flush_w)}}) | (thread_w[7:0] & {8{pref_inst_w & excep_only_flush_w}}) ; lsu_lmc_ctlmsff_ctl_macro__width_8 dff_pref_issued ( .scan_in(dff_pref_issued_scanin), .scan_out(dff_pref_issued_scanout), .din (pref_issued[7:0]), .dout (lmc_pref_issued[7:0]), .l1clk(l1clk), .siclk(siclk), .soclk(soclk) ); //////////////////////////////////////////////////////////////////////////////// // Figure size mask for loads // CAS(X)A uses the store format (00001111, 11110000, or 11111111) // Loads use 00=byte, 01=hw, 10=wd, 11=dw, 100=quad; 5 MSB's are zero //////////////////////////////////////////////////////////////////////////////// assign lmc_ld_sz[4] = casa_ld_to_pcx & (~lmd_addrb2 | lmd_sz_b0); assign lmc_ld_sz[3] = casa_ld_to_pcx & (lmd_addrb2 | lmd_sz_b0); assign lmc_ld_sz[2] = lmc_ld_sz[3] | (lmd_ldbl & lmd_sz_b0); assign lmc_ld_sz[1] = lmc_ld_sz[3] | (~casa_ld_to_pcx & lmd_sz_b1 & ~lmd_sz_b0) | (~lmd_ldbl & lmd_sz_b1 & lmd_sz_b0); assign lmc_ld_sz[0] = (casa_ld_to_pcx & lmd_addrb2) | (lmd_ldbl ^ lmd_sz_b0); //////////////////////////////////////////////////////////////////////////////// // Select hi or low 64b for load return // For LDD (sz=10), addr[3] determines // For QUAD (sz=11), first pass is hi, second is low //////////////////////////////////////////////////////////////////////////////// assign lmc_byp_data_hi = cic_cpq_ld_rdy & ~lmd_fill_addr_b3_e & ~(cic_oddrd_e & lmd_fill_sz_b0_e); //////////////////////////////////////////////////////////////////////////////// // Clock enable for the bypass/fill data register assign lmc_byp_data_enable = cic_l2fill_vld_e | byp_vld_e | cic_ext_interrupt; //////////////////////////////////////////////////////////////////////////////// // Parity errors require an inval request to be sent to L2. //////////////////////////////////////////////////////////////////////////////// assign perr_set[7:0] = {8{perror_w & ~(ld_raw_bypass_w | flush_w)}} & thread_w[7:0]; assign perr_inv_in[7:0] = perr_inv[7:0] & ~ld_pcx_rq_sel[7:0]; lsu_lmc_ctlmsff_ctl_macro__width_9 dff_perr ( .scan_in(dff_perr_scanin), .scan_out(dff_perr_scanout), .l1clk (l1clk_pm1), .din ({perr_inv_in[7:0], ld_inv_p3}), .dout ({perr_inv_out[7:0],ld_inv_p4}), .siclk(siclk), .soclk(soclk) ); assign perr_inv[7:0] = perr_inv_out[7:0] | perr_set[7:0]; // INV bit in pcx is asserted for line invalidation requests and for CAS2 packets // if the store buffer had a UE assign ld_inv_p3 = |(ld_pcx_rq_sel[7:0] & perr_inv[7:0]) | (sbc_force_inv & casa_bypass_e); // INV bit is also asserted for prefetch ICE assign lmc_ld_inv_p4 = ld_inv_p4 | (lmd_pcx_pref & lmd_ldbl); // Error is reported when the inval_all packet comes back // encoded error type: 00=valid, 01=tag, 10=mhit, 11=data assign lsu_dcvp_err_e2 = cic_set_inval & (~lmd_dc_err_e[1] & ~lmd_dc_err_e[0]); assign lsu_dctp_err_e2 = cic_set_inval & (~lmd_dc_err_e[1] & lmd_dc_err_e[0]); assign lsu_dcmh_err_e2 = cic_set_inval & ( lmd_dc_err_e[1] & ~lmd_dc_err_e[0]); assign lsu_dcdp_err_e2 = cic_set_inval & ( lmd_dc_err_e[1] & lmd_dc_err_e[0]); lsu_lmc_ctlmsff_ctl_macro__width_4 dff_dcerr ( .scan_in(dff_dcerr_scanin), .scan_out(dff_dcerr_scanout), .din ({lsu_dcvp_err_e2,lsu_dctp_err_e2,lsu_dcmh_err_e2,lsu_dcdp_err_e2}), .dout ({lsu_dcvp_err_g ,lsu_dctp_err_g ,lsu_dcmh_err_g ,lsu_dcdp_err_g }), .l1clk(l1clk), .siclk(siclk), .soclk(soclk) ); assign lsu_dcerr_tid_g[2:0] = lmc_cpq_tid_m[2:0]; // Check that errors are never signaled during normal testing //////////////////////////////////////////////////////////////////////////////// // L2 errors // Multi-cycle loads (LDD,BLD) must wait until the final update to report the // error. Block loads will stop updating registers once an unc. error is detected. // If multiple errors of different types are detected on the block load helpers, // the highest priority error will be reported. (UE > ND > CE) //////////////////////////////////////////////////////////////////////////////// assign l2_err[1:0] = ({2{cpq_mx_thread[0]}} & l2_err0[1:0]) | ({2{cpq_mx_thread[1]}} & l2_err1[1:0]) | ({2{cpq_mx_thread[2]}} & l2_err2[1:0]) | ({2{cpq_mx_thread[3]}} & l2_err3[1:0]) | ({2{cpq_mx_thread[4]}} & l2_err4[1:0]) | ({2{cpq_mx_thread[5]}} & l2_err5[1:0]) | ({2{cpq_mx_thread[6]}} & l2_err6[1:0]) | ({2{cpq_mx_thread[7]}} & l2_err7[1:0]) ; assign l2_err_qual[1] = cic_cpq_ld_rdy & ceter_pscce_cpq & ((cid_err[1] & ~cid_err[0] & cid_dcsoc_err_e & cerer_socu) | (cid_err[1] & ~cid_err[0] & ~cid_dcsoc_err_e & cerer_dcl2u) | (cid_err[1] & cid_err[0] & cerer_dcl2nd)); assign l2_err_qual[0] = cic_cpq_ld_rdy & ((~cid_err[1] & cid_err[0] & cid_dcsoc_err_e & cerer_socc) | (~cid_err[1] & cid_err[0] & ~cid_dcsoc_err_e & cerer_dcl2c) | ( cid_err[1] & cid_err[0] & ceter_pscce_cpq & cerer_dcl2nd)); assign l2_err_new[1] = l2_err[1] | l2_err_qual[1]; assign l2_err_new[0] = (l2_err[0] & ~l2_err_qual[1]) | (l2_err_qual[1] & l2_err_qual[0]) | (~l2_err[1] & l2_err_qual[0]) | (l2_err[1] & l2_err[0]); // Suppress register update on any uncorrectable error, including accumulated errors. assign lmc_l2_err_noup = l2_err_new[1]; // For uncorrectable errors on fill data, inject a parity error into the D$ // Don't need to worry about the accumulated error since LDD & BLD don't fill // Inject errors even if ceter.pscce is off (for timing reasons). assign lmc_l2_uerr = (cerer_dcl2u & cid_err[1] & ~cid_err[0]) | (cerer_dcl2nd & cid_err[1] & cid_err[0]); assign l2_err0_in[1:0] = cpq_mx_thread[0] ? (l2_err_new[1:0] & {2{~report_and_clear_error}}) : l2_err0[1:0]; assign l2_err1_in[1:0] = cpq_mx_thread[1] ? (l2_err_new[1:0] & {2{~report_and_clear_error}}) : l2_err1[1:0]; assign l2_err2_in[1:0] = cpq_mx_thread[2] ? (l2_err_new[1:0] & {2{~report_and_clear_error}}) : l2_err2[1:0]; assign l2_err3_in[1:0] = cpq_mx_thread[3] ? (l2_err_new[1:0] & {2{~report_and_clear_error}}) : l2_err3[1:0]; assign l2_err4_in[1:0] = cpq_mx_thread[4] ? (l2_err_new[1:0] & {2{~report_and_clear_error}}) : l2_err4[1:0]; assign l2_err5_in[1:0] = cpq_mx_thread[5] ? (l2_err_new[1:0] & {2{~report_and_clear_error}}) : l2_err5[1:0]; assign l2_err6_in[1:0] = cpq_mx_thread[6] ? (l2_err_new[1:0] & {2{~report_and_clear_error}}) : l2_err6[1:0]; assign l2_err7_in[1:0] = cpq_mx_thread[7] ? (l2_err_new[1:0] & {2{~report_and_clear_error}}) : l2_err7[1:0]; lsu_lmc_ctlmsff_ctl_macro__width_16 dff_l2errcode ( .scan_in(dff_l2errcode_scanin), .scan_out(dff_l2errcode_scanout), .din ({l2_err0_in[1:0],l2_err1_in[1:0],l2_err2_in[1:0],l2_err3_in[1:0], l2_err4_in[1:0],l2_err5_in[1:0],l2_err6_in[1:0],l2_err7_in[1:0]}), .dout ({l2_err0[1:0], l2_err1[1:0], l2_err2[1:0], l2_err3[1:0], l2_err4[1:0], l2_err5[1:0], l2_err6[1:0], l2_err7[1:0]}), .l1clk(l1clk), .siclk(siclk), .soclk(soclk) ); assign report_and_clear_error = cic_rtn_cmplt & ~block_load_annul; assign dcl2c_err = report_and_clear_error & (~l2_err_new[1] & l2_err_new[0]); assign dcl2u_err = report_and_clear_error & ( l2_err_new[1] & ~l2_err_new[0]); assign dcl2nd_err = report_and_clear_error & ( l2_err_new[1] & l2_err_new[0]); lsu_lmc_ctlmsff_ctl_macro__width_3 dff_l2err ( .scan_in(dff_l2err_scanin), .scan_out(dff_l2err_scanout), .din ({dcl2c_err, dcl2u_err, dcl2nd_err}), .dout ({lsu_dcl2c_err_g,lsu_dcl2u_err_g,lsu_dcl2nd_err_g}), .l1clk(l1clk), .siclk(siclk), .soclk(soclk) ); //////////////////////////////////////////////////////////////////////////////// // STB RAW errors //////////////////////////////////////////////////////////////////////////////// assign sbdlc_err = ld_raw_bypass_w3 & stb_cecc_err & ~stb_uecc_err & ceter_pscce_w3 & cerer_sbdlc; assign sbdlu_err = ld_raw_bypass_w3 & stb_uecc_err & ceter_pscce_w3 & cerer_sbdlu; assign stberr_tid[2:0] = ld_raw_bypass_w3 ? tid_w3[2:0] : sbc_st_sel_tid_p4[2:0]; lsu_lmc_ctlmsff_ctl_macro__width_5 dff_stberr ( .scan_in(dff_stberr_scanin), .scan_out(dff_stberr_scanout), .din ({sbdlc_err, sbdlu_err, stberr_tid[2:0]}), .dout ({lsu_sbdlc_err_g,lsu_sbdlu_err_g,lsu_stberr_tid_g[2:0]}), .l1clk(l1clk), .siclk(siclk), .soclk(soclk) ); //////////////////////////////////////////////////////////////////////////////// // xinval control // Because the IFU does not queue incoming packets, there is the possibility // that they process an ifill which requires D$ invalidation much earlier than // the LSU. This causes a problem because the fill will occur and the thread // could miss again before the D$ inval occurs. I will signal when an inval // is pending. During this time, the I$ will not service a miss from that thread. //////////////////////////////////////////////////////////////////////////////// assign xinval_pend_in[0] = cic_xinval[0] | (xinval_pend[0] & ~(cpq_xinval_m & lmc_cpq_tid_m[2:0] == 3'b000)); assign xinval_pend_in[1] = cic_xinval[1] | (xinval_pend[1] & ~(cpq_xinval_m & lmc_cpq_tid_m[2:0] == 3'b001)); assign xinval_pend_in[2] = cic_xinval[2] | (xinval_pend[2] & ~(cpq_xinval_m & lmc_cpq_tid_m[2:0] == 3'b010)); assign xinval_pend_in[3] = cic_xinval[3] | (xinval_pend[3] & ~(cpq_xinval_m & lmc_cpq_tid_m[2:0] == 3'b011)); assign xinval_pend_in[4] = cic_xinval[4] | (xinval_pend[4] & ~(cpq_xinval_m & lmc_cpq_tid_m[2:0] == 3'b100)); assign xinval_pend_in[5] = cic_xinval[5] | (xinval_pend[5] & ~(cpq_xinval_m & lmc_cpq_tid_m[2:0] == 3'b101)); assign xinval_pend_in[6] = cic_xinval[6] | (xinval_pend[6] & ~(cpq_xinval_m & lmc_cpq_tid_m[2:0] == 3'b110)); assign xinval_pend_in[7] = cic_xinval[7] | (xinval_pend[7] & ~(cpq_xinval_m & lmc_cpq_tid_m[2:0] == 3'b111)); lsu_lmc_ctlmsff_ctl_macro__width_9 dff_xinval_pend ( .scan_in(dff_xinval_pend_scanin), .scan_out(dff_xinval_pend_scanout), .din ({xinval_pend_in[7:0],cic_xinval_e}), .dout ({xinval_pend[7:0], cpq_xinval_m}), .l1clk(l1clk), .siclk(siclk), .soclk(soclk) ); assign lsu_ifu_no_miss[7:0] = xinval_pend[7:0]; //////////////////////////////////////////////////////////////////////////////// // Power management. // lmc has 2 clock domains. // 1. Free running (l1clk) // 2. Any load request pending (l1clk_pm1) // A third possible domain which represends any load miss outstanding could // gate ~50 flops but would require adding 8 flops and logic. Not worth it. //////////////////////////////////////////////////////////////////////////////// assign rqpend_clken = ~lsu_lsu_pmen | ld_inst_vld_b | ld_inst_nopref_w | pref_inst_w | (|(ld_pcx_vld[7:0])) | (|(ld_asi_vld[7:0])) | (|(ld_all_sel_p4[7:0])); //////////////////////////////////////////////////////////////////////////////// // BIST/DIAG //////////////////////////////////////////////////////////////////////////////// lsu_lmc_ctlmsff_ctl_macro__width_2 dff_bist_diag ( .scan_in(dff_bist_diag_scanin), .scan_out(dff_bist_diag_scanout), .din ({mbi_run, bist_or_diag_d}), .dout ({lmc_mbi_run,lmc_bist_or_diag_e}), .l1clk(l1clk), .siclk(siclk), .soclk(soclk) ); assign bist_or_diag_d = lmc_mbi_run | dcc_cache_diag_wr_b; lsu_lmc_ctlmsff_ctl_macro__scanreverse_1__width_6 dff_spares ( .scan_in(spares_scanin), .scan_out(spares_scanout), .din ({ld_inst_vld_b,5'b0 }), .dout ({ld_inst_vld_w,unused[4:0]}), .l1clk(l1clk), .siclk(siclk), .soclk(soclk) ); //spare_ctl_macro spares (num=6) ( // .scan_in(spares_scanin), // .scan_out(spares_scanout), // .l1clk (l1clk) //); supply0 vss; supply1 vdd; // fixscan start: assign dff_ceter_scanin = scan_in ; assign dff_cerer_scanin = dff_ceter_scanout ; assign dff_thread_w_scanin = dff_cerer_scanout ; assign dff_flush_b_scanin = dff_thread_w_scanout ; assign dff_flush_w_scanin = dff_flush_b_scanout ; assign dff_inst_b_scanin = dff_flush_w_scanout ; assign dff_inst_w_scanin = dff_inst_b_scanout ; assign dff_l2fill_scanin = dff_inst_w_scanout ; assign dff_unfilled_scanin = dff_l2fill_scanout ; assign dff_stb_raw_scanin = dff_unfilled_scanout ; assign dff_rawp_disable_scanin = dff_stb_raw_scanout ; assign dff_ldd_vld_scanin = dff_rawp_disable_scanout ; assign dff_ld_lmq_en_b_scanin = dff_ldd_vld_scanout ; assign dff_ld_pcx_vld_scanin = dff_ld_lmq_en_b_scanout ; assign dff_ld_asi_vld_scanin = dff_ld_pcx_vld_scanout ; assign lru8_scanin = dff_ld_asi_vld_scanout ; assign dff_ld_sel_scanin = lru8_scanout ; assign dff_ldd_out_scanin = dff_ld_sel_scanout ; assign dff_st_atom_p4_scanin = dff_ldd_out_scanout ; assign dff_st_atom_p5_scanin = dff_st_atom_p4_scanout ; assign dff_asi_indet_scanin = dff_st_atom_p5_scanout ; assign dff_cpq_tid_scanin = dff_asi_indet_scanout ; assign dff_ld_raw_w_scanin = dff_cpq_tid_scanout ; assign dff_ld_raw_w2_scanin = dff_ld_raw_w_scanout ; assign dff_ld_raw_w3_scanin = dff_ld_raw_w2_scanout ; assign dff_ldbyp_vld_scanin = dff_ld_raw_w3_scanout ; assign dff_ld_inst_e_scanin = dff_ldbyp_vld_scanout ; assign dff_byp_cnt_scanin = dff_ld_inst_e_scanout ; assign dff_thrd_byp_sel_m_scanin = dff_byp_cnt_scanout ; assign dff_bld_pending_scanin = dff_thrd_byp_sel_m_scanout; assign dff_bld_addr_scanin = dff_bld_pending_scanout ; assign dff_bld_cnt0_scanin = dff_bld_addr_scanout ; assign dff_bld_cnt1_scanin = dff_bld_cnt0_scanout ; assign dff_bld_cnt2_scanin = dff_bld_cnt1_scanout ; assign dff_bld_cnt3_scanin = dff_bld_cnt2_scanout ; assign dff_bld_cnt4_scanin = dff_bld_cnt3_scanout ; assign dff_bld_cnt5_scanin = dff_bld_cnt4_scanout ; assign dff_bld_cnt6_scanin = dff_bld_cnt5_scanout ; assign dff_bld_cnt7_scanin = dff_bld_cnt6_scanout ; assign dff_bld_bypass_scanin = dff_bld_cnt7_scanout ; assign dff_bld_miss_scanin = dff_bld_bypass_scanout ; assign dff_pref_issued_scanin = dff_bld_miss_scanout ; assign dff_perr_scanin = dff_pref_issued_scanout ; assign dff_dcerr_scanin = dff_perr_scanout ; assign dff_l2errcode_scanin = dff_dcerr_scanout ; assign dff_l2err_scanin = dff_l2errcode_scanout ; assign dff_stberr_scanin = dff_l2err_scanout ; assign dff_xinval_pend_scanin = dff_stberr_scanout ; assign dff_bist_diag_scanin = dff_xinval_pend_scanout ; assign spares_scanin = dff_bist_diag_scanout ; assign scan_out = spares_scanout ; // fixscan end: endmodule // any PARAMS parms go into naming of macro module lsu_lmc_ctll1clkhdr_ctl_macro ( l2clk, l1en, pce_ov, stop, se, l1clk); input l2clk; input l1en; input pce_ov; input stop; input se; output l1clk; cl_sc1_l1hdr_8x c_0 ( .l2clk(l2clk), .pce(l1en), .l1clk(l1clk), .se(se), .pce_ov(pce_ov), .stop(stop) ); endmodule // any PARAMS parms go into naming of macro module lsu_lmc_ctlmsff_ctl_macro__width_9 ( din, l1clk, scan_in, siclk, soclk, dout, scan_out); wire [8:0] fdin; wire [7:0] so; input [8:0] din; input l1clk; input scan_in; input siclk; input soclk; output [8:0] dout; output scan_out; assign fdin[8:0] = din[8:0]; dff #(9) d0_0 ( .l1clk(l1clk), .siclk(siclk), .soclk(soclk), .d(fdin[8:0]), .si({scan_in,so[7:0]}), .so({so[7:0],scan_out}), .q(dout[8:0]) ); endmodule // any PARAMS parms go into naming of macro module lsu_lmc_ctlmsff_ctl_macro__width_7 ( din, l1clk, scan_in, siclk, soclk, dout, scan_out); wire [6:0] fdin; wire [5:0] so; input [6:0] din; input l1clk; input scan_in; input siclk; input soclk; output [6:0] dout; output scan_out; assign fdin[6:0] = din[6:0]; dff #(7) d0_0 ( .l1clk(l1clk), .siclk(siclk), .soclk(soclk), .d(fdin[6:0]), .si({scan_in,so[5:0]}), .so({so[5:0],scan_out}), .q(dout[6:0]) ); endmodule // any PARAMS parms go into naming of macro module lsu_lmc_ctlmsff_ctl_macro__width_8 ( din, l1clk, scan_in, siclk, soclk, dout, scan_out); wire [7:0] fdin; wire [6:0] so; input [7:0] din; input l1clk; input scan_in; input siclk; input soclk; output [7:0] dout; output scan_out; assign fdin[7:0] = din[7:0]; dff #(8) d0_0 ( .l1clk(l1clk), .siclk(siclk), .soclk(soclk), .d(fdin[7:0]), .si({scan_in,so[6:0]}), .so({so[6:0],scan_out}), .q(dout[7:0]) ); endmodule // any PARAMS parms go into naming of macro module lsu_lmc_ctlmsff_ctl_macro__width_1 ( din, l1clk, scan_in, siclk, soclk, dout, scan_out); wire [0:0] fdin; input [0:0] din; input l1clk; input scan_in; input siclk; input soclk; output [0:0] dout; output scan_out; assign fdin[0:0] = din[0:0]; dff #(1) d0_0 ( .l1clk(l1clk), .siclk(siclk), .soclk(soclk), .d(fdin[0:0]), .si(scan_in), .so(scan_out), .q(dout[0:0]) ); endmodule // any PARAMS parms go into naming of macro module lsu_lmc_ctlmsff_ctl_macro__width_2 ( din, l1clk, scan_in, siclk, soclk, dout, scan_out); wire [1:0] fdin; wire [0:0] so; input [1:0] din; input l1clk; input scan_in; input siclk; input soclk; output [1:0] dout; output scan_out; assign fdin[1:0] = din[1:0]; dff #(2) d0_0 ( .l1clk(l1clk), .siclk(siclk), .soclk(soclk), .d(fdin[1:0]), .si({scan_in,so[0:0]}), .so({so[0:0],scan_out}), .q(dout[1:0]) ); endmodule // any PARAMS parms go into naming of macro module lsu_lmc_ctlmsff_ctl_macro__width_6 ( din, l1clk, scan_in, siclk, soclk, dout, scan_out); wire [5:0] fdin; wire [4:0] so; input [5:0] din; input l1clk; input scan_in; input siclk; input soclk; output [5:0] dout; output scan_out; assign fdin[5:0] = din[5:0]; dff #(6) d0_0 ( .l1clk(l1clk), .siclk(siclk), .soclk(soclk), .d(fdin[5:0]), .si({scan_in,so[4:0]}), .so({so[4:0],scan_out}), .q(dout[5:0]) ); endmodule // any PARAMS parms go into naming of macro module lsu_lmc_ctlmsff_ctl_macro__width_5 ( din, l1clk, scan_in, siclk, soclk, dout, scan_out); wire [4:0] fdin; wire [3:0] so; input [4:0] din; input l1clk; input scan_in; input siclk; input soclk; output [4:0] dout; output scan_out; assign fdin[4:0] = din[4:0]; dff #(5) d0_0 ( .l1clk(l1clk), .siclk(siclk), .soclk(soclk), .d(fdin[4:0]), .si({scan_in,so[3:0]}), .so({so[3:0],scan_out}), .q(dout[4:0]) ); endmodule // any PARAMS parms go into naming of macro module lsu_lmc_ctlmsff_ctl_macro__width_3 ( din, l1clk, scan_in, siclk, soclk, dout, scan_out); wire [2:0] fdin; wire [1:0] so; input [2:0] din; input l1clk; input scan_in; input siclk; input soclk; output [2:0] dout; output scan_out; assign fdin[2:0] = din[2:0]; dff #(3) d0_0 ( .l1clk(l1clk), .siclk(siclk), .soclk(soclk), .d(fdin[2:0]), .si({scan_in,so[1:0]}), .so({so[1:0],scan_out}), .q(dout[2:0]) ); endmodule // any PARAMS parms go into naming of macro module lsu_lmc_ctlmsff_ctl_macro__width_10 ( din, l1clk, scan_in, siclk, soclk, dout, scan_out); wire [9:0] fdin; wire [8:0] so; input [9:0] din; input l1clk; input scan_in; input siclk; input soclk; output [9:0] dout; output scan_out; assign fdin[9:0] = din[9:0]; dff #(10) d0_0 ( .l1clk(l1clk), .siclk(siclk), .soclk(soclk), .d(fdin[9:0]), .si({scan_in,so[8:0]}), .so({so[8:0],scan_out}), .q(dout[9:0]) ); endmodule // any PARAMS parms go into naming of macro module lsu_lmc_ctlmsff_ctl_macro__width_4 ( din, l1clk, scan_in, siclk, soclk, dout, scan_out); wire [3:0] fdin; wire [2:0] so; input [3:0] din; input l1clk; input scan_in; input siclk; input soclk; output [3:0] dout; output scan_out; assign fdin[3:0] = din[3:0]; dff #(4) d0_0 ( .l1clk(l1clk), .siclk(siclk), .soclk(soclk), .d(fdin[3:0]), .si({scan_in,so[2:0]}), .so({so[2:0],scan_out}), .q(dout[3:0]) ); endmodule // any PARAMS parms go into naming of macro module lsu_lmc_ctlmsff_ctl_macro__width_16 ( din, l1clk, scan_in, siclk, soclk, dout, scan_out); wire [15:0] fdin; wire [14:0] so; input [15:0] din; input l1clk; input scan_in; input siclk; input soclk; output [15:0] dout; output scan_out; assign fdin[15:0] = din[15:0]; dff #(16) d0_0 ( .l1clk(l1clk), .siclk(siclk), .soclk(soclk), .d(fdin[15:0]), .si({scan_in,so[14:0]}), .so({so[14:0],scan_out}), .q(dout[15:0]) ); endmodule // any PARAMS parms go into naming of macro module lsu_lmc_ctlmsff_ctl_macro__scanreverse_1__width_6 ( din, l1clk, scan_in, siclk, soclk, dout, scan_out); wire [5:0] fdin; wire [0:4] so; input [5:0] din; input l1clk; input scan_in; input siclk; input soclk; output [5:0] dout; output scan_out; assign fdin[5:0] = din[5:0]; dff #(6) d0_0 ( .l1clk(l1clk), .siclk(siclk), .soclk(soclk), .d(fdin[5:0]), .si({so[0:4],scan_in}), .so({scan_out,so[0:4]}), .q(dout[5:0]) ); endmodule