// ========== Copyright Header Begin ==========================================
// OpenSPARC T2 Processor File: lsu_mon.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
// ========== Copyright Header End ============================================
`define ASI_AIU_BIS_QUAD_LDD_P 8'h22
`define ASI_AIU_BIS_QUAD_LDD_S 8'h23
`define ASI_NUCLEUS_BIS_QUAD_LDD 8'h27
`define ASI_AIU_BIS_QUAD_LDD_P_LITTLE 8'h2A
`define ASI_AIU_BIS_QUAD_LDD_S_LITTLE 8'h2B
`define ASI_NUCLEUS_BIS_QUAD_LDD_LITTLE 8'h2F
`define ASI_BIS_QUAD_LDD_P 8'hE2
`define ASI_BIS_QUAD_LDD_S 8'hE3
`define ASI_BIS_QUAD_LDD_P_LITTLE 8'hEA
`define ASI_BIS_QUAD_LDD_S_LITTLE 8'hEB
`define ASI_QUAD_LDD 8'h24
`define ASI_QUAD_LDD_REAL 8'h26
`define ASI_QUAD_LDD_L 8'h2C
`define ASI_QUAD_LDD_REAL_L 8'h2E
`define ASI_BLK_AIUP 8'h16
`define ASI_BLK_AIUS 8'h17
`define ASI_BLK_AIUPL 8'h1e
`define ASI_BLK_AIUSL 8'h1f
`define ASI_BLK_COMMIT_P 8'hE0
`define ASI_BLK_COMMIT_S 8'hE1
`define PCX_RQTYP 128:124
`define PCX_CPU_ID 122:120
`define PCX_THR_ID 119:117
`define PCX_SWAP_LDSTUB 5'h7
`define CPX_RTNTYP 144:141
`define CPX_THR_ID 136:134
`define CPX_LSB_BITS 63:0
`define CPX_INVAL_VEC 95:64
`define LSU_MON_INST 188:168
`define TLB_MISS_Pend_Width 127:0
`define LD_Pend_Width 212:0
`define STB_Pend_Width 204:0
`define LAST_INST_Pend_Width 135:0
// If vcs_build_args NO_MONITORS, then module will be empty
reg [7:0] asi_e, imm_asi_e, asi_m, asi_b;
reg dec_altspace_e, dec_altspace_b, dec_altspace_m;
reg [1:0] exu_lsu_va_error_b;
reg [2:0] dec_lsu_tid_e, dec_lsu_tid_m, dec_lsu_tid_b, dec_lsu_tid_w;
reg [47:0] inst_pc_e, inst_pc_m, inst_pc_b, inst_pc_w;
reg [31:0] inst_e, inst_m, inst_b;
reg [47:0] vaddr_m, vaddr_b;
reg [63:0] int_st_data_m, int_st_data_b;
reg [63:0] fp_st_sata_fx2;
reg [20:0] lsu_inst_e, lsu_inst_m, lsu_inst_b;
reg mmu_dtlb_reload_d1, mmu_dtlb_reload_d2;
reg [`LD_Pend_Width] ld_pend_array[7:0];
reg [`LAST_INST_Pend_Width] last_inst_array[7:0];
reg [2:0] wrptr[7:0]; //Pts. to the STB entry into which data will be written next
reg [2:0] rdptr[7:0]; //Tracks the dealloc signal from STB
reg [2:0] iss_ptr[7:0]; //keeps track of when a store is issued from the STB to PCX
reg [2:0] ret_ptr[7:0]; //keeps track of when the response is received from
reg [`STB_Pend_Width] stb[63:0];
//reg [`TLB_MISS_Pend_Width] tlbmiss_pend_array[7:0];
reg [7:0] dcache_inv_cnt[7:0];
reg [7:0] st_rmo_cnt[7:0];
reg [31:0] dec_tg0_inst_d, dec_tg1_inst_d;
reg [7:0] lsu_bst_active;
reg [195:0] stb_alloc_data;
reg [195:0] bst_data, bst_inst_data;
reg [2:0] bst_active_thid;
reg [7:0] is_blkld; //reqd by lsu_ras_chkr to chk errors on blk ld.
reg [1:0] l2_blk_ld_errtype[7:0]; //Gives the type of err the ahd be reported by LSU if
//different types of err occur on blk ld helper returns
reg [1:0] st_priv[7:0]; //Gives the final priv level for an sbdiou/sbapp err that shd be
for (i = 0; i < 8; i = i+1)
l2_blk_ld_errtype[i] = 2'b0;
// avoid time zero ugliness. jp
//@(posedge `SPC0.l2clk);
//@(negedge `SPC0.l2clk);
//if (`PARGS.lsu_mon_on) enabled = 1;
3'h0: finish_mask = `PARGS.finish_mask[7:0];
3'h1: finish_mask = `PARGS.finish_mask[15:8];
3'h2: finish_mask = `PARGS.finish_mask[23:16];
3'h3: finish_mask = `PARGS.finish_mask[31:24];
3'h4: finish_mask = `PARGS.finish_mask[39:32];
3'h5: finish_mask = `PARGS.finish_mask[47:40];
3'h6: finish_mask = `PARGS.finish_mask[55:48];
3'h7: finish_mask = `PARGS.finish_mask[63:56];
if (~`TOP.in_reset & `PARGS.lsu_mon_on & ~reset_in_middle)
`PR_ALWAYS("lsu_mon", `ALWAYS, "Lsu_mon on, in_reset = 0.");
if (`TOP.in_reset & enabled)
`PR_ALWAYS("lsu_mon", `ALWAYS, "Reset asserted in the middle of the diag. Turned off Lsu_mon.");
always @ (posedge (tb_top.sim_status[0] & enabled))
if (|(ld_valid[7:0] & finish_mask[7:0]))
for (i = 0; i < 8; i=i+1)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> Ld requests pending at the end of simulation. ld_valid = %0h", core_id, ld_valid);
for (i = 0; i < 64; i=i+1)
if (stb_valid[i] & finish_mask[i[5:3]])
//chkr resets the stb valid bits when block_store_kill is asserted.
//in couple of failures block_store_kill was sampled asserted two cycles after
//lsu asserted stb_empty. The simulation ended the cycle stb_empty was sampled high
//causing moniotr firings with valid entries in stb at end of simulation. Now
//don't flag an error if squash bit is set and stb_valid is asserted at end
if (~is_squash_bit_set(i[5:0]))
Disp_STB_entry(i[5:3],i[2:0]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> Store requests pending at the end of simulation. stb_valid = %0h", core_id, stb_valid);
for (i = 0; i < 8; i=i+1)
if (finish_mask[i] & (pf_cnt[i] != 0))
`PR_ALWAYS("lsu_mon", `ALWAYS, "<C%h> <T%0h> Prefetches not finished. Pf_cnt = %0d", core_id, i, pf_cnt[i]);
if (finish_mask[i] & (dcache_inv_cnt[i] != 0))
`PR_ALWAYS("lsu_mon", `ALWAYS, "<C%h> <T%0h> D pkt not received for all invalidate reqs. issued by the thread. dcache_inv_cnt = %0d", core_id, i, dcache_inv_cnt[i]);
if (finish_mask[i] & (st_rmo_cnt[i] != 0))
`PR_ALWAYS("lsu_mon", `ALWAYS, "<C%h> <T%0h> rmo_cnt not zero. rmo_cnt = %0d", core_id, i, st_rmo_cnt[i]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> Prefetch/D/RMO_stores requests pending at the end of simulation.", core_id);
function is_squash_bit_set;
is_squash_bit_set = 1'b1;
is_squash_bit_set = 1'b0;
always @ (negedge (`SPC0.l2clk & enabled))
asi_e = `SPC0.lsu.dcc.dcc_asi_e[7:0];
lsu_inst_e[`LD] <= `SPC0.dec_ld_inst_e;
lsu_inst_e[`ST] <= `SPC0.dec_st_inst_e;
lsu_inst_e[`FP] <= `SPC0.dec_fpldst_inst_e;
lsu_inst_e[`PREF] <= `SPC0.dec_pref_inst_e;
lsu_inst_e[`SWAP] <= `SPC0.dec_swap_inst_e;
lsu_inst_e[`CASA] <= `SPC0.dec_casa_inst_e;
lsu_inst_e[`LDSTUB] <= `SPC0.dec_ldstub_inst_e;
lsu_inst_e[`FLUSH] <= `SPC0.dec_flush_inst_e;
lsu_inst_e[`MEMBAR] <= `SPC0.dec_memstbar_inst_e;
lsu_inst_e[`LDD] <= `SPC0.dec_ld_inst_e & `SPC0.dec_ldst_dbl_e & ~`SPC0.dec_fpldst_inst_e;
lsu_inst_e[`STD] <= `SPC0.dec_st_inst_e & `SPC0.dec_ldst_dbl_e & ~`SPC0.lsu.dec_fpldst_inst_e;
lsu_inst_e[`BLKLD] <= `SPC0.dec_ld_inst_e & `SPC0.dec_fpldst_inst_e & dec_altspace_e & Is_blk_asi(asi_e);
lsu_inst_e[`BLKST] <= `SPC0.dec_st_inst_e & `SPC0.dec_fpldst_inst_e & dec_altspace_e & Is_blk_asi(asi_e);
lsu_inst_e[`QLD] <= `SPC0.dec_ld_inst_e & dec_altspace_e & Is_qld_asi(asi_e);
lsu_inst_e[`ASR_RD_WR] <= `SPC0.dec_sr_inst_e & (`SPC0.dec_ld_inst_e | `SPC0.dec_st_inst_e);
lsu_inst_e[`PR_RD_WR] <= `SPC0.dec_pr_inst_e & (`SPC0.dec_ld_inst_e | `SPC0.dec_st_inst_e);
lsu_inst_e[`HPR_RD_WR] <= `SPC0.dec_hpr_inst_e & (`SPC0.dec_ld_inst_e | `SPC0.dec_st_inst_e);
lsu_inst_e[`FSR_RD_WR] <= `SPC0.dec_fsr_ldst_e & (`SPC0.dec_ld_inst_e | `SPC0.dec_st_inst_e);
always @ (posedge (`SPC0.l2clk & enabled))
dec_tg0_inst_d <= `SPC0.dec.ded0.decode_mux[31:0];
dec_tg1_inst_d <= `SPC0.dec.ded1.decode_mux[31:0];
imm_asi_vld_e <= `SPC0.lsu.dec_imm_asi_vld_d;
imm_asi_e <= `SPC0.lsu.dec_imm_asi_d;
dec_altspace_e <= `SPC0.dec_altspace_d;
dec_altspace_m <= dec_altspace_e;
dec_altspace_b <= dec_altspace_m;
exu_ecc_b <= `SPC0.exu_ecc_m;
exu_lsu_va_error_b <= `SPC0.exu_lsu_va_error_m;
dec_lsu_tid_e <= `SPC0.dec_lsu_tg_d ? {1'b1, `SPC0.dec_lsu_tid1_d} : {1'b0, `SPC0.dec_lsu_tid0_d};
dec_lsu_tid_m <= dec_lsu_tid_e;
dec_lsu_tid_b <= dec_lsu_tid_m;
dec_lsu_tid_w <= dec_lsu_tid_b;
inst_pc_e <= `SPC0.dec_lsu_tg_d ? {`SPC0.tlu.tlu_pc_1_d[47:2], 2'b0} : {`SPC0.tlu.tlu_pc_0_d[47:2], 2'b0};
inst_e <= `SPC0.dec_lsu_tg_d ? dec_tg1_inst_d : dec_tg0_inst_d;
vaddr_m <= `SPC0.exu_lsu_address_e;
int_st_data_m <= `SPC0.exu_lsu_store_data_e;
int_st_data_b <= int_st_data_m;
fp_st_sata_fx2 <= `SPC0.fgu_lsu_fst_data_fx1;
mmu_dtlb_reload_d1 <= `SPC0.mmu_dtlb_reload;
mmu_dtlb_reload_d2 <= mmu_dtlb_reload_d1;
//pcx_thid_d1 <= `SPC0.lsu.spc_pcx_data_pa[`PCX_THR_ID];
lsu_inst_m <= lsu_inst_e;
lsu_inst_b <= lsu_inst_m;
Is_blk_asi = (asi == `ASI_BLK_AIUP) | (asi == `ASI_BLK_AIUS) |
(asi == `ASI_BLK_AIUPL) | (asi == `ASI_BLK_AIUSL) |
(asi == `ASI_BLK_P) | (asi == `ASI_BLK_S) |
(asi == `ASI_BLK_PL) | (asi == `ASI_BLK_SL) |
(asi == `ASI_BLK_COMMIT_P) | (asi == `ASI_BLK_COMMIT_S);
Is_qld_asi = (asi == `ASI_AIU_BIS_QUAD_LDD_P) | (asi == `ASI_AIU_BIS_QUAD_LDD_S) |
(asi == `ASI_AIU_BIS_QUAD_LDD_P_LITTLE) | (asi == `ASI_AIU_BIS_QUAD_LDD_S_LITTLE) |
(asi == `ASI_NUCLEUS_BIS_QUAD_LDD) | (asi == `ASI_NUCLEUS_BIS_QUAD_LDD_LITTLE) |
(asi == `ASI_BIS_QUAD_LDD_P) | (asi == `ASI_BIS_QUAD_LDD_S) |
(asi == `ASI_BIS_QUAD_LDD_P_LITTLE) | (asi == `ASI_BIS_QUAD_LDD_S_LITTLE) |
(asi == `ASI_QUAD_LDD) | (asi == `ASI_QUAD_LDD_REAL) |
(asi == `ASI_QUAD_LDD_L) | (asi == `ASI_QUAD_LDD_REAL_L);
Is_bis_asi = (asi == `ASI_AIU_BIS_QUAD_LDD_P) | (asi == `ASI_AIU_BIS_QUAD_LDD_S) |
(asi == `ASI_AIU_BIS_QUAD_LDD_P_LITTLE) | (asi == `ASI_AIU_BIS_QUAD_LDD_S_LITTLE) |
(asi == `ASI_NUCLEUS_BIS_QUAD_LDD) | (asi == `ASI_NUCLEUS_BIS_QUAD_LDD_LITTLE) |
(asi == `ASI_BIS_QUAD_LDD_P) | (asi == `ASI_BIS_QUAD_LDD_S) |
(asi == `ASI_BIS_QUAD_LDD_P_LITTLE) | (asi == `ASI_BIS_QUAD_LDD_S_LITTLE);
always @ (negedge (`SPC0.l2clk & enabled))
`PR_INFO("lsu_mon", 21, "<C%0h> <T%0h> <%0h> M_stage: %s(VA=%0h) Flushed due to IFU Flush.", core_id, dec_lsu_tid_m, inst_pc_m, tb_top.intf0.xlate(inst_m),vaddr_m);
if (lsu_inst_b[`BLKLD]) print_inst = " BLKLD,";
else if (lsu_inst_b[`BLKST]) print_inst = " BLKST,";
else if (lsu_inst_b[`QLD]) print_inst = " QLD,";
`PR_INFO("lsu_mon", 21, "<C%0h> <T%0h> <%0h> B_stage: %s(VA=%0h) Flushed due to IFU Flush.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b);
else if (`SPC0.tlu_flush_lsu_b)
`PR_INFO("lsu_mon", 21, "<C%h> <T%0h> <%0h> B_stage: %s(VA=%0h) Flushed due to TLU Flush.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b);
//casa is a two cycle operation. If there is an err on the 2nd cycle of casa then also
//This function will also chk for errors on 2nd cycle.
else if (Is_exu_error(exu_lsu_va_error_b, exu_ecc_b))
`PR_INFO("lsu_mon", 21, "<C%h> <T%0h <%0h> B_stage: %s(VA=%0h) Flushed due to EXU error.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b);
else if ((`SPC0.fgu_cecc_fx2 || `SPC0.fgu_uecc_fx2) && lsu_inst_b[`ST] && lsu_inst_b[`FP])
`PR_INFO("lsu_mon", 21, "<C%h> <T%0h> <%0h> B_stage: %s(VA=%0h) Flushed due to FGU error.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b);
else if (!`SPC0.lsu_tlb_miss_b_)
`PR_INFO("lsu_mon", 23, "<C%h> <T%0h> <%0h> B_stage: %s(VA=%0h)%s ASI = %0h. DTLB miss.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b, print_inst, asi_b);
//Lsu doesn't assert lsu_sync for an exception or dtlb miss. Since for
//an exception tlu anyway tells the front end to flush itself there is
//no reason for LSU to flush the front end then TLU to flush it again.
//Lsu treats the dtlbmiss as an exception that it flushes the inst and
//handles it when it is reissued by the front end.
if (`SPC0.lsu_tlb_bypass_b)
if (`SPC0.lsu_sync != 8'b0)
`PR_INFO("lsu_mon", 23, "<C%h> <T%0h> <%0h>: %s(VA=%0h)%s PA = %0h, ASI = %0h. LSU_sync. DTLB Bypass.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b, print_inst, {`SPC0.lsu.tlb_pgnum[39:13], vaddr_b[12:0]}, asi_b);
`PR_INFO("lsu_mon", 23, "<C%h> <T%0h> <%0h>: %s(VA=%0h)%s PA = %0h, ASI = %0h. DTLB Bypass.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b, print_inst, {`SPC0.lsu.tlb_pgnum[39:13], vaddr_b[12:0]}, asi_b);
if (`SPC0.lsu_sync != 8'b0)
`PR_INFO("lsu_mon", 23, "<C%h> <T%0h> <%0h>: %s(VA=%0h)%s PA = %0h, ASI = %0h, Store_data = %0h. LSU_sync. DTLB hit.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b, print_inst, {`SPC0.lsu.tlb_pgnum[39:13], vaddr_b[12:0]}, asi_b,int_st_data_b);
`PR_INFO("lsu_mon", 23, "<C%h> <T%0h> <%0h>: %s(VA=%0h)%s PA = %0h, ASI = %0h. LSU_sync. DTLB hit.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b, print_inst, {`SPC0.lsu.tlb_pgnum[39:13], vaddr_b[12:0]}, asi_b);
`PR_INFO("lsu_mon", 23, "<C%h> <T%0h> <%0h>: %s(VA=%0h)%s PA = %0h, ASI = %0h, Store_data = %0h. DTLB hit.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b, print_inst, {`SPC0.lsu.tlb_pgnum[39:13], vaddr_b[12:0]}, asi_b, int_st_data_b);
`PR_INFO("lsu_mon", 23, "<C%h> <T%0h> <%0h>: %s(VA=%0h)%s PA = %0h, ASI = %0h. DTLB hit.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b, print_inst, {`SPC0.lsu.tlb_pgnum[39:13], vaddr_b[12:0]}, asi_b);
if (lsu_inst_b[`LD] || lsu_inst_b[`PREF] || lsu_inst_b[`SWAP] || lsu_inst_b[`CASA] || lsu_inst_b[`LDSTUB])
if (((lsu_inst_b == 16'h1) || (lsu_inst_b == 16'h5)) & `SPC0.lsu.stb_cam_hit)
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> <%0h>: LSU_sync asserted due to STB RAW.", core_id, dec_lsu_tid_b, inst_pc_b);
if (lsu_inst_b[`ST]) //for atomics both ld and store signals are asserted
Insert_in_last_inst_array;
if (`SPC0.lsu_trap_flush[7:0])
`PR_INFO("lsu_mon", 21, "<C%h> <T%0h> Trap Flush asserted.", core_id, decode_tid(`SPC0.lsu_trap_flush[7:0]));
//This is how we test squashing of stores by LSU_mon:
//Whenever lsu asserts err_sbdiou signal, the monitor sets the squash
//bit in the STB for the rest of the stores. If any of these squashed stores
//is issued on the asi ring or to the PCX interface the monitor complains.
//The squashed stores are deallocated when either a block_store_kill is
//asserted or dealloc signals are asserted by the LSU.
//When the block_store_kill is asserted, it tells the IFU to dealloc
//all the pending stores in the IFU. It means the when block_store_kill
//is asserted we have deallocated all the non-squashed requests from STB.
//The 0in_chkr ensures that LSU flags the correct index and priv with the
//the sbdiou signal to TLU.
always @ (negedge (`SPC0.l2clk & enabled))
if (`SPC0.lsu_l15_valid & `SPC0.lsu.spc_pcx_data_pa[129])
Chk_pcx_req_pkt(`SPC0.lsu.spc_pcx_data_pa[129:0]); //chk if we need .lsu here
if ((`SPC0.lsu_rngl_cdbus[64:63] == 2'b11) & ~`SPC0.lsu_rngl_cdbus[59])
Chk_st_on_ASI_ring(`LOCAL);
if ((`SPC0.lsu_rngf_cdbus[64:63] == 2'b11) & ~`SPC0.lsu_rngf_cdbus[59])
Chk_st_on_ASI_ring(`FAST);
//if (`SPC0.l15_lsu_valid)
//Chk_cpx_response_pkt({`SPC0.l15_lsu_valid, `SPC0.l15_lsu_cpkt[17:13],`SPC0.l15_lsu_cpkt[11:0],`SPC0.l15_spc_data1[127:0]});
if (`SPC0.cpx_spc_data_cx[145])
Chk_cpx_response_pkt(`SPC0.cpx_spc_data_cx);
if (`SPC0.lsu_complete[7:0] != 8'b0)
if (`SPC0.lsu_complete[0]) Chk_ld_complete(0);
if (`SPC0.lsu_complete[1]) Chk_ld_complete(1);
if (`SPC0.lsu_complete[2]) Chk_ld_complete(2);
if (`SPC0.lsu_complete[3]) Chk_ld_complete(3);
if (`SPC0.lsu_complete[4]) Chk_ld_complete(4);
if (`SPC0.lsu_complete[5]) Chk_ld_complete(5);
if (`SPC0.lsu_complete[6]) Chk_ld_complete(6);
if (`SPC0.lsu_complete[7]) Chk_ld_complete(7);
if (`SPC0.lsu_block_store_kill[7:0] != 8'b0)
if (`SPC0.lsu_block_store_kill[0]) Squash_STB(0);
if (`SPC0.lsu_block_store_kill[1]) Squash_STB(1);
if (`SPC0.lsu_block_store_kill[2]) Squash_STB(2);
if (`SPC0.lsu_block_store_kill[3]) Squash_STB(3);
if (`SPC0.lsu_block_store_kill[4]) Squash_STB(4);
if (`SPC0.lsu_block_store_kill[5]) Squash_STB(5);
if (`SPC0.lsu_block_store_kill[6]) Squash_STB(6);
if (`SPC0.lsu_block_store_kill[7]) Squash_STB(7);
if (`SPC0.lsu_stb_dealloc[7:0] != 8'b0)
if (`SPC0.lsu_stb_dealloc[0]) Dealloc_STB(0);
if (`SPC0.lsu_stb_dealloc[1]) Dealloc_STB(1);
if (`SPC0.lsu_stb_dealloc[2]) Dealloc_STB(2);
if (`SPC0.lsu_stb_dealloc[3]) Dealloc_STB(3);
if (`SPC0.lsu_stb_dealloc[4]) Dealloc_STB(4);
if (`SPC0.lsu_stb_dealloc[5]) Dealloc_STB(5);
if (`SPC0.lsu_stb_dealloc[6]) Dealloc_STB(6);
if (`SPC0.lsu_stb_dealloc[7]) Dealloc_STB(7);
if (`SPC0.lsu_block_store_stall)
if (`SPC0.lsu.lsu_block_store_alloc[7:0] != 8'b0)
Set_block_store_parameters;
if (`SPC0.lsu_sbdiou_err_g || `SPC0.lsu_sbapp_err_g)
if (`SPC0.lsu_stb_flush_g)
st_priv[`SPC0.lsu_stberr_tid_g] = get_priv_on_flush(`SPC0.lsu_stberr_tid_g);
function [1:0] get_priv_on_flush;
sq_index = `SPC0.lsu_stberr_index_g;
tmp = stb[{tid, sq_index}];
get_priv_on_flush = tmp[`ST_PRIV];
thid = `SPC0.lsu_block_store_tid;
bst_inst_data = stb[{thid, rdptr[thid]}];
inst = bst_inst_data[`LSU_MON_INST];
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> LSU asserted blk_store_stall while the req at the top of STB is not blkst as shown above", core_id, thid);
//lsu can assert block_store_stall for a new block store while it has not yet written
//the 8 stb entries from the previous blk store.
task Set_block_store_parameters;
thid = decode_tid(`SPC0.lsu.lsu_block_store_alloc[7:0]);
if (lsu_bst_active[thid])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> LSU asserted blk_store_alloc while the bst_active is already set for this thread.", core_id, thid);
lsu_bst_active[thid] = 1'b1;
if (`SPC0.lsu.fgu_fst_ecc_error_fx2)
thid = `SPC0.lsu_stberr_tid_g;
sq_index = `SPC0.lsu_stberr_index_g;
priv = `SPC0.lsu_stberr_priv_g;
tmp = stb[{thid, sq_index}];
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> Sbdiou/sbapp seen for index = %h and priv = %h.", core_id, thid, sq_index, priv);
st_priv[thid] = tmp[`ST_PRIV];
//lsu can assert deallocate before it asserts the sbdiou signal.
//In that case iss_ptr won't be equal to sbdiou index.
//if (sq_index != iss_ptr[thid])
// Disp_STB_entry(thid, iss_ptr[thid]);
// `PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> LSU asserted sbdiou/sbapp with index %0h while the next req to be issued is at index %0h.", core_id, thid, sq_index, iss_ptr[thid]);
//If there is only one store in the store buffer which gets an sbdiou error, then LSU can deallocate
//the store and then assert sbdiou. The deallocation will cause the stb issue_ptr to move
//forward to an inst. that has already been issued and completed and this chk can fire. So
// Disp_STB_entry(thid, iss_ptr[thid]);
// `PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> Store reissued on the PCX interface.", core_id, thid, tmp[`MEMOP_PA]);
if (iss_ptr[thid] == wrptr[thid])
if (stb_valid[{thid, wrptr[thid]}])
//changing it to an info message because if there is only one valid entry in store buffer that
//gets an sbdiou then LSU can deallocate the entry and then issue sbdiou.
//`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Lsu asserted sbdiou/sbapp while there are no valid entries in STB to be issued.", core_id, thid);
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> sbdiou/sbapp squashed only one entry in STB.", core_id, thid);
if (iss_ptr[thid] < wrptr[thid])
squash_cnt = wrptr[thid] - iss_ptr[thid];
else if (iss_ptr[thid] > wrptr[thid])
squash_cnt = wrptr[thid] + (8 - iss_ptr[thid]);
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> SQUASH_STORE:iss_ptr = %0h, wrptr = %0h, squash_cnt = %0h.", core_id, thid, iss_ptr[thid], wrptr[thid], squash_cnt);
if (priv < tmp[`ST_PRIV])
`PR_INFO("lsu_mon", `INFO, "<C%h> <T%0h> <PA = %0h> Sbdiou/sbapp signalled. Err in user/priv level store is squashing a higher priv level store.", core_id, thid, tmp[`MEMOP_PA]);
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> <PA = %0h> STB_entry[%0h] squashed.", core_id, thid, tmp[`MEMOP_PA], i);
squash_cnt = squash_cnt - 1'b1;
function [2:0] decode_tid;
8'h10: decode_tid = 3'h4;
8'h20: decode_tid = 3'h5;
8'h40: decode_tid = 3'h6;
8'h80: decode_tid = 3'h7;
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> decode_tid. Incorrect value of thid input = %0h.", core_id, thid_encode, thid_encode);
reg [`LD_Pend_Width] tmp;
tmp = ld_pend_array[thid];
if ((tmp[`L2_ISS] != 4'hf) || (tmp[`L2_RESP] != 4'hf))
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> LSU asserted lsu_complete while the l2_iss and l2_resp bits are not F.", core_id, thid);
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> <%0h> %s(VA=%0h) Complete. Setting ld_valid to 0.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA]);
tmp = last_inst_array[thid];
`PR_INFO("lsu_mon", 24, "<C%h> <T%0h> <%0h> %s(VA=%0h) Complete.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA]);
reg [`LD_Pend_Width] tmp, tmp1;
thid = pcx_pkt[`PCX_THR_ID];
tmp = ld_pend_array[thid];
inst = tmp[`LSU_MON_INST];
req = DispPCXReq(pcx_pkt);
addr = pcx_pkt[`PCX_ADDR];
if (pcx_pkt[`PCX_CPU_ID] != core_id)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> cpu_id (spc_pcx_data_pa[122:120]) = %h is not = %0h when the lsu made a %s req to gasket.", core_id, pcx_pkt[`PCX_THR_ID], addr, pcx_pkt[122:120], core_id, req);
if ((pcx_pkt[`PCX_RQTYP] == `PCX_LOAD) || (pcx_pkt[`PCX_RQTYP] == `PCX_CAS1) || (pcx_pkt[`PCX_RQTYP] == `PCX_CAS2) || (pcx_pkt[`PCX_RQTYP] == `PCX_SWAP_LDSTUB))
ld_valid[thid] = 1'b1; //we have sent a req to gasket and are waiting for response
`PR_INFO("lsu_mon", 22, "<C%0h> <T%0h> Setting ld_valid[%0h].", core_id, thid, thid);
if (tmp[`MEMOP_PA] != addr)
if ((tmp[`INST_ASI] == 8'h41) || (tmp[`INST_ASI] == 8'h73) || ((tmp[`INST_ASI] == 8'h45) && ((tmp[`MEMOP_PA] == 8'h10) || (tmp[`MEMOP_PA] == 8'h18))))
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <PA = %0h> PA mismatch on gasket for %s request. Ignoring the mismatch as inst. is issued with asi 41, 73 or 45 (with VA 0x10 or 18).", core_id, thid, addr, req);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> A %s request made to gasket by LSU while the pending req is with PA %0h.", core_id, thid, addr, req, tmp[`MEMOP_PA]);
case (pcx_pkt[`PCX_RQTYP])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> A prefetch request made to gasket by LSU which mismatches the pending request from the thread.", core_id, thid, addr);
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: PREF_ICE(VA=%0h) Issued. pf_cnt not updated.", core_id, thid, tmp[`INST_VA], tmp[`MEMOP_VA]);
pf_cnt[thid] = pf_cnt[thid] + 1'b1;
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) Issued. pf_cnt = %0d.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], pf_cnt[thid]);
tmp[`L2_RESP] = 4'hF; //we don't wait for a prefetch response from gasket
ld_pend_array[thid] = tmp;
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) Dcache invalidate pkt issued to CCX.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA]);
dcache_inv_cnt[thid] = dcache_inv_cnt[thid] + 1'b1;
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> CASA request made to gasket by LSU while no such request request is pending from this thread.", core_id, thid, addr);
if (pcx_pkt[`PCX_RQTYP] == `PCX_CAS1)
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) (CAS1) Issued to gasket.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA]);
ld_pend_array[thid] = tmp;
if (pcx_pkt[`PCX_RQTYP] == `PCX_CAS2)
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) (CAS2) Issued to gasket.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA]);
ld_pend_array[thid] = tmp;
chk_store_issue_to_pcx(pcx_pkt);
if (~inst[`SWAP] && ~inst[`LDSTUB])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> %s request made to gasket by LSU while no such request request is pending from this thread.", core_id, thid, addr, req);
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) Issued to gasket. store_data = %0h", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], pcx_pkt[`PCX_DATA]);
ld_pend_array[thid] = tmp;
chk_store_issue_to_pcx(pcx_pkt);
chk_store_issue_to_pcx(pcx_pkt);
default: `PR_INFO("lsu_mon", 21, "<C%h> <T%0h> <%0h>: %s Issued to gasket.", core_id, thid, addr, req);
task Chk_cpx_response_pkt;
thid = cpx_pkt[`CPX_THR_ID];
casex ({cpx_pkt[`CPX_RTNTYP], cpx_pkt[`CPX_ERR], cpx_pkt[`CPX_NC], cpx_pkt[`CPX_ATM], cpx_pkt[`CPX_PF]})
{4'b0, 2'bxx, 1'bx, 1'b0, 1'b0}:
chk_ccx_ld_response(cpx_pkt);
{4'b0, 2'bxx, 1'b1, 1'b0, 1'b1}:
if (pf_cnt[thid] == 8'b0)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Prefetch response received from gasket while the pf_cnt is 0 for this thread.", core_id, thid);
pf_cnt[thid] = pf_cnt[thid] - 1'b1;
`PR_INFO("lsu_mon", 26, "<C%h> <T%0h> Prefetch response received. pfcnt = %0d.", core_id, thid, pf_cnt[thid]);
{4'h8, 2'bxx, 1'b1, 1'b0, 1'b0}:
chk_ccx_ld_response(cpx_pkt);
{4'h4, 2'bxx, 1'bx, 1'b0, 1'b0}:
if (cpx_pkt[123]) //D pkt
if (cpx_pkt[120:118] != core_id)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> D response received from gasket with core_id =%h.", core_id, thid, cpx_pkt[120:118]);
if (dcache_inv_cnt[thid] == 8'b0)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> D response received from gasket while the Dcache_inv_cnt is 0 for this thread.", core_id, thid);
dcache_inv_cnt[thid] = dcache_inv_cnt[thid] - 1'b1;
`PR_INFO("lsu_mon", 26, "<C%h> <T%0h> D response received. Dcache_inv_cnt = %0d.", core_id, thid, dcache_inv_cnt[thid]);
else if (cpx_pkt[124]) //I pkt
if (cpx_pkt[120:118] != core_id)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> I response received from gasket with core_id =%h.", core_id, thid, cpx_pkt[120:118]);
//`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> I pkt.", core_id, thid);
else if (cpx_pkt[124:123] == 2'b0)
if (cpx_pkt[120:118] == core_id)
chk_ccx_st_response(cpx_pkt);
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> Store Ack pkt received from core %0h.", core_id, thid, cpx_pkt[120:118]);
{4'h1, 2'bxx, 1'bx, 1'b0, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> IFILL1 return.", core_id, thid);
{4'h1, 2'bxx, 1'bx, 1'b1, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> IFILL2 return.", core_id, thid);
{4'h9, 2'bxx, 1'b1, 1'b0, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> NCU IFILL return.", core_id, thid);
{4'b0, 2'bxx, 1'b1, 1'b1, 1'b0}:
chk_ccx_atm_response(cpx_pkt);
{4'h4, 2'bxx, 1'b1, 1'b1, 1'b0}:
if ((cpx_pkt[`CPX_RTNTYP] == 4'h4) & (cpx_pkt[120:118] == core_id))
chk_ccx_atm_response(cpx_pkt);
chk_ccx_st_response(cpx_pkt);
{4'h2, 2'bxx, 1'b1, 1'b0, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> Stream Ld return.", core_id, thid);
{4'h6, 2'bxx, 1'bx, 1'bx, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> Stream store Ack.", core_id, thid);
{4'h5, 2'bxx, 1'b1, 1'b0, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> MMU ld return.", core_id, thid);
{4'h7, 2'b00, 1'b0, 1'bx, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> Interrupt return.", core_id, thid);
{4'h3, 2'b00, 1'bx, 1'bx, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> Eviction Invalidation.", core_id, thid);
{4'hc, 2'bxx, 1'bx, 1'bx, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> L2 Indication.", core_id, thid);
{4'hd, 2'bxx, 1'bx, 1'bx, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> Soc Error Indication.", core_id, thid);
`PR_ALWAYS("lsu_mon", `ALWAYS, "CPX_PKT data.");
`PR_ALWAYS("lsu_mon", `ALWAYS, "<C%0h> <T%0h> rtn_typ = %0h, err_bits = %0h, nc=%0b, atm = %0b, pf = %0b", core_id, cpx_pkt[`CPX_THR_ID], cpx_pkt[`CPX_RTNTYP], cpx_pkt[`CPX_ERR], cpx_pkt[`CPX_NC], cpx_pkt[`CPX_ATM], cpx_pkt[`CPX_PF]);
`PR_ERROR("lsu_mon", `ERROR, "<C%0h> <T%0h> Can't recognise the CPX pkt.", core_id, thid);
task chk_ccx_ld_response;
reg [39:0] cpx_pa, inst_pa;
reg [`LD_Pend_Width] tmp;
thid = cpx_pkt[`CPX_THR_ID];
tmp = ld_pend_array[thid];
inst = tmp[`LSU_MON_INST];
inst_pa = tmp[`MEMOP_PA];
pkt_type = cpx_pkt[`CPX_RTNTYP];
`PR_INFO("lsu_mon", 26, "<C%0h> <T%0h> <%0h> %s(VA=%0h) L2 response.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA]);
if (inst_pa[39] != pkt_type[3])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> ccx pkt_type = %h mismatches the ld_pa bit 39. ld_pa = %0h.", core_id, thid, pkt_type, inst_pa);
if (tmp[`L2_RESP] == 4'h0)
tmp[`L2_ERR0] = cpx_pkt[`CPX_ERR];
if ((cpx_pkt[`CPX_ERR] == `ND) || (cpx_pkt[`CPX_ERR] == `UE))
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> UE/ND err on blk ld helper 1.", core_id, thid);
else if (tmp[`L2_RESP] == 4'h1)
tmp[`L2_ERR1] = cpx_pkt[`CPX_ERR];
if ((cpx_pkt[`CPX_ERR] == `ND) || (cpx_pkt[`CPX_ERR] == `UE))
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> UE/ND err on blk ld helper 2.", core_id, thid);
else if (tmp[`L2_RESP] == 4'h3)
tmp[`L2_ERR2] = cpx_pkt[`CPX_ERR];
if ((cpx_pkt[`CPX_ERR] == `ND) || (cpx_pkt[`CPX_ERR] == `UE))
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> UE/ND err on blk ld helper 3.", core_id, thid);
else if (tmp[`L2_RESP] == 4'h7)
tmp[`L2_ERR3] = cpx_pkt[`CPX_ERR];
if ((cpx_pkt[`CPX_ERR] == `ND) || (cpx_pkt[`CPX_ERR] == `UE))
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> UE/ND err on blk ld helper 4.", core_id, thid);
if ((tmp[`L2_ERR0] == `ND) || (tmp[`L2_ERR1] == `ND) || (tmp[`L2_ERR2] == `ND) || (tmp[`L2_ERR3] == `ND))
l2_blk_ld_errtype[thid] = `ND;
else if ((tmp[`L2_ERR0] == `UE) || (tmp[`L2_ERR1] == `UE) || (tmp[`L2_ERR2] == `UE) || (tmp[`L2_ERR3] == `UE))
l2_blk_ld_errtype[thid] = `UE;
else if ((tmp[`L2_ERR0] == `CE) || (tmp[`L2_ERR1] == `CE) || (tmp[`L2_ERR2] == `CE) || (tmp[`L2_ERR3] == `CE))
l2_blk_ld_errtype[thid] = `CE;
l2_blk_ld_errtype[thid] = `NE;
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Illegal value of l2_resp cnt when response pkt received from ccx.", core_id, thid);
else if (Is_single_pcx_req_ld(inst))
if (tmp[`L2_RESP] != 4'hE)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Illegal value of l2_resp cnt when response pkt received from ccx.", core_id, thid);
//`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> Setting L2_resp bits to F.", core_id, thid);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Load response received from gasket for thid %h while no load request pending from core for this thread.", core_id, thid, thid);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Load response received from gasket while no load request pending from core for this thread.", core_id, thid);
ld_pend_array[thid] = tmp;
task chk_ccx_atm_response;
reg [`LD_Pend_Width] tmp;
thid = cpx_pkt[`CPX_THR_ID];
tmp = ld_pend_array[thid];
inst = tmp[`LSU_MON_INST];
inst_pa = tmp[`MEMOP_PA];
if (cpx_pkt[`CPX_RTNTYP] == 4'b0)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Atomic ld response received from gasket while no request pending from core for this thread.", core_id, thid);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Atomic ack response received from gasket while no request pending from core for this thread.", core_id, thid);
if (~inst[`SWAP] && ~inst[`CASA] && ~inst[`LDSTUB])
if (cpx_pkt[`CPX_RTNTYP] == 4'b0)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Atomic ld response received from gasket which mismatches the request pending from this thread.", core_id, thid);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Atomic ack response received from gasket which mismatches the request pending from this thread.", core_id, thid);
if (cpx_pkt[`CPX_RTNTYP] == 4'b0)
`PR_INFO("lsu_mon", 26, "<C%0h> <T%0h> <%0h> %s(VA=%0h) Atomic ld response.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA]);
`PR_INFO("lsu_mon", 26, "<C%0h> <T%0h> <%0h> %s(VA=%0h) Atomic ack.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA]);
if (cpx_pkt[`CPX_RTNTYP] == 4'b0)
if (tmp[`L2_RESP] == 4'hC) tmp[`L2_RESP] = 4'hD;
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Illegal value of l2_resp cnt when atomic ld return pkt received from ccx.", core_id, thid);
if (tmp[`L2_RESP] == 4'hD) tmp[`L2_RESP] = 4'hF;
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Illegal value of l2_resp cnt when atomic ack pkt received from ccx.", core_id, thid);
ld_pend_array[thid] = tmp;
task chk_ccx_st_response;
reg [39:0] cpx_pa, inst_pa;
thid = cpx_pkt[`CPX_THR_ID];
tmp = stb[{thid, ret_ptr[thid]}];
inst = tmp[`LSU_MON_INST];
inst_pa = tmp[`MEMOP_PA];
pkt_type = cpx_pkt[`CPX_RTNTYP];
//is received. There could be some other store sitting in the STB at that time.
//Chk for squash bit only for non-bis responses.
if (cpx_pkt[`CPX_BIS]) //response to rmo store
if (st_rmo_cnt[thid] == 0)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> L2 response received for an rmo store while the st_rmo_cnt for this thread is 0.", core_id, thid);
st_rmo_cnt[thid] = st_rmo_cnt[thid] - 1'b1;
`PR_INFO("lsu_mon", 25, "<C%0h> <T%0h> Store ack received for RMO store. rmo_cnt = %0d", core_id, thid, st_rmo_cnt[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> L2 response received while the SQUASH bit is set in the STB entry %0h.", core_id, thid, ret_ptr[thid]);
if (~stb_valid[{thid, ret_ptr[thid]}])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Store ack received while that entry is invalid in STB.", core_id, thid);
if (~cpx_pkt[`CPX_ATM]) //don't print this message for atomic return
`PR_INFO("lsu_mon", 26, "<C%0h> <T%0h> <%0h> %s(VA=%0h) STB[%0d] Store ack.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA], ret_ptr[thid]);
stb[{thid, ret_ptr[thid]}] = tmp;
ret_ptr[thid] = ret_ptr[thid] + 1'b1;
//`PR_INFO("lsu_mon", 22, "<C%0h> <T%0h> ret_ptr = %0d.", core_id, thid, ret_ptr[thid]);
reg [`LD_Pend_Width] tmp;
reg [39:0] pcx_pa, inst_pa;
thid = pcx_pkt[`PCX_THR_ID];
tmp = ld_pend_array[thid];
inst = tmp[`LSU_MON_INST];
pcx_pa = pcx_pkt[`PCX_ADDR];
inst_pa = tmp[`MEMOP_PA];
req = DispPCXReq(pcx_pkt);
if (pcx_pa[39:6] != inst_pa[39:6])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> A load request made to gasket by LSU while the pending req has PA %0h.", core_id, thid, pcx_pa, tmp[`MEMOP_PA]);
if (tmp[`L2_ISS] != 4'h0 )
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> 1st load request (pa[5:0] = 6'b0) made to gasket by LSU for blkld while this request has already been issued to gasket.", core_id, thid, pcx_pa);
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) 1st blkld helper Issued to gasket.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA]);
if (pcx_pa[5:0] == 6'h10)
if (tmp[`L2_ISS] != 4'h1)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> 2nd load request (pa[5:0] = 6'h10) made to gasket by LSU for blkld while this request has already been issued to gasket.", core_id, thid, pcx_pa);
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) 2nd blkld helper Issued to gasket.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA]);
if (pcx_pa[5:0] == 6'h20)
if (tmp[`L2_ISS] != 4'h3)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> 3rd load request (pa[5:0] = 6'h20) made to gasket by LSU for blkld while this request has already been issued to gasket.", core_id, thid, pcx_pa);
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) 3rd blkld helper Issued to gasket.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA]);
if (pcx_pa[5:0] == 6'h30)
if (tmp[`L2_ISS] != 4'h7)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> 4th load request (pa[5:0] = 6'h30) made to gasket by LSU for blkld while this request has already been issued to gasket.", core_id, thid, pcx_pa);
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) 4th blkld helper Issued to gasket.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA]);
ld_pend_array[thid] = tmp;
else if (Is_single_pcx_req_ld(inst))
if (tmp[`L2_ISS] == 4'hF)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> Load request made to gasket by LSU while this request has already been issued to gasket.", core_id, thid, pcx_pa);
ld_pend_array[thid] = tmp;
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) Issued to gasket.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> A load request made to gasket by LSU while there is no such ld request pending from this thread.", core_id, thid, pcx_pa);
function Is_single_pcx_req_ld;
if (inst[`LDD] || inst[`QLD] || inst[`FSR_RD_WR] || (inst == 21'h1) || (inst == 21'h5))
Is_single_pcx_req_ld = 1'b1;
Is_single_pcx_req_ld = 1'b0;
//`PR_INFO("lsu_mon", 22, "<C%0h> Is_single_pcx_req_ld = %b. ", core_id, Is_single_pcx_req_ld);
case (`SPC0.lsu_trap_flush[7:0])
8'h01: if (tid == 3'h0) Is_trap = 1'b1;
8'h02: if (tid == 3'h1) Is_trap = 1'b1;
8'h04: if (tid == 3'h2) Is_trap = 1'b1;
8'h08: if (tid == 3'h3) Is_trap = 1'b1;
8'h10: if (tid == 3'h4) Is_trap = 1'b1;
8'h20: if (tid == 3'h5) Is_trap = 1'b1;
8'h40: if (tid == 3'h6) Is_trap = 1'b1;
8'h80: if (tid == 3'h7) Is_trap = 1'b1;
function [8*11:0] DispPCXReq;
casex ({pcx_pkt[`PCX_RQTYP], pcx_pkt[`PCX_NC], pcx_pkt[`PCX_INV], pcx_pkt[`PCX_PF], pcx_pkt[`PCX_BIS]})
{5'h0, 1'b1, 1'b0, 1'b1, 1'b0}: DispPCXReq = "PREF";
{5'h0, 1'b1, 1'b1, 1'b1, 1'b0}: DispPCXReq = "PREF_ICE";
{5'h0, 1'bx, 1'b0, 1'b0, 1'b0}: DispPCXReq = "LD";
{5'h0, 1'bx, 1'b1, 1'b0, 1'b0}: DispPCXReq = "D";
{5'h10, 1'bx, 1'b0, 1'b0, 1'b0}: DispPCXReq = "I";
{5'h10, 1'b0, 1'b1, 1'b0, 1'b0}: DispPCXReq = "I";
{5'h1, 1'bX, 1'bX, 1'b0, 1'b0}: DispPCXReq = "ST";
{5'h1, 1'bX, 1'bX, 1'b1, 1'b1}: DispPCXReq = "BLKST";
{5'h1, 1'bX, 1'bX, 1'b0, 1'b1}: DispPCXReq = "BIS";
{5'h2, 1'b1, 1'bX, 1'b0, 1'b0}: DispPCXReq = "CASA1";
{5'h3, 1'b1, 1'bX, 1'b0, 1'b0}: DispPCXReq = "CASA2";
{5'h7, 1'b1, 1'bX, 1'b0, 1'b0}: DispPCXReq = "SWAP_LDSTUB";
{5'h4, 1'b1, 1'b0, 1'b0, 1'b0}: DispPCXReq = "STREAM_LD";
{5'h5, 1'b1, 1'b0, 1'b0, 1'bx}: DispPCXReq = "STREAM_ST";
{5'h8, 1'b1, 1'b0, 1'b0, 1'b0}: DispPCXReq = "MMU_LD";
//{5'h9, 1'b0, 1'b0, 1'b0, 1'b0}: DispPCXReq = "INT";
`PR_ERROR("lsu_mon", `ERROR, "<C%0h> <T%0h> <%0h> Can't recognise the PCX pkt type. rq_type = %h, nc_bit = %0b, inv_bit = %0b, pf_bit = %0b, bis_bit = %0b. pcx_pkt[129:0] = %h", core_id, pcx_pkt[`PCX_THR_ID], pcx_pkt[`PCX_ADDR], pcx_pkt[`PCX_RQTYP], pcx_pkt[`PCX_NC], pcx_pkt[`PCX_INV], pcx_pkt[`PCX_PF], pcx_pkt[`PCX_BIS], pcx_pkt);
if (`SPC0.lsu_align_b) DispExc = "Addr_not_aligned";
if (`SPC0.lsu_lddf_align_b) DispExc = "LDDF_Addr_not_aligned";
if (`SPC0.lsu_stdf_align_b) DispExc = "STDF_Addr_not_aligned";
if (`SPC0.lsu_priv_action_b) DispExc = "Priv_actio";
if (`SPC0.lsu_va_watchpoint_b) DispExc = "VA_watchpoint";
if (`SPC0.lsu_pa_watchpoint_b) DispExc = "PA_watchpoint";
//if (`SPC0.lsu_tlb_miss_b_) DispExc = "Tlb_miss";
if (`SPC0.lsu_illegal_inst_b) DispExc = "Illegal_inst";
if (`SPC0.lsu_daccess_prot_b) DispExc = "Data_access_prot_exc";
if (`SPC0.lsu_dae_invalid_asi_b) DispExc = "Dae_Invalid_asi";
if (`SPC0.lsu_dae_nc_page_b) DispExc = "Dae_nc_page";
if (`SPC0.lsu_dae_nfo_page_b) DispExc = "Dae_NFO_page";
if (`SPC0.lsu_dae_priv_viol_b) DispExc = "Dae_Priv_viol";
if (`SPC0.lsu_dae_so_page) DispExc = "Dae_so_page";
//if (`SPC0.lsu_perfmon_trap_b) DispExc = "Perf_mon_trap";
if (`SPC0.lsu_dtmh_err_b) DispExc = "DTLB_data_par_err";
if (`SPC0.lsu_dttp_err_b) DispExc = "DTLB_tag_par_err";
if (`SPC0.lsu_dtdp_err_b) DispExc = "DTLB_data_par_err";
`PR_INFO("lsu_mon", 23, "<C%0h> <T%0h> <%0h> B_stage: %s(VA=%0h) ASI = %0h. %s Exception.",core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b, asi_b, DispExc);
input [1:0] exu_lsu_va_error_b; // VA error requiring a flush
input [1:0] exu_ecc_b; // ECC error requiring a flush
err_b = dec_lsu_tid_b[2] ? (exu_ecc_b[1] | (exu_lsu_va_error_b[1] & ~`SPC0.lsu_tlb_bypass_b)):
(exu_ecc_b[0] | (exu_lsu_va_error_b[0] & ~`SPC0.lsu_tlb_bypass_b));
err_m = (dec_lsu_tid_b[2] ? `SPC0.exu_ecc_m[1] : `SPC0.exu_ecc_m[0]) & `SPC0.lsu.dcc.twocycle_b;
Is_exu_error = err_b | err_m;
task Insert_tlb_miss_info;
if (tlb_valid[dec_lsu_tid_b])
tmp = tlbmiss_pend_array[dec_lsu_tid_b];
Disp_tlbmiss_pend_array_entry(dec_lsu_tid_b);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <%0h> B_stage: %s(VA=%0h>) A new tlb miss request received while there is already a Tlb miss request pending from this thread as shown above.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b);
tlb_valid[dec_lsu_tid_b] <= 1'b1;
tmp[`INST_VA] = inst_pc_b;
tmp[`MEMOP_VA] = vaddr_b;
tlbmiss_pend_array[dec_lsu_tid_b] = tmp;
//problem with the signal.
always @ (negedge `SPC0.l2clk)
if (`SPC0.tlu_trap_pc_0_valid)
thid = {1'b0, `SPC0.tlu_trap_0_tid};
else if (`SPC0.tlu_trap_pc_1_valid)
thid = {1'b0, `SPC0.tlu_trap_1_tid};
`PR_ERROR("lsu_mon", `ERROR, "<C%h> mmu_dtlb_reload asserted but trap_pc_0_valid and trap_pc_1_valid are both 0", core_id);
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> mmu_dtlb_reload asserted while tlb_valid is 0.", core_id, thid);
tmp = tlbmiss_pend_array[dec_lsu_tid_b];
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> %s(VA=%0h> DTLB reloaded for VA = %0h.", core_id, thid, tb_top.intf0.xlate(tmp[`INST]), tmp[`INST_VA], tmp[`MEMOP_VA] );
task Insert_ld_miss_info;
reg [`LD_Pend_Width] tmp;
if (ld_valid[dec_lsu_tid_b])
tmp = ld_pend_array[dec_lsu_tid_b];
DispPendReq(dec_lsu_tid_b);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <%0h> B_stage: %s(VA=%0h>) A new request received while there is already a request pending from this thread as shown above.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b);
//ld_valid[dec_lsu_tid_b] <= 1'b1;
tmp[`INST_VA] = inst_pc_b;
tmp[`MEMOP_VA] = vaddr_b;
tmp[`MEMOP_PA] = {`SPC0.lsu.tlb_pgnum[39:13], vaddr_b[12:0]};
is_blkld[dec_lsu_tid_b] = 1'b1;
is_blkld[dec_lsu_tid_b] = 1'b0;
if (lsu_inst_b[`SWAP] || lsu_inst_b[`LDSTUB] || lsu_inst_b[`CASA])
tmp[`LSU_MON_INST] = lsu_inst_b;
ld_pend_array[dec_lsu_tid_b] = tmp;
task Insert_in_last_inst_array;
tmp[`INST_VA] = inst_pc_b;
tmp[`MEMOP_VA] = vaddr_b;
last_inst_array[dec_lsu_tid_b] = tmp;
reg [`LD_Pend_Width] tmp;
tmp = ld_pend_array[thid];
`PR_ALWAYS("lsu_mon", `ALWAYS, "LD_PEND_ARRAY[%0h] Data.", thid);
`PR_ALWAYS("lsu_mon", `ALWAYS, "<C%h> <T%0h> <%0h> %s(VA=%0h). PA = %0h. L2_ISS = %0h. L2_RESP = %0h, LSU_MON_INST=%h.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA], tmp[`MEMOP_PA], tmp[`L2_ISS], tmp[`L2_RESP], tmp[`LSU_MON_INST]);
`PR_ALWAYS("lsu_mon", `ALWAYS, "<C%h> <T%0h> STB[%0h] data.", core_id, thid, ptr);
`PR_ALWAYS("lsu_mon", `ALWAYS, "<C%h> <T%0h> <%0h> %s(VA=%0h). PA = %0h. L2_ISS = %0h. L2_ACK = %0h, LSU_MON_INST=%h. RMO = %0b", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA], tmp[`MEMOP_PA], tmp[`L2_ST_ISS], tmp[`L2_ACK], tmp[`LSU_MON_INST], tmp[`RMO]);
task Disp_tlbmiss_pend_array_entry;
tmp = tlbmiss_pend_array[thid];
`PR_INFO("lsu_mon", 23, "TLB_MISS_PEND_ARRAY[%0h] Data.", thid);
`PR_INFO("lsu_mon", 23, "<C%h> <T%0h> <%0h> %s(VA=%0h).", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA]);
`PR_ALWAYS("lsu_mon", `ALWAYS, "CPX_PKT data.");
`PR_ALWAYS("lsu_mon", `ALWAYS, "<C%0h> <T%0h> rtn_typ = %0h, err_bits = %0h, nc=%0b, atm = %0b, pf = %0b", core_id, cpx_pkt[`CPX_THR_ID], cpx_pkt[`CPX_RTNTYP], cpx_pkt[`CPX_ERR], cpx_pkt[`CPX_NC], cpx_pkt[`CPX_ATM], cpx_pkt[`CPX_PF]);
tmp[`INST_VA] = inst_pc_b;
tmp[`MEMOP_VA] = vaddr_b;
tmp[`MEMOP_PA] = {`SPC0.lsu.tlb_pgnum[39:13], vaddr_b[12:0]};
tmp[`LSU_MON_INST] = lsu_inst_b;
if (`SPC0.lsu.tlu_lsu_hpstate_hpriv[dec_lsu_tid_b])
else if (`SPC0.lsu.tlu_lsu_pstate_priv[dec_lsu_tid_b])
//bis_asi to io space is not rmo
tmp[`RMO] = lsu_inst_b[`BLKST] | (dec_altspace_b & Is_bis_asi(asi_b) & ~`SPC0.lsu.tlb_pgnum[39]);
input [195:0] store_data;
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> STB full and a new store received for insertion in STB.", core_id, thid);
stb[{thid, wrptr[thid]}] = store_data;
//Disp_STB_entry(thid, wrptr[thid]);
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> <%0h> %s(VA=%0h). STB[%0h] Inserted.", core_id, thid, store_data[`INST_VA], tb_top.intf0.xlate(store_data[`INST]), store_data[`MEMOP_VA], wrptr[thid]);
stb_valid[{thid, wrptr[thid]}] = 1'b1;
wrptr[thid] = wrptr[thid] + 1'b1;
//`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> wrptr = %0d.", core_id, thid, wrptr[thid]);
if ((wrptr[thid] == rdptr[thid]) && stb_valid[{thid, wrptr[thid]}])
//thid = decode_tid(`SPC0.lsu_stb_dealloc);
tmp = stb[{thid, rdptr[thid]}];
lsu_inst = tmp[`LSU_MON_INST];
if (~stb_valid[{thid, rdptr[thid]}])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> lsu_stb_dealloc = %0h asserted while the stb entry is invalid for that thid.", core_id, thid, `SPC0.lsu_stb_dealloc);
Disp_STB_entry(thid, rdptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> lsu_stb_dealloc = %0h asserted when we haven't received the response from the gasket.", core_id, thid, `SPC0.lsu_stb_dealloc);
else if (tmp[`ASI_ST_ISS])
ret_ptr[thid] = ret_ptr[thid] + 1'b1;
//blkst inst. is not issued anywhere, blkst helpers are issued.
//in case of bis stores, lsu issues the dealloc in P3, i.e when the req is issued to PCX.
//IF it is bis to cp sapce and there is an err then the store is issued to PCX with nd set
//However for ue onbis to IO space, dealloc is sent to IFU, issued on PCX with valid bit 0.
//The sbdiou signal is sent in next cycle. We need to take bis io stores in this equation.
else if (tmp[`ST_SQUASH] || lsu_inst[`BLKST] || (tmp[`RMO] & ~lsu_inst[`BLKST] & ~`SPC0.lsu.sbc.kill_store_p4_))
iss_ptr[thid] = iss_ptr[thid] + 1'b1;
ret_ptr[thid] = ret_ptr[thid] + 1'b1;
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> lsu_stb_dealloc = %0h asserted which is not issued to asi ring, or PCX or is not squashed.", core_id, thid, `SPC0.lsu_stb_dealloc);
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> <%0h>: %s(VA=%0h) PA = %0h. STB[%0d] Deallocated.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], tmp[`MEMOP_PA], rdptr[thid]);
stb_valid[{thid, rdptr[thid]}] = 1'b0;
rdptr[thid] = rdptr[thid] + 1'b1;
//`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> rd_ptr = %0d.", core_id, thid, rdptr[thid]);
st_rmo_cnt[thid] = st_rmo_cnt[thid] + 1'b1;
if (ret_ptr[thid] != iss_ptr[thid])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> lsu_block_store_kill asserted while the ret_ptr = %0h != iss_ptr = %0h.", core_id, thid, tmp[`MEMOP_PA], ret_ptr[thid], iss_ptr[thid]);
if (rdptr[thid] != iss_ptr[thid])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> lsu_block_store_kill asserted while the rdptr = %0h != iss_ptr = %0h.", core_id, thid, tmp[`MEMOP_PA], rdptr[thid], iss_ptr[thid]);
if (iss_ptr[thid] == wrptr[thid])
if (stb_valid[{thid, wrptr[thid]}])
/* Lsu can assert both dealloc and block_store_kill for a request.
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Lsu asserted block_store_kill while there are no valid entries in STB to be deallocated.", core_id, thid);
if (iss_ptr[thid] < wrptr[thid])
squash_cnt = wrptr[thid] - iss_ptr[thid];
else if (iss_ptr[thid] > wrptr[thid])
squash_cnt = wrptr[thid] + (8 - iss_ptr[thid]);
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> SQUASH_STB:iss_ptr = %0h, wrptr = %0h, squash_cnt = %0h.", core_id, thid, iss_ptr[thid], wrptr[thid], squash_cnt);
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> Block store kill changed issue_ptr:%0h->%0h. ret_ptr: %0h->%0h. rdptr:%0h->%0h.", core_id, thid, iss_ptr[thid], iss_ptr[thid]+squash_cnt, ret_ptr[thid], ret_ptr[thid]+squash_cnt, rdptr[thid], rdptr[thid]+squash_cnt);
ret_ptr[thid] = ret_ptr[thid] + squash_cnt;
rdptr[thid] = rdptr[thid] + squash_cnt;
iss_ptr[thid] = iss_ptr[thid] + squash_cnt;
if (~stb_valid[{thid, i}])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h><PA = %0h> lsu_block_store_kill asserted while the stb entry %0h is invalid.", core_id, thid, tmp[`MEMOP_PA], i);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h>st_issue bit is set when the block_store_kill is asserted for stb entry %0h.", core_id, thid, tmp[`MEMOP_PA], i);
//commenting out the chk below. Lsu can assert sbdiou and then in the next cycle insert a new entry into
//stb. LSU will squash this new entry and won't issue it to PCX/asi but its squash bit won't be
//set in the chkr which was causin it to fire.
//`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> lsu_block_store_kill asserted while the squash bit is 0 in the STB entry %0h.", core_id, thid, tmp[`MEMOP_PA], i);
stb_valid[{thid, i}] = 1'b0;
squash_cnt = squash_cnt - 1'b1;
if ((bst_cnt > 0) && (`SPC0.lsu_stb_alloc == 8'b0))
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Blk store entries are not allocated back to back in STB.", core_id, bst_active_thid);
//For bst the stb is still written even though we have errors.
//Stb is written in W stage. Howvere for first blk store helper
//the err will be flagged by FGU in b stage. We can miss the
// err signal if we don't sample in B.
//for the last helper err will be signalled in B stage of last helper and at
if (lsu_bst_active[bst_active_thid] & `SPC0.fgu_fst_ecc_error_fx2 & (bst_cnt < 7))
if (`SPC0.lsu_stb_alloc[7:0] != 8'b0)
thid = decode_tid(`SPC0.lsu_stb_alloc[7:0]);
if (thid != dec_lsu_tid_w)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> lsu_stb_alloc = %0h mismatches the thid %0h.", core_id, dec_lsu_tid_w, `SPC0.lsu_stb_alloc[7:0], dec_lsu_tid_w);
Insert_in_STB(stb_alloc_data, dec_lsu_tid_w);
if (lsu_bst_active[thid])
bst_data = bst_inst_data;
if (thid != bst_active_thid)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> lsu_stb_alloc = %0h mismatches the active blkstore thid = %0h.", core_id, bst_active_thid, `SPC0.lsu_stb_alloc[7:0], bst_active_thid);
addr = bst_data[`MEMOP_VA];
bst_data[`MEMOP_VA] = {addr[47:6], bst_cnt[2:0], 3'b0};
addr = bst_data[`MEMOP_PA];
bst_data[`MEMOP_PA] = {addr[39:6], bst_cnt[2:0], 3'b0};
Insert_in_STB(bst_data, bst_active_thid);
lsu_bst_active[thid] = 1'b0;
if (bst_fgu_err) //set the squash bit to 0 for all the stb entries
for (i = 0; i < 8; i=i+1)
tmp = stb[{thid, i[2:0]}];
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> Squash bit already set when trying to set it for a bst fgu errerr.", core_id, thid, tmp[`MEMOP_PA]);
stb[{thid, i[2:0]}] = tmp;
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> <PA = %0h> STB_entry[%0h] squashed due to FGU err.", core_id, thid, tmp[`MEMOP_PA], i);
`PR_ERROR("lsu_mon", `ERROR, "<C%h>: LSU asserted lsu_stb_alloc = %0h while no store pending to be written in STB.", core_id, `SPC0.lsu_stb_alloc[7:0]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <%0h> W_stage: LSU did not assert lsu_stb_alloc for the store.", core_id, dec_lsu_tid_w, inst_pc_w);
reg [47:0] addr, act_addr;
thid =`SPC0.lsu_rngl_cdbus[58:56];
thid =`SPC0.lsu_rngf_cdbus[58:56];
asi =`SPC0.lsu_rngl_cdbus[55:48];
asi =`SPC0.lsu_rngf_cdbus[55:48];
addr =`SPC0.lsu_rngl_cdbus[47:0];
addr =`SPC0.lsu_rngf_cdbus[47:0];
req_type =`SPC0.lsu_rngl_cdbus[61:60];
req_type =`SPC0.lsu_rngf_cdbus[61:60];
tmp = stb[{thid, iss_ptr[thid]}];
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> Store reissued on the ASI interface.", core_id, thid, addr);
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> Store issued on the ASI interface that has been squashed.", core_id, thid, addr);
act_addr = tmp[`MEMOP_PA];
act_addr = {act_addr[39:3], 3'b0};
//47 is D tag rd asi. LSU issues that on the ring but changes
if ((addr == act_addr) || (asi == 8'h47) || (asi == 8'h46))
stb[{thid, iss_ptr[thid]}] = tmp;
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) STB[%0d] Issued on local ring.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], iss_ptr[thid]);
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) STB[%0d] Issued on fast ring.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], iss_ptr[thid]);
iss_ptr[thid] = iss_ptr[thid] + 1'b1;
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <%0h>: %s(VA=%0h) STB[%0d] PA mismatch for asi req on local ring. Expected PA = %0h, actual PA = %0h", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], iss_ptr[thid], tmp[`MEMOP_PA], addr);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <%0h>: %s(VA=%0h) STB[%0d] PA mismatch for asi req on fast ring. Expected PA = %0h, actual PA = %0h", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], iss_ptr[thid], tmp[`MEMOP_PA], addr);
task chk_store_issue_to_pcx;
reg [39:0] pcx_pa, inst_pa;
thid = pcx_pkt[`PCX_THR_ID];
tmp = stb[{thid, iss_ptr[thid]}];
inst = tmp[`LSU_MON_INST];
pcx_pa = pcx_pkt[`PCX_ADDR];
inst_pa = tmp[`MEMOP_PA];
if (pcx_pkt[`PCX_RQTYP] == `PCX_STORE)
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) STB[%0d] Issued to gasket.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], iss_ptr[thid]);
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) STB[%0d] Issued to gasket with ND set.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], iss_ptr[thid]);
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> A store request made to gasket by LSU while the pending req is not store.", core_id, thid, pcx_pkt[`PCX_ADDR]);
if (pcx_pa[39:0] != inst_pa[39:0])
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> A store request made to gasket by LSU while the pending req has PA %0h.", core_id, thid, pcx_pkt[`PCX_ADDR], tmp[`MEMOP_PA]);
if ((tmp[`INST_ASI] == 8'h73) & (pcx_pa[39:0] != {8'h90, core_id, thid, tmp[`INST_ASI], 18'h0}))
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> pcx_pa is not correct for asi write to interrupt vector dispatch register.", core_id, thid, pcx_pkt[`PCX_ADDR]);
if (inst[`BLKST] && ~pcx_pkt[`PCX_BST])
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> Bst bit is not set in the PCX pkt by LSU for a blk st request.", core_id, thid, pcx_pkt[`PCX_ADDR]);
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> Store reissued on the PCX interface.", core_id, thid, pcx_pkt[`PCX_ADDR]);
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> Store issued on the PCX interface that has been squashed.", core_id, thid, pcx_pkt[`PCX_ADDR]);
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> BIS bit is not set in the PCX pkt by LSU for an RMO store.", core_id, thid, pcx_pkt[`PCX_ADDR]);
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> L2ack bit is set when the RMO store is issued to PCX.", core_id, thid, pcx_pkt[`PCX_ADDR]);
ret_ptr[thid] = ret_ptr[thid] + 1; //this will be deallocated before
//response seen from stub
st_rmo_cnt[thid] = st_rmo_cnt[thid] + 1'b1;
stb[{thid, iss_ptr[thid]}] = tmp;
iss_ptr[thid] = iss_ptr[thid] + 1;
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> iss_ptr = %0d. ret_ptr = %0d, st_rmo_cnt = %0d", core_id, thid, iss_ptr[thid], ret_ptr[thid], st_rmo_cnt[thid]);
`ifdef INJ_STB_ERR_IN_CMP
reg [2:0] err_tid, stb_err_tid_d1, stb_err_tid_d2;
reg [2:0] err_index, stb_err_index_d1, stb_err_index_d2;
reg stb_err_inj, stb_err_inj_d1, stb_err_inj_d2;
reg [1:0] err_priv, stb_err_priv_d1, stb_err_priv_d2;
if (("cmp_stb_err_inj_on"))
always @ (negedge (`SPC0.l2clk & enabled & cmp_stb_err_inj))
//valid stb ram rd for issue to pcx
if (`SPC0.lsu.sbc.ram_rptr_vld_2 & `SPC0.lsu.sbc.st_pcx_rq_p3 & `SPC0.lsu.pic.pic_st_sel_p3)
err_tid = decode_tid(`SPC0.lsu.sbc.st_rq_sel_p3[7:0]);
err_index = `SPC0.lsu.sbc.ram_rptr_d1;
err_tmp = stb[{err_tid, err_index}];
err_inst = err_tmp[`LSU_MON_INST];
cam_data = `SPC0.lsu.stb_cam.cam_array.stb_rdata[44:0];
err_priv = err_tmp[`ST_PRIV];
//if (err_inst[`SWAP] || err_inst[`CASA] || err_inst[`LDSTUB])
err_inj_cnt = err_inj_cnt + 1;
11, 12: err_bit = err_bit + 1;
force `SPC0.lsu.stb_cam.cam_array.stb_rdata[44:0] = cam_data ^ (1 << err_bit);
`PR_INFO("stb_err", 22, "<T%0h> <%0h> STB[%0h]: SBAPP forced for CASA. err_bit = %0h", err_tid, {cam_data[44:8], 3'b0}, err_index, err_bit);
release `SPC0.lsu.stb_cam.cam_array.stb_rdata[44:0];
if (~`SPC0.lsu_sbapp_err_g)
`PR_ERROR("lsu_mon", `ERROR, "<T%0h> sbapp err not asserted when err is injected for atomic.", stb_err_tid_d2);
if ((`SPC0.lsu_stberr_tid_g != stb_err_tid_d2) ||
(`SPC0.lsu_stberr_index_g != stb_err_index_d2) ||
(`SPC0.lsu_stberr_priv_g != stb_err_priv_d2))
`PR_ERROR("lsu_mon", `ERROR, "<T%0h> sbapp err parameters mismatch.", stb_err_tid_d2);
if (`SPC0.lsu_sbapp_err_g)
`PR_ERROR("lsu_mon", `ERROR, "<T%0h> sbapp err asserted when none expected.", `SPC0.lsu_stberr_tid_g);
always @ (posedge (`SPC0.l2clk & enabled & cmp_stb_err_inj))
stb_err_inj_d1 <= stb_err_inj;
stb_err_inj_d2 <= stb_err_inj_d1;
stb_err_tid_d1 <= err_tid;
stb_err_tid_d2 <= stb_err_tid_d1;
stb_err_index_d1 <= err_index;
stb_err_index_d2 <= stb_err_index_d1;
stb_err_priv_d1 <= err_priv;
stb_err_priv_d2 <= stb_err_priv_d1;
// If vcs_build_args NO_MONITORS, then module will be empty
reg [7:0] asi_e, imm_asi_e, asi_m, asi_b;
reg dec_altspace_e, dec_altspace_b, dec_altspace_m;
reg [1:0] exu_lsu_va_error_b;
reg [2:0] dec_lsu_tid_e, dec_lsu_tid_m, dec_lsu_tid_b, dec_lsu_tid_w;
reg [47:0] inst_pc_e, inst_pc_m, inst_pc_b, inst_pc_w;
reg [31:0] inst_e, inst_m, inst_b;
reg [47:0] vaddr_m, vaddr_b;
reg [63:0] int_st_data_m, int_st_data_b;
reg [63:0] fp_st_sata_fx2;
reg [20:0] lsu_inst_e, lsu_inst_m, lsu_inst_b;
reg mmu_dtlb_reload_d1, mmu_dtlb_reload_d2;
reg [`LD_Pend_Width] ld_pend_array[7:0];
reg [`LAST_INST_Pend_Width] last_inst_array[7:0];
reg [2:0] wrptr[7:0]; //Pts. to the STB entry into which data will be written next
reg [2:0] rdptr[7:0]; //Tracks the dealloc signal from STB
reg [2:0] iss_ptr[7:0]; //keeps track of when a store is issued from the STB to PCX
reg [2:0] ret_ptr[7:0]; //keeps track of when the response is received from
reg [`STB_Pend_Width] stb[63:0];
//reg [`TLB_MISS_Pend_Width] tlbmiss_pend_array[7:0];
reg [7:0] dcache_inv_cnt[7:0];
reg [7:0] st_rmo_cnt[7:0];
reg [31:0] dec_tg0_inst_d, dec_tg1_inst_d;
reg [7:0] lsu_bst_active;
reg [195:0] stb_alloc_data;
reg [195:0] bst_data, bst_inst_data;
reg [2:0] bst_active_thid;
reg [7:0] is_blkld; //reqd by lsu_ras_chkr to chk errors on blk ld.
reg [1:0] l2_blk_ld_errtype[7:0]; //Gives the type of err the ahd be reported by LSU if
//different types of err occur on blk ld helper returns
reg [1:0] st_priv[7:0]; //Gives the final priv level for an sbdiou/sbapp err that shd be
for (i = 0; i < 8; i = i+1)
l2_blk_ld_errtype[i] = 2'b0;
// avoid time zero ugliness. jp
//@(posedge `SPC0.l2clk);
//@(negedge `SPC0.l2clk);
//if (`PARGS.lsu_mon_on) enabled = 1;
3'h0: finish_mask = `PARGS.finish_mask[7:0];
3'h1: finish_mask = `PARGS.finish_mask[15:8];
3'h2: finish_mask = `PARGS.finish_mask[23:16];
3'h3: finish_mask = `PARGS.finish_mask[31:24];
3'h4: finish_mask = `PARGS.finish_mask[39:32];
3'h5: finish_mask = `PARGS.finish_mask[47:40];
3'h6: finish_mask = `PARGS.finish_mask[55:48];
3'h7: finish_mask = `PARGS.finish_mask[63:56];
if (~`TOP.in_reset & `PARGS.lsu_mon_on & ~reset_in_middle)
`PR_ALWAYS("lsu_mon", `ALWAYS, "Lsu_mon on, in_reset = 0.");
if (`TOP.in_reset & enabled)
`PR_ALWAYS("lsu_mon", `ALWAYS, "Reset asserted in the middle of the diag. Turned off Lsu_mon.");
always @ (posedge (tb_top.sim_status[0] & enabled))
if (|(ld_valid[7:0] & finish_mask[7:0]))
for (i = 0; i < 8; i=i+1)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> Ld requests pending at the end of simulation. ld_valid = %0h", core_id, ld_valid);
for (i = 0; i < 64; i=i+1)
if (stb_valid[i] & finish_mask[i[5:3]])
//chkr resets the stb valid bits when block_store_kill is asserted.
//in couple of failures block_store_kill was sampled asserted two cycles after
//lsu asserted stb_empty. The simulation ended the cycle stb_empty was sampled high
//causing moniotr firings with valid entries in stb at end of simulation. Now
//don't flag an error if squash bit is set and stb_valid is asserted at end
if (~is_squash_bit_set(i[5:0]))
Disp_STB_entry(i[5:3],i[2:0]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> Store requests pending at the end of simulation. stb_valid = %0h", core_id, stb_valid);
for (i = 0; i < 8; i=i+1)
if (finish_mask[i] & (pf_cnt[i] != 0))
`PR_ALWAYS("lsu_mon", `ALWAYS, "<C%h> <T%0h> Prefetches not finished. Pf_cnt = %0d", core_id, i, pf_cnt[i]);
if (finish_mask[i] & (dcache_inv_cnt[i] != 0))
`PR_ALWAYS("lsu_mon", `ALWAYS, "<C%h> <T%0h> D pkt not received for all invalidate reqs. issued by the thread. dcache_inv_cnt = %0d", core_id, i, dcache_inv_cnt[i]);
if (finish_mask[i] & (st_rmo_cnt[i] != 0))
`PR_ALWAYS("lsu_mon", `ALWAYS, "<C%h> <T%0h> rmo_cnt not zero. rmo_cnt = %0d", core_id, i, st_rmo_cnt[i]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> Prefetch/D/RMO_stores requests pending at the end of simulation.", core_id);
function is_squash_bit_set;
is_squash_bit_set = 1'b1;
is_squash_bit_set = 1'b0;
always @ (negedge (`SPC1.l2clk & enabled))
asi_e = `SPC1.lsu.dcc.dcc_asi_e[7:0];
lsu_inst_e[`LD] <= `SPC1.dec_ld_inst_e;
lsu_inst_e[`ST] <= `SPC1.dec_st_inst_e;
lsu_inst_e[`FP] <= `SPC1.dec_fpldst_inst_e;
lsu_inst_e[`PREF] <= `SPC1.dec_pref_inst_e;
lsu_inst_e[`SWAP] <= `SPC1.dec_swap_inst_e;
lsu_inst_e[`CASA] <= `SPC1.dec_casa_inst_e;
lsu_inst_e[`LDSTUB] <= `SPC1.dec_ldstub_inst_e;
lsu_inst_e[`FLUSH] <= `SPC1.dec_flush_inst_e;
lsu_inst_e[`MEMBAR] <= `SPC1.dec_memstbar_inst_e;
lsu_inst_e[`LDD] <= `SPC1.dec_ld_inst_e & `SPC1.dec_ldst_dbl_e & ~`SPC1.dec_fpldst_inst_e;
lsu_inst_e[`STD] <= `SPC1.dec_st_inst_e & `SPC1.dec_ldst_dbl_e & ~`SPC1.lsu.dec_fpldst_inst_e;
lsu_inst_e[`BLKLD] <= `SPC1.dec_ld_inst_e & `SPC1.dec_fpldst_inst_e & dec_altspace_e & Is_blk_asi(asi_e);
lsu_inst_e[`BLKST] <= `SPC1.dec_st_inst_e & `SPC1.dec_fpldst_inst_e & dec_altspace_e & Is_blk_asi(asi_e);
lsu_inst_e[`QLD] <= `SPC1.dec_ld_inst_e & dec_altspace_e & Is_qld_asi(asi_e);
lsu_inst_e[`ASR_RD_WR] <= `SPC1.dec_sr_inst_e & (`SPC1.dec_ld_inst_e | `SPC1.dec_st_inst_e);
lsu_inst_e[`PR_RD_WR] <= `SPC1.dec_pr_inst_e & (`SPC1.dec_ld_inst_e | `SPC1.dec_st_inst_e);
lsu_inst_e[`HPR_RD_WR] <= `SPC1.dec_hpr_inst_e & (`SPC1.dec_ld_inst_e | `SPC1.dec_st_inst_e);
lsu_inst_e[`FSR_RD_WR] <= `SPC1.dec_fsr_ldst_e & (`SPC1.dec_ld_inst_e | `SPC1.dec_st_inst_e);
always @ (posedge (`SPC1.l2clk & enabled))
dec_tg0_inst_d <= `SPC1.dec.ded0.decode_mux[31:0];
dec_tg1_inst_d <= `SPC1.dec.ded1.decode_mux[31:0];
imm_asi_vld_e <= `SPC1.lsu.dec_imm_asi_vld_d;
imm_asi_e <= `SPC1.lsu.dec_imm_asi_d;
dec_altspace_e <= `SPC1.dec_altspace_d;
dec_altspace_m <= dec_altspace_e;
dec_altspace_b <= dec_altspace_m;
exu_ecc_b <= `SPC1.exu_ecc_m;
exu_lsu_va_error_b <= `SPC1.exu_lsu_va_error_m;
dec_lsu_tid_e <= `SPC1.dec_lsu_tg_d ? {1'b1, `SPC1.dec_lsu_tid1_d} : {1'b0, `SPC1.dec_lsu_tid0_d};
dec_lsu_tid_m <= dec_lsu_tid_e;
dec_lsu_tid_b <= dec_lsu_tid_m;
dec_lsu_tid_w <= dec_lsu_tid_b;
inst_pc_e <= `SPC1.dec_lsu_tg_d ? {`SPC1.tlu.tlu_pc_1_d[47:2], 2'b0} : {`SPC1.tlu.tlu_pc_0_d[47:2], 2'b0};
inst_e <= `SPC1.dec_lsu_tg_d ? dec_tg1_inst_d : dec_tg0_inst_d;
vaddr_m <= `SPC1.exu_lsu_address_e;
int_st_data_m <= `SPC1.exu_lsu_store_data_e;
int_st_data_b <= int_st_data_m;
fp_st_sata_fx2 <= `SPC1.fgu_lsu_fst_data_fx1;
mmu_dtlb_reload_d1 <= `SPC1.mmu_dtlb_reload;
mmu_dtlb_reload_d2 <= mmu_dtlb_reload_d1;
//pcx_thid_d1 <= `SPC1.lsu.spc_pcx_data_pa[`PCX_THR_ID];
lsu_inst_m <= lsu_inst_e;
lsu_inst_b <= lsu_inst_m;
Is_blk_asi = (asi == `ASI_BLK_AIUP) | (asi == `ASI_BLK_AIUS) |
(asi == `ASI_BLK_AIUPL) | (asi == `ASI_BLK_AIUSL) |
(asi == `ASI_BLK_P) | (asi == `ASI_BLK_S) |
(asi == `ASI_BLK_PL) | (asi == `ASI_BLK_SL) |
(asi == `ASI_BLK_COMMIT_P) | (asi == `ASI_BLK_COMMIT_S);
Is_qld_asi = (asi == `ASI_AIU_BIS_QUAD_LDD_P) | (asi == `ASI_AIU_BIS_QUAD_LDD_S) |
(asi == `ASI_AIU_BIS_QUAD_LDD_P_LITTLE) | (asi == `ASI_AIU_BIS_QUAD_LDD_S_LITTLE) |
(asi == `ASI_NUCLEUS_BIS_QUAD_LDD) | (asi == `ASI_NUCLEUS_BIS_QUAD_LDD_LITTLE) |
(asi == `ASI_BIS_QUAD_LDD_P) | (asi == `ASI_BIS_QUAD_LDD_S) |
(asi == `ASI_BIS_QUAD_LDD_P_LITTLE) | (asi == `ASI_BIS_QUAD_LDD_S_LITTLE) |
(asi == `ASI_QUAD_LDD) | (asi == `ASI_QUAD_LDD_REAL) |
(asi == `ASI_QUAD_LDD_L) | (asi == `ASI_QUAD_LDD_REAL_L);
Is_bis_asi = (asi == `ASI_AIU_BIS_QUAD_LDD_P) | (asi == `ASI_AIU_BIS_QUAD_LDD_S) |
(asi == `ASI_AIU_BIS_QUAD_LDD_P_LITTLE) | (asi == `ASI_AIU_BIS_QUAD_LDD_S_LITTLE) |
(asi == `ASI_NUCLEUS_BIS_QUAD_LDD) | (asi == `ASI_NUCLEUS_BIS_QUAD_LDD_LITTLE) |
(asi == `ASI_BIS_QUAD_LDD_P) | (asi == `ASI_BIS_QUAD_LDD_S) |
(asi == `ASI_BIS_QUAD_LDD_P_LITTLE) | (asi == `ASI_BIS_QUAD_LDD_S_LITTLE);
always @ (negedge (`SPC1.l2clk & enabled))
`PR_INFO("lsu_mon", 21, "<C%0h> <T%0h> <%0h> M_stage: %s(VA=%0h) Flushed due to IFU Flush.", core_id, dec_lsu_tid_m, inst_pc_m, tb_top.intf0.xlate(inst_m),vaddr_m);
if (lsu_inst_b[`BLKLD]) print_inst = " BLKLD,";
else if (lsu_inst_b[`BLKST]) print_inst = " BLKST,";
else if (lsu_inst_b[`QLD]) print_inst = " QLD,";
`PR_INFO("lsu_mon", 21, "<C%0h> <T%0h> <%0h> B_stage: %s(VA=%0h) Flushed due to IFU Flush.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b);
else if (`SPC1.tlu_flush_lsu_b)
`PR_INFO("lsu_mon", 21, "<C%h> <T%0h> <%0h> B_stage: %s(VA=%0h) Flushed due to TLU Flush.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b);
//casa is a two cycle operation. If there is an err on the 2nd cycle of casa then also
//This function will also chk for errors on 2nd cycle.
else if (Is_exu_error(exu_lsu_va_error_b, exu_ecc_b))
`PR_INFO("lsu_mon", 21, "<C%h> <T%0h <%0h> B_stage: %s(VA=%0h) Flushed due to EXU error.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b);
else if ((`SPC1.fgu_cecc_fx2 || `SPC1.fgu_uecc_fx2) && lsu_inst_b[`ST] && lsu_inst_b[`FP])
`PR_INFO("lsu_mon", 21, "<C%h> <T%0h> <%0h> B_stage: %s(VA=%0h) Flushed due to FGU error.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b);
else if (!`SPC1.lsu_tlb_miss_b_)
`PR_INFO("lsu_mon", 23, "<C%h> <T%0h> <%0h> B_stage: %s(VA=%0h)%s ASI = %0h. DTLB miss.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b, print_inst, asi_b);
//Lsu doesn't assert lsu_sync for an exception or dtlb miss. Since for
//an exception tlu anyway tells the front end to flush itself there is
//no reason for LSU to flush the front end then TLU to flush it again.
//Lsu treats the dtlbmiss as an exception that it flushes the inst and
//handles it when it is reissued by the front end.
if (`SPC1.lsu_tlb_bypass_b)
if (`SPC1.lsu_sync != 8'b0)
`PR_INFO("lsu_mon", 23, "<C%h> <T%0h> <%0h>: %s(VA=%0h)%s PA = %0h, ASI = %0h. LSU_sync. DTLB Bypass.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b, print_inst, {`SPC1.lsu.tlb_pgnum[39:13], vaddr_b[12:0]}, asi_b);
`PR_INFO("lsu_mon", 23, "<C%h> <T%0h> <%0h>: %s(VA=%0h)%s PA = %0h, ASI = %0h. DTLB Bypass.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b, print_inst, {`SPC1.lsu.tlb_pgnum[39:13], vaddr_b[12:0]}, asi_b);
if (`SPC1.lsu_sync != 8'b0)
`PR_INFO("lsu_mon", 23, "<C%h> <T%0h> <%0h>: %s(VA=%0h)%s PA = %0h, ASI = %0h, Store_data = %0h. LSU_sync. DTLB hit.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b, print_inst, {`SPC1.lsu.tlb_pgnum[39:13], vaddr_b[12:0]}, asi_b,int_st_data_b);
`PR_INFO("lsu_mon", 23, "<C%h> <T%0h> <%0h>: %s(VA=%0h)%s PA = %0h, ASI = %0h. LSU_sync. DTLB hit.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b, print_inst, {`SPC1.lsu.tlb_pgnum[39:13], vaddr_b[12:0]}, asi_b);
`PR_INFO("lsu_mon", 23, "<C%h> <T%0h> <%0h>: %s(VA=%0h)%s PA = %0h, ASI = %0h, Store_data = %0h. DTLB hit.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b, print_inst, {`SPC1.lsu.tlb_pgnum[39:13], vaddr_b[12:0]}, asi_b, int_st_data_b);
`PR_INFO("lsu_mon", 23, "<C%h> <T%0h> <%0h>: %s(VA=%0h)%s PA = %0h, ASI = %0h. DTLB hit.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b, print_inst, {`SPC1.lsu.tlb_pgnum[39:13], vaddr_b[12:0]}, asi_b);
if (lsu_inst_b[`LD] || lsu_inst_b[`PREF] || lsu_inst_b[`SWAP] || lsu_inst_b[`CASA] || lsu_inst_b[`LDSTUB])
if (((lsu_inst_b == 16'h1) || (lsu_inst_b == 16'h5)) & `SPC1.lsu.stb_cam_hit)
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> <%0h>: LSU_sync asserted due to STB RAW.", core_id, dec_lsu_tid_b, inst_pc_b);
if (lsu_inst_b[`ST]) //for atomics both ld and store signals are asserted
Insert_in_last_inst_array;
if (`SPC1.lsu_trap_flush[7:0])
`PR_INFO("lsu_mon", 21, "<C%h> <T%0h> Trap Flush asserted.", core_id, decode_tid(`SPC1.lsu_trap_flush[7:0]));
//This is how we test squashing of stores by LSU_mon:
//Whenever lsu asserts err_sbdiou signal, the monitor sets the squash
//bit in the STB for the rest of the stores. If any of these squashed stores
//is issued on the asi ring or to the PCX interface the monitor complains.
//The squashed stores are deallocated when either a block_store_kill is
//asserted or dealloc signals are asserted by the LSU.
//When the block_store_kill is asserted, it tells the IFU to dealloc
//all the pending stores in the IFU. It means the when block_store_kill
//is asserted we have deallocated all the non-squashed requests from STB.
//The 0in_chkr ensures that LSU flags the correct index and priv with the
//the sbdiou signal to TLU.
always @ (negedge (`SPC1.l2clk & enabled))
if (`SPC1.lsu_l15_valid & `SPC1.lsu.spc_pcx_data_pa[129])
Chk_pcx_req_pkt(`SPC1.lsu.spc_pcx_data_pa[129:0]); //chk if we need .lsu here
if ((`SPC1.lsu_rngl_cdbus[64:63] == 2'b11) & ~`SPC1.lsu_rngl_cdbus[59])
Chk_st_on_ASI_ring(`LOCAL);
if ((`SPC1.lsu_rngf_cdbus[64:63] == 2'b11) & ~`SPC1.lsu_rngf_cdbus[59])
Chk_st_on_ASI_ring(`FAST);
//if (`SPC1.l15_lsu_valid)
//Chk_cpx_response_pkt({`SPC1.l15_lsu_valid, `SPC1.l15_lsu_cpkt[17:13],`SPC1.l15_lsu_cpkt[11:0],`SPC1.l15_spc_data1[127:0]});
if (`SPC1.cpx_spc_data_cx[145])
Chk_cpx_response_pkt(`SPC1.cpx_spc_data_cx);
if (`SPC1.lsu_complete[7:0] != 8'b0)
if (`SPC1.lsu_complete[0]) Chk_ld_complete(0);
if (`SPC1.lsu_complete[1]) Chk_ld_complete(1);
if (`SPC1.lsu_complete[2]) Chk_ld_complete(2);
if (`SPC1.lsu_complete[3]) Chk_ld_complete(3);
if (`SPC1.lsu_complete[4]) Chk_ld_complete(4);
if (`SPC1.lsu_complete[5]) Chk_ld_complete(5);
if (`SPC1.lsu_complete[6]) Chk_ld_complete(6);
if (`SPC1.lsu_complete[7]) Chk_ld_complete(7);
if (`SPC1.lsu_block_store_kill[7:0] != 8'b0)
if (`SPC1.lsu_block_store_kill[0]) Squash_STB(0);
if (`SPC1.lsu_block_store_kill[1]) Squash_STB(1);
if (`SPC1.lsu_block_store_kill[2]) Squash_STB(2);
if (`SPC1.lsu_block_store_kill[3]) Squash_STB(3);
if (`SPC1.lsu_block_store_kill[4]) Squash_STB(4);
if (`SPC1.lsu_block_store_kill[5]) Squash_STB(5);
if (`SPC1.lsu_block_store_kill[6]) Squash_STB(6);
if (`SPC1.lsu_block_store_kill[7]) Squash_STB(7);
if (`SPC1.lsu_stb_dealloc[7:0] != 8'b0)
if (`SPC1.lsu_stb_dealloc[0]) Dealloc_STB(0);
if (`SPC1.lsu_stb_dealloc[1]) Dealloc_STB(1);
if (`SPC1.lsu_stb_dealloc[2]) Dealloc_STB(2);
if (`SPC1.lsu_stb_dealloc[3]) Dealloc_STB(3);
if (`SPC1.lsu_stb_dealloc[4]) Dealloc_STB(4);
if (`SPC1.lsu_stb_dealloc[5]) Dealloc_STB(5);
if (`SPC1.lsu_stb_dealloc[6]) Dealloc_STB(6);
if (`SPC1.lsu_stb_dealloc[7]) Dealloc_STB(7);
if (`SPC1.lsu_block_store_stall)
if (`SPC1.lsu.lsu_block_store_alloc[7:0] != 8'b0)
Set_block_store_parameters;
if (`SPC1.lsu_sbdiou_err_g || `SPC1.lsu_sbapp_err_g)
if (`SPC1.lsu_stb_flush_g)
st_priv[`SPC1.lsu_stberr_tid_g] = get_priv_on_flush(`SPC1.lsu_stberr_tid_g);
function [1:0] get_priv_on_flush;
sq_index = `SPC1.lsu_stberr_index_g;
tmp = stb[{tid, sq_index}];
get_priv_on_flush = tmp[`ST_PRIV];
thid = `SPC1.lsu_block_store_tid;
bst_inst_data = stb[{thid, rdptr[thid]}];
inst = bst_inst_data[`LSU_MON_INST];
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> LSU asserted blk_store_stall while the req at the top of STB is not blkst as shown above", core_id, thid);
//lsu can assert block_store_stall for a new block store while it has not yet written
//the 8 stb entries from the previous blk store.
task Set_block_store_parameters;
thid = decode_tid(`SPC1.lsu.lsu_block_store_alloc[7:0]);
if (lsu_bst_active[thid])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> LSU asserted blk_store_alloc while the bst_active is already set for this thread.", core_id, thid);
lsu_bst_active[thid] = 1'b1;
if (`SPC1.lsu.fgu_fst_ecc_error_fx2)
thid = `SPC1.lsu_stberr_tid_g;
sq_index = `SPC1.lsu_stberr_index_g;
priv = `SPC1.lsu_stberr_priv_g;
tmp = stb[{thid, sq_index}];
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> Sbdiou/sbapp seen for index = %h and priv = %h.", core_id, thid, sq_index, priv);
st_priv[thid] = tmp[`ST_PRIV];
//lsu can assert deallocate before it asserts the sbdiou signal.
//In that case iss_ptr won't be equal to sbdiou index.
//if (sq_index != iss_ptr[thid])
// Disp_STB_entry(thid, iss_ptr[thid]);
// `PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> LSU asserted sbdiou/sbapp with index %0h while the next req to be issued is at index %0h.", core_id, thid, sq_index, iss_ptr[thid]);
//If there is only one store in the store buffer which gets an sbdiou error, then LSU can deallocate
//the store and then assert sbdiou. The deallocation will cause the stb issue_ptr to move
//forward to an inst. that has already been issued and completed and this chk can fire. So
// Disp_STB_entry(thid, iss_ptr[thid]);
// `PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> Store reissued on the PCX interface.", core_id, thid, tmp[`MEMOP_PA]);
if (iss_ptr[thid] == wrptr[thid])
if (stb_valid[{thid, wrptr[thid]}])
//changing it to an info message because if there is only one valid entry in store buffer that
//gets an sbdiou then LSU can deallocate the entry and then issue sbdiou.
//`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Lsu asserted sbdiou/sbapp while there are no valid entries in STB to be issued.", core_id, thid);
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> sbdiou/sbapp squashed only one entry in STB.", core_id, thid);
if (iss_ptr[thid] < wrptr[thid])
squash_cnt = wrptr[thid] - iss_ptr[thid];
else if (iss_ptr[thid] > wrptr[thid])
squash_cnt = wrptr[thid] + (8 - iss_ptr[thid]);
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> SQUASH_STORE:iss_ptr = %0h, wrptr = %0h, squash_cnt = %0h.", core_id, thid, iss_ptr[thid], wrptr[thid], squash_cnt);
if (priv < tmp[`ST_PRIV])
`PR_INFO("lsu_mon", `INFO, "<C%h> <T%0h> <PA = %0h> Sbdiou/sbapp signalled. Err in user/priv level store is squashing a higher priv level store.", core_id, thid, tmp[`MEMOP_PA]);
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> <PA = %0h> STB_entry[%0h] squashed.", core_id, thid, tmp[`MEMOP_PA], i);
squash_cnt = squash_cnt - 1'b1;
function [2:0] decode_tid;
8'h10: decode_tid = 3'h4;
8'h20: decode_tid = 3'h5;
8'h40: decode_tid = 3'h6;
8'h80: decode_tid = 3'h7;
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> decode_tid. Incorrect value of thid input = %0h.", core_id, thid_encode, thid_encode);
reg [`LD_Pend_Width] tmp;
tmp = ld_pend_array[thid];
if ((tmp[`L2_ISS] != 4'hf) || (tmp[`L2_RESP] != 4'hf))
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> LSU asserted lsu_complete while the l2_iss and l2_resp bits are not F.", core_id, thid);
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> <%0h> %s(VA=%0h) Complete. Setting ld_valid to 0.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA]);
tmp = last_inst_array[thid];
`PR_INFO("lsu_mon", 24, "<C%h> <T%0h> <%0h> %s(VA=%0h) Complete.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA]);
reg [`LD_Pend_Width] tmp, tmp1;
thid = pcx_pkt[`PCX_THR_ID];
tmp = ld_pend_array[thid];
inst = tmp[`LSU_MON_INST];
req = DispPCXReq(pcx_pkt);
addr = pcx_pkt[`PCX_ADDR];
if (pcx_pkt[`PCX_CPU_ID] != core_id)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> cpu_id (spc_pcx_data_pa[122:120]) = %h is not = %0h when the lsu made a %s req to gasket.", core_id, pcx_pkt[`PCX_THR_ID], addr, pcx_pkt[122:120], core_id, req);
if ((pcx_pkt[`PCX_RQTYP] == `PCX_LOAD) || (pcx_pkt[`PCX_RQTYP] == `PCX_CAS1) || (pcx_pkt[`PCX_RQTYP] == `PCX_CAS2) || (pcx_pkt[`PCX_RQTYP] == `PCX_SWAP_LDSTUB))
ld_valid[thid] = 1'b1; //we have sent a req to gasket and are waiting for response
`PR_INFO("lsu_mon", 22, "<C%0h> <T%0h> Setting ld_valid[%0h].", core_id, thid, thid);
if (tmp[`MEMOP_PA] != addr)
if ((tmp[`INST_ASI] == 8'h41) || (tmp[`INST_ASI] == 8'h73) || ((tmp[`INST_ASI] == 8'h45) && ((tmp[`MEMOP_PA] == 8'h10) || (tmp[`MEMOP_PA] == 8'h18))))
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <PA = %0h> PA mismatch on gasket for %s request. Ignoring the mismatch as inst. is issued with asi 41, 73 or 45 (with VA 0x10 or 18).", core_id, thid, addr, req);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> A %s request made to gasket by LSU while the pending req is with PA %0h.", core_id, thid, addr, req, tmp[`MEMOP_PA]);
case (pcx_pkt[`PCX_RQTYP])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> A prefetch request made to gasket by LSU which mismatches the pending request from the thread.", core_id, thid, addr);
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: PREF_ICE(VA=%0h) Issued. pf_cnt not updated.", core_id, thid, tmp[`INST_VA], tmp[`MEMOP_VA]);
pf_cnt[thid] = pf_cnt[thid] + 1'b1;
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) Issued. pf_cnt = %0d.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], pf_cnt[thid]);
tmp[`L2_RESP] = 4'hF; //we don't wait for a prefetch response from gasket
ld_pend_array[thid] = tmp;
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) Dcache invalidate pkt issued to CCX.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA]);
dcache_inv_cnt[thid] = dcache_inv_cnt[thid] + 1'b1;
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> CASA request made to gasket by LSU while no such request request is pending from this thread.", core_id, thid, addr);
if (pcx_pkt[`PCX_RQTYP] == `PCX_CAS1)
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) (CAS1) Issued to gasket.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA]);
ld_pend_array[thid] = tmp;
if (pcx_pkt[`PCX_RQTYP] == `PCX_CAS2)
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) (CAS2) Issued to gasket.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA]);
ld_pend_array[thid] = tmp;
chk_store_issue_to_pcx(pcx_pkt);
if (~inst[`SWAP] && ~inst[`LDSTUB])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> %s request made to gasket by LSU while no such request request is pending from this thread.", core_id, thid, addr, req);
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) Issued to gasket. store_data = %0h", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], pcx_pkt[`PCX_DATA]);
ld_pend_array[thid] = tmp;
chk_store_issue_to_pcx(pcx_pkt);
chk_store_issue_to_pcx(pcx_pkt);
default: `PR_INFO("lsu_mon", 21, "<C%h> <T%0h> <%0h>: %s Issued to gasket.", core_id, thid, addr, req);
task Chk_cpx_response_pkt;
thid = cpx_pkt[`CPX_THR_ID];
casex ({cpx_pkt[`CPX_RTNTYP], cpx_pkt[`CPX_ERR], cpx_pkt[`CPX_NC], cpx_pkt[`CPX_ATM], cpx_pkt[`CPX_PF]})
{4'b0, 2'bxx, 1'bx, 1'b0, 1'b0}:
chk_ccx_ld_response(cpx_pkt);
{4'b0, 2'bxx, 1'b1, 1'b0, 1'b1}:
if (pf_cnt[thid] == 8'b0)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Prefetch response received from gasket while the pf_cnt is 0 for this thread.", core_id, thid);
pf_cnt[thid] = pf_cnt[thid] - 1'b1;
`PR_INFO("lsu_mon", 26, "<C%h> <T%0h> Prefetch response received. pfcnt = %0d.", core_id, thid, pf_cnt[thid]);
{4'h8, 2'bxx, 1'b1, 1'b0, 1'b0}:
chk_ccx_ld_response(cpx_pkt);
{4'h4, 2'bxx, 1'bx, 1'b0, 1'b0}:
if (cpx_pkt[123]) //D pkt
if (cpx_pkt[120:118] != core_id)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> D response received from gasket with core_id =%h.", core_id, thid, cpx_pkt[120:118]);
if (dcache_inv_cnt[thid] == 8'b0)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> D response received from gasket while the Dcache_inv_cnt is 0 for this thread.", core_id, thid);
dcache_inv_cnt[thid] = dcache_inv_cnt[thid] - 1'b1;
`PR_INFO("lsu_mon", 26, "<C%h> <T%0h> D response received. Dcache_inv_cnt = %0d.", core_id, thid, dcache_inv_cnt[thid]);
else if (cpx_pkt[124]) //I pkt
if (cpx_pkt[120:118] != core_id)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> I response received from gasket with core_id =%h.", core_id, thid, cpx_pkt[120:118]);
//`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> I pkt.", core_id, thid);
else if (cpx_pkt[124:123] == 2'b0)
if (cpx_pkt[120:118] == core_id)
chk_ccx_st_response(cpx_pkt);
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> Store Ack pkt received from core %0h.", core_id, thid, cpx_pkt[120:118]);
{4'h1, 2'bxx, 1'bx, 1'b0, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> IFILL1 return.", core_id, thid);
{4'h1, 2'bxx, 1'bx, 1'b1, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> IFILL2 return.", core_id, thid);
{4'h9, 2'bxx, 1'b1, 1'b0, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> NCU IFILL return.", core_id, thid);
{4'b0, 2'bxx, 1'b1, 1'b1, 1'b0}:
chk_ccx_atm_response(cpx_pkt);
{4'h4, 2'bxx, 1'b1, 1'b1, 1'b0}:
if ((cpx_pkt[`CPX_RTNTYP] == 4'h4) & (cpx_pkt[120:118] == core_id))
chk_ccx_atm_response(cpx_pkt);
chk_ccx_st_response(cpx_pkt);
{4'h2, 2'bxx, 1'b1, 1'b0, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> Stream Ld return.", core_id, thid);
{4'h6, 2'bxx, 1'bx, 1'bx, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> Stream store Ack.", core_id, thid);
{4'h5, 2'bxx, 1'b1, 1'b0, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> MMU ld return.", core_id, thid);
{4'h7, 2'b00, 1'b0, 1'bx, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> Interrupt return.", core_id, thid);
{4'h3, 2'b00, 1'bx, 1'bx, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> Eviction Invalidation.", core_id, thid);
{4'hc, 2'bxx, 1'bx, 1'bx, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> L2 Indication.", core_id, thid);
{4'hd, 2'bxx, 1'bx, 1'bx, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> Soc Error Indication.", core_id, thid);
`PR_ALWAYS("lsu_mon", `ALWAYS, "CPX_PKT data.");
`PR_ALWAYS("lsu_mon", `ALWAYS, "<C%0h> <T%0h> rtn_typ = %0h, err_bits = %0h, nc=%0b, atm = %0b, pf = %0b", core_id, cpx_pkt[`CPX_THR_ID], cpx_pkt[`CPX_RTNTYP], cpx_pkt[`CPX_ERR], cpx_pkt[`CPX_NC], cpx_pkt[`CPX_ATM], cpx_pkt[`CPX_PF]);
`PR_ERROR("lsu_mon", `ERROR, "<C%0h> <T%0h> Can't recognise the CPX pkt.", core_id, thid);
task chk_ccx_ld_response;
reg [39:0] cpx_pa, inst_pa;
reg [`LD_Pend_Width] tmp;
thid = cpx_pkt[`CPX_THR_ID];
tmp = ld_pend_array[thid];
inst = tmp[`LSU_MON_INST];
inst_pa = tmp[`MEMOP_PA];
pkt_type = cpx_pkt[`CPX_RTNTYP];
`PR_INFO("lsu_mon", 26, "<C%0h> <T%0h> <%0h> %s(VA=%0h) L2 response.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA]);
if (inst_pa[39] != pkt_type[3])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> ccx pkt_type = %h mismatches the ld_pa bit 39. ld_pa = %0h.", core_id, thid, pkt_type, inst_pa);
if (tmp[`L2_RESP] == 4'h0)
tmp[`L2_ERR0] = cpx_pkt[`CPX_ERR];
if ((cpx_pkt[`CPX_ERR] == `ND) || (cpx_pkt[`CPX_ERR] == `UE))
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> UE/ND err on blk ld helper 1.", core_id, thid);
else if (tmp[`L2_RESP] == 4'h1)
tmp[`L2_ERR1] = cpx_pkt[`CPX_ERR];
if ((cpx_pkt[`CPX_ERR] == `ND) || (cpx_pkt[`CPX_ERR] == `UE))
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> UE/ND err on blk ld helper 2.", core_id, thid);
else if (tmp[`L2_RESP] == 4'h3)
tmp[`L2_ERR2] = cpx_pkt[`CPX_ERR];
if ((cpx_pkt[`CPX_ERR] == `ND) || (cpx_pkt[`CPX_ERR] == `UE))
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> UE/ND err on blk ld helper 3.", core_id, thid);
else if (tmp[`L2_RESP] == 4'h7)
tmp[`L2_ERR3] = cpx_pkt[`CPX_ERR];
if ((cpx_pkt[`CPX_ERR] == `ND) || (cpx_pkt[`CPX_ERR] == `UE))
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> UE/ND err on blk ld helper 4.", core_id, thid);
if ((tmp[`L2_ERR0] == `ND) || (tmp[`L2_ERR1] == `ND) || (tmp[`L2_ERR2] == `ND) || (tmp[`L2_ERR3] == `ND))
l2_blk_ld_errtype[thid] = `ND;
else if ((tmp[`L2_ERR0] == `UE) || (tmp[`L2_ERR1] == `UE) || (tmp[`L2_ERR2] == `UE) || (tmp[`L2_ERR3] == `UE))
l2_blk_ld_errtype[thid] = `UE;
else if ((tmp[`L2_ERR0] == `CE) || (tmp[`L2_ERR1] == `CE) || (tmp[`L2_ERR2] == `CE) || (tmp[`L2_ERR3] == `CE))
l2_blk_ld_errtype[thid] = `CE;
l2_blk_ld_errtype[thid] = `NE;
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Illegal value of l2_resp cnt when response pkt received from ccx.", core_id, thid);
else if (Is_single_pcx_req_ld(inst))
if (tmp[`L2_RESP] != 4'hE)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Illegal value of l2_resp cnt when response pkt received from ccx.", core_id, thid);
//`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> Setting L2_resp bits to F.", core_id, thid);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Load response received from gasket for thid %h while no load request pending from core for this thread.", core_id, thid, thid);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Load response received from gasket while no load request pending from core for this thread.", core_id, thid);
ld_pend_array[thid] = tmp;
task chk_ccx_atm_response;
reg [`LD_Pend_Width] tmp;
thid = cpx_pkt[`CPX_THR_ID];
tmp = ld_pend_array[thid];
inst = tmp[`LSU_MON_INST];
inst_pa = tmp[`MEMOP_PA];
if (cpx_pkt[`CPX_RTNTYP] == 4'b0)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Atomic ld response received from gasket while no request pending from core for this thread.", core_id, thid);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Atomic ack response received from gasket while no request pending from core for this thread.", core_id, thid);
if (~inst[`SWAP] && ~inst[`CASA] && ~inst[`LDSTUB])
if (cpx_pkt[`CPX_RTNTYP] == 4'b0)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Atomic ld response received from gasket which mismatches the request pending from this thread.", core_id, thid);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Atomic ack response received from gasket which mismatches the request pending from this thread.", core_id, thid);
if (cpx_pkt[`CPX_RTNTYP] == 4'b0)
`PR_INFO("lsu_mon", 26, "<C%0h> <T%0h> <%0h> %s(VA=%0h) Atomic ld response.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA]);
`PR_INFO("lsu_mon", 26, "<C%0h> <T%0h> <%0h> %s(VA=%0h) Atomic ack.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA]);
if (cpx_pkt[`CPX_RTNTYP] == 4'b0)
if (tmp[`L2_RESP] == 4'hC) tmp[`L2_RESP] = 4'hD;
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Illegal value of l2_resp cnt when atomic ld return pkt received from ccx.", core_id, thid);
if (tmp[`L2_RESP] == 4'hD) tmp[`L2_RESP] = 4'hF;
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Illegal value of l2_resp cnt when atomic ack pkt received from ccx.", core_id, thid);
ld_pend_array[thid] = tmp;
task chk_ccx_st_response;
reg [39:0] cpx_pa, inst_pa;
thid = cpx_pkt[`CPX_THR_ID];
tmp = stb[{thid, ret_ptr[thid]}];
inst = tmp[`LSU_MON_INST];
inst_pa = tmp[`MEMOP_PA];
pkt_type = cpx_pkt[`CPX_RTNTYP];
//is received. There could be some other store sitting in the STB at that time.
//Chk for squash bit only for non-bis responses.
if (cpx_pkt[`CPX_BIS]) //response to rmo store
if (st_rmo_cnt[thid] == 0)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> L2 response received for an rmo store while the st_rmo_cnt for this thread is 0.", core_id, thid);
st_rmo_cnt[thid] = st_rmo_cnt[thid] - 1'b1;
`PR_INFO("lsu_mon", 25, "<C%0h> <T%0h> Store ack received for RMO store. rmo_cnt = %0d", core_id, thid, st_rmo_cnt[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> L2 response received while the SQUASH bit is set in the STB entry %0h.", core_id, thid, ret_ptr[thid]);
if (~stb_valid[{thid, ret_ptr[thid]}])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Store ack received while that entry is invalid in STB.", core_id, thid);
if (~cpx_pkt[`CPX_ATM]) //don't print this message for atomic return
`PR_INFO("lsu_mon", 26, "<C%0h> <T%0h> <%0h> %s(VA=%0h) STB[%0d] Store ack.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA], ret_ptr[thid]);
stb[{thid, ret_ptr[thid]}] = tmp;
ret_ptr[thid] = ret_ptr[thid] + 1'b1;
//`PR_INFO("lsu_mon", 22, "<C%0h> <T%0h> ret_ptr = %0d.", core_id, thid, ret_ptr[thid]);
reg [`LD_Pend_Width] tmp;
reg [39:0] pcx_pa, inst_pa;
thid = pcx_pkt[`PCX_THR_ID];
tmp = ld_pend_array[thid];
inst = tmp[`LSU_MON_INST];
pcx_pa = pcx_pkt[`PCX_ADDR];
inst_pa = tmp[`MEMOP_PA];
req = DispPCXReq(pcx_pkt);
if (pcx_pa[39:6] != inst_pa[39:6])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> A load request made to gasket by LSU while the pending req has PA %0h.", core_id, thid, pcx_pa, tmp[`MEMOP_PA]);
if (tmp[`L2_ISS] != 4'h0 )
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> 1st load request (pa[5:0] = 6'b0) made to gasket by LSU for blkld while this request has already been issued to gasket.", core_id, thid, pcx_pa);
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) 1st blkld helper Issued to gasket.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA]);
if (pcx_pa[5:0] == 6'h10)
if (tmp[`L2_ISS] != 4'h1)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> 2nd load request (pa[5:0] = 6'h10) made to gasket by LSU for blkld while this request has already been issued to gasket.", core_id, thid, pcx_pa);
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) 2nd blkld helper Issued to gasket.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA]);
if (pcx_pa[5:0] == 6'h20)
if (tmp[`L2_ISS] != 4'h3)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> 3rd load request (pa[5:0] = 6'h20) made to gasket by LSU for blkld while this request has already been issued to gasket.", core_id, thid, pcx_pa);
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) 3rd blkld helper Issued to gasket.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA]);
if (pcx_pa[5:0] == 6'h30)
if (tmp[`L2_ISS] != 4'h7)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> 4th load request (pa[5:0] = 6'h30) made to gasket by LSU for blkld while this request has already been issued to gasket.", core_id, thid, pcx_pa);
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) 4th blkld helper Issued to gasket.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA]);
ld_pend_array[thid] = tmp;
else if (Is_single_pcx_req_ld(inst))
if (tmp[`L2_ISS] == 4'hF)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> Load request made to gasket by LSU while this request has already been issued to gasket.", core_id, thid, pcx_pa);
ld_pend_array[thid] = tmp;
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) Issued to gasket.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> A load request made to gasket by LSU while there is no such ld request pending from this thread.", core_id, thid, pcx_pa);
function Is_single_pcx_req_ld;
if (inst[`LDD] || inst[`QLD] || inst[`FSR_RD_WR] || (inst == 21'h1) || (inst == 21'h5))
Is_single_pcx_req_ld = 1'b1;
Is_single_pcx_req_ld = 1'b0;
//`PR_INFO("lsu_mon", 22, "<C%0h> Is_single_pcx_req_ld = %b. ", core_id, Is_single_pcx_req_ld);
case (`SPC1.lsu_trap_flush[7:0])
8'h01: if (tid == 3'h0) Is_trap = 1'b1;
8'h02: if (tid == 3'h1) Is_trap = 1'b1;
8'h04: if (tid == 3'h2) Is_trap = 1'b1;
8'h08: if (tid == 3'h3) Is_trap = 1'b1;
8'h10: if (tid == 3'h4) Is_trap = 1'b1;
8'h20: if (tid == 3'h5) Is_trap = 1'b1;
8'h40: if (tid == 3'h6) Is_trap = 1'b1;
8'h80: if (tid == 3'h7) Is_trap = 1'b1;
function [8*11:0] DispPCXReq;
casex ({pcx_pkt[`PCX_RQTYP], pcx_pkt[`PCX_NC], pcx_pkt[`PCX_INV], pcx_pkt[`PCX_PF], pcx_pkt[`PCX_BIS]})
{5'h0, 1'b1, 1'b0, 1'b1, 1'b0}: DispPCXReq = "PREF";
{5'h0, 1'b1, 1'b1, 1'b1, 1'b0}: DispPCXReq = "PREF_ICE";
{5'h0, 1'bx, 1'b0, 1'b0, 1'b0}: DispPCXReq = "LD";
{5'h0, 1'bx, 1'b1, 1'b0, 1'b0}: DispPCXReq = "D";
{5'h10, 1'bx, 1'b0, 1'b0, 1'b0}: DispPCXReq = "I";
{5'h10, 1'b0, 1'b1, 1'b0, 1'b0}: DispPCXReq = "I";
{5'h1, 1'bX, 1'bX, 1'b0, 1'b0}: DispPCXReq = "ST";
{5'h1, 1'bX, 1'bX, 1'b1, 1'b1}: DispPCXReq = "BLKST";
{5'h1, 1'bX, 1'bX, 1'b0, 1'b1}: DispPCXReq = "BIS";
{5'h2, 1'b1, 1'bX, 1'b0, 1'b0}: DispPCXReq = "CASA1";
{5'h3, 1'b1, 1'bX, 1'b0, 1'b0}: DispPCXReq = "CASA2";
{5'h7, 1'b1, 1'bX, 1'b0, 1'b0}: DispPCXReq = "SWAP_LDSTUB";
{5'h4, 1'b1, 1'b0, 1'b0, 1'b0}: DispPCXReq = "STREAM_LD";
{5'h5, 1'b1, 1'b0, 1'b0, 1'bx}: DispPCXReq = "STREAM_ST";
{5'h8, 1'b1, 1'b0, 1'b0, 1'b0}: DispPCXReq = "MMU_LD";
//{5'h9, 1'b0, 1'b0, 1'b0, 1'b0}: DispPCXReq = "INT";
`PR_ERROR("lsu_mon", `ERROR, "<C%0h> <T%0h> <%0h> Can't recognise the PCX pkt type. rq_type = %h, nc_bit = %0b, inv_bit = %0b, pf_bit = %0b, bis_bit = %0b. pcx_pkt[129:0] = %h", core_id, pcx_pkt[`PCX_THR_ID], pcx_pkt[`PCX_ADDR], pcx_pkt[`PCX_RQTYP], pcx_pkt[`PCX_NC], pcx_pkt[`PCX_INV], pcx_pkt[`PCX_PF], pcx_pkt[`PCX_BIS], pcx_pkt);
if (`SPC1.lsu_align_b) DispExc = "Addr_not_aligned";
if (`SPC1.lsu_lddf_align_b) DispExc = "LDDF_Addr_not_aligned";
if (`SPC1.lsu_stdf_align_b) DispExc = "STDF_Addr_not_aligned";
if (`SPC1.lsu_priv_action_b) DispExc = "Priv_actio";
if (`SPC1.lsu_va_watchpoint_b) DispExc = "VA_watchpoint";
if (`SPC1.lsu_pa_watchpoint_b) DispExc = "PA_watchpoint";
//if (`SPC1.lsu_tlb_miss_b_) DispExc = "Tlb_miss";
if (`SPC1.lsu_illegal_inst_b) DispExc = "Illegal_inst";
if (`SPC1.lsu_daccess_prot_b) DispExc = "Data_access_prot_exc";
if (`SPC1.lsu_dae_invalid_asi_b) DispExc = "Dae_Invalid_asi";
if (`SPC1.lsu_dae_nc_page_b) DispExc = "Dae_nc_page";
if (`SPC1.lsu_dae_nfo_page_b) DispExc = "Dae_NFO_page";
if (`SPC1.lsu_dae_priv_viol_b) DispExc = "Dae_Priv_viol";
if (`SPC1.lsu_dae_so_page) DispExc = "Dae_so_page";
//if (`SPC1.lsu_perfmon_trap_b) DispExc = "Perf_mon_trap";
if (`SPC1.lsu_dtmh_err_b) DispExc = "DTLB_data_par_err";
if (`SPC1.lsu_dttp_err_b) DispExc = "DTLB_tag_par_err";
if (`SPC1.lsu_dtdp_err_b) DispExc = "DTLB_data_par_err";
`PR_INFO("lsu_mon", 23, "<C%0h> <T%0h> <%0h> B_stage: %s(VA=%0h) ASI = %0h. %s Exception.",core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b, asi_b, DispExc);
input [1:0] exu_lsu_va_error_b; // VA error requiring a flush
input [1:0] exu_ecc_b; // ECC error requiring a flush
err_b = dec_lsu_tid_b[2] ? (exu_ecc_b[1] | (exu_lsu_va_error_b[1] & ~`SPC1.lsu_tlb_bypass_b)):
(exu_ecc_b[0] | (exu_lsu_va_error_b[0] & ~`SPC1.lsu_tlb_bypass_b));
err_m = (dec_lsu_tid_b[2] ? `SPC1.exu_ecc_m[1] : `SPC1.exu_ecc_m[0]) & `SPC1.lsu.dcc.twocycle_b;
Is_exu_error = err_b | err_m;
task Insert_tlb_miss_info;
if (tlb_valid[dec_lsu_tid_b])
tmp = tlbmiss_pend_array[dec_lsu_tid_b];
Disp_tlbmiss_pend_array_entry(dec_lsu_tid_b);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <%0h> B_stage: %s(VA=%0h>) A new tlb miss request received while there is already a Tlb miss request pending from this thread as shown above.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b);
tlb_valid[dec_lsu_tid_b] <= 1'b1;
tmp[`INST_VA] = inst_pc_b;
tmp[`MEMOP_VA] = vaddr_b;
tlbmiss_pend_array[dec_lsu_tid_b] = tmp;
//problem with the signal.
always @ (negedge `SPC1.l2clk)
if (`SPC1.tlu_trap_pc_0_valid)
thid = {1'b0, `SPC1.tlu_trap_0_tid};
else if (`SPC1.tlu_trap_pc_1_valid)
thid = {1'b0, `SPC1.tlu_trap_1_tid};
`PR_ERROR("lsu_mon", `ERROR, "<C%h> mmu_dtlb_reload asserted but trap_pc_0_valid and trap_pc_1_valid are both 0", core_id);
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> mmu_dtlb_reload asserted while tlb_valid is 0.", core_id, thid);
tmp = tlbmiss_pend_array[dec_lsu_tid_b];
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> %s(VA=%0h> DTLB reloaded for VA = %0h.", core_id, thid, tb_top.intf0.xlate(tmp[`INST]), tmp[`INST_VA], tmp[`MEMOP_VA] );
task Insert_ld_miss_info;
reg [`LD_Pend_Width] tmp;
if (ld_valid[dec_lsu_tid_b])
tmp = ld_pend_array[dec_lsu_tid_b];
DispPendReq(dec_lsu_tid_b);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <%0h> B_stage: %s(VA=%0h>) A new request received while there is already a request pending from this thread as shown above.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b);
//ld_valid[dec_lsu_tid_b] <= 1'b1;
tmp[`INST_VA] = inst_pc_b;
tmp[`MEMOP_VA] = vaddr_b;
tmp[`MEMOP_PA] = {`SPC1.lsu.tlb_pgnum[39:13], vaddr_b[12:0]};
is_blkld[dec_lsu_tid_b] = 1'b1;
is_blkld[dec_lsu_tid_b] = 1'b0;
if (lsu_inst_b[`SWAP] || lsu_inst_b[`LDSTUB] || lsu_inst_b[`CASA])
tmp[`LSU_MON_INST] = lsu_inst_b;
ld_pend_array[dec_lsu_tid_b] = tmp;
task Insert_in_last_inst_array;
tmp[`INST_VA] = inst_pc_b;
tmp[`MEMOP_VA] = vaddr_b;
last_inst_array[dec_lsu_tid_b] = tmp;
reg [`LD_Pend_Width] tmp;
tmp = ld_pend_array[thid];
`PR_ALWAYS("lsu_mon", `ALWAYS, "LD_PEND_ARRAY[%0h] Data.", thid);
`PR_ALWAYS("lsu_mon", `ALWAYS, "<C%h> <T%0h> <%0h> %s(VA=%0h). PA = %0h. L2_ISS = %0h. L2_RESP = %0h, LSU_MON_INST=%h.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA], tmp[`MEMOP_PA], tmp[`L2_ISS], tmp[`L2_RESP], tmp[`LSU_MON_INST]);
`PR_ALWAYS("lsu_mon", `ALWAYS, "<C%h> <T%0h> STB[%0h] data.", core_id, thid, ptr);
`PR_ALWAYS("lsu_mon", `ALWAYS, "<C%h> <T%0h> <%0h> %s(VA=%0h). PA = %0h. L2_ISS = %0h. L2_ACK = %0h, LSU_MON_INST=%h. RMO = %0b", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA], tmp[`MEMOP_PA], tmp[`L2_ST_ISS], tmp[`L2_ACK], tmp[`LSU_MON_INST], tmp[`RMO]);
task Disp_tlbmiss_pend_array_entry;
tmp = tlbmiss_pend_array[thid];
`PR_INFO("lsu_mon", 23, "TLB_MISS_PEND_ARRAY[%0h] Data.", thid);
`PR_INFO("lsu_mon", 23, "<C%h> <T%0h> <%0h> %s(VA=%0h).", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA]);
`PR_ALWAYS("lsu_mon", `ALWAYS, "CPX_PKT data.");
`PR_ALWAYS("lsu_mon", `ALWAYS, "<C%0h> <T%0h> rtn_typ = %0h, err_bits = %0h, nc=%0b, atm = %0b, pf = %0b", core_id, cpx_pkt[`CPX_THR_ID], cpx_pkt[`CPX_RTNTYP], cpx_pkt[`CPX_ERR], cpx_pkt[`CPX_NC], cpx_pkt[`CPX_ATM], cpx_pkt[`CPX_PF]);
tmp[`INST_VA] = inst_pc_b;
tmp[`MEMOP_VA] = vaddr_b;
tmp[`MEMOP_PA] = {`SPC1.lsu.tlb_pgnum[39:13], vaddr_b[12:0]};
tmp[`LSU_MON_INST] = lsu_inst_b;
if (`SPC1.lsu.tlu_lsu_hpstate_hpriv[dec_lsu_tid_b])
else if (`SPC1.lsu.tlu_lsu_pstate_priv[dec_lsu_tid_b])
//bis_asi to io space is not rmo
tmp[`RMO] = lsu_inst_b[`BLKST] | (dec_altspace_b & Is_bis_asi(asi_b) & ~`SPC1.lsu.tlb_pgnum[39]);
input [195:0] store_data;
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> STB full and a new store received for insertion in STB.", core_id, thid);
stb[{thid, wrptr[thid]}] = store_data;
//Disp_STB_entry(thid, wrptr[thid]);
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> <%0h> %s(VA=%0h). STB[%0h] Inserted.", core_id, thid, store_data[`INST_VA], tb_top.intf0.xlate(store_data[`INST]), store_data[`MEMOP_VA], wrptr[thid]);
stb_valid[{thid, wrptr[thid]}] = 1'b1;
wrptr[thid] = wrptr[thid] + 1'b1;
//`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> wrptr = %0d.", core_id, thid, wrptr[thid]);
if ((wrptr[thid] == rdptr[thid]) && stb_valid[{thid, wrptr[thid]}])
//thid = decode_tid(`SPC1.lsu_stb_dealloc);
tmp = stb[{thid, rdptr[thid]}];
lsu_inst = tmp[`LSU_MON_INST];
if (~stb_valid[{thid, rdptr[thid]}])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> lsu_stb_dealloc = %0h asserted while the stb entry is invalid for that thid.", core_id, thid, `SPC1.lsu_stb_dealloc);
Disp_STB_entry(thid, rdptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> lsu_stb_dealloc = %0h asserted when we haven't received the response from the gasket.", core_id, thid, `SPC1.lsu_stb_dealloc);
else if (tmp[`ASI_ST_ISS])
ret_ptr[thid] = ret_ptr[thid] + 1'b1;
//blkst inst. is not issued anywhere, blkst helpers are issued.
//in case of bis stores, lsu issues the dealloc in P3, i.e when the req is issued to PCX.
//IF it is bis to cp sapce and there is an err then the store is issued to PCX with nd set
//However for ue onbis to IO space, dealloc is sent to IFU, issued on PCX with valid bit 0.
//The sbdiou signal is sent in next cycle. We need to take bis io stores in this equation.
else if (tmp[`ST_SQUASH] || lsu_inst[`BLKST] || (tmp[`RMO] & ~lsu_inst[`BLKST] & ~`SPC0.lsu.sbc.kill_store_p4_))
iss_ptr[thid] = iss_ptr[thid] + 1'b1;
ret_ptr[thid] = ret_ptr[thid] + 1'b1;
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> lsu_stb_dealloc = %0h asserted which is not issued to asi ring, or PCX or is not squashed.", core_id, thid, `SPC1.lsu_stb_dealloc);
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> <%0h>: %s(VA=%0h) PA = %0h. STB[%0d] Deallocated.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], tmp[`MEMOP_PA], rdptr[thid]);
stb_valid[{thid, rdptr[thid]}] = 1'b0;
rdptr[thid] = rdptr[thid] + 1'b1;
//`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> rd_ptr = %0d.", core_id, thid, rdptr[thid]);
st_rmo_cnt[thid] = st_rmo_cnt[thid] + 1'b1;
if (ret_ptr[thid] != iss_ptr[thid])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> lsu_block_store_kill asserted while the ret_ptr = %0h != iss_ptr = %0h.", core_id, thid, tmp[`MEMOP_PA], ret_ptr[thid], iss_ptr[thid]);
if (rdptr[thid] != iss_ptr[thid])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> lsu_block_store_kill asserted while the rdptr = %0h != iss_ptr = %0h.", core_id, thid, tmp[`MEMOP_PA], rdptr[thid], iss_ptr[thid]);
if (iss_ptr[thid] == wrptr[thid])
if (stb_valid[{thid, wrptr[thid]}])
/* Lsu can assert both dealloc and block_store_kill for a request.
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Lsu asserted block_store_kill while there are no valid entries in STB to be deallocated.", core_id, thid);
if (iss_ptr[thid] < wrptr[thid])
squash_cnt = wrptr[thid] - iss_ptr[thid];
else if (iss_ptr[thid] > wrptr[thid])
squash_cnt = wrptr[thid] + (8 - iss_ptr[thid]);
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> SQUASH_STB:iss_ptr = %0h, wrptr = %0h, squash_cnt = %0h.", core_id, thid, iss_ptr[thid], wrptr[thid], squash_cnt);
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> Block store kill changed issue_ptr:%0h->%0h. ret_ptr: %0h->%0h. rdptr:%0h->%0h.", core_id, thid, iss_ptr[thid], iss_ptr[thid]+squash_cnt, ret_ptr[thid], ret_ptr[thid]+squash_cnt, rdptr[thid], rdptr[thid]+squash_cnt);
ret_ptr[thid] = ret_ptr[thid] + squash_cnt;
rdptr[thid] = rdptr[thid] + squash_cnt;
iss_ptr[thid] = iss_ptr[thid] + squash_cnt;
if (~stb_valid[{thid, i}])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h><PA = %0h> lsu_block_store_kill asserted while the stb entry %0h is invalid.", core_id, thid, tmp[`MEMOP_PA], i);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h>st_issue bit is set when the block_store_kill is asserted for stb entry %0h.", core_id, thid, tmp[`MEMOP_PA], i);
//commenting out the chk below. Lsu can assert sbdiou and then in the next cycle insert a new entry into
//stb. LSU will squash this new entry and won't issue it to PCX/asi but its squash bit won't be
//set in the chkr which was causin it to fire.
//`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> lsu_block_store_kill asserted while the squash bit is 0 in the STB entry %0h.", core_id, thid, tmp[`MEMOP_PA], i);
stb_valid[{thid, i}] = 1'b0;
squash_cnt = squash_cnt - 1'b1;
if ((bst_cnt > 0) && (`SPC1.lsu_stb_alloc == 8'b0))
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Blk store entries are not allocated back to back in STB.", core_id, bst_active_thid);
//For bst the stb is still written even though we have errors.
//Stb is written in W stage. Howvere for first blk store helper
//the err will be flagged by FGU in b stage. We can miss the
// err signal if we don't sample in B.
//for the last helper err will be signalled in B stage of last helper and at
if (lsu_bst_active[bst_active_thid] & `SPC0.fgu_fst_ecc_error_fx2 & (bst_cnt < 7))
if (`SPC1.lsu_stb_alloc[7:0] != 8'b0)
thid = decode_tid(`SPC1.lsu_stb_alloc[7:0]);
if (thid != dec_lsu_tid_w)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> lsu_stb_alloc = %0h mismatches the thid %0h.", core_id, dec_lsu_tid_w, `SPC1.lsu_stb_alloc[7:0], dec_lsu_tid_w);
Insert_in_STB(stb_alloc_data, dec_lsu_tid_w);
if (lsu_bst_active[thid])
bst_data = bst_inst_data;
if (thid != bst_active_thid)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> lsu_stb_alloc = %0h mismatches the active blkstore thid = %0h.", core_id, bst_active_thid, `SPC1.lsu_stb_alloc[7:0], bst_active_thid);
addr = bst_data[`MEMOP_VA];
bst_data[`MEMOP_VA] = {addr[47:6], bst_cnt[2:0], 3'b0};
addr = bst_data[`MEMOP_PA];
bst_data[`MEMOP_PA] = {addr[39:6], bst_cnt[2:0], 3'b0};
Insert_in_STB(bst_data, bst_active_thid);
lsu_bst_active[thid] = 1'b0;
if (bst_fgu_err) //set the squash bit to 0 for all the stb entries
for (i = 0; i < 8; i=i+1)
tmp = stb[{thid, i[2:0]}];
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> Squash bit already set when trying to set it for a bst fgu errerr.", core_id, thid, tmp[`MEMOP_PA]);
stb[{thid, i[2:0]}] = tmp;
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> <PA = %0h> STB_entry[%0h] squashed due to FGU err.", core_id, thid, tmp[`MEMOP_PA], i);
`PR_ERROR("lsu_mon", `ERROR, "<C%h>: LSU asserted lsu_stb_alloc = %0h while no store pending to be written in STB.", core_id, `SPC1.lsu_stb_alloc[7:0]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <%0h> W_stage: LSU did not assert lsu_stb_alloc for the store.", core_id, dec_lsu_tid_w, inst_pc_w);
reg [47:0] addr, act_addr;
thid =`SPC1.lsu_rngl_cdbus[58:56];
thid =`SPC1.lsu_rngf_cdbus[58:56];
asi =`SPC1.lsu_rngl_cdbus[55:48];
asi =`SPC1.lsu_rngf_cdbus[55:48];
addr =`SPC1.lsu_rngl_cdbus[47:0];
addr =`SPC1.lsu_rngf_cdbus[47:0];
req_type =`SPC1.lsu_rngl_cdbus[61:60];
req_type =`SPC1.lsu_rngf_cdbus[61:60];
tmp = stb[{thid, iss_ptr[thid]}];
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> Store reissued on the ASI interface.", core_id, thid, addr);
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> Store issued on the ASI interface that has been squashed.", core_id, thid, addr);
act_addr = tmp[`MEMOP_PA];
act_addr = {act_addr[39:3], 3'b0};
//47 is D tag rd asi. LSU issues that on the ring but changes
if ((addr == act_addr) || (asi == 8'h47) || (asi == 8'h46))
stb[{thid, iss_ptr[thid]}] = tmp;
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) STB[%0d] Issued on local ring.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], iss_ptr[thid]);
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) STB[%0d] Issued on fast ring.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], iss_ptr[thid]);
iss_ptr[thid] = iss_ptr[thid] + 1'b1;
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <%0h>: %s(VA=%0h) STB[%0d] PA mismatch for asi req on local ring. Expected PA = %0h, actual PA = %0h", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], iss_ptr[thid], tmp[`MEMOP_PA], addr);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <%0h>: %s(VA=%0h) STB[%0d] PA mismatch for asi req on fast ring. Expected PA = %0h, actual PA = %0h", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], iss_ptr[thid], tmp[`MEMOP_PA], addr);
task chk_store_issue_to_pcx;
reg [39:0] pcx_pa, inst_pa;
thid = pcx_pkt[`PCX_THR_ID];
tmp = stb[{thid, iss_ptr[thid]}];
inst = tmp[`LSU_MON_INST];
pcx_pa = pcx_pkt[`PCX_ADDR];
inst_pa = tmp[`MEMOP_PA];
if (pcx_pkt[`PCX_RQTYP] == `PCX_STORE)
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) STB[%0d] Issued to gasket.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], iss_ptr[thid]);
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) STB[%0d] Issued to gasket with ND set.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], iss_ptr[thid]);
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> A store request made to gasket by LSU while the pending req is not store.", core_id, thid, pcx_pkt[`PCX_ADDR]);
if (pcx_pa[39:0] != inst_pa[39:0])
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> A store request made to gasket by LSU while the pending req has PA %0h.", core_id, thid, pcx_pkt[`PCX_ADDR], tmp[`MEMOP_PA]);
if ((tmp[`INST_ASI] == 8'h73) & (pcx_pa[39:0] != {8'h90, core_id, thid, tmp[`INST_ASI], 18'h0}))
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> pcx_pa is not correct for asi write to interrupt vector dispatch register.", core_id, thid, pcx_pkt[`PCX_ADDR]);
if (inst[`BLKST] && ~pcx_pkt[`PCX_BST])
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> Bst bit is not set in the PCX pkt by LSU for a blk st request.", core_id, thid, pcx_pkt[`PCX_ADDR]);
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> Store reissued on the PCX interface.", core_id, thid, pcx_pkt[`PCX_ADDR]);
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> Store issued on the PCX interface that has been squashed.", core_id, thid, pcx_pkt[`PCX_ADDR]);
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> BIS bit is not set in the PCX pkt by LSU for an RMO store.", core_id, thid, pcx_pkt[`PCX_ADDR]);
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> L2ack bit is set when the RMO store is issued to PCX.", core_id, thid, pcx_pkt[`PCX_ADDR]);
ret_ptr[thid] = ret_ptr[thid] + 1; //this will be deallocated before
//response seen from stub
st_rmo_cnt[thid] = st_rmo_cnt[thid] + 1'b1;
stb[{thid, iss_ptr[thid]}] = tmp;
iss_ptr[thid] = iss_ptr[thid] + 1;
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> iss_ptr = %0d. ret_ptr = %0d, st_rmo_cnt = %0d", core_id, thid, iss_ptr[thid], ret_ptr[thid], st_rmo_cnt[thid]);
`ifdef INJ_STB_ERR_IN_CMP
reg [2:0] err_tid, stb_err_tid_d1, stb_err_tid_d2;
reg [2:0] err_index, stb_err_index_d1, stb_err_index_d2;
reg stb_err_inj, stb_err_inj_d1, stb_err_inj_d2;
reg [1:0] err_priv, stb_err_priv_d1, stb_err_priv_d2;
if (("cmp_stb_err_inj_on"))
always @ (negedge (`SPC1.l2clk & enabled & cmp_stb_err_inj))
//valid stb ram rd for issue to pcx
if (`SPC1.lsu.sbc.ram_rptr_vld_2 & `SPC1.lsu.sbc.st_pcx_rq_p3 & `SPC1.lsu.pic.pic_st_sel_p3)
err_tid = decode_tid(`SPC1.lsu.sbc.st_rq_sel_p3[7:0]);
err_index = `SPC1.lsu.sbc.ram_rptr_d1;
err_tmp = stb[{err_tid, err_index}];
err_inst = err_tmp[`LSU_MON_INST];
cam_data = `SPC1.lsu.stb_cam.cam_array.stb_rdata[44:0];
err_priv = err_tmp[`ST_PRIV];
//if (err_inst[`SWAP] || err_inst[`CASA] || err_inst[`LDSTUB])
err_inj_cnt = err_inj_cnt + 1;
11, 12: err_bit = err_bit + 1;
force `SPC0.lsu.stb_cam.cam_array.stb_rdata[44:0] = cam_data ^ (1 << err_bit);
`PR_INFO("stb_err", 22, "<T%0h> <%0h> STB[%0h]: SBAPP forced for CASA. err_bit = %0h", err_tid, {cam_data[44:8], 3'b0}, err_index, err_bit);
release `SPC0.lsu.stb_cam.cam_array.stb_rdata[44:0];
if (~`SPC1.lsu_sbapp_err_g)
`PR_ERROR("lsu_mon", `ERROR, "<T%0h> sbapp err not asserted when err is injected for atomic.", stb_err_tid_d2);
if ((`SPC1.lsu_stberr_tid_g != stb_err_tid_d2) ||
(`SPC1.lsu_stberr_index_g != stb_err_index_d2) ||
(`SPC1.lsu_stberr_priv_g != stb_err_priv_d2))
`PR_ERROR("lsu_mon", `ERROR, "<T%0h> sbapp err parameters mismatch.", stb_err_tid_d2);
if (`SPC1.lsu_sbapp_err_g)
`PR_ERROR("lsu_mon", `ERROR, "<T%0h> sbapp err asserted when none expected.", `SPC1.lsu_stberr_tid_g);
always @ (posedge (`SPC1.l2clk & enabled & cmp_stb_err_inj))
stb_err_inj_d1 <= stb_err_inj;
stb_err_inj_d2 <= stb_err_inj_d1;
stb_err_tid_d1 <= err_tid;
stb_err_tid_d2 <= stb_err_tid_d1;
stb_err_index_d1 <= err_index;
stb_err_index_d2 <= stb_err_index_d1;
stb_err_priv_d1 <= err_priv;
stb_err_priv_d2 <= stb_err_priv_d1;
// If vcs_build_args NO_MONITORS, then module will be empty
reg [7:0] asi_e, imm_asi_e, asi_m, asi_b;
reg dec_altspace_e, dec_altspace_b, dec_altspace_m;
reg [1:0] exu_lsu_va_error_b;
reg [2:0] dec_lsu_tid_e, dec_lsu_tid_m, dec_lsu_tid_b, dec_lsu_tid_w;
reg [47:0] inst_pc_e, inst_pc_m, inst_pc_b, inst_pc_w;
reg [31:0] inst_e, inst_m, inst_b;
reg [47:0] vaddr_m, vaddr_b;
reg [63:0] int_st_data_m, int_st_data_b;
reg [63:0] fp_st_sata_fx2;
reg [20:0] lsu_inst_e, lsu_inst_m, lsu_inst_b;
reg mmu_dtlb_reload_d1, mmu_dtlb_reload_d2;
reg [`LD_Pend_Width] ld_pend_array[7:0];
reg [`LAST_INST_Pend_Width] last_inst_array[7:0];
reg [2:0] wrptr[7:0]; //Pts. to the STB entry into which data will be written next
reg [2:0] rdptr[7:0]; //Tracks the dealloc signal from STB
reg [2:0] iss_ptr[7:0]; //keeps track of when a store is issued from the STB to PCX
reg [2:0] ret_ptr[7:0]; //keeps track of when the response is received from
reg [`STB_Pend_Width] stb[63:0];
//reg [`TLB_MISS_Pend_Width] tlbmiss_pend_array[7:0];
reg [7:0] dcache_inv_cnt[7:0];
reg [7:0] st_rmo_cnt[7:0];
reg [31:0] dec_tg0_inst_d, dec_tg1_inst_d;
reg [7:0] lsu_bst_active;
reg [195:0] stb_alloc_data;
reg [195:0] bst_data, bst_inst_data;
reg [2:0] bst_active_thid;
reg [7:0] is_blkld; //reqd by lsu_ras_chkr to chk errors on blk ld.
reg [1:0] l2_blk_ld_errtype[7:0]; //Gives the type of err the ahd be reported by LSU if
//different types of err occur on blk ld helper returns
reg [1:0] st_priv[7:0]; //Gives the final priv level for an sbdiou/sbapp err that shd be
for (i = 0; i < 8; i = i+1)
l2_blk_ld_errtype[i] = 2'b0;
// avoid time zero ugliness. jp
//@(posedge `SPC0.l2clk);
//@(negedge `SPC0.l2clk);
//if (`PARGS.lsu_mon_on) enabled = 1;
3'h0: finish_mask = `PARGS.finish_mask[7:0];
3'h1: finish_mask = `PARGS.finish_mask[15:8];
3'h2: finish_mask = `PARGS.finish_mask[23:16];
3'h3: finish_mask = `PARGS.finish_mask[31:24];
3'h4: finish_mask = `PARGS.finish_mask[39:32];
3'h5: finish_mask = `PARGS.finish_mask[47:40];
3'h6: finish_mask = `PARGS.finish_mask[55:48];
3'h7: finish_mask = `PARGS.finish_mask[63:56];
if (~`TOP.in_reset & `PARGS.lsu_mon_on & ~reset_in_middle)
`PR_ALWAYS("lsu_mon", `ALWAYS, "Lsu_mon on, in_reset = 0.");
if (`TOP.in_reset & enabled)
`PR_ALWAYS("lsu_mon", `ALWAYS, "Reset asserted in the middle of the diag. Turned off Lsu_mon.");
always @ (posedge (tb_top.sim_status[0] & enabled))
if (|(ld_valid[7:0] & finish_mask[7:0]))
for (i = 0; i < 8; i=i+1)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> Ld requests pending at the end of simulation. ld_valid = %0h", core_id, ld_valid);
for (i = 0; i < 64; i=i+1)
if (stb_valid[i] & finish_mask[i[5:3]])
//chkr resets the stb valid bits when block_store_kill is asserted.
//in couple of failures block_store_kill was sampled asserted two cycles after
//lsu asserted stb_empty. The simulation ended the cycle stb_empty was sampled high
//causing moniotr firings with valid entries in stb at end of simulation. Now
//don't flag an error if squash bit is set and stb_valid is asserted at end
if (~is_squash_bit_set(i[5:0]))
Disp_STB_entry(i[5:3],i[2:0]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> Store requests pending at the end of simulation. stb_valid = %0h", core_id, stb_valid);
for (i = 0; i < 8; i=i+1)
if (finish_mask[i] & (pf_cnt[i] != 0))
`PR_ALWAYS("lsu_mon", `ALWAYS, "<C%h> <T%0h> Prefetches not finished. Pf_cnt = %0d", core_id, i, pf_cnt[i]);
if (finish_mask[i] & (dcache_inv_cnt[i] != 0))
`PR_ALWAYS("lsu_mon", `ALWAYS, "<C%h> <T%0h> D pkt not received for all invalidate reqs. issued by the thread. dcache_inv_cnt = %0d", core_id, i, dcache_inv_cnt[i]);
if (finish_mask[i] & (st_rmo_cnt[i] != 0))
`PR_ALWAYS("lsu_mon", `ALWAYS, "<C%h> <T%0h> rmo_cnt not zero. rmo_cnt = %0d", core_id, i, st_rmo_cnt[i]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> Prefetch/D/RMO_stores requests pending at the end of simulation.", core_id);
function is_squash_bit_set;
is_squash_bit_set = 1'b1;
is_squash_bit_set = 1'b0;
always @ (negedge (`SPC2.l2clk & enabled))
asi_e = `SPC2.lsu.dcc.dcc_asi_e[7:0];
lsu_inst_e[`LD] <= `SPC2.dec_ld_inst_e;
lsu_inst_e[`ST] <= `SPC2.dec_st_inst_e;
lsu_inst_e[`FP] <= `SPC2.dec_fpldst_inst_e;
lsu_inst_e[`PREF] <= `SPC2.dec_pref_inst_e;
lsu_inst_e[`SWAP] <= `SPC2.dec_swap_inst_e;
lsu_inst_e[`CASA] <= `SPC2.dec_casa_inst_e;
lsu_inst_e[`LDSTUB] <= `SPC2.dec_ldstub_inst_e;
lsu_inst_e[`FLUSH] <= `SPC2.dec_flush_inst_e;
lsu_inst_e[`MEMBAR] <= `SPC2.dec_memstbar_inst_e;
lsu_inst_e[`LDD] <= `SPC2.dec_ld_inst_e & `SPC2.dec_ldst_dbl_e & ~`SPC2.dec_fpldst_inst_e;
lsu_inst_e[`STD] <= `SPC2.dec_st_inst_e & `SPC2.dec_ldst_dbl_e & ~`SPC2.lsu.dec_fpldst_inst_e;
lsu_inst_e[`BLKLD] <= `SPC2.dec_ld_inst_e & `SPC2.dec_fpldst_inst_e & dec_altspace_e & Is_blk_asi(asi_e);
lsu_inst_e[`BLKST] <= `SPC2.dec_st_inst_e & `SPC2.dec_fpldst_inst_e & dec_altspace_e & Is_blk_asi(asi_e);
lsu_inst_e[`QLD] <= `SPC2.dec_ld_inst_e & dec_altspace_e & Is_qld_asi(asi_e);
lsu_inst_e[`ASR_RD_WR] <= `SPC2.dec_sr_inst_e & (`SPC2.dec_ld_inst_e | `SPC2.dec_st_inst_e);
lsu_inst_e[`PR_RD_WR] <= `SPC2.dec_pr_inst_e & (`SPC2.dec_ld_inst_e | `SPC2.dec_st_inst_e);
lsu_inst_e[`HPR_RD_WR] <= `SPC2.dec_hpr_inst_e & (`SPC2.dec_ld_inst_e | `SPC2.dec_st_inst_e);
lsu_inst_e[`FSR_RD_WR] <= `SPC2.dec_fsr_ldst_e & (`SPC2.dec_ld_inst_e | `SPC2.dec_st_inst_e);
always @ (posedge (`SPC2.l2clk & enabled))
dec_tg0_inst_d <= `SPC2.dec.ded0.decode_mux[31:0];
dec_tg1_inst_d <= `SPC2.dec.ded1.decode_mux[31:0];
imm_asi_vld_e <= `SPC2.lsu.dec_imm_asi_vld_d;
imm_asi_e <= `SPC2.lsu.dec_imm_asi_d;
dec_altspace_e <= `SPC2.dec_altspace_d;
dec_altspace_m <= dec_altspace_e;
dec_altspace_b <= dec_altspace_m;
exu_ecc_b <= `SPC2.exu_ecc_m;
exu_lsu_va_error_b <= `SPC2.exu_lsu_va_error_m;
dec_lsu_tid_e <= `SPC2.dec_lsu_tg_d ? {1'b1, `SPC2.dec_lsu_tid1_d} : {1'b0, `SPC2.dec_lsu_tid0_d};
dec_lsu_tid_m <= dec_lsu_tid_e;
dec_lsu_tid_b <= dec_lsu_tid_m;
dec_lsu_tid_w <= dec_lsu_tid_b;
inst_pc_e <= `SPC2.dec_lsu_tg_d ? {`SPC2.tlu.tlu_pc_1_d[47:2], 2'b0} : {`SPC2.tlu.tlu_pc_0_d[47:2], 2'b0};
inst_e <= `SPC2.dec_lsu_tg_d ? dec_tg1_inst_d : dec_tg0_inst_d;
vaddr_m <= `SPC2.exu_lsu_address_e;
int_st_data_m <= `SPC2.exu_lsu_store_data_e;
int_st_data_b <= int_st_data_m;
fp_st_sata_fx2 <= `SPC2.fgu_lsu_fst_data_fx1;
mmu_dtlb_reload_d1 <= `SPC2.mmu_dtlb_reload;
mmu_dtlb_reload_d2 <= mmu_dtlb_reload_d1;
//pcx_thid_d1 <= `SPC2.lsu.spc_pcx_data_pa[`PCX_THR_ID];
lsu_inst_m <= lsu_inst_e;
lsu_inst_b <= lsu_inst_m;
Is_blk_asi = (asi == `ASI_BLK_AIUP) | (asi == `ASI_BLK_AIUS) |
(asi == `ASI_BLK_AIUPL) | (asi == `ASI_BLK_AIUSL) |
(asi == `ASI_BLK_P) | (asi == `ASI_BLK_S) |
(asi == `ASI_BLK_PL) | (asi == `ASI_BLK_SL) |
(asi == `ASI_BLK_COMMIT_P) | (asi == `ASI_BLK_COMMIT_S);
Is_qld_asi = (asi == `ASI_AIU_BIS_QUAD_LDD_P) | (asi == `ASI_AIU_BIS_QUAD_LDD_S) |
(asi == `ASI_AIU_BIS_QUAD_LDD_P_LITTLE) | (asi == `ASI_AIU_BIS_QUAD_LDD_S_LITTLE) |
(asi == `ASI_NUCLEUS_BIS_QUAD_LDD) | (asi == `ASI_NUCLEUS_BIS_QUAD_LDD_LITTLE) |
(asi == `ASI_BIS_QUAD_LDD_P) | (asi == `ASI_BIS_QUAD_LDD_S) |
(asi == `ASI_BIS_QUAD_LDD_P_LITTLE) | (asi == `ASI_BIS_QUAD_LDD_S_LITTLE) |
(asi == `ASI_QUAD_LDD) | (asi == `ASI_QUAD_LDD_REAL) |
(asi == `ASI_QUAD_LDD_L) | (asi == `ASI_QUAD_LDD_REAL_L);
Is_bis_asi = (asi == `ASI_AIU_BIS_QUAD_LDD_P) | (asi == `ASI_AIU_BIS_QUAD_LDD_S) |
(asi == `ASI_AIU_BIS_QUAD_LDD_P_LITTLE) | (asi == `ASI_AIU_BIS_QUAD_LDD_S_LITTLE) |
(asi == `ASI_NUCLEUS_BIS_QUAD_LDD) | (asi == `ASI_NUCLEUS_BIS_QUAD_LDD_LITTLE) |
(asi == `ASI_BIS_QUAD_LDD_P) | (asi == `ASI_BIS_QUAD_LDD_S) |
(asi == `ASI_BIS_QUAD_LDD_P_LITTLE) | (asi == `ASI_BIS_QUAD_LDD_S_LITTLE);
always @ (negedge (`SPC2.l2clk & enabled))
`PR_INFO("lsu_mon", 21, "<C%0h> <T%0h> <%0h> M_stage: %s(VA=%0h) Flushed due to IFU Flush.", core_id, dec_lsu_tid_m, inst_pc_m, tb_top.intf0.xlate(inst_m),vaddr_m);
if (lsu_inst_b[`BLKLD]) print_inst = " BLKLD,";
else if (lsu_inst_b[`BLKST]) print_inst = " BLKST,";
else if (lsu_inst_b[`QLD]) print_inst = " QLD,";
`PR_INFO("lsu_mon", 21, "<C%0h> <T%0h> <%0h> B_stage: %s(VA=%0h) Flushed due to IFU Flush.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b);
else if (`SPC2.tlu_flush_lsu_b)
`PR_INFO("lsu_mon", 21, "<C%h> <T%0h> <%0h> B_stage: %s(VA=%0h) Flushed due to TLU Flush.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b);
//casa is a two cycle operation. If there is an err on the 2nd cycle of casa then also
//This function will also chk for errors on 2nd cycle.
else if (Is_exu_error(exu_lsu_va_error_b, exu_ecc_b))
`PR_INFO("lsu_mon", 21, "<C%h> <T%0h <%0h> B_stage: %s(VA=%0h) Flushed due to EXU error.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b);
else if ((`SPC2.fgu_cecc_fx2 || `SPC2.fgu_uecc_fx2) && lsu_inst_b[`ST] && lsu_inst_b[`FP])
`PR_INFO("lsu_mon", 21, "<C%h> <T%0h> <%0h> B_stage: %s(VA=%0h) Flushed due to FGU error.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b);
else if (!`SPC2.lsu_tlb_miss_b_)
`PR_INFO("lsu_mon", 23, "<C%h> <T%0h> <%0h> B_stage: %s(VA=%0h)%s ASI = %0h. DTLB miss.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b, print_inst, asi_b);
//Lsu doesn't assert lsu_sync for an exception or dtlb miss. Since for
//an exception tlu anyway tells the front end to flush itself there is
//no reason for LSU to flush the front end then TLU to flush it again.
//Lsu treats the dtlbmiss as an exception that it flushes the inst and
//handles it when it is reissued by the front end.
if (`SPC2.lsu_tlb_bypass_b)
if (`SPC2.lsu_sync != 8'b0)
`PR_INFO("lsu_mon", 23, "<C%h> <T%0h> <%0h>: %s(VA=%0h)%s PA = %0h, ASI = %0h. LSU_sync. DTLB Bypass.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b, print_inst, {`SPC2.lsu.tlb_pgnum[39:13], vaddr_b[12:0]}, asi_b);
`PR_INFO("lsu_mon", 23, "<C%h> <T%0h> <%0h>: %s(VA=%0h)%s PA = %0h, ASI = %0h. DTLB Bypass.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b, print_inst, {`SPC2.lsu.tlb_pgnum[39:13], vaddr_b[12:0]}, asi_b);
if (`SPC2.lsu_sync != 8'b0)
`PR_INFO("lsu_mon", 23, "<C%h> <T%0h> <%0h>: %s(VA=%0h)%s PA = %0h, ASI = %0h, Store_data = %0h. LSU_sync. DTLB hit.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b, print_inst, {`SPC2.lsu.tlb_pgnum[39:13], vaddr_b[12:0]}, asi_b,int_st_data_b);
`PR_INFO("lsu_mon", 23, "<C%h> <T%0h> <%0h>: %s(VA=%0h)%s PA = %0h, ASI = %0h. LSU_sync. DTLB hit.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b, print_inst, {`SPC2.lsu.tlb_pgnum[39:13], vaddr_b[12:0]}, asi_b);
`PR_INFO("lsu_mon", 23, "<C%h> <T%0h> <%0h>: %s(VA=%0h)%s PA = %0h, ASI = %0h, Store_data = %0h. DTLB hit.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b, print_inst, {`SPC2.lsu.tlb_pgnum[39:13], vaddr_b[12:0]}, asi_b, int_st_data_b);
`PR_INFO("lsu_mon", 23, "<C%h> <T%0h> <%0h>: %s(VA=%0h)%s PA = %0h, ASI = %0h. DTLB hit.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b, print_inst, {`SPC2.lsu.tlb_pgnum[39:13], vaddr_b[12:0]}, asi_b);
if (lsu_inst_b[`LD] || lsu_inst_b[`PREF] || lsu_inst_b[`SWAP] || lsu_inst_b[`CASA] || lsu_inst_b[`LDSTUB])
if (((lsu_inst_b == 16'h1) || (lsu_inst_b == 16'h5)) & `SPC2.lsu.stb_cam_hit)
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> <%0h>: LSU_sync asserted due to STB RAW.", core_id, dec_lsu_tid_b, inst_pc_b);
if (lsu_inst_b[`ST]) //for atomics both ld and store signals are asserted
Insert_in_last_inst_array;
if (`SPC2.lsu_trap_flush[7:0])
`PR_INFO("lsu_mon", 21, "<C%h> <T%0h> Trap Flush asserted.", core_id, decode_tid(`SPC2.lsu_trap_flush[7:0]));
//This is how we test squashing of stores by LSU_mon:
//Whenever lsu asserts err_sbdiou signal, the monitor sets the squash
//bit in the STB for the rest of the stores. If any of these squashed stores
//is issued on the asi ring or to the PCX interface the monitor complains.
//The squashed stores are deallocated when either a block_store_kill is
//asserted or dealloc signals are asserted by the LSU.
//When the block_store_kill is asserted, it tells the IFU to dealloc
//all the pending stores in the IFU. It means the when block_store_kill
//is asserted we have deallocated all the non-squashed requests from STB.
//The 0in_chkr ensures that LSU flags the correct index and priv with the
//the sbdiou signal to TLU.
always @ (negedge (`SPC2.l2clk & enabled))
if (`SPC2.lsu_l15_valid & `SPC2.lsu.spc_pcx_data_pa[129])
Chk_pcx_req_pkt(`SPC2.lsu.spc_pcx_data_pa[129:0]); //chk if we need .lsu here
if ((`SPC2.lsu_rngl_cdbus[64:63] == 2'b11) & ~`SPC2.lsu_rngl_cdbus[59])
Chk_st_on_ASI_ring(`LOCAL);
if ((`SPC2.lsu_rngf_cdbus[64:63] == 2'b11) & ~`SPC2.lsu_rngf_cdbus[59])
Chk_st_on_ASI_ring(`FAST);
//if (`SPC2.l15_lsu_valid)
//Chk_cpx_response_pkt({`SPC2.l15_lsu_valid, `SPC2.l15_lsu_cpkt[17:13],`SPC2.l15_lsu_cpkt[11:0],`SPC2.l15_spc_data1[127:0]});
if (`SPC2.cpx_spc_data_cx[145])
Chk_cpx_response_pkt(`SPC2.cpx_spc_data_cx);
if (`SPC2.lsu_complete[7:0] != 8'b0)
if (`SPC2.lsu_complete[0]) Chk_ld_complete(0);
if (`SPC2.lsu_complete[1]) Chk_ld_complete(1);
if (`SPC2.lsu_complete[2]) Chk_ld_complete(2);
if (`SPC2.lsu_complete[3]) Chk_ld_complete(3);
if (`SPC2.lsu_complete[4]) Chk_ld_complete(4);
if (`SPC2.lsu_complete[5]) Chk_ld_complete(5);
if (`SPC2.lsu_complete[6]) Chk_ld_complete(6);
if (`SPC2.lsu_complete[7]) Chk_ld_complete(7);
if (`SPC2.lsu_block_store_kill[7:0] != 8'b0)
if (`SPC2.lsu_block_store_kill[0]) Squash_STB(0);
if (`SPC2.lsu_block_store_kill[1]) Squash_STB(1);
if (`SPC2.lsu_block_store_kill[2]) Squash_STB(2);
if (`SPC2.lsu_block_store_kill[3]) Squash_STB(3);
if (`SPC2.lsu_block_store_kill[4]) Squash_STB(4);
if (`SPC2.lsu_block_store_kill[5]) Squash_STB(5);
if (`SPC2.lsu_block_store_kill[6]) Squash_STB(6);
if (`SPC2.lsu_block_store_kill[7]) Squash_STB(7);
if (`SPC2.lsu_stb_dealloc[7:0] != 8'b0)
if (`SPC2.lsu_stb_dealloc[0]) Dealloc_STB(0);
if (`SPC2.lsu_stb_dealloc[1]) Dealloc_STB(1);
if (`SPC2.lsu_stb_dealloc[2]) Dealloc_STB(2);
if (`SPC2.lsu_stb_dealloc[3]) Dealloc_STB(3);
if (`SPC2.lsu_stb_dealloc[4]) Dealloc_STB(4);
if (`SPC2.lsu_stb_dealloc[5]) Dealloc_STB(5);
if (`SPC2.lsu_stb_dealloc[6]) Dealloc_STB(6);
if (`SPC2.lsu_stb_dealloc[7]) Dealloc_STB(7);
if (`SPC2.lsu_block_store_stall)
if (`SPC2.lsu.lsu_block_store_alloc[7:0] != 8'b0)
Set_block_store_parameters;
if (`SPC2.lsu_sbdiou_err_g || `SPC2.lsu_sbapp_err_g)
if (`SPC2.lsu_stb_flush_g)
st_priv[`SPC2.lsu_stberr_tid_g] = get_priv_on_flush(`SPC2.lsu_stberr_tid_g);
function [1:0] get_priv_on_flush;
sq_index = `SPC2.lsu_stberr_index_g;
tmp = stb[{tid, sq_index}];
get_priv_on_flush = tmp[`ST_PRIV];
thid = `SPC2.lsu_block_store_tid;
bst_inst_data = stb[{thid, rdptr[thid]}];
inst = bst_inst_data[`LSU_MON_INST];
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> LSU asserted blk_store_stall while the req at the top of STB is not blkst as shown above", core_id, thid);
//lsu can assert block_store_stall for a new block store while it has not yet written
//the 8 stb entries from the previous blk store.
task Set_block_store_parameters;
thid = decode_tid(`SPC2.lsu.lsu_block_store_alloc[7:0]);
if (lsu_bst_active[thid])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> LSU asserted blk_store_alloc while the bst_active is already set for this thread.", core_id, thid);
lsu_bst_active[thid] = 1'b1;
if (`SPC2.lsu.fgu_fst_ecc_error_fx2)
thid = `SPC2.lsu_stberr_tid_g;
sq_index = `SPC2.lsu_stberr_index_g;
priv = `SPC2.lsu_stberr_priv_g;
tmp = stb[{thid, sq_index}];
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> Sbdiou/sbapp seen for index = %h and priv = %h.", core_id, thid, sq_index, priv);
st_priv[thid] = tmp[`ST_PRIV];
//lsu can assert deallocate before it asserts the sbdiou signal.
//In that case iss_ptr won't be equal to sbdiou index.
//if (sq_index != iss_ptr[thid])
// Disp_STB_entry(thid, iss_ptr[thid]);
// `PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> LSU asserted sbdiou/sbapp with index %0h while the next req to be issued is at index %0h.", core_id, thid, sq_index, iss_ptr[thid]);
//If there is only one store in the store buffer which gets an sbdiou error, then LSU can deallocate
//the store and then assert sbdiou. The deallocation will cause the stb issue_ptr to move
//forward to an inst. that has already been issued and completed and this chk can fire. So
// Disp_STB_entry(thid, iss_ptr[thid]);
// `PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> Store reissued on the PCX interface.", core_id, thid, tmp[`MEMOP_PA]);
if (iss_ptr[thid] == wrptr[thid])
if (stb_valid[{thid, wrptr[thid]}])
//changing it to an info message because if there is only one valid entry in store buffer that
//gets an sbdiou then LSU can deallocate the entry and then issue sbdiou.
//`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Lsu asserted sbdiou/sbapp while there are no valid entries in STB to be issued.", core_id, thid);
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> sbdiou/sbapp squashed only one entry in STB.", core_id, thid);
if (iss_ptr[thid] < wrptr[thid])
squash_cnt = wrptr[thid] - iss_ptr[thid];
else if (iss_ptr[thid] > wrptr[thid])
squash_cnt = wrptr[thid] + (8 - iss_ptr[thid]);
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> SQUASH_STORE:iss_ptr = %0h, wrptr = %0h, squash_cnt = %0h.", core_id, thid, iss_ptr[thid], wrptr[thid], squash_cnt);
if (priv < tmp[`ST_PRIV])
`PR_INFO("lsu_mon", `INFO, "<C%h> <T%0h> <PA = %0h> Sbdiou/sbapp signalled. Err in user/priv level store is squashing a higher priv level store.", core_id, thid, tmp[`MEMOP_PA]);
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> <PA = %0h> STB_entry[%0h] squashed.", core_id, thid, tmp[`MEMOP_PA], i);
squash_cnt = squash_cnt - 1'b1;
function [2:0] decode_tid;
8'h10: decode_tid = 3'h4;
8'h20: decode_tid = 3'h5;
8'h40: decode_tid = 3'h6;
8'h80: decode_tid = 3'h7;
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> decode_tid. Incorrect value of thid input = %0h.", core_id, thid_encode, thid_encode);
reg [`LD_Pend_Width] tmp;
tmp = ld_pend_array[thid];
if ((tmp[`L2_ISS] != 4'hf) || (tmp[`L2_RESP] != 4'hf))
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> LSU asserted lsu_complete while the l2_iss and l2_resp bits are not F.", core_id, thid);
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> <%0h> %s(VA=%0h) Complete. Setting ld_valid to 0.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA]);
tmp = last_inst_array[thid];
`PR_INFO("lsu_mon", 24, "<C%h> <T%0h> <%0h> %s(VA=%0h) Complete.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA]);
reg [`LD_Pend_Width] tmp, tmp1;
thid = pcx_pkt[`PCX_THR_ID];
tmp = ld_pend_array[thid];
inst = tmp[`LSU_MON_INST];
req = DispPCXReq(pcx_pkt);
addr = pcx_pkt[`PCX_ADDR];
if (pcx_pkt[`PCX_CPU_ID] != core_id)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> cpu_id (spc_pcx_data_pa[122:120]) = %h is not = %0h when the lsu made a %s req to gasket.", core_id, pcx_pkt[`PCX_THR_ID], addr, pcx_pkt[122:120], core_id, req);
if ((pcx_pkt[`PCX_RQTYP] == `PCX_LOAD) || (pcx_pkt[`PCX_RQTYP] == `PCX_CAS1) || (pcx_pkt[`PCX_RQTYP] == `PCX_CAS2) || (pcx_pkt[`PCX_RQTYP] == `PCX_SWAP_LDSTUB))
ld_valid[thid] = 1'b1; //we have sent a req to gasket and are waiting for response
`PR_INFO("lsu_mon", 22, "<C%0h> <T%0h> Setting ld_valid[%0h].", core_id, thid, thid);
if (tmp[`MEMOP_PA] != addr)
if ((tmp[`INST_ASI] == 8'h41) || (tmp[`INST_ASI] == 8'h73) || ((tmp[`INST_ASI] == 8'h45) && ((tmp[`MEMOP_PA] == 8'h10) || (tmp[`MEMOP_PA] == 8'h18))))
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <PA = %0h> PA mismatch on gasket for %s request. Ignoring the mismatch as inst. is issued with asi 41, 73 or 45 (with VA 0x10 or 18).", core_id, thid, addr, req);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> A %s request made to gasket by LSU while the pending req is with PA %0h.", core_id, thid, addr, req, tmp[`MEMOP_PA]);
case (pcx_pkt[`PCX_RQTYP])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> A prefetch request made to gasket by LSU which mismatches the pending request from the thread.", core_id, thid, addr);
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: PREF_ICE(VA=%0h) Issued. pf_cnt not updated.", core_id, thid, tmp[`INST_VA], tmp[`MEMOP_VA]);
pf_cnt[thid] = pf_cnt[thid] + 1'b1;
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) Issued. pf_cnt = %0d.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], pf_cnt[thid]);
tmp[`L2_RESP] = 4'hF; //we don't wait for a prefetch response from gasket
ld_pend_array[thid] = tmp;
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) Dcache invalidate pkt issued to CCX.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA]);
dcache_inv_cnt[thid] = dcache_inv_cnt[thid] + 1'b1;
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> CASA request made to gasket by LSU while no such request request is pending from this thread.", core_id, thid, addr);
if (pcx_pkt[`PCX_RQTYP] == `PCX_CAS1)
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) (CAS1) Issued to gasket.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA]);
ld_pend_array[thid] = tmp;
if (pcx_pkt[`PCX_RQTYP] == `PCX_CAS2)
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) (CAS2) Issued to gasket.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA]);
ld_pend_array[thid] = tmp;
chk_store_issue_to_pcx(pcx_pkt);
if (~inst[`SWAP] && ~inst[`LDSTUB])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> %s request made to gasket by LSU while no such request request is pending from this thread.", core_id, thid, addr, req);
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) Issued to gasket. store_data = %0h", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], pcx_pkt[`PCX_DATA]);
ld_pend_array[thid] = tmp;
chk_store_issue_to_pcx(pcx_pkt);
chk_store_issue_to_pcx(pcx_pkt);
default: `PR_INFO("lsu_mon", 21, "<C%h> <T%0h> <%0h>: %s Issued to gasket.", core_id, thid, addr, req);
task Chk_cpx_response_pkt;
thid = cpx_pkt[`CPX_THR_ID];
casex ({cpx_pkt[`CPX_RTNTYP], cpx_pkt[`CPX_ERR], cpx_pkt[`CPX_NC], cpx_pkt[`CPX_ATM], cpx_pkt[`CPX_PF]})
{4'b0, 2'bxx, 1'bx, 1'b0, 1'b0}:
chk_ccx_ld_response(cpx_pkt);
{4'b0, 2'bxx, 1'b1, 1'b0, 1'b1}:
if (pf_cnt[thid] == 8'b0)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Prefetch response received from gasket while the pf_cnt is 0 for this thread.", core_id, thid);
pf_cnt[thid] = pf_cnt[thid] - 1'b1;
`PR_INFO("lsu_mon", 26, "<C%h> <T%0h> Prefetch response received. pfcnt = %0d.", core_id, thid, pf_cnt[thid]);
{4'h8, 2'bxx, 1'b1, 1'b0, 1'b0}:
chk_ccx_ld_response(cpx_pkt);
{4'h4, 2'bxx, 1'bx, 1'b0, 1'b0}:
if (cpx_pkt[123]) //D pkt
if (cpx_pkt[120:118] != core_id)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> D response received from gasket with core_id =%h.", core_id, thid, cpx_pkt[120:118]);
if (dcache_inv_cnt[thid] == 8'b0)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> D response received from gasket while the Dcache_inv_cnt is 0 for this thread.", core_id, thid);
dcache_inv_cnt[thid] = dcache_inv_cnt[thid] - 1'b1;
`PR_INFO("lsu_mon", 26, "<C%h> <T%0h> D response received. Dcache_inv_cnt = %0d.", core_id, thid, dcache_inv_cnt[thid]);
else if (cpx_pkt[124]) //I pkt
if (cpx_pkt[120:118] != core_id)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> I response received from gasket with core_id =%h.", core_id, thid, cpx_pkt[120:118]);
//`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> I pkt.", core_id, thid);
else if (cpx_pkt[124:123] == 2'b0)
if (cpx_pkt[120:118] == core_id)
chk_ccx_st_response(cpx_pkt);
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> Store Ack pkt received from core %0h.", core_id, thid, cpx_pkt[120:118]);
{4'h1, 2'bxx, 1'bx, 1'b0, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> IFILL1 return.", core_id, thid);
{4'h1, 2'bxx, 1'bx, 1'b1, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> IFILL2 return.", core_id, thid);
{4'h9, 2'bxx, 1'b1, 1'b0, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> NCU IFILL return.", core_id, thid);
{4'b0, 2'bxx, 1'b1, 1'b1, 1'b0}:
chk_ccx_atm_response(cpx_pkt);
{4'h4, 2'bxx, 1'b1, 1'b1, 1'b0}:
if ((cpx_pkt[`CPX_RTNTYP] == 4'h4) & (cpx_pkt[120:118] == core_id))
chk_ccx_atm_response(cpx_pkt);
chk_ccx_st_response(cpx_pkt);
{4'h2, 2'bxx, 1'b1, 1'b0, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> Stream Ld return.", core_id, thid);
{4'h6, 2'bxx, 1'bx, 1'bx, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> Stream store Ack.", core_id, thid);
{4'h5, 2'bxx, 1'b1, 1'b0, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> MMU ld return.", core_id, thid);
{4'h7, 2'b00, 1'b0, 1'bx, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> Interrupt return.", core_id, thid);
{4'h3, 2'b00, 1'bx, 1'bx, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> Eviction Invalidation.", core_id, thid);
{4'hc, 2'bxx, 1'bx, 1'bx, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> L2 Indication.", core_id, thid);
{4'hd, 2'bxx, 1'bx, 1'bx, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> Soc Error Indication.", core_id, thid);
`PR_ALWAYS("lsu_mon", `ALWAYS, "CPX_PKT data.");
`PR_ALWAYS("lsu_mon", `ALWAYS, "<C%0h> <T%0h> rtn_typ = %0h, err_bits = %0h, nc=%0b, atm = %0b, pf = %0b", core_id, cpx_pkt[`CPX_THR_ID], cpx_pkt[`CPX_RTNTYP], cpx_pkt[`CPX_ERR], cpx_pkt[`CPX_NC], cpx_pkt[`CPX_ATM], cpx_pkt[`CPX_PF]);
`PR_ERROR("lsu_mon", `ERROR, "<C%0h> <T%0h> Can't recognise the CPX pkt.", core_id, thid);
task chk_ccx_ld_response;
reg [39:0] cpx_pa, inst_pa;
reg [`LD_Pend_Width] tmp;
thid = cpx_pkt[`CPX_THR_ID];
tmp = ld_pend_array[thid];
inst = tmp[`LSU_MON_INST];
inst_pa = tmp[`MEMOP_PA];
pkt_type = cpx_pkt[`CPX_RTNTYP];
`PR_INFO("lsu_mon", 26, "<C%0h> <T%0h> <%0h> %s(VA=%0h) L2 response.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA]);
if (inst_pa[39] != pkt_type[3])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> ccx pkt_type = %h mismatches the ld_pa bit 39. ld_pa = %0h.", core_id, thid, pkt_type, inst_pa);
if (tmp[`L2_RESP] == 4'h0)
tmp[`L2_ERR0] = cpx_pkt[`CPX_ERR];
if ((cpx_pkt[`CPX_ERR] == `ND) || (cpx_pkt[`CPX_ERR] == `UE))
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> UE/ND err on blk ld helper 1.", core_id, thid);
else if (tmp[`L2_RESP] == 4'h1)
tmp[`L2_ERR1] = cpx_pkt[`CPX_ERR];
if ((cpx_pkt[`CPX_ERR] == `ND) || (cpx_pkt[`CPX_ERR] == `UE))
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> UE/ND err on blk ld helper 2.", core_id, thid);
else if (tmp[`L2_RESP] == 4'h3)
tmp[`L2_ERR2] = cpx_pkt[`CPX_ERR];
if ((cpx_pkt[`CPX_ERR] == `ND) || (cpx_pkt[`CPX_ERR] == `UE))
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> UE/ND err on blk ld helper 3.", core_id, thid);
else if (tmp[`L2_RESP] == 4'h7)
tmp[`L2_ERR3] = cpx_pkt[`CPX_ERR];
if ((cpx_pkt[`CPX_ERR] == `ND) || (cpx_pkt[`CPX_ERR] == `UE))
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> UE/ND err on blk ld helper 4.", core_id, thid);
if ((tmp[`L2_ERR0] == `ND) || (tmp[`L2_ERR1] == `ND) || (tmp[`L2_ERR2] == `ND) || (tmp[`L2_ERR3] == `ND))
l2_blk_ld_errtype[thid] = `ND;
else if ((tmp[`L2_ERR0] == `UE) || (tmp[`L2_ERR1] == `UE) || (tmp[`L2_ERR2] == `UE) || (tmp[`L2_ERR3] == `UE))
l2_blk_ld_errtype[thid] = `UE;
else if ((tmp[`L2_ERR0] == `CE) || (tmp[`L2_ERR1] == `CE) || (tmp[`L2_ERR2] == `CE) || (tmp[`L2_ERR3] == `CE))
l2_blk_ld_errtype[thid] = `CE;
l2_blk_ld_errtype[thid] = `NE;
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Illegal value of l2_resp cnt when response pkt received from ccx.", core_id, thid);
else if (Is_single_pcx_req_ld(inst))
if (tmp[`L2_RESP] != 4'hE)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Illegal value of l2_resp cnt when response pkt received from ccx.", core_id, thid);
//`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> Setting L2_resp bits to F.", core_id, thid);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Load response received from gasket for thid %h while no load request pending from core for this thread.", core_id, thid, thid);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Load response received from gasket while no load request pending from core for this thread.", core_id, thid);
ld_pend_array[thid] = tmp;
task chk_ccx_atm_response;
reg [`LD_Pend_Width] tmp;
thid = cpx_pkt[`CPX_THR_ID];
tmp = ld_pend_array[thid];
inst = tmp[`LSU_MON_INST];
inst_pa = tmp[`MEMOP_PA];
if (cpx_pkt[`CPX_RTNTYP] == 4'b0)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Atomic ld response received from gasket while no request pending from core for this thread.", core_id, thid);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Atomic ack response received from gasket while no request pending from core for this thread.", core_id, thid);
if (~inst[`SWAP] && ~inst[`CASA] && ~inst[`LDSTUB])
if (cpx_pkt[`CPX_RTNTYP] == 4'b0)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Atomic ld response received from gasket which mismatches the request pending from this thread.", core_id, thid);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Atomic ack response received from gasket which mismatches the request pending from this thread.", core_id, thid);
if (cpx_pkt[`CPX_RTNTYP] == 4'b0)
`PR_INFO("lsu_mon", 26, "<C%0h> <T%0h> <%0h> %s(VA=%0h) Atomic ld response.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA]);
`PR_INFO("lsu_mon", 26, "<C%0h> <T%0h> <%0h> %s(VA=%0h) Atomic ack.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA]);
if (cpx_pkt[`CPX_RTNTYP] == 4'b0)
if (tmp[`L2_RESP] == 4'hC) tmp[`L2_RESP] = 4'hD;
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Illegal value of l2_resp cnt when atomic ld return pkt received from ccx.", core_id, thid);
if (tmp[`L2_RESP] == 4'hD) tmp[`L2_RESP] = 4'hF;
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Illegal value of l2_resp cnt when atomic ack pkt received from ccx.", core_id, thid);
ld_pend_array[thid] = tmp;
task chk_ccx_st_response;
reg [39:0] cpx_pa, inst_pa;
thid = cpx_pkt[`CPX_THR_ID];
tmp = stb[{thid, ret_ptr[thid]}];
inst = tmp[`LSU_MON_INST];
inst_pa = tmp[`MEMOP_PA];
pkt_type = cpx_pkt[`CPX_RTNTYP];
//is received. There could be some other store sitting in the STB at that time.
//Chk for squash bit only for non-bis responses.
if (cpx_pkt[`CPX_BIS]) //response to rmo store
if (st_rmo_cnt[thid] == 0)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> L2 response received for an rmo store while the st_rmo_cnt for this thread is 0.", core_id, thid);
st_rmo_cnt[thid] = st_rmo_cnt[thid] - 1'b1;
`PR_INFO("lsu_mon", 25, "<C%0h> <T%0h> Store ack received for RMO store. rmo_cnt = %0d", core_id, thid, st_rmo_cnt[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> L2 response received while the SQUASH bit is set in the STB entry %0h.", core_id, thid, ret_ptr[thid]);
if (~stb_valid[{thid, ret_ptr[thid]}])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Store ack received while that entry is invalid in STB.", core_id, thid);
if (~cpx_pkt[`CPX_ATM]) //don't print this message for atomic return
`PR_INFO("lsu_mon", 26, "<C%0h> <T%0h> <%0h> %s(VA=%0h) STB[%0d] Store ack.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA], ret_ptr[thid]);
stb[{thid, ret_ptr[thid]}] = tmp;
ret_ptr[thid] = ret_ptr[thid] + 1'b1;
//`PR_INFO("lsu_mon", 22, "<C%0h> <T%0h> ret_ptr = %0d.", core_id, thid, ret_ptr[thid]);
reg [`LD_Pend_Width] tmp;
reg [39:0] pcx_pa, inst_pa;
thid = pcx_pkt[`PCX_THR_ID];
tmp = ld_pend_array[thid];
inst = tmp[`LSU_MON_INST];
pcx_pa = pcx_pkt[`PCX_ADDR];
inst_pa = tmp[`MEMOP_PA];
req = DispPCXReq(pcx_pkt);
if (pcx_pa[39:6] != inst_pa[39:6])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> A load request made to gasket by LSU while the pending req has PA %0h.", core_id, thid, pcx_pa, tmp[`MEMOP_PA]);
if (tmp[`L2_ISS] != 4'h0 )
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> 1st load request (pa[5:0] = 6'b0) made to gasket by LSU for blkld while this request has already been issued to gasket.", core_id, thid, pcx_pa);
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) 1st blkld helper Issued to gasket.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA]);
if (pcx_pa[5:0] == 6'h10)
if (tmp[`L2_ISS] != 4'h1)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> 2nd load request (pa[5:0] = 6'h10) made to gasket by LSU for blkld while this request has already been issued to gasket.", core_id, thid, pcx_pa);
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) 2nd blkld helper Issued to gasket.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA]);
if (pcx_pa[5:0] == 6'h20)
if (tmp[`L2_ISS] != 4'h3)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> 3rd load request (pa[5:0] = 6'h20) made to gasket by LSU for blkld while this request has already been issued to gasket.", core_id, thid, pcx_pa);
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) 3rd blkld helper Issued to gasket.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA]);
if (pcx_pa[5:0] == 6'h30)
if (tmp[`L2_ISS] != 4'h7)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> 4th load request (pa[5:0] = 6'h30) made to gasket by LSU for blkld while this request has already been issued to gasket.", core_id, thid, pcx_pa);
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) 4th blkld helper Issued to gasket.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA]);
ld_pend_array[thid] = tmp;
else if (Is_single_pcx_req_ld(inst))
if (tmp[`L2_ISS] == 4'hF)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> Load request made to gasket by LSU while this request has already been issued to gasket.", core_id, thid, pcx_pa);
ld_pend_array[thid] = tmp;
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) Issued to gasket.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> A load request made to gasket by LSU while there is no such ld request pending from this thread.", core_id, thid, pcx_pa);
function Is_single_pcx_req_ld;
if (inst[`LDD] || inst[`QLD] || inst[`FSR_RD_WR] || (inst == 21'h1) || (inst == 21'h5))
Is_single_pcx_req_ld = 1'b1;
Is_single_pcx_req_ld = 1'b0;
//`PR_INFO("lsu_mon", 22, "<C%0h> Is_single_pcx_req_ld = %b. ", core_id, Is_single_pcx_req_ld);
case (`SPC2.lsu_trap_flush[7:0])
8'h01: if (tid == 3'h0) Is_trap = 1'b1;
8'h02: if (tid == 3'h1) Is_trap = 1'b1;
8'h04: if (tid == 3'h2) Is_trap = 1'b1;
8'h08: if (tid == 3'h3) Is_trap = 1'b1;
8'h10: if (tid == 3'h4) Is_trap = 1'b1;
8'h20: if (tid == 3'h5) Is_trap = 1'b1;
8'h40: if (tid == 3'h6) Is_trap = 1'b1;
8'h80: if (tid == 3'h7) Is_trap = 1'b1;
function [8*11:0] DispPCXReq;
casex ({pcx_pkt[`PCX_RQTYP], pcx_pkt[`PCX_NC], pcx_pkt[`PCX_INV], pcx_pkt[`PCX_PF], pcx_pkt[`PCX_BIS]})
{5'h0, 1'b1, 1'b0, 1'b1, 1'b0}: DispPCXReq = "PREF";
{5'h0, 1'b1, 1'b1, 1'b1, 1'b0}: DispPCXReq = "PREF_ICE";
{5'h0, 1'bx, 1'b0, 1'b0, 1'b0}: DispPCXReq = "LD";
{5'h0, 1'bx, 1'b1, 1'b0, 1'b0}: DispPCXReq = "D";
{5'h10, 1'bx, 1'b0, 1'b0, 1'b0}: DispPCXReq = "I";
{5'h10, 1'b0, 1'b1, 1'b0, 1'b0}: DispPCXReq = "I";
{5'h1, 1'bX, 1'bX, 1'b0, 1'b0}: DispPCXReq = "ST";
{5'h1, 1'bX, 1'bX, 1'b1, 1'b1}: DispPCXReq = "BLKST";
{5'h1, 1'bX, 1'bX, 1'b0, 1'b1}: DispPCXReq = "BIS";
{5'h2, 1'b1, 1'bX, 1'b0, 1'b0}: DispPCXReq = "CASA1";
{5'h3, 1'b1, 1'bX, 1'b0, 1'b0}: DispPCXReq = "CASA2";
{5'h7, 1'b1, 1'bX, 1'b0, 1'b0}: DispPCXReq = "SWAP_LDSTUB";
{5'h4, 1'b1, 1'b0, 1'b0, 1'b0}: DispPCXReq = "STREAM_LD";
{5'h5, 1'b1, 1'b0, 1'b0, 1'bx}: DispPCXReq = "STREAM_ST";
{5'h8, 1'b1, 1'b0, 1'b0, 1'b0}: DispPCXReq = "MMU_LD";
//{5'h9, 1'b0, 1'b0, 1'b0, 1'b0}: DispPCXReq = "INT";
`PR_ERROR("lsu_mon", `ERROR, "<C%0h> <T%0h> <%0h> Can't recognise the PCX pkt type. rq_type = %h, nc_bit = %0b, inv_bit = %0b, pf_bit = %0b, bis_bit = %0b. pcx_pkt[129:0] = %h", core_id, pcx_pkt[`PCX_THR_ID], pcx_pkt[`PCX_ADDR], pcx_pkt[`PCX_RQTYP], pcx_pkt[`PCX_NC], pcx_pkt[`PCX_INV], pcx_pkt[`PCX_PF], pcx_pkt[`PCX_BIS], pcx_pkt);
if (`SPC2.lsu_align_b) DispExc = "Addr_not_aligned";
if (`SPC2.lsu_lddf_align_b) DispExc = "LDDF_Addr_not_aligned";
if (`SPC2.lsu_stdf_align_b) DispExc = "STDF_Addr_not_aligned";
if (`SPC2.lsu_priv_action_b) DispExc = "Priv_actio";
if (`SPC2.lsu_va_watchpoint_b) DispExc = "VA_watchpoint";
if (`SPC2.lsu_pa_watchpoint_b) DispExc = "PA_watchpoint";
//if (`SPC2.lsu_tlb_miss_b_) DispExc = "Tlb_miss";
if (`SPC2.lsu_illegal_inst_b) DispExc = "Illegal_inst";
if (`SPC2.lsu_daccess_prot_b) DispExc = "Data_access_prot_exc";
if (`SPC2.lsu_dae_invalid_asi_b) DispExc = "Dae_Invalid_asi";
if (`SPC2.lsu_dae_nc_page_b) DispExc = "Dae_nc_page";
if (`SPC2.lsu_dae_nfo_page_b) DispExc = "Dae_NFO_page";
if (`SPC2.lsu_dae_priv_viol_b) DispExc = "Dae_Priv_viol";
if (`SPC2.lsu_dae_so_page) DispExc = "Dae_so_page";
//if (`SPC2.lsu_perfmon_trap_b) DispExc = "Perf_mon_trap";
if (`SPC2.lsu_dtmh_err_b) DispExc = "DTLB_data_par_err";
if (`SPC2.lsu_dttp_err_b) DispExc = "DTLB_tag_par_err";
if (`SPC2.lsu_dtdp_err_b) DispExc = "DTLB_data_par_err";
`PR_INFO("lsu_mon", 23, "<C%0h> <T%0h> <%0h> B_stage: %s(VA=%0h) ASI = %0h. %s Exception.",core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b, asi_b, DispExc);
input [1:0] exu_lsu_va_error_b; // VA error requiring a flush
input [1:0] exu_ecc_b; // ECC error requiring a flush
err_b = dec_lsu_tid_b[2] ? (exu_ecc_b[1] | (exu_lsu_va_error_b[1] & ~`SPC2.lsu_tlb_bypass_b)):
(exu_ecc_b[0] | (exu_lsu_va_error_b[0] & ~`SPC2.lsu_tlb_bypass_b));
err_m = (dec_lsu_tid_b[2] ? `SPC2.exu_ecc_m[1] : `SPC2.exu_ecc_m[0]) & `SPC2.lsu.dcc.twocycle_b;
Is_exu_error = err_b | err_m;
task Insert_tlb_miss_info;
if (tlb_valid[dec_lsu_tid_b])
tmp = tlbmiss_pend_array[dec_lsu_tid_b];
Disp_tlbmiss_pend_array_entry(dec_lsu_tid_b);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <%0h> B_stage: %s(VA=%0h>) A new tlb miss request received while there is already a Tlb miss request pending from this thread as shown above.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b);
tlb_valid[dec_lsu_tid_b] <= 1'b1;
tmp[`INST_VA] = inst_pc_b;
tmp[`MEMOP_VA] = vaddr_b;
tlbmiss_pend_array[dec_lsu_tid_b] = tmp;
//problem with the signal.
always @ (negedge `SPC2.l2clk)
if (`SPC2.tlu_trap_pc_0_valid)
thid = {1'b0, `SPC2.tlu_trap_0_tid};
else if (`SPC2.tlu_trap_pc_1_valid)
thid = {1'b0, `SPC2.tlu_trap_1_tid};
`PR_ERROR("lsu_mon", `ERROR, "<C%h> mmu_dtlb_reload asserted but trap_pc_0_valid and trap_pc_1_valid are both 0", core_id);
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> mmu_dtlb_reload asserted while tlb_valid is 0.", core_id, thid);
tmp = tlbmiss_pend_array[dec_lsu_tid_b];
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> %s(VA=%0h> DTLB reloaded for VA = %0h.", core_id, thid, tb_top.intf0.xlate(tmp[`INST]), tmp[`INST_VA], tmp[`MEMOP_VA] );
task Insert_ld_miss_info;
reg [`LD_Pend_Width] tmp;
if (ld_valid[dec_lsu_tid_b])
tmp = ld_pend_array[dec_lsu_tid_b];
DispPendReq(dec_lsu_tid_b);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <%0h> B_stage: %s(VA=%0h>) A new request received while there is already a request pending from this thread as shown above.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b);
//ld_valid[dec_lsu_tid_b] <= 1'b1;
tmp[`INST_VA] = inst_pc_b;
tmp[`MEMOP_VA] = vaddr_b;
tmp[`MEMOP_PA] = {`SPC2.lsu.tlb_pgnum[39:13], vaddr_b[12:0]};
is_blkld[dec_lsu_tid_b] = 1'b1;
is_blkld[dec_lsu_tid_b] = 1'b0;
if (lsu_inst_b[`SWAP] || lsu_inst_b[`LDSTUB] || lsu_inst_b[`CASA])
tmp[`LSU_MON_INST] = lsu_inst_b;
ld_pend_array[dec_lsu_tid_b] = tmp;
task Insert_in_last_inst_array;
tmp[`INST_VA] = inst_pc_b;
tmp[`MEMOP_VA] = vaddr_b;
last_inst_array[dec_lsu_tid_b] = tmp;
reg [`LD_Pend_Width] tmp;
tmp = ld_pend_array[thid];
`PR_ALWAYS("lsu_mon", `ALWAYS, "LD_PEND_ARRAY[%0h] Data.", thid);
`PR_ALWAYS("lsu_mon", `ALWAYS, "<C%h> <T%0h> <%0h> %s(VA=%0h). PA = %0h. L2_ISS = %0h. L2_RESP = %0h, LSU_MON_INST=%h.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA], tmp[`MEMOP_PA], tmp[`L2_ISS], tmp[`L2_RESP], tmp[`LSU_MON_INST]);
`PR_ALWAYS("lsu_mon", `ALWAYS, "<C%h> <T%0h> STB[%0h] data.", core_id, thid, ptr);
`PR_ALWAYS("lsu_mon", `ALWAYS, "<C%h> <T%0h> <%0h> %s(VA=%0h). PA = %0h. L2_ISS = %0h. L2_ACK = %0h, LSU_MON_INST=%h. RMO = %0b", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA], tmp[`MEMOP_PA], tmp[`L2_ST_ISS], tmp[`L2_ACK], tmp[`LSU_MON_INST], tmp[`RMO]);
task Disp_tlbmiss_pend_array_entry;
tmp = tlbmiss_pend_array[thid];
`PR_INFO("lsu_mon", 23, "TLB_MISS_PEND_ARRAY[%0h] Data.", thid);
`PR_INFO("lsu_mon", 23, "<C%h> <T%0h> <%0h> %s(VA=%0h).", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA]);
`PR_ALWAYS("lsu_mon", `ALWAYS, "CPX_PKT data.");
`PR_ALWAYS("lsu_mon", `ALWAYS, "<C%0h> <T%0h> rtn_typ = %0h, err_bits = %0h, nc=%0b, atm = %0b, pf = %0b", core_id, cpx_pkt[`CPX_THR_ID], cpx_pkt[`CPX_RTNTYP], cpx_pkt[`CPX_ERR], cpx_pkt[`CPX_NC], cpx_pkt[`CPX_ATM], cpx_pkt[`CPX_PF]);
tmp[`INST_VA] = inst_pc_b;
tmp[`MEMOP_VA] = vaddr_b;
tmp[`MEMOP_PA] = {`SPC2.lsu.tlb_pgnum[39:13], vaddr_b[12:0]};
tmp[`LSU_MON_INST] = lsu_inst_b;
if (`SPC2.lsu.tlu_lsu_hpstate_hpriv[dec_lsu_tid_b])
else if (`SPC2.lsu.tlu_lsu_pstate_priv[dec_lsu_tid_b])
//bis_asi to io space is not rmo
tmp[`RMO] = lsu_inst_b[`BLKST] | (dec_altspace_b & Is_bis_asi(asi_b) & ~`SPC2.lsu.tlb_pgnum[39]);
input [195:0] store_data;
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> STB full and a new store received for insertion in STB.", core_id, thid);
stb[{thid, wrptr[thid]}] = store_data;
//Disp_STB_entry(thid, wrptr[thid]);
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> <%0h> %s(VA=%0h). STB[%0h] Inserted.", core_id, thid, store_data[`INST_VA], tb_top.intf0.xlate(store_data[`INST]), store_data[`MEMOP_VA], wrptr[thid]);
stb_valid[{thid, wrptr[thid]}] = 1'b1;
wrptr[thid] = wrptr[thid] + 1'b1;
//`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> wrptr = %0d.", core_id, thid, wrptr[thid]);
if ((wrptr[thid] == rdptr[thid]) && stb_valid[{thid, wrptr[thid]}])
//thid = decode_tid(`SPC2.lsu_stb_dealloc);
tmp = stb[{thid, rdptr[thid]}];
lsu_inst = tmp[`LSU_MON_INST];
if (~stb_valid[{thid, rdptr[thid]}])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> lsu_stb_dealloc = %0h asserted while the stb entry is invalid for that thid.", core_id, thid, `SPC2.lsu_stb_dealloc);
Disp_STB_entry(thid, rdptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> lsu_stb_dealloc = %0h asserted when we haven't received the response from the gasket.", core_id, thid, `SPC2.lsu_stb_dealloc);
else if (tmp[`ASI_ST_ISS])
ret_ptr[thid] = ret_ptr[thid] + 1'b1;
//blkst inst. is not issued anywhere, blkst helpers are issued.
//in case of bis stores, lsu issues the dealloc in P3, i.e when the req is issued to PCX.
//IF it is bis to cp sapce and there is an err then the store is issued to PCX with nd set
//However for ue onbis to IO space, dealloc is sent to IFU, issued on PCX with valid bit 0.
//The sbdiou signal is sent in next cycle. We need to take bis io stores in this equation.
else if (tmp[`ST_SQUASH] || lsu_inst[`BLKST] || (tmp[`RMO] & ~lsu_inst[`BLKST] & ~`SPC0.lsu.sbc.kill_store_p4_))
iss_ptr[thid] = iss_ptr[thid] + 1'b1;
ret_ptr[thid] = ret_ptr[thid] + 1'b1;
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> lsu_stb_dealloc = %0h asserted which is not issued to asi ring, or PCX or is not squashed.", core_id, thid, `SPC2.lsu_stb_dealloc);
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> <%0h>: %s(VA=%0h) PA = %0h. STB[%0d] Deallocated.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], tmp[`MEMOP_PA], rdptr[thid]);
stb_valid[{thid, rdptr[thid]}] = 1'b0;
rdptr[thid] = rdptr[thid] + 1'b1;
//`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> rd_ptr = %0d.", core_id, thid, rdptr[thid]);
st_rmo_cnt[thid] = st_rmo_cnt[thid] + 1'b1;
if (ret_ptr[thid] != iss_ptr[thid])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> lsu_block_store_kill asserted while the ret_ptr = %0h != iss_ptr = %0h.", core_id, thid, tmp[`MEMOP_PA], ret_ptr[thid], iss_ptr[thid]);
if (rdptr[thid] != iss_ptr[thid])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> lsu_block_store_kill asserted while the rdptr = %0h != iss_ptr = %0h.", core_id, thid, tmp[`MEMOP_PA], rdptr[thid], iss_ptr[thid]);
if (iss_ptr[thid] == wrptr[thid])
if (stb_valid[{thid, wrptr[thid]}])
/* Lsu can assert both dealloc and block_store_kill for a request.
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Lsu asserted block_store_kill while there are no valid entries in STB to be deallocated.", core_id, thid);
if (iss_ptr[thid] < wrptr[thid])
squash_cnt = wrptr[thid] - iss_ptr[thid];
else if (iss_ptr[thid] > wrptr[thid])
squash_cnt = wrptr[thid] + (8 - iss_ptr[thid]);
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> SQUASH_STB:iss_ptr = %0h, wrptr = %0h, squash_cnt = %0h.", core_id, thid, iss_ptr[thid], wrptr[thid], squash_cnt);
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> Block store kill changed issue_ptr:%0h->%0h. ret_ptr: %0h->%0h. rdptr:%0h->%0h.", core_id, thid, iss_ptr[thid], iss_ptr[thid]+squash_cnt, ret_ptr[thid], ret_ptr[thid]+squash_cnt, rdptr[thid], rdptr[thid]+squash_cnt);
ret_ptr[thid] = ret_ptr[thid] + squash_cnt;
rdptr[thid] = rdptr[thid] + squash_cnt;
iss_ptr[thid] = iss_ptr[thid] + squash_cnt;
if (~stb_valid[{thid, i}])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h><PA = %0h> lsu_block_store_kill asserted while the stb entry %0h is invalid.", core_id, thid, tmp[`MEMOP_PA], i);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h>st_issue bit is set when the block_store_kill is asserted for stb entry %0h.", core_id, thid, tmp[`MEMOP_PA], i);
//commenting out the chk below. Lsu can assert sbdiou and then in the next cycle insert a new entry into
//stb. LSU will squash this new entry and won't issue it to PCX/asi but its squash bit won't be
//set in the chkr which was causin it to fire.
//`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> lsu_block_store_kill asserted while the squash bit is 0 in the STB entry %0h.", core_id, thid, tmp[`MEMOP_PA], i);
stb_valid[{thid, i}] = 1'b0;
squash_cnt = squash_cnt - 1'b1;
if ((bst_cnt > 0) && (`SPC2.lsu_stb_alloc == 8'b0))
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Blk store entries are not allocated back to back in STB.", core_id, bst_active_thid);
//For bst the stb is still written even though we have errors.
//Stb is written in W stage. Howvere for first blk store helper
//the err will be flagged by FGU in b stage. We can miss the
// err signal if we don't sample in B.
//for the last helper err will be signalled in B stage of last helper and at
if (lsu_bst_active[bst_active_thid] & `SPC0.fgu_fst_ecc_error_fx2 & (bst_cnt < 7))
if (`SPC2.lsu_stb_alloc[7:0] != 8'b0)
thid = decode_tid(`SPC2.lsu_stb_alloc[7:0]);
if (thid != dec_lsu_tid_w)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> lsu_stb_alloc = %0h mismatches the thid %0h.", core_id, dec_lsu_tid_w, `SPC2.lsu_stb_alloc[7:0], dec_lsu_tid_w);
Insert_in_STB(stb_alloc_data, dec_lsu_tid_w);
if (lsu_bst_active[thid])
bst_data = bst_inst_data;
if (thid != bst_active_thid)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> lsu_stb_alloc = %0h mismatches the active blkstore thid = %0h.", core_id, bst_active_thid, `SPC2.lsu_stb_alloc[7:0], bst_active_thid);
addr = bst_data[`MEMOP_VA];
bst_data[`MEMOP_VA] = {addr[47:6], bst_cnt[2:0], 3'b0};
addr = bst_data[`MEMOP_PA];
bst_data[`MEMOP_PA] = {addr[39:6], bst_cnt[2:0], 3'b0};
Insert_in_STB(bst_data, bst_active_thid);
lsu_bst_active[thid] = 1'b0;
if (bst_fgu_err) //set the squash bit to 0 for all the stb entries
for (i = 0; i < 8; i=i+1)
tmp = stb[{thid, i[2:0]}];
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> Squash bit already set when trying to set it for a bst fgu errerr.", core_id, thid, tmp[`MEMOP_PA]);
stb[{thid, i[2:0]}] = tmp;
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> <PA = %0h> STB_entry[%0h] squashed due to FGU err.", core_id, thid, tmp[`MEMOP_PA], i);
`PR_ERROR("lsu_mon", `ERROR, "<C%h>: LSU asserted lsu_stb_alloc = %0h while no store pending to be written in STB.", core_id, `SPC2.lsu_stb_alloc[7:0]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <%0h> W_stage: LSU did not assert lsu_stb_alloc for the store.", core_id, dec_lsu_tid_w, inst_pc_w);
reg [47:0] addr, act_addr;
thid =`SPC2.lsu_rngl_cdbus[58:56];
thid =`SPC2.lsu_rngf_cdbus[58:56];
asi =`SPC2.lsu_rngl_cdbus[55:48];
asi =`SPC2.lsu_rngf_cdbus[55:48];
addr =`SPC2.lsu_rngl_cdbus[47:0];
addr =`SPC2.lsu_rngf_cdbus[47:0];
req_type =`SPC2.lsu_rngl_cdbus[61:60];
req_type =`SPC2.lsu_rngf_cdbus[61:60];
tmp = stb[{thid, iss_ptr[thid]}];
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> Store reissued on the ASI interface.", core_id, thid, addr);
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> Store issued on the ASI interface that has been squashed.", core_id, thid, addr);
act_addr = tmp[`MEMOP_PA];
act_addr = {act_addr[39:3], 3'b0};
//47 is D tag rd asi. LSU issues that on the ring but changes
if ((addr == act_addr) || (asi == 8'h47) || (asi == 8'h46))
stb[{thid, iss_ptr[thid]}] = tmp;
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) STB[%0d] Issued on local ring.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], iss_ptr[thid]);
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) STB[%0d] Issued on fast ring.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], iss_ptr[thid]);
iss_ptr[thid] = iss_ptr[thid] + 1'b1;
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <%0h>: %s(VA=%0h) STB[%0d] PA mismatch for asi req on local ring. Expected PA = %0h, actual PA = %0h", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], iss_ptr[thid], tmp[`MEMOP_PA], addr);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <%0h>: %s(VA=%0h) STB[%0d] PA mismatch for asi req on fast ring. Expected PA = %0h, actual PA = %0h", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], iss_ptr[thid], tmp[`MEMOP_PA], addr);
task chk_store_issue_to_pcx;
reg [39:0] pcx_pa, inst_pa;
thid = pcx_pkt[`PCX_THR_ID];
tmp = stb[{thid, iss_ptr[thid]}];
inst = tmp[`LSU_MON_INST];
pcx_pa = pcx_pkt[`PCX_ADDR];
inst_pa = tmp[`MEMOP_PA];
if (pcx_pkt[`PCX_RQTYP] == `PCX_STORE)
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) STB[%0d] Issued to gasket.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], iss_ptr[thid]);
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) STB[%0d] Issued to gasket with ND set.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], iss_ptr[thid]);
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> A store request made to gasket by LSU while the pending req is not store.", core_id, thid, pcx_pkt[`PCX_ADDR]);
if (pcx_pa[39:0] != inst_pa[39:0])
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> A store request made to gasket by LSU while the pending req has PA %0h.", core_id, thid, pcx_pkt[`PCX_ADDR], tmp[`MEMOP_PA]);
if ((tmp[`INST_ASI] == 8'h73) & (pcx_pa[39:0] != {8'h90, core_id, thid, tmp[`INST_ASI], 18'h0}))
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> pcx_pa is not correct for asi write to interrupt vector dispatch register.", core_id, thid, pcx_pkt[`PCX_ADDR]);
if (inst[`BLKST] && ~pcx_pkt[`PCX_BST])
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> Bst bit is not set in the PCX pkt by LSU for a blk st request.", core_id, thid, pcx_pkt[`PCX_ADDR]);
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> Store reissued on the PCX interface.", core_id, thid, pcx_pkt[`PCX_ADDR]);
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> Store issued on the PCX interface that has been squashed.", core_id, thid, pcx_pkt[`PCX_ADDR]);
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> BIS bit is not set in the PCX pkt by LSU for an RMO store.", core_id, thid, pcx_pkt[`PCX_ADDR]);
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> L2ack bit is set when the RMO store is issued to PCX.", core_id, thid, pcx_pkt[`PCX_ADDR]);
ret_ptr[thid] = ret_ptr[thid] + 1; //this will be deallocated before
//response seen from stub
st_rmo_cnt[thid] = st_rmo_cnt[thid] + 1'b1;
stb[{thid, iss_ptr[thid]}] = tmp;
iss_ptr[thid] = iss_ptr[thid] + 1;
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> iss_ptr = %0d. ret_ptr = %0d, st_rmo_cnt = %0d", core_id, thid, iss_ptr[thid], ret_ptr[thid], st_rmo_cnt[thid]);
`ifdef INJ_STB_ERR_IN_CMP
reg [2:0] err_tid, stb_err_tid_d1, stb_err_tid_d2;
reg [2:0] err_index, stb_err_index_d1, stb_err_index_d2;
reg stb_err_inj, stb_err_inj_d1, stb_err_inj_d2;
reg [1:0] err_priv, stb_err_priv_d1, stb_err_priv_d2;
if (("cmp_stb_err_inj_on"))
always @ (negedge (`SPC2.l2clk & enabled & cmp_stb_err_inj))
//valid stb ram rd for issue to pcx
if (`SPC2.lsu.sbc.ram_rptr_vld_2 & `SPC2.lsu.sbc.st_pcx_rq_p3 & `SPC2.lsu.pic.pic_st_sel_p3)
err_tid = decode_tid(`SPC2.lsu.sbc.st_rq_sel_p3[7:0]);
err_index = `SPC2.lsu.sbc.ram_rptr_d1;
err_tmp = stb[{err_tid, err_index}];
err_inst = err_tmp[`LSU_MON_INST];
cam_data = `SPC2.lsu.stb_cam.cam_array.stb_rdata[44:0];
err_priv = err_tmp[`ST_PRIV];
//if (err_inst[`SWAP] || err_inst[`CASA] || err_inst[`LDSTUB])
err_inj_cnt = err_inj_cnt + 1;
11, 12: err_bit = err_bit + 1;
force `SPC0.lsu.stb_cam.cam_array.stb_rdata[44:0] = cam_data ^ (1 << err_bit);
`PR_INFO("stb_err", 22, "<T%0h> <%0h> STB[%0h]: SBAPP forced for CASA. err_bit = %0h", err_tid, {cam_data[44:8], 3'b0}, err_index, err_bit);
release `SPC0.lsu.stb_cam.cam_array.stb_rdata[44:0];
if (~`SPC2.lsu_sbapp_err_g)
`PR_ERROR("lsu_mon", `ERROR, "<T%0h> sbapp err not asserted when err is injected for atomic.", stb_err_tid_d2);
if ((`SPC2.lsu_stberr_tid_g != stb_err_tid_d2) ||
(`SPC2.lsu_stberr_index_g != stb_err_index_d2) ||
(`SPC2.lsu_stberr_priv_g != stb_err_priv_d2))
`PR_ERROR("lsu_mon", `ERROR, "<T%0h> sbapp err parameters mismatch.", stb_err_tid_d2);
if (`SPC2.lsu_sbapp_err_g)
`PR_ERROR("lsu_mon", `ERROR, "<T%0h> sbapp err asserted when none expected.", `SPC2.lsu_stberr_tid_g);
always @ (posedge (`SPC2.l2clk & enabled & cmp_stb_err_inj))
stb_err_inj_d1 <= stb_err_inj;
stb_err_inj_d2 <= stb_err_inj_d1;
stb_err_tid_d1 <= err_tid;
stb_err_tid_d2 <= stb_err_tid_d1;
stb_err_index_d1 <= err_index;
stb_err_index_d2 <= stb_err_index_d1;
stb_err_priv_d1 <= err_priv;
stb_err_priv_d2 <= stb_err_priv_d1;
// If vcs_build_args NO_MONITORS, then module will be empty
reg [7:0] asi_e, imm_asi_e, asi_m, asi_b;
reg dec_altspace_e, dec_altspace_b, dec_altspace_m;
reg [1:0] exu_lsu_va_error_b;
reg [2:0] dec_lsu_tid_e, dec_lsu_tid_m, dec_lsu_tid_b, dec_lsu_tid_w;
reg [47:0] inst_pc_e, inst_pc_m, inst_pc_b, inst_pc_w;
reg [31:0] inst_e, inst_m, inst_b;
reg [47:0] vaddr_m, vaddr_b;
reg [63:0] int_st_data_m, int_st_data_b;
reg [63:0] fp_st_sata_fx2;
reg [20:0] lsu_inst_e, lsu_inst_m, lsu_inst_b;
reg mmu_dtlb_reload_d1, mmu_dtlb_reload_d2;
reg [`LD_Pend_Width] ld_pend_array[7:0];
reg [`LAST_INST_Pend_Width] last_inst_array[7:0];
reg [2:0] wrptr[7:0]; //Pts. to the STB entry into which data will be written next
reg [2:0] rdptr[7:0]; //Tracks the dealloc signal from STB
reg [2:0] iss_ptr[7:0]; //keeps track of when a store is issued from the STB to PCX
reg [2:0] ret_ptr[7:0]; //keeps track of when the response is received from
reg [`STB_Pend_Width] stb[63:0];
//reg [`TLB_MISS_Pend_Width] tlbmiss_pend_array[7:0];
reg [7:0] dcache_inv_cnt[7:0];
reg [7:0] st_rmo_cnt[7:0];
reg [31:0] dec_tg0_inst_d, dec_tg1_inst_d;
reg [7:0] lsu_bst_active;
reg [195:0] stb_alloc_data;
reg [195:0] bst_data, bst_inst_data;
reg [2:0] bst_active_thid;
reg [7:0] is_blkld; //reqd by lsu_ras_chkr to chk errors on blk ld.
reg [1:0] l2_blk_ld_errtype[7:0]; //Gives the type of err the ahd be reported by LSU if
//different types of err occur on blk ld helper returns
reg [1:0] st_priv[7:0]; //Gives the final priv level for an sbdiou/sbapp err that shd be
for (i = 0; i < 8; i = i+1)
l2_blk_ld_errtype[i] = 2'b0;
// avoid time zero ugliness. jp
//@(posedge `SPC0.l2clk);
//@(negedge `SPC0.l2clk);
//if (`PARGS.lsu_mon_on) enabled = 1;
3'h0: finish_mask = `PARGS.finish_mask[7:0];
3'h1: finish_mask = `PARGS.finish_mask[15:8];
3'h2: finish_mask = `PARGS.finish_mask[23:16];
3'h3: finish_mask = `PARGS.finish_mask[31:24];
3'h4: finish_mask = `PARGS.finish_mask[39:32];
3'h5: finish_mask = `PARGS.finish_mask[47:40];
3'h6: finish_mask = `PARGS.finish_mask[55:48];
3'h7: finish_mask = `PARGS.finish_mask[63:56];
if (~`TOP.in_reset & `PARGS.lsu_mon_on & ~reset_in_middle)
`PR_ALWAYS("lsu_mon", `ALWAYS, "Lsu_mon on, in_reset = 0.");
if (`TOP.in_reset & enabled)
`PR_ALWAYS("lsu_mon", `ALWAYS, "Reset asserted in the middle of the diag. Turned off Lsu_mon.");
always @ (posedge (tb_top.sim_status[0] & enabled))
if (|(ld_valid[7:0] & finish_mask[7:0]))
for (i = 0; i < 8; i=i+1)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> Ld requests pending at the end of simulation. ld_valid = %0h", core_id, ld_valid);
for (i = 0; i < 64; i=i+1)
if (stb_valid[i] & finish_mask[i[5:3]])
//chkr resets the stb valid bits when block_store_kill is asserted.
//in couple of failures block_store_kill was sampled asserted two cycles after
//lsu asserted stb_empty. The simulation ended the cycle stb_empty was sampled high
//causing moniotr firings with valid entries in stb at end of simulation. Now
//don't flag an error if squash bit is set and stb_valid is asserted at end
if (~is_squash_bit_set(i[5:0]))
Disp_STB_entry(i[5:3],i[2:0]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> Store requests pending at the end of simulation. stb_valid = %0h", core_id, stb_valid);
for (i = 0; i < 8; i=i+1)
if (finish_mask[i] & (pf_cnt[i] != 0))
`PR_ALWAYS("lsu_mon", `ALWAYS, "<C%h> <T%0h> Prefetches not finished. Pf_cnt = %0d", core_id, i, pf_cnt[i]);
if (finish_mask[i] & (dcache_inv_cnt[i] != 0))
`PR_ALWAYS("lsu_mon", `ALWAYS, "<C%h> <T%0h> D pkt not received for all invalidate reqs. issued by the thread. dcache_inv_cnt = %0d", core_id, i, dcache_inv_cnt[i]);
if (finish_mask[i] & (st_rmo_cnt[i] != 0))
`PR_ALWAYS("lsu_mon", `ALWAYS, "<C%h> <T%0h> rmo_cnt not zero. rmo_cnt = %0d", core_id, i, st_rmo_cnt[i]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> Prefetch/D/RMO_stores requests pending at the end of simulation.", core_id);
function is_squash_bit_set;
is_squash_bit_set = 1'b1;
is_squash_bit_set = 1'b0;
always @ (negedge (`SPC3.l2clk & enabled))
asi_e = `SPC3.lsu.dcc.dcc_asi_e[7:0];
lsu_inst_e[`LD] <= `SPC3.dec_ld_inst_e;
lsu_inst_e[`ST] <= `SPC3.dec_st_inst_e;
lsu_inst_e[`FP] <= `SPC3.dec_fpldst_inst_e;
lsu_inst_e[`PREF] <= `SPC3.dec_pref_inst_e;
lsu_inst_e[`SWAP] <= `SPC3.dec_swap_inst_e;
lsu_inst_e[`CASA] <= `SPC3.dec_casa_inst_e;
lsu_inst_e[`LDSTUB] <= `SPC3.dec_ldstub_inst_e;
lsu_inst_e[`FLUSH] <= `SPC3.dec_flush_inst_e;
lsu_inst_e[`MEMBAR] <= `SPC3.dec_memstbar_inst_e;
lsu_inst_e[`LDD] <= `SPC3.dec_ld_inst_e & `SPC3.dec_ldst_dbl_e & ~`SPC3.dec_fpldst_inst_e;
lsu_inst_e[`STD] <= `SPC3.dec_st_inst_e & `SPC3.dec_ldst_dbl_e & ~`SPC3.lsu.dec_fpldst_inst_e;
lsu_inst_e[`BLKLD] <= `SPC3.dec_ld_inst_e & `SPC3.dec_fpldst_inst_e & dec_altspace_e & Is_blk_asi(asi_e);
lsu_inst_e[`BLKST] <= `SPC3.dec_st_inst_e & `SPC3.dec_fpldst_inst_e & dec_altspace_e & Is_blk_asi(asi_e);
lsu_inst_e[`QLD] <= `SPC3.dec_ld_inst_e & dec_altspace_e & Is_qld_asi(asi_e);
lsu_inst_e[`ASR_RD_WR] <= `SPC3.dec_sr_inst_e & (`SPC3.dec_ld_inst_e | `SPC3.dec_st_inst_e);
lsu_inst_e[`PR_RD_WR] <= `SPC3.dec_pr_inst_e & (`SPC3.dec_ld_inst_e | `SPC3.dec_st_inst_e);
lsu_inst_e[`HPR_RD_WR] <= `SPC3.dec_hpr_inst_e & (`SPC3.dec_ld_inst_e | `SPC3.dec_st_inst_e);
lsu_inst_e[`FSR_RD_WR] <= `SPC3.dec_fsr_ldst_e & (`SPC3.dec_ld_inst_e | `SPC3.dec_st_inst_e);
always @ (posedge (`SPC3.l2clk & enabled))
dec_tg0_inst_d <= `SPC3.dec.ded0.decode_mux[31:0];
dec_tg1_inst_d <= `SPC3.dec.ded1.decode_mux[31:0];
imm_asi_vld_e <= `SPC3.lsu.dec_imm_asi_vld_d;
imm_asi_e <= `SPC3.lsu.dec_imm_asi_d;
dec_altspace_e <= `SPC3.dec_altspace_d;
dec_altspace_m <= dec_altspace_e;
dec_altspace_b <= dec_altspace_m;
exu_ecc_b <= `SPC3.exu_ecc_m;
exu_lsu_va_error_b <= `SPC3.exu_lsu_va_error_m;
dec_lsu_tid_e <= `SPC3.dec_lsu_tg_d ? {1'b1, `SPC3.dec_lsu_tid1_d} : {1'b0, `SPC3.dec_lsu_tid0_d};
dec_lsu_tid_m <= dec_lsu_tid_e;
dec_lsu_tid_b <= dec_lsu_tid_m;
dec_lsu_tid_w <= dec_lsu_tid_b;
inst_pc_e <= `SPC3.dec_lsu_tg_d ? {`SPC3.tlu.tlu_pc_1_d[47:2], 2'b0} : {`SPC3.tlu.tlu_pc_0_d[47:2], 2'b0};
inst_e <= `SPC3.dec_lsu_tg_d ? dec_tg1_inst_d : dec_tg0_inst_d;
vaddr_m <= `SPC3.exu_lsu_address_e;
int_st_data_m <= `SPC3.exu_lsu_store_data_e;
int_st_data_b <= int_st_data_m;
fp_st_sata_fx2 <= `SPC3.fgu_lsu_fst_data_fx1;
mmu_dtlb_reload_d1 <= `SPC3.mmu_dtlb_reload;
mmu_dtlb_reload_d2 <= mmu_dtlb_reload_d1;
//pcx_thid_d1 <= `SPC3.lsu.spc_pcx_data_pa[`PCX_THR_ID];
lsu_inst_m <= lsu_inst_e;
lsu_inst_b <= lsu_inst_m;
Is_blk_asi = (asi == `ASI_BLK_AIUP) | (asi == `ASI_BLK_AIUS) |
(asi == `ASI_BLK_AIUPL) | (asi == `ASI_BLK_AIUSL) |
(asi == `ASI_BLK_P) | (asi == `ASI_BLK_S) |
(asi == `ASI_BLK_PL) | (asi == `ASI_BLK_SL) |
(asi == `ASI_BLK_COMMIT_P) | (asi == `ASI_BLK_COMMIT_S);
Is_qld_asi = (asi == `ASI_AIU_BIS_QUAD_LDD_P) | (asi == `ASI_AIU_BIS_QUAD_LDD_S) |
(asi == `ASI_AIU_BIS_QUAD_LDD_P_LITTLE) | (asi == `ASI_AIU_BIS_QUAD_LDD_S_LITTLE) |
(asi == `ASI_NUCLEUS_BIS_QUAD_LDD) | (asi == `ASI_NUCLEUS_BIS_QUAD_LDD_LITTLE) |
(asi == `ASI_BIS_QUAD_LDD_P) | (asi == `ASI_BIS_QUAD_LDD_S) |
(asi == `ASI_BIS_QUAD_LDD_P_LITTLE) | (asi == `ASI_BIS_QUAD_LDD_S_LITTLE) |
(asi == `ASI_QUAD_LDD) | (asi == `ASI_QUAD_LDD_REAL) |
(asi == `ASI_QUAD_LDD_L) | (asi == `ASI_QUAD_LDD_REAL_L);
Is_bis_asi = (asi == `ASI_AIU_BIS_QUAD_LDD_P) | (asi == `ASI_AIU_BIS_QUAD_LDD_S) |
(asi == `ASI_AIU_BIS_QUAD_LDD_P_LITTLE) | (asi == `ASI_AIU_BIS_QUAD_LDD_S_LITTLE) |
(asi == `ASI_NUCLEUS_BIS_QUAD_LDD) | (asi == `ASI_NUCLEUS_BIS_QUAD_LDD_LITTLE) |
(asi == `ASI_BIS_QUAD_LDD_P) | (asi == `ASI_BIS_QUAD_LDD_S) |
(asi == `ASI_BIS_QUAD_LDD_P_LITTLE) | (asi == `ASI_BIS_QUAD_LDD_S_LITTLE);
always @ (negedge (`SPC3.l2clk & enabled))
`PR_INFO("lsu_mon", 21, "<C%0h> <T%0h> <%0h> M_stage: %s(VA=%0h) Flushed due to IFU Flush.", core_id, dec_lsu_tid_m, inst_pc_m, tb_top.intf0.xlate(inst_m),vaddr_m);
if (lsu_inst_b[`BLKLD]) print_inst = " BLKLD,";
else if (lsu_inst_b[`BLKST]) print_inst = " BLKST,";
else if (lsu_inst_b[`QLD]) print_inst = " QLD,";
`PR_INFO("lsu_mon", 21, "<C%0h> <T%0h> <%0h> B_stage: %s(VA=%0h) Flushed due to IFU Flush.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b);
else if (`SPC3.tlu_flush_lsu_b)
`PR_INFO("lsu_mon", 21, "<C%h> <T%0h> <%0h> B_stage: %s(VA=%0h) Flushed due to TLU Flush.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b);
//casa is a two cycle operation. If there is an err on the 2nd cycle of casa then also
//This function will also chk for errors on 2nd cycle.
else if (Is_exu_error(exu_lsu_va_error_b, exu_ecc_b))
`PR_INFO("lsu_mon", 21, "<C%h> <T%0h <%0h> B_stage: %s(VA=%0h) Flushed due to EXU error.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b);
else if ((`SPC3.fgu_cecc_fx2 || `SPC3.fgu_uecc_fx2) && lsu_inst_b[`ST] && lsu_inst_b[`FP])
`PR_INFO("lsu_mon", 21, "<C%h> <T%0h> <%0h> B_stage: %s(VA=%0h) Flushed due to FGU error.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b);
else if (!`SPC3.lsu_tlb_miss_b_)
`PR_INFO("lsu_mon", 23, "<C%h> <T%0h> <%0h> B_stage: %s(VA=%0h)%s ASI = %0h. DTLB miss.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b, print_inst, asi_b);
//Lsu doesn't assert lsu_sync for an exception or dtlb miss. Since for
//an exception tlu anyway tells the front end to flush itself there is
//no reason for LSU to flush the front end then TLU to flush it again.
//Lsu treats the dtlbmiss as an exception that it flushes the inst and
//handles it when it is reissued by the front end.
if (`SPC3.lsu_tlb_bypass_b)
if (`SPC3.lsu_sync != 8'b0)
`PR_INFO("lsu_mon", 23, "<C%h> <T%0h> <%0h>: %s(VA=%0h)%s PA = %0h, ASI = %0h. LSU_sync. DTLB Bypass.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b, print_inst, {`SPC3.lsu.tlb_pgnum[39:13], vaddr_b[12:0]}, asi_b);
`PR_INFO("lsu_mon", 23, "<C%h> <T%0h> <%0h>: %s(VA=%0h)%s PA = %0h, ASI = %0h. DTLB Bypass.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b, print_inst, {`SPC3.lsu.tlb_pgnum[39:13], vaddr_b[12:0]}, asi_b);
if (`SPC3.lsu_sync != 8'b0)
`PR_INFO("lsu_mon", 23, "<C%h> <T%0h> <%0h>: %s(VA=%0h)%s PA = %0h, ASI = %0h, Store_data = %0h. LSU_sync. DTLB hit.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b, print_inst, {`SPC3.lsu.tlb_pgnum[39:13], vaddr_b[12:0]}, asi_b,int_st_data_b);
`PR_INFO("lsu_mon", 23, "<C%h> <T%0h> <%0h>: %s(VA=%0h)%s PA = %0h, ASI = %0h. LSU_sync. DTLB hit.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b, print_inst, {`SPC3.lsu.tlb_pgnum[39:13], vaddr_b[12:0]}, asi_b);
`PR_INFO("lsu_mon", 23, "<C%h> <T%0h> <%0h>: %s(VA=%0h)%s PA = %0h, ASI = %0h, Store_data = %0h. DTLB hit.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b, print_inst, {`SPC3.lsu.tlb_pgnum[39:13], vaddr_b[12:0]}, asi_b, int_st_data_b);
`PR_INFO("lsu_mon", 23, "<C%h> <T%0h> <%0h>: %s(VA=%0h)%s PA = %0h, ASI = %0h. DTLB hit.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b, print_inst, {`SPC3.lsu.tlb_pgnum[39:13], vaddr_b[12:0]}, asi_b);
if (lsu_inst_b[`LD] || lsu_inst_b[`PREF] || lsu_inst_b[`SWAP] || lsu_inst_b[`CASA] || lsu_inst_b[`LDSTUB])
if (((lsu_inst_b == 16'h1) || (lsu_inst_b == 16'h5)) & `SPC3.lsu.stb_cam_hit)
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> <%0h>: LSU_sync asserted due to STB RAW.", core_id, dec_lsu_tid_b, inst_pc_b);
if (lsu_inst_b[`ST]) //for atomics both ld and store signals are asserted
Insert_in_last_inst_array;
if (`SPC3.lsu_trap_flush[7:0])
`PR_INFO("lsu_mon", 21, "<C%h> <T%0h> Trap Flush asserted.", core_id, decode_tid(`SPC3.lsu_trap_flush[7:0]));
//This is how we test squashing of stores by LSU_mon:
//Whenever lsu asserts err_sbdiou signal, the monitor sets the squash
//bit in the STB for the rest of the stores. If any of these squashed stores
//is issued on the asi ring or to the PCX interface the monitor complains.
//The squashed stores are deallocated when either a block_store_kill is
//asserted or dealloc signals are asserted by the LSU.
//When the block_store_kill is asserted, it tells the IFU to dealloc
//all the pending stores in the IFU. It means the when block_store_kill
//is asserted we have deallocated all the non-squashed requests from STB.
//The 0in_chkr ensures that LSU flags the correct index and priv with the
//the sbdiou signal to TLU.
always @ (negedge (`SPC3.l2clk & enabled))
if (`SPC3.lsu_l15_valid & `SPC3.lsu.spc_pcx_data_pa[129])
Chk_pcx_req_pkt(`SPC3.lsu.spc_pcx_data_pa[129:0]); //chk if we need .lsu here
if ((`SPC3.lsu_rngl_cdbus[64:63] == 2'b11) & ~`SPC3.lsu_rngl_cdbus[59])
Chk_st_on_ASI_ring(`LOCAL);
if ((`SPC3.lsu_rngf_cdbus[64:63] == 2'b11) & ~`SPC3.lsu_rngf_cdbus[59])
Chk_st_on_ASI_ring(`FAST);
//if (`SPC3.l15_lsu_valid)
//Chk_cpx_response_pkt({`SPC3.l15_lsu_valid, `SPC3.l15_lsu_cpkt[17:13],`SPC3.l15_lsu_cpkt[11:0],`SPC3.l15_spc_data1[127:0]});
if (`SPC3.cpx_spc_data_cx[145])
Chk_cpx_response_pkt(`SPC3.cpx_spc_data_cx);
if (`SPC3.lsu_complete[7:0] != 8'b0)
if (`SPC3.lsu_complete[0]) Chk_ld_complete(0);
if (`SPC3.lsu_complete[1]) Chk_ld_complete(1);
if (`SPC3.lsu_complete[2]) Chk_ld_complete(2);
if (`SPC3.lsu_complete[3]) Chk_ld_complete(3);
if (`SPC3.lsu_complete[4]) Chk_ld_complete(4);
if (`SPC3.lsu_complete[5]) Chk_ld_complete(5);
if (`SPC3.lsu_complete[6]) Chk_ld_complete(6);
if (`SPC3.lsu_complete[7]) Chk_ld_complete(7);
if (`SPC3.lsu_block_store_kill[7:0] != 8'b0)
if (`SPC3.lsu_block_store_kill[0]) Squash_STB(0);
if (`SPC3.lsu_block_store_kill[1]) Squash_STB(1);
if (`SPC3.lsu_block_store_kill[2]) Squash_STB(2);
if (`SPC3.lsu_block_store_kill[3]) Squash_STB(3);
if (`SPC3.lsu_block_store_kill[4]) Squash_STB(4);
if (`SPC3.lsu_block_store_kill[5]) Squash_STB(5);
if (`SPC3.lsu_block_store_kill[6]) Squash_STB(6);
if (`SPC3.lsu_block_store_kill[7]) Squash_STB(7);
if (`SPC3.lsu_stb_dealloc[7:0] != 8'b0)
if (`SPC3.lsu_stb_dealloc[0]) Dealloc_STB(0);
if (`SPC3.lsu_stb_dealloc[1]) Dealloc_STB(1);
if (`SPC3.lsu_stb_dealloc[2]) Dealloc_STB(2);
if (`SPC3.lsu_stb_dealloc[3]) Dealloc_STB(3);
if (`SPC3.lsu_stb_dealloc[4]) Dealloc_STB(4);
if (`SPC3.lsu_stb_dealloc[5]) Dealloc_STB(5);
if (`SPC3.lsu_stb_dealloc[6]) Dealloc_STB(6);
if (`SPC3.lsu_stb_dealloc[7]) Dealloc_STB(7);
if (`SPC3.lsu_block_store_stall)
if (`SPC3.lsu.lsu_block_store_alloc[7:0] != 8'b0)
Set_block_store_parameters;
if (`SPC3.lsu_sbdiou_err_g || `SPC3.lsu_sbapp_err_g)
if (`SPC3.lsu_stb_flush_g)
st_priv[`SPC3.lsu_stberr_tid_g] = get_priv_on_flush(`SPC3.lsu_stberr_tid_g);
function [1:0] get_priv_on_flush;
sq_index = `SPC3.lsu_stberr_index_g;
tmp = stb[{tid, sq_index}];
get_priv_on_flush = tmp[`ST_PRIV];
thid = `SPC3.lsu_block_store_tid;
bst_inst_data = stb[{thid, rdptr[thid]}];
inst = bst_inst_data[`LSU_MON_INST];
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> LSU asserted blk_store_stall while the req at the top of STB is not blkst as shown above", core_id, thid);
//lsu can assert block_store_stall for a new block store while it has not yet written
//the 8 stb entries from the previous blk store.
task Set_block_store_parameters;
thid = decode_tid(`SPC3.lsu.lsu_block_store_alloc[7:0]);
if (lsu_bst_active[thid])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> LSU asserted blk_store_alloc while the bst_active is already set for this thread.", core_id, thid);
lsu_bst_active[thid] = 1'b1;
if (`SPC3.lsu.fgu_fst_ecc_error_fx2)
thid = `SPC3.lsu_stberr_tid_g;
sq_index = `SPC3.lsu_stberr_index_g;
priv = `SPC3.lsu_stberr_priv_g;
tmp = stb[{thid, sq_index}];
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> Sbdiou/sbapp seen for index = %h and priv = %h.", core_id, thid, sq_index, priv);
st_priv[thid] = tmp[`ST_PRIV];
//lsu can assert deallocate before it asserts the sbdiou signal.
//In that case iss_ptr won't be equal to sbdiou index.
//if (sq_index != iss_ptr[thid])
// Disp_STB_entry(thid, iss_ptr[thid]);
// `PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> LSU asserted sbdiou/sbapp with index %0h while the next req to be issued is at index %0h.", core_id, thid, sq_index, iss_ptr[thid]);
//If there is only one store in the store buffer which gets an sbdiou error, then LSU can deallocate
//the store and then assert sbdiou. The deallocation will cause the stb issue_ptr to move
//forward to an inst. that has already been issued and completed and this chk can fire. So
// Disp_STB_entry(thid, iss_ptr[thid]);
// `PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> Store reissued on the PCX interface.", core_id, thid, tmp[`MEMOP_PA]);
if (iss_ptr[thid] == wrptr[thid])
if (stb_valid[{thid, wrptr[thid]}])
//changing it to an info message because if there is only one valid entry in store buffer that
//gets an sbdiou then LSU can deallocate the entry and then issue sbdiou.
//`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Lsu asserted sbdiou/sbapp while there are no valid entries in STB to be issued.", core_id, thid);
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> sbdiou/sbapp squashed only one entry in STB.", core_id, thid);
if (iss_ptr[thid] < wrptr[thid])
squash_cnt = wrptr[thid] - iss_ptr[thid];
else if (iss_ptr[thid] > wrptr[thid])
squash_cnt = wrptr[thid] + (8 - iss_ptr[thid]);
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> SQUASH_STORE:iss_ptr = %0h, wrptr = %0h, squash_cnt = %0h.", core_id, thid, iss_ptr[thid], wrptr[thid], squash_cnt);
if (priv < tmp[`ST_PRIV])
`PR_INFO("lsu_mon", `INFO, "<C%h> <T%0h> <PA = %0h> Sbdiou/sbapp signalled. Err in user/priv level store is squashing a higher priv level store.", core_id, thid, tmp[`MEMOP_PA]);
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> <PA = %0h> STB_entry[%0h] squashed.", core_id, thid, tmp[`MEMOP_PA], i);
squash_cnt = squash_cnt - 1'b1;
function [2:0] decode_tid;
8'h10: decode_tid = 3'h4;
8'h20: decode_tid = 3'h5;
8'h40: decode_tid = 3'h6;
8'h80: decode_tid = 3'h7;
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> decode_tid. Incorrect value of thid input = %0h.", core_id, thid_encode, thid_encode);
reg [`LD_Pend_Width] tmp;
tmp = ld_pend_array[thid];
if ((tmp[`L2_ISS] != 4'hf) || (tmp[`L2_RESP] != 4'hf))
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> LSU asserted lsu_complete while the l2_iss and l2_resp bits are not F.", core_id, thid);
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> <%0h> %s(VA=%0h) Complete. Setting ld_valid to 0.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA]);
tmp = last_inst_array[thid];
`PR_INFO("lsu_mon", 24, "<C%h> <T%0h> <%0h> %s(VA=%0h) Complete.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA]);
reg [`LD_Pend_Width] tmp, tmp1;
thid = pcx_pkt[`PCX_THR_ID];
tmp = ld_pend_array[thid];
inst = tmp[`LSU_MON_INST];
req = DispPCXReq(pcx_pkt);
addr = pcx_pkt[`PCX_ADDR];
if (pcx_pkt[`PCX_CPU_ID] != core_id)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> cpu_id (spc_pcx_data_pa[122:120]) = %h is not = %0h when the lsu made a %s req to gasket.", core_id, pcx_pkt[`PCX_THR_ID], addr, pcx_pkt[122:120], core_id, req);
if ((pcx_pkt[`PCX_RQTYP] == `PCX_LOAD) || (pcx_pkt[`PCX_RQTYP] == `PCX_CAS1) || (pcx_pkt[`PCX_RQTYP] == `PCX_CAS2) || (pcx_pkt[`PCX_RQTYP] == `PCX_SWAP_LDSTUB))
ld_valid[thid] = 1'b1; //we have sent a req to gasket and are waiting for response
`PR_INFO("lsu_mon", 22, "<C%0h> <T%0h> Setting ld_valid[%0h].", core_id, thid, thid);
if (tmp[`MEMOP_PA] != addr)
if ((tmp[`INST_ASI] == 8'h41) || (tmp[`INST_ASI] == 8'h73) || ((tmp[`INST_ASI] == 8'h45) && ((tmp[`MEMOP_PA] == 8'h10) || (tmp[`MEMOP_PA] == 8'h18))))
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <PA = %0h> PA mismatch on gasket for %s request. Ignoring the mismatch as inst. is issued with asi 41, 73 or 45 (with VA 0x10 or 18).", core_id, thid, addr, req);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> A %s request made to gasket by LSU while the pending req is with PA %0h.", core_id, thid, addr, req, tmp[`MEMOP_PA]);
case (pcx_pkt[`PCX_RQTYP])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> A prefetch request made to gasket by LSU which mismatches the pending request from the thread.", core_id, thid, addr);
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: PREF_ICE(VA=%0h) Issued. pf_cnt not updated.", core_id, thid, tmp[`INST_VA], tmp[`MEMOP_VA]);
pf_cnt[thid] = pf_cnt[thid] + 1'b1;
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) Issued. pf_cnt = %0d.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], pf_cnt[thid]);
tmp[`L2_RESP] = 4'hF; //we don't wait for a prefetch response from gasket
ld_pend_array[thid] = tmp;
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) Dcache invalidate pkt issued to CCX.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA]);
dcache_inv_cnt[thid] = dcache_inv_cnt[thid] + 1'b1;
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> CASA request made to gasket by LSU while no such request request is pending from this thread.", core_id, thid, addr);
if (pcx_pkt[`PCX_RQTYP] == `PCX_CAS1)
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) (CAS1) Issued to gasket.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA]);
ld_pend_array[thid] = tmp;
if (pcx_pkt[`PCX_RQTYP] == `PCX_CAS2)
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) (CAS2) Issued to gasket.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA]);
ld_pend_array[thid] = tmp;
chk_store_issue_to_pcx(pcx_pkt);
if (~inst[`SWAP] && ~inst[`LDSTUB])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> %s request made to gasket by LSU while no such request request is pending from this thread.", core_id, thid, addr, req);
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) Issued to gasket. store_data = %0h", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], pcx_pkt[`PCX_DATA]);
ld_pend_array[thid] = tmp;
chk_store_issue_to_pcx(pcx_pkt);
chk_store_issue_to_pcx(pcx_pkt);
default: `PR_INFO("lsu_mon", 21, "<C%h> <T%0h> <%0h>: %s Issued to gasket.", core_id, thid, addr, req);
task Chk_cpx_response_pkt;
thid = cpx_pkt[`CPX_THR_ID];
casex ({cpx_pkt[`CPX_RTNTYP], cpx_pkt[`CPX_ERR], cpx_pkt[`CPX_NC], cpx_pkt[`CPX_ATM], cpx_pkt[`CPX_PF]})
{4'b0, 2'bxx, 1'bx, 1'b0, 1'b0}:
chk_ccx_ld_response(cpx_pkt);
{4'b0, 2'bxx, 1'b1, 1'b0, 1'b1}:
if (pf_cnt[thid] == 8'b0)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Prefetch response received from gasket while the pf_cnt is 0 for this thread.", core_id, thid);
pf_cnt[thid] = pf_cnt[thid] - 1'b1;
`PR_INFO("lsu_mon", 26, "<C%h> <T%0h> Prefetch response received. pfcnt = %0d.", core_id, thid, pf_cnt[thid]);
{4'h8, 2'bxx, 1'b1, 1'b0, 1'b0}:
chk_ccx_ld_response(cpx_pkt);
{4'h4, 2'bxx, 1'bx, 1'b0, 1'b0}:
if (cpx_pkt[123]) //D pkt
if (cpx_pkt[120:118] != core_id)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> D response received from gasket with core_id =%h.", core_id, thid, cpx_pkt[120:118]);
if (dcache_inv_cnt[thid] == 8'b0)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> D response received from gasket while the Dcache_inv_cnt is 0 for this thread.", core_id, thid);
dcache_inv_cnt[thid] = dcache_inv_cnt[thid] - 1'b1;
`PR_INFO("lsu_mon", 26, "<C%h> <T%0h> D response received. Dcache_inv_cnt = %0d.", core_id, thid, dcache_inv_cnt[thid]);
else if (cpx_pkt[124]) //I pkt
if (cpx_pkt[120:118] != core_id)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> I response received from gasket with core_id =%h.", core_id, thid, cpx_pkt[120:118]);
//`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> I pkt.", core_id, thid);
else if (cpx_pkt[124:123] == 2'b0)
if (cpx_pkt[120:118] == core_id)
chk_ccx_st_response(cpx_pkt);
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> Store Ack pkt received from core %0h.", core_id, thid, cpx_pkt[120:118]);
{4'h1, 2'bxx, 1'bx, 1'b0, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> IFILL1 return.", core_id, thid);
{4'h1, 2'bxx, 1'bx, 1'b1, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> IFILL2 return.", core_id, thid);
{4'h9, 2'bxx, 1'b1, 1'b0, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> NCU IFILL return.", core_id, thid);
{4'b0, 2'bxx, 1'b1, 1'b1, 1'b0}:
chk_ccx_atm_response(cpx_pkt);
{4'h4, 2'bxx, 1'b1, 1'b1, 1'b0}:
if ((cpx_pkt[`CPX_RTNTYP] == 4'h4) & (cpx_pkt[120:118] == core_id))
chk_ccx_atm_response(cpx_pkt);
chk_ccx_st_response(cpx_pkt);
{4'h2, 2'bxx, 1'b1, 1'b0, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> Stream Ld return.", core_id, thid);
{4'h6, 2'bxx, 1'bx, 1'bx, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> Stream store Ack.", core_id, thid);
{4'h5, 2'bxx, 1'b1, 1'b0, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> MMU ld return.", core_id, thid);
{4'h7, 2'b00, 1'b0, 1'bx, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> Interrupt return.", core_id, thid);
{4'h3, 2'b00, 1'bx, 1'bx, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> Eviction Invalidation.", core_id, thid);
{4'hc, 2'bxx, 1'bx, 1'bx, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> L2 Indication.", core_id, thid);
{4'hd, 2'bxx, 1'bx, 1'bx, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> Soc Error Indication.", core_id, thid);
`PR_ALWAYS("lsu_mon", `ALWAYS, "CPX_PKT data.");
`PR_ALWAYS("lsu_mon", `ALWAYS, "<C%0h> <T%0h> rtn_typ = %0h, err_bits = %0h, nc=%0b, atm = %0b, pf = %0b", core_id, cpx_pkt[`CPX_THR_ID], cpx_pkt[`CPX_RTNTYP], cpx_pkt[`CPX_ERR], cpx_pkt[`CPX_NC], cpx_pkt[`CPX_ATM], cpx_pkt[`CPX_PF]);
`PR_ERROR("lsu_mon", `ERROR, "<C%0h> <T%0h> Can't recognise the CPX pkt.", core_id, thid);
task chk_ccx_ld_response;
reg [39:0] cpx_pa, inst_pa;
reg [`LD_Pend_Width] tmp;
thid = cpx_pkt[`CPX_THR_ID];
tmp = ld_pend_array[thid];
inst = tmp[`LSU_MON_INST];
inst_pa = tmp[`MEMOP_PA];
pkt_type = cpx_pkt[`CPX_RTNTYP];
`PR_INFO("lsu_mon", 26, "<C%0h> <T%0h> <%0h> %s(VA=%0h) L2 response.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA]);
if (inst_pa[39] != pkt_type[3])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> ccx pkt_type = %h mismatches the ld_pa bit 39. ld_pa = %0h.", core_id, thid, pkt_type, inst_pa);
if (tmp[`L2_RESP] == 4'h0)
tmp[`L2_ERR0] = cpx_pkt[`CPX_ERR];
if ((cpx_pkt[`CPX_ERR] == `ND) || (cpx_pkt[`CPX_ERR] == `UE))
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> UE/ND err on blk ld helper 1.", core_id, thid);
else if (tmp[`L2_RESP] == 4'h1)
tmp[`L2_ERR1] = cpx_pkt[`CPX_ERR];
if ((cpx_pkt[`CPX_ERR] == `ND) || (cpx_pkt[`CPX_ERR] == `UE))
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> UE/ND err on blk ld helper 2.", core_id, thid);
else if (tmp[`L2_RESP] == 4'h3)
tmp[`L2_ERR2] = cpx_pkt[`CPX_ERR];
if ((cpx_pkt[`CPX_ERR] == `ND) || (cpx_pkt[`CPX_ERR] == `UE))
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> UE/ND err on blk ld helper 3.", core_id, thid);
else if (tmp[`L2_RESP] == 4'h7)
tmp[`L2_ERR3] = cpx_pkt[`CPX_ERR];
if ((cpx_pkt[`CPX_ERR] == `ND) || (cpx_pkt[`CPX_ERR] == `UE))
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> UE/ND err on blk ld helper 4.", core_id, thid);
if ((tmp[`L2_ERR0] == `ND) || (tmp[`L2_ERR1] == `ND) || (tmp[`L2_ERR2] == `ND) || (tmp[`L2_ERR3] == `ND))
l2_blk_ld_errtype[thid] = `ND;
else if ((tmp[`L2_ERR0] == `UE) || (tmp[`L2_ERR1] == `UE) || (tmp[`L2_ERR2] == `UE) || (tmp[`L2_ERR3] == `UE))
l2_blk_ld_errtype[thid] = `UE;
else if ((tmp[`L2_ERR0] == `CE) || (tmp[`L2_ERR1] == `CE) || (tmp[`L2_ERR2] == `CE) || (tmp[`L2_ERR3] == `CE))
l2_blk_ld_errtype[thid] = `CE;
l2_blk_ld_errtype[thid] = `NE;
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Illegal value of l2_resp cnt when response pkt received from ccx.", core_id, thid);
else if (Is_single_pcx_req_ld(inst))
if (tmp[`L2_RESP] != 4'hE)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Illegal value of l2_resp cnt when response pkt received from ccx.", core_id, thid);
//`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> Setting L2_resp bits to F.", core_id, thid);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Load response received from gasket for thid %h while no load request pending from core for this thread.", core_id, thid, thid);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Load response received from gasket while no load request pending from core for this thread.", core_id, thid);
ld_pend_array[thid] = tmp;
task chk_ccx_atm_response;
reg [`LD_Pend_Width] tmp;
thid = cpx_pkt[`CPX_THR_ID];
tmp = ld_pend_array[thid];
inst = tmp[`LSU_MON_INST];
inst_pa = tmp[`MEMOP_PA];
if (cpx_pkt[`CPX_RTNTYP] == 4'b0)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Atomic ld response received from gasket while no request pending from core for this thread.", core_id, thid);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Atomic ack response received from gasket while no request pending from core for this thread.", core_id, thid);
if (~inst[`SWAP] && ~inst[`CASA] && ~inst[`LDSTUB])
if (cpx_pkt[`CPX_RTNTYP] == 4'b0)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Atomic ld response received from gasket which mismatches the request pending from this thread.", core_id, thid);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Atomic ack response received from gasket which mismatches the request pending from this thread.", core_id, thid);
if (cpx_pkt[`CPX_RTNTYP] == 4'b0)
`PR_INFO("lsu_mon", 26, "<C%0h> <T%0h> <%0h> %s(VA=%0h) Atomic ld response.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA]);
`PR_INFO("lsu_mon", 26, "<C%0h> <T%0h> <%0h> %s(VA=%0h) Atomic ack.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA]);
if (cpx_pkt[`CPX_RTNTYP] == 4'b0)
if (tmp[`L2_RESP] == 4'hC) tmp[`L2_RESP] = 4'hD;
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Illegal value of l2_resp cnt when atomic ld return pkt received from ccx.", core_id, thid);
if (tmp[`L2_RESP] == 4'hD) tmp[`L2_RESP] = 4'hF;
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Illegal value of l2_resp cnt when atomic ack pkt received from ccx.", core_id, thid);
ld_pend_array[thid] = tmp;
task chk_ccx_st_response;
reg [39:0] cpx_pa, inst_pa;
thid = cpx_pkt[`CPX_THR_ID];
tmp = stb[{thid, ret_ptr[thid]}];
inst = tmp[`LSU_MON_INST];
inst_pa = tmp[`MEMOP_PA];
pkt_type = cpx_pkt[`CPX_RTNTYP];
//is received. There could be some other store sitting in the STB at that time.
//Chk for squash bit only for non-bis responses.
if (cpx_pkt[`CPX_BIS]) //response to rmo store
if (st_rmo_cnt[thid] == 0)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> L2 response received for an rmo store while the st_rmo_cnt for this thread is 0.", core_id, thid);
st_rmo_cnt[thid] = st_rmo_cnt[thid] - 1'b1;
`PR_INFO("lsu_mon", 25, "<C%0h> <T%0h> Store ack received for RMO store. rmo_cnt = %0d", core_id, thid, st_rmo_cnt[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> L2 response received while the SQUASH bit is set in the STB entry %0h.", core_id, thid, ret_ptr[thid]);
if (~stb_valid[{thid, ret_ptr[thid]}])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Store ack received while that entry is invalid in STB.", core_id, thid);
if (~cpx_pkt[`CPX_ATM]) //don't print this message for atomic return
`PR_INFO("lsu_mon", 26, "<C%0h> <T%0h> <%0h> %s(VA=%0h) STB[%0d] Store ack.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA], ret_ptr[thid]);
stb[{thid, ret_ptr[thid]}] = tmp;
ret_ptr[thid] = ret_ptr[thid] + 1'b1;
//`PR_INFO("lsu_mon", 22, "<C%0h> <T%0h> ret_ptr = %0d.", core_id, thid, ret_ptr[thid]);
reg [`LD_Pend_Width] tmp;
reg [39:0] pcx_pa, inst_pa;
thid = pcx_pkt[`PCX_THR_ID];
tmp = ld_pend_array[thid];
inst = tmp[`LSU_MON_INST];
pcx_pa = pcx_pkt[`PCX_ADDR];
inst_pa = tmp[`MEMOP_PA];
req = DispPCXReq(pcx_pkt);
if (pcx_pa[39:6] != inst_pa[39:6])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> A load request made to gasket by LSU while the pending req has PA %0h.", core_id, thid, pcx_pa, tmp[`MEMOP_PA]);
if (tmp[`L2_ISS] != 4'h0 )
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> 1st load request (pa[5:0] = 6'b0) made to gasket by LSU for blkld while this request has already been issued to gasket.", core_id, thid, pcx_pa);
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) 1st blkld helper Issued to gasket.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA]);
if (pcx_pa[5:0] == 6'h10)
if (tmp[`L2_ISS] != 4'h1)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> 2nd load request (pa[5:0] = 6'h10) made to gasket by LSU for blkld while this request has already been issued to gasket.", core_id, thid, pcx_pa);
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) 2nd blkld helper Issued to gasket.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA]);
if (pcx_pa[5:0] == 6'h20)
if (tmp[`L2_ISS] != 4'h3)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> 3rd load request (pa[5:0] = 6'h20) made to gasket by LSU for blkld while this request has already been issued to gasket.", core_id, thid, pcx_pa);
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) 3rd blkld helper Issued to gasket.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA]);
if (pcx_pa[5:0] == 6'h30)
if (tmp[`L2_ISS] != 4'h7)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> 4th load request (pa[5:0] = 6'h30) made to gasket by LSU for blkld while this request has already been issued to gasket.", core_id, thid, pcx_pa);
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) 4th blkld helper Issued to gasket.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA]);
ld_pend_array[thid] = tmp;
else if (Is_single_pcx_req_ld(inst))
if (tmp[`L2_ISS] == 4'hF)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> Load request made to gasket by LSU while this request has already been issued to gasket.", core_id, thid, pcx_pa);
ld_pend_array[thid] = tmp;
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) Issued to gasket.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> A load request made to gasket by LSU while there is no such ld request pending from this thread.", core_id, thid, pcx_pa);
function Is_single_pcx_req_ld;
if (inst[`LDD] || inst[`QLD] || inst[`FSR_RD_WR] || (inst == 21'h1) || (inst == 21'h5))
Is_single_pcx_req_ld = 1'b1;
Is_single_pcx_req_ld = 1'b0;
//`PR_INFO("lsu_mon", 22, "<C%0h> Is_single_pcx_req_ld = %b. ", core_id, Is_single_pcx_req_ld);
case (`SPC3.lsu_trap_flush[7:0])
8'h01: if (tid == 3'h0) Is_trap = 1'b1;
8'h02: if (tid == 3'h1) Is_trap = 1'b1;
8'h04: if (tid == 3'h2) Is_trap = 1'b1;
8'h08: if (tid == 3'h3) Is_trap = 1'b1;
8'h10: if (tid == 3'h4) Is_trap = 1'b1;
8'h20: if (tid == 3'h5) Is_trap = 1'b1;
8'h40: if (tid == 3'h6) Is_trap = 1'b1;
8'h80: if (tid == 3'h7) Is_trap = 1'b1;
function [8*11:0] DispPCXReq;
casex ({pcx_pkt[`PCX_RQTYP], pcx_pkt[`PCX_NC], pcx_pkt[`PCX_INV], pcx_pkt[`PCX_PF], pcx_pkt[`PCX_BIS]})
{5'h0, 1'b1, 1'b0, 1'b1, 1'b0}: DispPCXReq = "PREF";
{5'h0, 1'b1, 1'b1, 1'b1, 1'b0}: DispPCXReq = "PREF_ICE";
{5'h0, 1'bx, 1'b0, 1'b0, 1'b0}: DispPCXReq = "LD";
{5'h0, 1'bx, 1'b1, 1'b0, 1'b0}: DispPCXReq = "D";
{5'h10, 1'bx, 1'b0, 1'b0, 1'b0}: DispPCXReq = "I";
{5'h10, 1'b0, 1'b1, 1'b0, 1'b0}: DispPCXReq = "I";
{5'h1, 1'bX, 1'bX, 1'b0, 1'b0}: DispPCXReq = "ST";
{5'h1, 1'bX, 1'bX, 1'b1, 1'b1}: DispPCXReq = "BLKST";
{5'h1, 1'bX, 1'bX, 1'b0, 1'b1}: DispPCXReq = "BIS";
{5'h2, 1'b1, 1'bX, 1'b0, 1'b0}: DispPCXReq = "CASA1";
{5'h3, 1'b1, 1'bX, 1'b0, 1'b0}: DispPCXReq = "CASA2";
{5'h7, 1'b1, 1'bX, 1'b0, 1'b0}: DispPCXReq = "SWAP_LDSTUB";
{5'h4, 1'b1, 1'b0, 1'b0, 1'b0}: DispPCXReq = "STREAM_LD";
{5'h5, 1'b1, 1'b0, 1'b0, 1'bx}: DispPCXReq = "STREAM_ST";
{5'h8, 1'b1, 1'b0, 1'b0, 1'b0}: DispPCXReq = "MMU_LD";
//{5'h9, 1'b0, 1'b0, 1'b0, 1'b0}: DispPCXReq = "INT";
`PR_ERROR("lsu_mon", `ERROR, "<C%0h> <T%0h> <%0h> Can't recognise the PCX pkt type. rq_type = %h, nc_bit = %0b, inv_bit = %0b, pf_bit = %0b, bis_bit = %0b. pcx_pkt[129:0] = %h", core_id, pcx_pkt[`PCX_THR_ID], pcx_pkt[`PCX_ADDR], pcx_pkt[`PCX_RQTYP], pcx_pkt[`PCX_NC], pcx_pkt[`PCX_INV], pcx_pkt[`PCX_PF], pcx_pkt[`PCX_BIS], pcx_pkt);
if (`SPC3.lsu_align_b) DispExc = "Addr_not_aligned";
if (`SPC3.lsu_lddf_align_b) DispExc = "LDDF_Addr_not_aligned";
if (`SPC3.lsu_stdf_align_b) DispExc = "STDF_Addr_not_aligned";
if (`SPC3.lsu_priv_action_b) DispExc = "Priv_actio";
if (`SPC3.lsu_va_watchpoint_b) DispExc = "VA_watchpoint";
if (`SPC3.lsu_pa_watchpoint_b) DispExc = "PA_watchpoint";
//if (`SPC3.lsu_tlb_miss_b_) DispExc = "Tlb_miss";
if (`SPC3.lsu_illegal_inst_b) DispExc = "Illegal_inst";
if (`SPC3.lsu_daccess_prot_b) DispExc = "Data_access_prot_exc";
if (`SPC3.lsu_dae_invalid_asi_b) DispExc = "Dae_Invalid_asi";
if (`SPC3.lsu_dae_nc_page_b) DispExc = "Dae_nc_page";
if (`SPC3.lsu_dae_nfo_page_b) DispExc = "Dae_NFO_page";
if (`SPC3.lsu_dae_priv_viol_b) DispExc = "Dae_Priv_viol";
if (`SPC3.lsu_dae_so_page) DispExc = "Dae_so_page";
//if (`SPC3.lsu_perfmon_trap_b) DispExc = "Perf_mon_trap";
if (`SPC3.lsu_dtmh_err_b) DispExc = "DTLB_data_par_err";
if (`SPC3.lsu_dttp_err_b) DispExc = "DTLB_tag_par_err";
if (`SPC3.lsu_dtdp_err_b) DispExc = "DTLB_data_par_err";
`PR_INFO("lsu_mon", 23, "<C%0h> <T%0h> <%0h> B_stage: %s(VA=%0h) ASI = %0h. %s Exception.",core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b, asi_b, DispExc);
input [1:0] exu_lsu_va_error_b; // VA error requiring a flush
input [1:0] exu_ecc_b; // ECC error requiring a flush
err_b = dec_lsu_tid_b[2] ? (exu_ecc_b[1] | (exu_lsu_va_error_b[1] & ~`SPC3.lsu_tlb_bypass_b)):
(exu_ecc_b[0] | (exu_lsu_va_error_b[0] & ~`SPC3.lsu_tlb_bypass_b));
err_m = (dec_lsu_tid_b[2] ? `SPC3.exu_ecc_m[1] : `SPC3.exu_ecc_m[0]) & `SPC3.lsu.dcc.twocycle_b;
Is_exu_error = err_b | err_m;
task Insert_tlb_miss_info;
if (tlb_valid[dec_lsu_tid_b])
tmp = tlbmiss_pend_array[dec_lsu_tid_b];
Disp_tlbmiss_pend_array_entry(dec_lsu_tid_b);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <%0h> B_stage: %s(VA=%0h>) A new tlb miss request received while there is already a Tlb miss request pending from this thread as shown above.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b);
tlb_valid[dec_lsu_tid_b] <= 1'b1;
tmp[`INST_VA] = inst_pc_b;
tmp[`MEMOP_VA] = vaddr_b;
tlbmiss_pend_array[dec_lsu_tid_b] = tmp;
//problem with the signal.
always @ (negedge `SPC3.l2clk)
if (`SPC3.tlu_trap_pc_0_valid)
thid = {1'b0, `SPC3.tlu_trap_0_tid};
else if (`SPC3.tlu_trap_pc_1_valid)
thid = {1'b0, `SPC3.tlu_trap_1_tid};
`PR_ERROR("lsu_mon", `ERROR, "<C%h> mmu_dtlb_reload asserted but trap_pc_0_valid and trap_pc_1_valid are both 0", core_id);
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> mmu_dtlb_reload asserted while tlb_valid is 0.", core_id, thid);
tmp = tlbmiss_pend_array[dec_lsu_tid_b];
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> %s(VA=%0h> DTLB reloaded for VA = %0h.", core_id, thid, tb_top.intf0.xlate(tmp[`INST]), tmp[`INST_VA], tmp[`MEMOP_VA] );
task Insert_ld_miss_info;
reg [`LD_Pend_Width] tmp;
if (ld_valid[dec_lsu_tid_b])
tmp = ld_pend_array[dec_lsu_tid_b];
DispPendReq(dec_lsu_tid_b);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <%0h> B_stage: %s(VA=%0h>) A new request received while there is already a request pending from this thread as shown above.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b);
//ld_valid[dec_lsu_tid_b] <= 1'b1;
tmp[`INST_VA] = inst_pc_b;
tmp[`MEMOP_VA] = vaddr_b;
tmp[`MEMOP_PA] = {`SPC3.lsu.tlb_pgnum[39:13], vaddr_b[12:0]};
is_blkld[dec_lsu_tid_b] = 1'b1;
is_blkld[dec_lsu_tid_b] = 1'b0;
if (lsu_inst_b[`SWAP] || lsu_inst_b[`LDSTUB] || lsu_inst_b[`CASA])
tmp[`LSU_MON_INST] = lsu_inst_b;
ld_pend_array[dec_lsu_tid_b] = tmp;
task Insert_in_last_inst_array;
tmp[`INST_VA] = inst_pc_b;
tmp[`MEMOP_VA] = vaddr_b;
last_inst_array[dec_lsu_tid_b] = tmp;
reg [`LD_Pend_Width] tmp;
tmp = ld_pend_array[thid];
`PR_ALWAYS("lsu_mon", `ALWAYS, "LD_PEND_ARRAY[%0h] Data.", thid);
`PR_ALWAYS("lsu_mon", `ALWAYS, "<C%h> <T%0h> <%0h> %s(VA=%0h). PA = %0h. L2_ISS = %0h. L2_RESP = %0h, LSU_MON_INST=%h.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA], tmp[`MEMOP_PA], tmp[`L2_ISS], tmp[`L2_RESP], tmp[`LSU_MON_INST]);
`PR_ALWAYS("lsu_mon", `ALWAYS, "<C%h> <T%0h> STB[%0h] data.", core_id, thid, ptr);
`PR_ALWAYS("lsu_mon", `ALWAYS, "<C%h> <T%0h> <%0h> %s(VA=%0h). PA = %0h. L2_ISS = %0h. L2_ACK = %0h, LSU_MON_INST=%h. RMO = %0b", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA], tmp[`MEMOP_PA], tmp[`L2_ST_ISS], tmp[`L2_ACK], tmp[`LSU_MON_INST], tmp[`RMO]);
task Disp_tlbmiss_pend_array_entry;
tmp = tlbmiss_pend_array[thid];
`PR_INFO("lsu_mon", 23, "TLB_MISS_PEND_ARRAY[%0h] Data.", thid);
`PR_INFO("lsu_mon", 23, "<C%h> <T%0h> <%0h> %s(VA=%0h).", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA]);
`PR_ALWAYS("lsu_mon", `ALWAYS, "CPX_PKT data.");
`PR_ALWAYS("lsu_mon", `ALWAYS, "<C%0h> <T%0h> rtn_typ = %0h, err_bits = %0h, nc=%0b, atm = %0b, pf = %0b", core_id, cpx_pkt[`CPX_THR_ID], cpx_pkt[`CPX_RTNTYP], cpx_pkt[`CPX_ERR], cpx_pkt[`CPX_NC], cpx_pkt[`CPX_ATM], cpx_pkt[`CPX_PF]);
tmp[`INST_VA] = inst_pc_b;
tmp[`MEMOP_VA] = vaddr_b;
tmp[`MEMOP_PA] = {`SPC3.lsu.tlb_pgnum[39:13], vaddr_b[12:0]};
tmp[`LSU_MON_INST] = lsu_inst_b;
if (`SPC3.lsu.tlu_lsu_hpstate_hpriv[dec_lsu_tid_b])
else if (`SPC3.lsu.tlu_lsu_pstate_priv[dec_lsu_tid_b])
//bis_asi to io space is not rmo
tmp[`RMO] = lsu_inst_b[`BLKST] | (dec_altspace_b & Is_bis_asi(asi_b) & ~`SPC3.lsu.tlb_pgnum[39]);
input [195:0] store_data;
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> STB full and a new store received for insertion in STB.", core_id, thid);
stb[{thid, wrptr[thid]}] = store_data;
//Disp_STB_entry(thid, wrptr[thid]);
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> <%0h> %s(VA=%0h). STB[%0h] Inserted.", core_id, thid, store_data[`INST_VA], tb_top.intf0.xlate(store_data[`INST]), store_data[`MEMOP_VA], wrptr[thid]);
stb_valid[{thid, wrptr[thid]}] = 1'b1;
wrptr[thid] = wrptr[thid] + 1'b1;
//`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> wrptr = %0d.", core_id, thid, wrptr[thid]);
if ((wrptr[thid] == rdptr[thid]) && stb_valid[{thid, wrptr[thid]}])
//thid = decode_tid(`SPC3.lsu_stb_dealloc);
tmp = stb[{thid, rdptr[thid]}];
lsu_inst = tmp[`LSU_MON_INST];
if (~stb_valid[{thid, rdptr[thid]}])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> lsu_stb_dealloc = %0h asserted while the stb entry is invalid for that thid.", core_id, thid, `SPC3.lsu_stb_dealloc);
Disp_STB_entry(thid, rdptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> lsu_stb_dealloc = %0h asserted when we haven't received the response from the gasket.", core_id, thid, `SPC3.lsu_stb_dealloc);
else if (tmp[`ASI_ST_ISS])
ret_ptr[thid] = ret_ptr[thid] + 1'b1;
//blkst inst. is not issued anywhere, blkst helpers are issued.
//in case of bis stores, lsu issues the dealloc in P3, i.e when the req is issued to PCX.
//IF it is bis to cp sapce and there is an err then the store is issued to PCX with nd set
//However for ue onbis to IO space, dealloc is sent to IFU, issued on PCX with valid bit 0.
//The sbdiou signal is sent in next cycle. We need to take bis io stores in this equation.
else if (tmp[`ST_SQUASH] || lsu_inst[`BLKST] || (tmp[`RMO] & ~lsu_inst[`BLKST] & ~`SPC0.lsu.sbc.kill_store_p4_))
iss_ptr[thid] = iss_ptr[thid] + 1'b1;
ret_ptr[thid] = ret_ptr[thid] + 1'b1;
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> lsu_stb_dealloc = %0h asserted which is not issued to asi ring, or PCX or is not squashed.", core_id, thid, `SPC3.lsu_stb_dealloc);
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> <%0h>: %s(VA=%0h) PA = %0h. STB[%0d] Deallocated.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], tmp[`MEMOP_PA], rdptr[thid]);
stb_valid[{thid, rdptr[thid]}] = 1'b0;
rdptr[thid] = rdptr[thid] + 1'b1;
//`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> rd_ptr = %0d.", core_id, thid, rdptr[thid]);
st_rmo_cnt[thid] = st_rmo_cnt[thid] + 1'b1;
if (ret_ptr[thid] != iss_ptr[thid])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> lsu_block_store_kill asserted while the ret_ptr = %0h != iss_ptr = %0h.", core_id, thid, tmp[`MEMOP_PA], ret_ptr[thid], iss_ptr[thid]);
if (rdptr[thid] != iss_ptr[thid])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> lsu_block_store_kill asserted while the rdptr = %0h != iss_ptr = %0h.", core_id, thid, tmp[`MEMOP_PA], rdptr[thid], iss_ptr[thid]);
if (iss_ptr[thid] == wrptr[thid])
if (stb_valid[{thid, wrptr[thid]}])
/* Lsu can assert both dealloc and block_store_kill for a request.
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Lsu asserted block_store_kill while there are no valid entries in STB to be deallocated.", core_id, thid);
if (iss_ptr[thid] < wrptr[thid])
squash_cnt = wrptr[thid] - iss_ptr[thid];
else if (iss_ptr[thid] > wrptr[thid])
squash_cnt = wrptr[thid] + (8 - iss_ptr[thid]);
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> SQUASH_STB:iss_ptr = %0h, wrptr = %0h, squash_cnt = %0h.", core_id, thid, iss_ptr[thid], wrptr[thid], squash_cnt);
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> Block store kill changed issue_ptr:%0h->%0h. ret_ptr: %0h->%0h. rdptr:%0h->%0h.", core_id, thid, iss_ptr[thid], iss_ptr[thid]+squash_cnt, ret_ptr[thid], ret_ptr[thid]+squash_cnt, rdptr[thid], rdptr[thid]+squash_cnt);
ret_ptr[thid] = ret_ptr[thid] + squash_cnt;
rdptr[thid] = rdptr[thid] + squash_cnt;
iss_ptr[thid] = iss_ptr[thid] + squash_cnt;
if (~stb_valid[{thid, i}])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h><PA = %0h> lsu_block_store_kill asserted while the stb entry %0h is invalid.", core_id, thid, tmp[`MEMOP_PA], i);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h>st_issue bit is set when the block_store_kill is asserted for stb entry %0h.", core_id, thid, tmp[`MEMOP_PA], i);
//commenting out the chk below. Lsu can assert sbdiou and then in the next cycle insert a new entry into
//stb. LSU will squash this new entry and won't issue it to PCX/asi but its squash bit won't be
//set in the chkr which was causin it to fire.
//`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> lsu_block_store_kill asserted while the squash bit is 0 in the STB entry %0h.", core_id, thid, tmp[`MEMOP_PA], i);
stb_valid[{thid, i}] = 1'b0;
squash_cnt = squash_cnt - 1'b1;
if ((bst_cnt > 0) && (`SPC3.lsu_stb_alloc == 8'b0))
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Blk store entries are not allocated back to back in STB.", core_id, bst_active_thid);
//For bst the stb is still written even though we have errors.
//Stb is written in W stage. Howvere for first blk store helper
//the err will be flagged by FGU in b stage. We can miss the
// err signal if we don't sample in B.
//for the last helper err will be signalled in B stage of last helper and at
if (lsu_bst_active[bst_active_thid] & `SPC0.fgu_fst_ecc_error_fx2 & (bst_cnt < 7))
if (`SPC3.lsu_stb_alloc[7:0] != 8'b0)
thid = decode_tid(`SPC3.lsu_stb_alloc[7:0]);
if (thid != dec_lsu_tid_w)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> lsu_stb_alloc = %0h mismatches the thid %0h.", core_id, dec_lsu_tid_w, `SPC3.lsu_stb_alloc[7:0], dec_lsu_tid_w);
Insert_in_STB(stb_alloc_data, dec_lsu_tid_w);
if (lsu_bst_active[thid])
bst_data = bst_inst_data;
if (thid != bst_active_thid)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> lsu_stb_alloc = %0h mismatches the active blkstore thid = %0h.", core_id, bst_active_thid, `SPC3.lsu_stb_alloc[7:0], bst_active_thid);
addr = bst_data[`MEMOP_VA];
bst_data[`MEMOP_VA] = {addr[47:6], bst_cnt[2:0], 3'b0};
addr = bst_data[`MEMOP_PA];
bst_data[`MEMOP_PA] = {addr[39:6], bst_cnt[2:0], 3'b0};
Insert_in_STB(bst_data, bst_active_thid);
lsu_bst_active[thid] = 1'b0;
if (bst_fgu_err) //set the squash bit to 0 for all the stb entries
for (i = 0; i < 8; i=i+1)
tmp = stb[{thid, i[2:0]}];
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> Squash bit already set when trying to set it for a bst fgu errerr.", core_id, thid, tmp[`MEMOP_PA]);
stb[{thid, i[2:0]}] = tmp;
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> <PA = %0h> STB_entry[%0h] squashed due to FGU err.", core_id, thid, tmp[`MEMOP_PA], i);
`PR_ERROR("lsu_mon", `ERROR, "<C%h>: LSU asserted lsu_stb_alloc = %0h while no store pending to be written in STB.", core_id, `SPC3.lsu_stb_alloc[7:0]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <%0h> W_stage: LSU did not assert lsu_stb_alloc for the store.", core_id, dec_lsu_tid_w, inst_pc_w);
reg [47:0] addr, act_addr;
thid =`SPC3.lsu_rngl_cdbus[58:56];
thid =`SPC3.lsu_rngf_cdbus[58:56];
asi =`SPC3.lsu_rngl_cdbus[55:48];
asi =`SPC3.lsu_rngf_cdbus[55:48];
addr =`SPC3.lsu_rngl_cdbus[47:0];
addr =`SPC3.lsu_rngf_cdbus[47:0];
req_type =`SPC3.lsu_rngl_cdbus[61:60];
req_type =`SPC3.lsu_rngf_cdbus[61:60];
tmp = stb[{thid, iss_ptr[thid]}];
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> Store reissued on the ASI interface.", core_id, thid, addr);
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> Store issued on the ASI interface that has been squashed.", core_id, thid, addr);
act_addr = tmp[`MEMOP_PA];
act_addr = {act_addr[39:3], 3'b0};
//47 is D tag rd asi. LSU issues that on the ring but changes
if ((addr == act_addr) || (asi == 8'h47) || (asi == 8'h46))
stb[{thid, iss_ptr[thid]}] = tmp;
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) STB[%0d] Issued on local ring.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], iss_ptr[thid]);
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) STB[%0d] Issued on fast ring.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], iss_ptr[thid]);
iss_ptr[thid] = iss_ptr[thid] + 1'b1;
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <%0h>: %s(VA=%0h) STB[%0d] PA mismatch for asi req on local ring. Expected PA = %0h, actual PA = %0h", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], iss_ptr[thid], tmp[`MEMOP_PA], addr);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <%0h>: %s(VA=%0h) STB[%0d] PA mismatch for asi req on fast ring. Expected PA = %0h, actual PA = %0h", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], iss_ptr[thid], tmp[`MEMOP_PA], addr);
task chk_store_issue_to_pcx;
reg [39:0] pcx_pa, inst_pa;
thid = pcx_pkt[`PCX_THR_ID];
tmp = stb[{thid, iss_ptr[thid]}];
inst = tmp[`LSU_MON_INST];
pcx_pa = pcx_pkt[`PCX_ADDR];
inst_pa = tmp[`MEMOP_PA];
if (pcx_pkt[`PCX_RQTYP] == `PCX_STORE)
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) STB[%0d] Issued to gasket.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], iss_ptr[thid]);
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) STB[%0d] Issued to gasket with ND set.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], iss_ptr[thid]);
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> A store request made to gasket by LSU while the pending req is not store.", core_id, thid, pcx_pkt[`PCX_ADDR]);
if (pcx_pa[39:0] != inst_pa[39:0])
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> A store request made to gasket by LSU while the pending req has PA %0h.", core_id, thid, pcx_pkt[`PCX_ADDR], tmp[`MEMOP_PA]);
if ((tmp[`INST_ASI] == 8'h73) & (pcx_pa[39:0] != {8'h90, core_id, thid, tmp[`INST_ASI], 18'h0}))
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> pcx_pa is not correct for asi write to interrupt vector dispatch register.", core_id, thid, pcx_pkt[`PCX_ADDR]);
if (inst[`BLKST] && ~pcx_pkt[`PCX_BST])
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> Bst bit is not set in the PCX pkt by LSU for a blk st request.", core_id, thid, pcx_pkt[`PCX_ADDR]);
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> Store reissued on the PCX interface.", core_id, thid, pcx_pkt[`PCX_ADDR]);
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> Store issued on the PCX interface that has been squashed.", core_id, thid, pcx_pkt[`PCX_ADDR]);
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> BIS bit is not set in the PCX pkt by LSU for an RMO store.", core_id, thid, pcx_pkt[`PCX_ADDR]);
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> L2ack bit is set when the RMO store is issued to PCX.", core_id, thid, pcx_pkt[`PCX_ADDR]);
ret_ptr[thid] = ret_ptr[thid] + 1; //this will be deallocated before
//response seen from stub
st_rmo_cnt[thid] = st_rmo_cnt[thid] + 1'b1;
stb[{thid, iss_ptr[thid]}] = tmp;
iss_ptr[thid] = iss_ptr[thid] + 1;
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> iss_ptr = %0d. ret_ptr = %0d, st_rmo_cnt = %0d", core_id, thid, iss_ptr[thid], ret_ptr[thid], st_rmo_cnt[thid]);
`ifdef INJ_STB_ERR_IN_CMP
reg [2:0] err_tid, stb_err_tid_d1, stb_err_tid_d2;
reg [2:0] err_index, stb_err_index_d1, stb_err_index_d2;
reg stb_err_inj, stb_err_inj_d1, stb_err_inj_d2;
reg [1:0] err_priv, stb_err_priv_d1, stb_err_priv_d2;
if (("cmp_stb_err_inj_on"))
always @ (negedge (`SPC3.l2clk & enabled & cmp_stb_err_inj))
//valid stb ram rd for issue to pcx
if (`SPC3.lsu.sbc.ram_rptr_vld_2 & `SPC3.lsu.sbc.st_pcx_rq_p3 & `SPC3.lsu.pic.pic_st_sel_p3)
err_tid = decode_tid(`SPC3.lsu.sbc.st_rq_sel_p3[7:0]);
err_index = `SPC3.lsu.sbc.ram_rptr_d1;
err_tmp = stb[{err_tid, err_index}];
err_inst = err_tmp[`LSU_MON_INST];
cam_data = `SPC3.lsu.stb_cam.cam_array.stb_rdata[44:0];
err_priv = err_tmp[`ST_PRIV];
//if (err_inst[`SWAP] || err_inst[`CASA] || err_inst[`LDSTUB])
err_inj_cnt = err_inj_cnt + 1;
11, 12: err_bit = err_bit + 1;
force `SPC0.lsu.stb_cam.cam_array.stb_rdata[44:0] = cam_data ^ (1 << err_bit);
`PR_INFO("stb_err", 22, "<T%0h> <%0h> STB[%0h]: SBAPP forced for CASA. err_bit = %0h", err_tid, {cam_data[44:8], 3'b0}, err_index, err_bit);
release `SPC0.lsu.stb_cam.cam_array.stb_rdata[44:0];
if (~`SPC3.lsu_sbapp_err_g)
`PR_ERROR("lsu_mon", `ERROR, "<T%0h> sbapp err not asserted when err is injected for atomic.", stb_err_tid_d2);
if ((`SPC3.lsu_stberr_tid_g != stb_err_tid_d2) ||
(`SPC3.lsu_stberr_index_g != stb_err_index_d2) ||
(`SPC3.lsu_stberr_priv_g != stb_err_priv_d2))
`PR_ERROR("lsu_mon", `ERROR, "<T%0h> sbapp err parameters mismatch.", stb_err_tid_d2);
if (`SPC3.lsu_sbapp_err_g)
`PR_ERROR("lsu_mon", `ERROR, "<T%0h> sbapp err asserted when none expected.", `SPC3.lsu_stberr_tid_g);
always @ (posedge (`SPC3.l2clk & enabled & cmp_stb_err_inj))
stb_err_inj_d1 <= stb_err_inj;
stb_err_inj_d2 <= stb_err_inj_d1;
stb_err_tid_d1 <= err_tid;
stb_err_tid_d2 <= stb_err_tid_d1;
stb_err_index_d1 <= err_index;
stb_err_index_d2 <= stb_err_index_d1;
stb_err_priv_d1 <= err_priv;
stb_err_priv_d2 <= stb_err_priv_d1;
// If vcs_build_args NO_MONITORS, then module will be empty
reg [7:0] asi_e, imm_asi_e, asi_m, asi_b;
reg dec_altspace_e, dec_altspace_b, dec_altspace_m;
reg [1:0] exu_lsu_va_error_b;
reg [2:0] dec_lsu_tid_e, dec_lsu_tid_m, dec_lsu_tid_b, dec_lsu_tid_w;
reg [47:0] inst_pc_e, inst_pc_m, inst_pc_b, inst_pc_w;
reg [31:0] inst_e, inst_m, inst_b;
reg [47:0] vaddr_m, vaddr_b;
reg [63:0] int_st_data_m, int_st_data_b;
reg [63:0] fp_st_sata_fx2;
reg [20:0] lsu_inst_e, lsu_inst_m, lsu_inst_b;
reg mmu_dtlb_reload_d1, mmu_dtlb_reload_d2;
reg [`LD_Pend_Width] ld_pend_array[7:0];
reg [`LAST_INST_Pend_Width] last_inst_array[7:0];
reg [2:0] wrptr[7:0]; //Pts. to the STB entry into which data will be written next
reg [2:0] rdptr[7:0]; //Tracks the dealloc signal from STB
reg [2:0] iss_ptr[7:0]; //keeps track of when a store is issued from the STB to PCX
reg [2:0] ret_ptr[7:0]; //keeps track of when the response is received from
reg [`STB_Pend_Width] stb[63:0];
//reg [`TLB_MISS_Pend_Width] tlbmiss_pend_array[7:0];
reg [7:0] dcache_inv_cnt[7:0];
reg [7:0] st_rmo_cnt[7:0];
reg [31:0] dec_tg0_inst_d, dec_tg1_inst_d;
reg [7:0] lsu_bst_active;
reg [195:0] stb_alloc_data;
reg [195:0] bst_data, bst_inst_data;
reg [2:0] bst_active_thid;
reg [7:0] is_blkld; //reqd by lsu_ras_chkr to chk errors on blk ld.
reg [1:0] l2_blk_ld_errtype[7:0]; //Gives the type of err the ahd be reported by LSU if
//different types of err occur on blk ld helper returns
reg [1:0] st_priv[7:0]; //Gives the final priv level for an sbdiou/sbapp err that shd be
for (i = 0; i < 8; i = i+1)
l2_blk_ld_errtype[i] = 2'b0;
// avoid time zero ugliness. jp
//@(posedge `SPC0.l2clk);
//@(negedge `SPC0.l2clk);
//if (`PARGS.lsu_mon_on) enabled = 1;
3'h0: finish_mask = `PARGS.finish_mask[7:0];
3'h1: finish_mask = `PARGS.finish_mask[15:8];
3'h2: finish_mask = `PARGS.finish_mask[23:16];
3'h3: finish_mask = `PARGS.finish_mask[31:24];
3'h4: finish_mask = `PARGS.finish_mask[39:32];
3'h5: finish_mask = `PARGS.finish_mask[47:40];
3'h6: finish_mask = `PARGS.finish_mask[55:48];
3'h7: finish_mask = `PARGS.finish_mask[63:56];
if (~`TOP.in_reset & `PARGS.lsu_mon_on & ~reset_in_middle)
`PR_ALWAYS("lsu_mon", `ALWAYS, "Lsu_mon on, in_reset = 0.");
if (`TOP.in_reset & enabled)
`PR_ALWAYS("lsu_mon", `ALWAYS, "Reset asserted in the middle of the diag. Turned off Lsu_mon.");
always @ (posedge (tb_top.sim_status[0] & enabled))
if (|(ld_valid[7:0] & finish_mask[7:0]))
for (i = 0; i < 8; i=i+1)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> Ld requests pending at the end of simulation. ld_valid = %0h", core_id, ld_valid);
for (i = 0; i < 64; i=i+1)
if (stb_valid[i] & finish_mask[i[5:3]])
//chkr resets the stb valid bits when block_store_kill is asserted.
//in couple of failures block_store_kill was sampled asserted two cycles after
//lsu asserted stb_empty. The simulation ended the cycle stb_empty was sampled high
//causing moniotr firings with valid entries in stb at end of simulation. Now
//don't flag an error if squash bit is set and stb_valid is asserted at end
if (~is_squash_bit_set(i[5:0]))
Disp_STB_entry(i[5:3],i[2:0]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> Store requests pending at the end of simulation. stb_valid = %0h", core_id, stb_valid);
for (i = 0; i < 8; i=i+1)
if (finish_mask[i] & (pf_cnt[i] != 0))
`PR_ALWAYS("lsu_mon", `ALWAYS, "<C%h> <T%0h> Prefetches not finished. Pf_cnt = %0d", core_id, i, pf_cnt[i]);
if (finish_mask[i] & (dcache_inv_cnt[i] != 0))
`PR_ALWAYS("lsu_mon", `ALWAYS, "<C%h> <T%0h> D pkt not received for all invalidate reqs. issued by the thread. dcache_inv_cnt = %0d", core_id, i, dcache_inv_cnt[i]);
if (finish_mask[i] & (st_rmo_cnt[i] != 0))
`PR_ALWAYS("lsu_mon", `ALWAYS, "<C%h> <T%0h> rmo_cnt not zero. rmo_cnt = %0d", core_id, i, st_rmo_cnt[i]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> Prefetch/D/RMO_stores requests pending at the end of simulation.", core_id);
function is_squash_bit_set;
is_squash_bit_set = 1'b1;
is_squash_bit_set = 1'b0;
always @ (negedge (`SPC4.l2clk & enabled))
asi_e = `SPC4.lsu.dcc.dcc_asi_e[7:0];
lsu_inst_e[`LD] <= `SPC4.dec_ld_inst_e;
lsu_inst_e[`ST] <= `SPC4.dec_st_inst_e;
lsu_inst_e[`FP] <= `SPC4.dec_fpldst_inst_e;
lsu_inst_e[`PREF] <= `SPC4.dec_pref_inst_e;
lsu_inst_e[`SWAP] <= `SPC4.dec_swap_inst_e;
lsu_inst_e[`CASA] <= `SPC4.dec_casa_inst_e;
lsu_inst_e[`LDSTUB] <= `SPC4.dec_ldstub_inst_e;
lsu_inst_e[`FLUSH] <= `SPC4.dec_flush_inst_e;
lsu_inst_e[`MEMBAR] <= `SPC4.dec_memstbar_inst_e;
lsu_inst_e[`LDD] <= `SPC4.dec_ld_inst_e & `SPC4.dec_ldst_dbl_e & ~`SPC4.dec_fpldst_inst_e;
lsu_inst_e[`STD] <= `SPC4.dec_st_inst_e & `SPC4.dec_ldst_dbl_e & ~`SPC4.lsu.dec_fpldst_inst_e;
lsu_inst_e[`BLKLD] <= `SPC4.dec_ld_inst_e & `SPC4.dec_fpldst_inst_e & dec_altspace_e & Is_blk_asi(asi_e);
lsu_inst_e[`BLKST] <= `SPC4.dec_st_inst_e & `SPC4.dec_fpldst_inst_e & dec_altspace_e & Is_blk_asi(asi_e);
lsu_inst_e[`QLD] <= `SPC4.dec_ld_inst_e & dec_altspace_e & Is_qld_asi(asi_e);
lsu_inst_e[`ASR_RD_WR] <= `SPC4.dec_sr_inst_e & (`SPC4.dec_ld_inst_e | `SPC4.dec_st_inst_e);
lsu_inst_e[`PR_RD_WR] <= `SPC4.dec_pr_inst_e & (`SPC4.dec_ld_inst_e | `SPC4.dec_st_inst_e);
lsu_inst_e[`HPR_RD_WR] <= `SPC4.dec_hpr_inst_e & (`SPC4.dec_ld_inst_e | `SPC4.dec_st_inst_e);
lsu_inst_e[`FSR_RD_WR] <= `SPC4.dec_fsr_ldst_e & (`SPC4.dec_ld_inst_e | `SPC4.dec_st_inst_e);
always @ (posedge (`SPC4.l2clk & enabled))
dec_tg0_inst_d <= `SPC4.dec.ded0.decode_mux[31:0];
dec_tg1_inst_d <= `SPC4.dec.ded1.decode_mux[31:0];
imm_asi_vld_e <= `SPC4.lsu.dec_imm_asi_vld_d;
imm_asi_e <= `SPC4.lsu.dec_imm_asi_d;
dec_altspace_e <= `SPC4.dec_altspace_d;
dec_altspace_m <= dec_altspace_e;
dec_altspace_b <= dec_altspace_m;
exu_ecc_b <= `SPC4.exu_ecc_m;
exu_lsu_va_error_b <= `SPC4.exu_lsu_va_error_m;
dec_lsu_tid_e <= `SPC4.dec_lsu_tg_d ? {1'b1, `SPC4.dec_lsu_tid1_d} : {1'b0, `SPC4.dec_lsu_tid0_d};
dec_lsu_tid_m <= dec_lsu_tid_e;
dec_lsu_tid_b <= dec_lsu_tid_m;
dec_lsu_tid_w <= dec_lsu_tid_b;
inst_pc_e <= `SPC4.dec_lsu_tg_d ? {`SPC4.tlu.tlu_pc_1_d[47:2], 2'b0} : {`SPC4.tlu.tlu_pc_0_d[47:2], 2'b0};
inst_e <= `SPC4.dec_lsu_tg_d ? dec_tg1_inst_d : dec_tg0_inst_d;
vaddr_m <= `SPC4.exu_lsu_address_e;
int_st_data_m <= `SPC4.exu_lsu_store_data_e;
int_st_data_b <= int_st_data_m;
fp_st_sata_fx2 <= `SPC4.fgu_lsu_fst_data_fx1;
mmu_dtlb_reload_d1 <= `SPC4.mmu_dtlb_reload;
mmu_dtlb_reload_d2 <= mmu_dtlb_reload_d1;
//pcx_thid_d1 <= `SPC4.lsu.spc_pcx_data_pa[`PCX_THR_ID];
lsu_inst_m <= lsu_inst_e;
lsu_inst_b <= lsu_inst_m;
Is_blk_asi = (asi == `ASI_BLK_AIUP) | (asi == `ASI_BLK_AIUS) |
(asi == `ASI_BLK_AIUPL) | (asi == `ASI_BLK_AIUSL) |
(asi == `ASI_BLK_P) | (asi == `ASI_BLK_S) |
(asi == `ASI_BLK_PL) | (asi == `ASI_BLK_SL) |
(asi == `ASI_BLK_COMMIT_P) | (asi == `ASI_BLK_COMMIT_S);
Is_qld_asi = (asi == `ASI_AIU_BIS_QUAD_LDD_P) | (asi == `ASI_AIU_BIS_QUAD_LDD_S) |
(asi == `ASI_AIU_BIS_QUAD_LDD_P_LITTLE) | (asi == `ASI_AIU_BIS_QUAD_LDD_S_LITTLE) |
(asi == `ASI_NUCLEUS_BIS_QUAD_LDD) | (asi == `ASI_NUCLEUS_BIS_QUAD_LDD_LITTLE) |
(asi == `ASI_BIS_QUAD_LDD_P) | (asi == `ASI_BIS_QUAD_LDD_S) |
(asi == `ASI_BIS_QUAD_LDD_P_LITTLE) | (asi == `ASI_BIS_QUAD_LDD_S_LITTLE) |
(asi == `ASI_QUAD_LDD) | (asi == `ASI_QUAD_LDD_REAL) |
(asi == `ASI_QUAD_LDD_L) | (asi == `ASI_QUAD_LDD_REAL_L);
Is_bis_asi = (asi == `ASI_AIU_BIS_QUAD_LDD_P) | (asi == `ASI_AIU_BIS_QUAD_LDD_S) |
(asi == `ASI_AIU_BIS_QUAD_LDD_P_LITTLE) | (asi == `ASI_AIU_BIS_QUAD_LDD_S_LITTLE) |
(asi == `ASI_NUCLEUS_BIS_QUAD_LDD) | (asi == `ASI_NUCLEUS_BIS_QUAD_LDD_LITTLE) |
(asi == `ASI_BIS_QUAD_LDD_P) | (asi == `ASI_BIS_QUAD_LDD_S) |
(asi == `ASI_BIS_QUAD_LDD_P_LITTLE) | (asi == `ASI_BIS_QUAD_LDD_S_LITTLE);
always @ (negedge (`SPC4.l2clk & enabled))
`PR_INFO("lsu_mon", 21, "<C%0h> <T%0h> <%0h> M_stage: %s(VA=%0h) Flushed due to IFU Flush.", core_id, dec_lsu_tid_m, inst_pc_m, tb_top.intf0.xlate(inst_m),vaddr_m);
if (lsu_inst_b[`BLKLD]) print_inst = " BLKLD,";
else if (lsu_inst_b[`BLKST]) print_inst = " BLKST,";
else if (lsu_inst_b[`QLD]) print_inst = " QLD,";
`PR_INFO("lsu_mon", 21, "<C%0h> <T%0h> <%0h> B_stage: %s(VA=%0h) Flushed due to IFU Flush.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b);
else if (`SPC4.tlu_flush_lsu_b)
`PR_INFO("lsu_mon", 21, "<C%h> <T%0h> <%0h> B_stage: %s(VA=%0h) Flushed due to TLU Flush.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b);
//casa is a two cycle operation. If there is an err on the 2nd cycle of casa then also
//This function will also chk for errors on 2nd cycle.
else if (Is_exu_error(exu_lsu_va_error_b, exu_ecc_b))
`PR_INFO("lsu_mon", 21, "<C%h> <T%0h <%0h> B_stage: %s(VA=%0h) Flushed due to EXU error.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b);
else if ((`SPC4.fgu_cecc_fx2 || `SPC4.fgu_uecc_fx2) && lsu_inst_b[`ST] && lsu_inst_b[`FP])
`PR_INFO("lsu_mon", 21, "<C%h> <T%0h> <%0h> B_stage: %s(VA=%0h) Flushed due to FGU error.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b);
else if (!`SPC4.lsu_tlb_miss_b_)
`PR_INFO("lsu_mon", 23, "<C%h> <T%0h> <%0h> B_stage: %s(VA=%0h)%s ASI = %0h. DTLB miss.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b, print_inst, asi_b);
//Lsu doesn't assert lsu_sync for an exception or dtlb miss. Since for
//an exception tlu anyway tells the front end to flush itself there is
//no reason for LSU to flush the front end then TLU to flush it again.
//Lsu treats the dtlbmiss as an exception that it flushes the inst and
//handles it when it is reissued by the front end.
if (`SPC4.lsu_tlb_bypass_b)
if (`SPC4.lsu_sync != 8'b0)
`PR_INFO("lsu_mon", 23, "<C%h> <T%0h> <%0h>: %s(VA=%0h)%s PA = %0h, ASI = %0h. LSU_sync. DTLB Bypass.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b, print_inst, {`SPC4.lsu.tlb_pgnum[39:13], vaddr_b[12:0]}, asi_b);
`PR_INFO("lsu_mon", 23, "<C%h> <T%0h> <%0h>: %s(VA=%0h)%s PA = %0h, ASI = %0h. DTLB Bypass.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b, print_inst, {`SPC4.lsu.tlb_pgnum[39:13], vaddr_b[12:0]}, asi_b);
if (`SPC4.lsu_sync != 8'b0)
`PR_INFO("lsu_mon", 23, "<C%h> <T%0h> <%0h>: %s(VA=%0h)%s PA = %0h, ASI = %0h, Store_data = %0h. LSU_sync. DTLB hit.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b, print_inst, {`SPC4.lsu.tlb_pgnum[39:13], vaddr_b[12:0]}, asi_b,int_st_data_b);
`PR_INFO("lsu_mon", 23, "<C%h> <T%0h> <%0h>: %s(VA=%0h)%s PA = %0h, ASI = %0h. LSU_sync. DTLB hit.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b, print_inst, {`SPC4.lsu.tlb_pgnum[39:13], vaddr_b[12:0]}, asi_b);
`PR_INFO("lsu_mon", 23, "<C%h> <T%0h> <%0h>: %s(VA=%0h)%s PA = %0h, ASI = %0h, Store_data = %0h. DTLB hit.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b, print_inst, {`SPC4.lsu.tlb_pgnum[39:13], vaddr_b[12:0]}, asi_b, int_st_data_b);
`PR_INFO("lsu_mon", 23, "<C%h> <T%0h> <%0h>: %s(VA=%0h)%s PA = %0h, ASI = %0h. DTLB hit.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b, print_inst, {`SPC4.lsu.tlb_pgnum[39:13], vaddr_b[12:0]}, asi_b);
if (lsu_inst_b[`LD] || lsu_inst_b[`PREF] || lsu_inst_b[`SWAP] || lsu_inst_b[`CASA] || lsu_inst_b[`LDSTUB])
if (((lsu_inst_b == 16'h1) || (lsu_inst_b == 16'h5)) & `SPC4.lsu.stb_cam_hit)
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> <%0h>: LSU_sync asserted due to STB RAW.", core_id, dec_lsu_tid_b, inst_pc_b);
if (lsu_inst_b[`ST]) //for atomics both ld and store signals are asserted
Insert_in_last_inst_array;
if (`SPC4.lsu_trap_flush[7:0])
`PR_INFO("lsu_mon", 21, "<C%h> <T%0h> Trap Flush asserted.", core_id, decode_tid(`SPC4.lsu_trap_flush[7:0]));
//This is how we test squashing of stores by LSU_mon:
//Whenever lsu asserts err_sbdiou signal, the monitor sets the squash
//bit in the STB for the rest of the stores. If any of these squashed stores
//is issued on the asi ring or to the PCX interface the monitor complains.
//The squashed stores are deallocated when either a block_store_kill is
//asserted or dealloc signals are asserted by the LSU.
//When the block_store_kill is asserted, it tells the IFU to dealloc
//all the pending stores in the IFU. It means the when block_store_kill
//is asserted we have deallocated all the non-squashed requests from STB.
//The 0in_chkr ensures that LSU flags the correct index and priv with the
//the sbdiou signal to TLU.
always @ (negedge (`SPC4.l2clk & enabled))
if (`SPC4.lsu_l15_valid & `SPC4.lsu.spc_pcx_data_pa[129])
Chk_pcx_req_pkt(`SPC4.lsu.spc_pcx_data_pa[129:0]); //chk if we need .lsu here
if ((`SPC4.lsu_rngl_cdbus[64:63] == 2'b11) & ~`SPC4.lsu_rngl_cdbus[59])
Chk_st_on_ASI_ring(`LOCAL);
if ((`SPC4.lsu_rngf_cdbus[64:63] == 2'b11) & ~`SPC4.lsu_rngf_cdbus[59])
Chk_st_on_ASI_ring(`FAST);
//if (`SPC4.l15_lsu_valid)
//Chk_cpx_response_pkt({`SPC4.l15_lsu_valid, `SPC4.l15_lsu_cpkt[17:13],`SPC4.l15_lsu_cpkt[11:0],`SPC4.l15_spc_data1[127:0]});
if (`SPC4.cpx_spc_data_cx[145])
Chk_cpx_response_pkt(`SPC4.cpx_spc_data_cx);
if (`SPC4.lsu_complete[7:0] != 8'b0)
if (`SPC4.lsu_complete[0]) Chk_ld_complete(0);
if (`SPC4.lsu_complete[1]) Chk_ld_complete(1);
if (`SPC4.lsu_complete[2]) Chk_ld_complete(2);
if (`SPC4.lsu_complete[3]) Chk_ld_complete(3);
if (`SPC4.lsu_complete[4]) Chk_ld_complete(4);
if (`SPC4.lsu_complete[5]) Chk_ld_complete(5);
if (`SPC4.lsu_complete[6]) Chk_ld_complete(6);
if (`SPC4.lsu_complete[7]) Chk_ld_complete(7);
if (`SPC4.lsu_block_store_kill[7:0] != 8'b0)
if (`SPC4.lsu_block_store_kill[0]) Squash_STB(0);
if (`SPC4.lsu_block_store_kill[1]) Squash_STB(1);
if (`SPC4.lsu_block_store_kill[2]) Squash_STB(2);
if (`SPC4.lsu_block_store_kill[3]) Squash_STB(3);
if (`SPC4.lsu_block_store_kill[4]) Squash_STB(4);
if (`SPC4.lsu_block_store_kill[5]) Squash_STB(5);
if (`SPC4.lsu_block_store_kill[6]) Squash_STB(6);
if (`SPC4.lsu_block_store_kill[7]) Squash_STB(7);
if (`SPC4.lsu_stb_dealloc[7:0] != 8'b0)
if (`SPC4.lsu_stb_dealloc[0]) Dealloc_STB(0);
if (`SPC4.lsu_stb_dealloc[1]) Dealloc_STB(1);
if (`SPC4.lsu_stb_dealloc[2]) Dealloc_STB(2);
if (`SPC4.lsu_stb_dealloc[3]) Dealloc_STB(3);
if (`SPC4.lsu_stb_dealloc[4]) Dealloc_STB(4);
if (`SPC4.lsu_stb_dealloc[5]) Dealloc_STB(5);
if (`SPC4.lsu_stb_dealloc[6]) Dealloc_STB(6);
if (`SPC4.lsu_stb_dealloc[7]) Dealloc_STB(7);
if (`SPC4.lsu_block_store_stall)
if (`SPC4.lsu.lsu_block_store_alloc[7:0] != 8'b0)
Set_block_store_parameters;
if (`SPC4.lsu_sbdiou_err_g || `SPC4.lsu_sbapp_err_g)
if (`SPC4.lsu_stb_flush_g)
st_priv[`SPC4.lsu_stberr_tid_g] = get_priv_on_flush(`SPC4.lsu_stberr_tid_g);
function [1:0] get_priv_on_flush;
sq_index = `SPC4.lsu_stberr_index_g;
tmp = stb[{tid, sq_index}];
get_priv_on_flush = tmp[`ST_PRIV];
thid = `SPC4.lsu_block_store_tid;
bst_inst_data = stb[{thid, rdptr[thid]}];
inst = bst_inst_data[`LSU_MON_INST];
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> LSU asserted blk_store_stall while the req at the top of STB is not blkst as shown above", core_id, thid);
//lsu can assert block_store_stall for a new block store while it has not yet written
//the 8 stb entries from the previous blk store.
task Set_block_store_parameters;
thid = decode_tid(`SPC4.lsu.lsu_block_store_alloc[7:0]);
if (lsu_bst_active[thid])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> LSU asserted blk_store_alloc while the bst_active is already set for this thread.", core_id, thid);
lsu_bst_active[thid] = 1'b1;
if (`SPC4.lsu.fgu_fst_ecc_error_fx2)
thid = `SPC4.lsu_stberr_tid_g;
sq_index = `SPC4.lsu_stberr_index_g;
priv = `SPC4.lsu_stberr_priv_g;
tmp = stb[{thid, sq_index}];
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> Sbdiou/sbapp seen for index = %h and priv = %h.", core_id, thid, sq_index, priv);
st_priv[thid] = tmp[`ST_PRIV];
//lsu can assert deallocate before it asserts the sbdiou signal.
//In that case iss_ptr won't be equal to sbdiou index.
//if (sq_index != iss_ptr[thid])
// Disp_STB_entry(thid, iss_ptr[thid]);
// `PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> LSU asserted sbdiou/sbapp with index %0h while the next req to be issued is at index %0h.", core_id, thid, sq_index, iss_ptr[thid]);
//If there is only one store in the store buffer which gets an sbdiou error, then LSU can deallocate
//the store and then assert sbdiou. The deallocation will cause the stb issue_ptr to move
//forward to an inst. that has already been issued and completed and this chk can fire. So
// Disp_STB_entry(thid, iss_ptr[thid]);
// `PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> Store reissued on the PCX interface.", core_id, thid, tmp[`MEMOP_PA]);
if (iss_ptr[thid] == wrptr[thid])
if (stb_valid[{thid, wrptr[thid]}])
//changing it to an info message because if there is only one valid entry in store buffer that
//gets an sbdiou then LSU can deallocate the entry and then issue sbdiou.
//`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Lsu asserted sbdiou/sbapp while there are no valid entries in STB to be issued.", core_id, thid);
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> sbdiou/sbapp squashed only one entry in STB.", core_id, thid);
if (iss_ptr[thid] < wrptr[thid])
squash_cnt = wrptr[thid] - iss_ptr[thid];
else if (iss_ptr[thid] > wrptr[thid])
squash_cnt = wrptr[thid] + (8 - iss_ptr[thid]);
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> SQUASH_STORE:iss_ptr = %0h, wrptr = %0h, squash_cnt = %0h.", core_id, thid, iss_ptr[thid], wrptr[thid], squash_cnt);
if (priv < tmp[`ST_PRIV])
`PR_INFO("lsu_mon", `INFO, "<C%h> <T%0h> <PA = %0h> Sbdiou/sbapp signalled. Err in user/priv level store is squashing a higher priv level store.", core_id, thid, tmp[`MEMOP_PA]);
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> <PA = %0h> STB_entry[%0h] squashed.", core_id, thid, tmp[`MEMOP_PA], i);
squash_cnt = squash_cnt - 1'b1;
function [2:0] decode_tid;
8'h10: decode_tid = 3'h4;
8'h20: decode_tid = 3'h5;
8'h40: decode_tid = 3'h6;
8'h80: decode_tid = 3'h7;
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> decode_tid. Incorrect value of thid input = %0h.", core_id, thid_encode, thid_encode);
reg [`LD_Pend_Width] tmp;
tmp = ld_pend_array[thid];
if ((tmp[`L2_ISS] != 4'hf) || (tmp[`L2_RESP] != 4'hf))
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> LSU asserted lsu_complete while the l2_iss and l2_resp bits are not F.", core_id, thid);
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> <%0h> %s(VA=%0h) Complete. Setting ld_valid to 0.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA]);
tmp = last_inst_array[thid];
`PR_INFO("lsu_mon", 24, "<C%h> <T%0h> <%0h> %s(VA=%0h) Complete.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA]);
reg [`LD_Pend_Width] tmp, tmp1;
thid = pcx_pkt[`PCX_THR_ID];
tmp = ld_pend_array[thid];
inst = tmp[`LSU_MON_INST];
req = DispPCXReq(pcx_pkt);
addr = pcx_pkt[`PCX_ADDR];
if (pcx_pkt[`PCX_CPU_ID] != core_id)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> cpu_id (spc_pcx_data_pa[122:120]) = %h is not = %0h when the lsu made a %s req to gasket.", core_id, pcx_pkt[`PCX_THR_ID], addr, pcx_pkt[122:120], core_id, req);
if ((pcx_pkt[`PCX_RQTYP] == `PCX_LOAD) || (pcx_pkt[`PCX_RQTYP] == `PCX_CAS1) || (pcx_pkt[`PCX_RQTYP] == `PCX_CAS2) || (pcx_pkt[`PCX_RQTYP] == `PCX_SWAP_LDSTUB))
ld_valid[thid] = 1'b1; //we have sent a req to gasket and are waiting for response
`PR_INFO("lsu_mon", 22, "<C%0h> <T%0h> Setting ld_valid[%0h].", core_id, thid, thid);
if (tmp[`MEMOP_PA] != addr)
if ((tmp[`INST_ASI] == 8'h41) || (tmp[`INST_ASI] == 8'h73) || ((tmp[`INST_ASI] == 8'h45) && ((tmp[`MEMOP_PA] == 8'h10) || (tmp[`MEMOP_PA] == 8'h18))))
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <PA = %0h> PA mismatch on gasket for %s request. Ignoring the mismatch as inst. is issued with asi 41, 73 or 45 (with VA 0x10 or 18).", core_id, thid, addr, req);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> A %s request made to gasket by LSU while the pending req is with PA %0h.", core_id, thid, addr, req, tmp[`MEMOP_PA]);
case (pcx_pkt[`PCX_RQTYP])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> A prefetch request made to gasket by LSU which mismatches the pending request from the thread.", core_id, thid, addr);
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: PREF_ICE(VA=%0h) Issued. pf_cnt not updated.", core_id, thid, tmp[`INST_VA], tmp[`MEMOP_VA]);
pf_cnt[thid] = pf_cnt[thid] + 1'b1;
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) Issued. pf_cnt = %0d.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], pf_cnt[thid]);
tmp[`L2_RESP] = 4'hF; //we don't wait for a prefetch response from gasket
ld_pend_array[thid] = tmp;
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) Dcache invalidate pkt issued to CCX.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA]);
dcache_inv_cnt[thid] = dcache_inv_cnt[thid] + 1'b1;
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> CASA request made to gasket by LSU while no such request request is pending from this thread.", core_id, thid, addr);
if (pcx_pkt[`PCX_RQTYP] == `PCX_CAS1)
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) (CAS1) Issued to gasket.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA]);
ld_pend_array[thid] = tmp;
if (pcx_pkt[`PCX_RQTYP] == `PCX_CAS2)
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) (CAS2) Issued to gasket.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA]);
ld_pend_array[thid] = tmp;
chk_store_issue_to_pcx(pcx_pkt);
if (~inst[`SWAP] && ~inst[`LDSTUB])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> %s request made to gasket by LSU while no such request request is pending from this thread.", core_id, thid, addr, req);
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) Issued to gasket. store_data = %0h", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], pcx_pkt[`PCX_DATA]);
ld_pend_array[thid] = tmp;
chk_store_issue_to_pcx(pcx_pkt);
chk_store_issue_to_pcx(pcx_pkt);
default: `PR_INFO("lsu_mon", 21, "<C%h> <T%0h> <%0h>: %s Issued to gasket.", core_id, thid, addr, req);
task Chk_cpx_response_pkt;
thid = cpx_pkt[`CPX_THR_ID];
casex ({cpx_pkt[`CPX_RTNTYP], cpx_pkt[`CPX_ERR], cpx_pkt[`CPX_NC], cpx_pkt[`CPX_ATM], cpx_pkt[`CPX_PF]})
{4'b0, 2'bxx, 1'bx, 1'b0, 1'b0}:
chk_ccx_ld_response(cpx_pkt);
{4'b0, 2'bxx, 1'b1, 1'b0, 1'b1}:
if (pf_cnt[thid] == 8'b0)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Prefetch response received from gasket while the pf_cnt is 0 for this thread.", core_id, thid);
pf_cnt[thid] = pf_cnt[thid] - 1'b1;
`PR_INFO("lsu_mon", 26, "<C%h> <T%0h> Prefetch response received. pfcnt = %0d.", core_id, thid, pf_cnt[thid]);
{4'h8, 2'bxx, 1'b1, 1'b0, 1'b0}:
chk_ccx_ld_response(cpx_pkt);
{4'h4, 2'bxx, 1'bx, 1'b0, 1'b0}:
if (cpx_pkt[123]) //D pkt
if (cpx_pkt[120:118] != core_id)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> D response received from gasket with core_id =%h.", core_id, thid, cpx_pkt[120:118]);
if (dcache_inv_cnt[thid] == 8'b0)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> D response received from gasket while the Dcache_inv_cnt is 0 for this thread.", core_id, thid);
dcache_inv_cnt[thid] = dcache_inv_cnt[thid] - 1'b1;
`PR_INFO("lsu_mon", 26, "<C%h> <T%0h> D response received. Dcache_inv_cnt = %0d.", core_id, thid, dcache_inv_cnt[thid]);
else if (cpx_pkt[124]) //I pkt
if (cpx_pkt[120:118] != core_id)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> I response received from gasket with core_id =%h.", core_id, thid, cpx_pkt[120:118]);
//`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> I pkt.", core_id, thid);
else if (cpx_pkt[124:123] == 2'b0)
if (cpx_pkt[120:118] == core_id)
chk_ccx_st_response(cpx_pkt);
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> Store Ack pkt received from core %0h.", core_id, thid, cpx_pkt[120:118]);
{4'h1, 2'bxx, 1'bx, 1'b0, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> IFILL1 return.", core_id, thid);
{4'h1, 2'bxx, 1'bx, 1'b1, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> IFILL2 return.", core_id, thid);
{4'h9, 2'bxx, 1'b1, 1'b0, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> NCU IFILL return.", core_id, thid);
{4'b0, 2'bxx, 1'b1, 1'b1, 1'b0}:
chk_ccx_atm_response(cpx_pkt);
{4'h4, 2'bxx, 1'b1, 1'b1, 1'b0}:
if ((cpx_pkt[`CPX_RTNTYP] == 4'h4) & (cpx_pkt[120:118] == core_id))
chk_ccx_atm_response(cpx_pkt);
chk_ccx_st_response(cpx_pkt);
{4'h2, 2'bxx, 1'b1, 1'b0, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> Stream Ld return.", core_id, thid);
{4'h6, 2'bxx, 1'bx, 1'bx, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> Stream store Ack.", core_id, thid);
{4'h5, 2'bxx, 1'b1, 1'b0, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> MMU ld return.", core_id, thid);
{4'h7, 2'b00, 1'b0, 1'bx, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> Interrupt return.", core_id, thid);
{4'h3, 2'b00, 1'bx, 1'bx, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> Eviction Invalidation.", core_id, thid);
{4'hc, 2'bxx, 1'bx, 1'bx, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> L2 Indication.", core_id, thid);
{4'hd, 2'bxx, 1'bx, 1'bx, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> Soc Error Indication.", core_id, thid);
`PR_ALWAYS("lsu_mon", `ALWAYS, "CPX_PKT data.");
`PR_ALWAYS("lsu_mon", `ALWAYS, "<C%0h> <T%0h> rtn_typ = %0h, err_bits = %0h, nc=%0b, atm = %0b, pf = %0b", core_id, cpx_pkt[`CPX_THR_ID], cpx_pkt[`CPX_RTNTYP], cpx_pkt[`CPX_ERR], cpx_pkt[`CPX_NC], cpx_pkt[`CPX_ATM], cpx_pkt[`CPX_PF]);
`PR_ERROR("lsu_mon", `ERROR, "<C%0h> <T%0h> Can't recognise the CPX pkt.", core_id, thid);
task chk_ccx_ld_response;
reg [39:0] cpx_pa, inst_pa;
reg [`LD_Pend_Width] tmp;
thid = cpx_pkt[`CPX_THR_ID];
tmp = ld_pend_array[thid];
inst = tmp[`LSU_MON_INST];
inst_pa = tmp[`MEMOP_PA];
pkt_type = cpx_pkt[`CPX_RTNTYP];
`PR_INFO("lsu_mon", 26, "<C%0h> <T%0h> <%0h> %s(VA=%0h) L2 response.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA]);
if (inst_pa[39] != pkt_type[3])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> ccx pkt_type = %h mismatches the ld_pa bit 39. ld_pa = %0h.", core_id, thid, pkt_type, inst_pa);
if (tmp[`L2_RESP] == 4'h0)
tmp[`L2_ERR0] = cpx_pkt[`CPX_ERR];
if ((cpx_pkt[`CPX_ERR] == `ND) || (cpx_pkt[`CPX_ERR] == `UE))
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> UE/ND err on blk ld helper 1.", core_id, thid);
else if (tmp[`L2_RESP] == 4'h1)
tmp[`L2_ERR1] = cpx_pkt[`CPX_ERR];
if ((cpx_pkt[`CPX_ERR] == `ND) || (cpx_pkt[`CPX_ERR] == `UE))
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> UE/ND err on blk ld helper 2.", core_id, thid);
else if (tmp[`L2_RESP] == 4'h3)
tmp[`L2_ERR2] = cpx_pkt[`CPX_ERR];
if ((cpx_pkt[`CPX_ERR] == `ND) || (cpx_pkt[`CPX_ERR] == `UE))
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> UE/ND err on blk ld helper 3.", core_id, thid);
else if (tmp[`L2_RESP] == 4'h7)
tmp[`L2_ERR3] = cpx_pkt[`CPX_ERR];
if ((cpx_pkt[`CPX_ERR] == `ND) || (cpx_pkt[`CPX_ERR] == `UE))
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> UE/ND err on blk ld helper 4.", core_id, thid);
if ((tmp[`L2_ERR0] == `ND) || (tmp[`L2_ERR1] == `ND) || (tmp[`L2_ERR2] == `ND) || (tmp[`L2_ERR3] == `ND))
l2_blk_ld_errtype[thid] = `ND;
else if ((tmp[`L2_ERR0] == `UE) || (tmp[`L2_ERR1] == `UE) || (tmp[`L2_ERR2] == `UE) || (tmp[`L2_ERR3] == `UE))
l2_blk_ld_errtype[thid] = `UE;
else if ((tmp[`L2_ERR0] == `CE) || (tmp[`L2_ERR1] == `CE) || (tmp[`L2_ERR2] == `CE) || (tmp[`L2_ERR3] == `CE))
l2_blk_ld_errtype[thid] = `CE;
l2_blk_ld_errtype[thid] = `NE;
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Illegal value of l2_resp cnt when response pkt received from ccx.", core_id, thid);
else if (Is_single_pcx_req_ld(inst))
if (tmp[`L2_RESP] != 4'hE)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Illegal value of l2_resp cnt when response pkt received from ccx.", core_id, thid);
//`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> Setting L2_resp bits to F.", core_id, thid);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Load response received from gasket for thid %h while no load request pending from core for this thread.", core_id, thid, thid);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Load response received from gasket while no load request pending from core for this thread.", core_id, thid);
ld_pend_array[thid] = tmp;
task chk_ccx_atm_response;
reg [`LD_Pend_Width] tmp;
thid = cpx_pkt[`CPX_THR_ID];
tmp = ld_pend_array[thid];
inst = tmp[`LSU_MON_INST];
inst_pa = tmp[`MEMOP_PA];
if (cpx_pkt[`CPX_RTNTYP] == 4'b0)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Atomic ld response received from gasket while no request pending from core for this thread.", core_id, thid);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Atomic ack response received from gasket while no request pending from core for this thread.", core_id, thid);
if (~inst[`SWAP] && ~inst[`CASA] && ~inst[`LDSTUB])
if (cpx_pkt[`CPX_RTNTYP] == 4'b0)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Atomic ld response received from gasket which mismatches the request pending from this thread.", core_id, thid);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Atomic ack response received from gasket which mismatches the request pending from this thread.", core_id, thid);
if (cpx_pkt[`CPX_RTNTYP] == 4'b0)
`PR_INFO("lsu_mon", 26, "<C%0h> <T%0h> <%0h> %s(VA=%0h) Atomic ld response.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA]);
`PR_INFO("lsu_mon", 26, "<C%0h> <T%0h> <%0h> %s(VA=%0h) Atomic ack.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA]);
if (cpx_pkt[`CPX_RTNTYP] == 4'b0)
if (tmp[`L2_RESP] == 4'hC) tmp[`L2_RESP] = 4'hD;
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Illegal value of l2_resp cnt when atomic ld return pkt received from ccx.", core_id, thid);
if (tmp[`L2_RESP] == 4'hD) tmp[`L2_RESP] = 4'hF;
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Illegal value of l2_resp cnt when atomic ack pkt received from ccx.", core_id, thid);
ld_pend_array[thid] = tmp;
task chk_ccx_st_response;
reg [39:0] cpx_pa, inst_pa;
thid = cpx_pkt[`CPX_THR_ID];
tmp = stb[{thid, ret_ptr[thid]}];
inst = tmp[`LSU_MON_INST];
inst_pa = tmp[`MEMOP_PA];
pkt_type = cpx_pkt[`CPX_RTNTYP];
//is received. There could be some other store sitting in the STB at that time.
//Chk for squash bit only for non-bis responses.
if (cpx_pkt[`CPX_BIS]) //response to rmo store
if (st_rmo_cnt[thid] == 0)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> L2 response received for an rmo store while the st_rmo_cnt for this thread is 0.", core_id, thid);
st_rmo_cnt[thid] = st_rmo_cnt[thid] - 1'b1;
`PR_INFO("lsu_mon", 25, "<C%0h> <T%0h> Store ack received for RMO store. rmo_cnt = %0d", core_id, thid, st_rmo_cnt[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> L2 response received while the SQUASH bit is set in the STB entry %0h.", core_id, thid, ret_ptr[thid]);
if (~stb_valid[{thid, ret_ptr[thid]}])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Store ack received while that entry is invalid in STB.", core_id, thid);
if (~cpx_pkt[`CPX_ATM]) //don't print this message for atomic return
`PR_INFO("lsu_mon", 26, "<C%0h> <T%0h> <%0h> %s(VA=%0h) STB[%0d] Store ack.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA], ret_ptr[thid]);
stb[{thid, ret_ptr[thid]}] = tmp;
ret_ptr[thid] = ret_ptr[thid] + 1'b1;
//`PR_INFO("lsu_mon", 22, "<C%0h> <T%0h> ret_ptr = %0d.", core_id, thid, ret_ptr[thid]);
reg [`LD_Pend_Width] tmp;
reg [39:0] pcx_pa, inst_pa;
thid = pcx_pkt[`PCX_THR_ID];
tmp = ld_pend_array[thid];
inst = tmp[`LSU_MON_INST];
pcx_pa = pcx_pkt[`PCX_ADDR];
inst_pa = tmp[`MEMOP_PA];
req = DispPCXReq(pcx_pkt);
if (pcx_pa[39:6] != inst_pa[39:6])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> A load request made to gasket by LSU while the pending req has PA %0h.", core_id, thid, pcx_pa, tmp[`MEMOP_PA]);
if (tmp[`L2_ISS] != 4'h0 )
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> 1st load request (pa[5:0] = 6'b0) made to gasket by LSU for blkld while this request has already been issued to gasket.", core_id, thid, pcx_pa);
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) 1st blkld helper Issued to gasket.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA]);
if (pcx_pa[5:0] == 6'h10)
if (tmp[`L2_ISS] != 4'h1)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> 2nd load request (pa[5:0] = 6'h10) made to gasket by LSU for blkld while this request has already been issued to gasket.", core_id, thid, pcx_pa);
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) 2nd blkld helper Issued to gasket.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA]);
if (pcx_pa[5:0] == 6'h20)
if (tmp[`L2_ISS] != 4'h3)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> 3rd load request (pa[5:0] = 6'h20) made to gasket by LSU for blkld while this request has already been issued to gasket.", core_id, thid, pcx_pa);
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) 3rd blkld helper Issued to gasket.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA]);
if (pcx_pa[5:0] == 6'h30)
if (tmp[`L2_ISS] != 4'h7)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> 4th load request (pa[5:0] = 6'h30) made to gasket by LSU for blkld while this request has already been issued to gasket.", core_id, thid, pcx_pa);
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) 4th blkld helper Issued to gasket.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA]);
ld_pend_array[thid] = tmp;
else if (Is_single_pcx_req_ld(inst))
if (tmp[`L2_ISS] == 4'hF)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> Load request made to gasket by LSU while this request has already been issued to gasket.", core_id, thid, pcx_pa);
ld_pend_array[thid] = tmp;
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) Issued to gasket.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> A load request made to gasket by LSU while there is no such ld request pending from this thread.", core_id, thid, pcx_pa);
function Is_single_pcx_req_ld;
if (inst[`LDD] || inst[`QLD] || inst[`FSR_RD_WR] || (inst == 21'h1) || (inst == 21'h5))
Is_single_pcx_req_ld = 1'b1;
Is_single_pcx_req_ld = 1'b0;
//`PR_INFO("lsu_mon", 22, "<C%0h> Is_single_pcx_req_ld = %b. ", core_id, Is_single_pcx_req_ld);
case (`SPC4.lsu_trap_flush[7:0])
8'h01: if (tid == 3'h0) Is_trap = 1'b1;
8'h02: if (tid == 3'h1) Is_trap = 1'b1;
8'h04: if (tid == 3'h2) Is_trap = 1'b1;
8'h08: if (tid == 3'h3) Is_trap = 1'b1;
8'h10: if (tid == 3'h4) Is_trap = 1'b1;
8'h20: if (tid == 3'h5) Is_trap = 1'b1;
8'h40: if (tid == 3'h6) Is_trap = 1'b1;
8'h80: if (tid == 3'h7) Is_trap = 1'b1;
function [8*11:0] DispPCXReq;
casex ({pcx_pkt[`PCX_RQTYP], pcx_pkt[`PCX_NC], pcx_pkt[`PCX_INV], pcx_pkt[`PCX_PF], pcx_pkt[`PCX_BIS]})
{5'h0, 1'b1, 1'b0, 1'b1, 1'b0}: DispPCXReq = "PREF";
{5'h0, 1'b1, 1'b1, 1'b1, 1'b0}: DispPCXReq = "PREF_ICE";
{5'h0, 1'bx, 1'b0, 1'b0, 1'b0}: DispPCXReq = "LD";
{5'h0, 1'bx, 1'b1, 1'b0, 1'b0}: DispPCXReq = "D";
{5'h10, 1'bx, 1'b0, 1'b0, 1'b0}: DispPCXReq = "I";
{5'h10, 1'b0, 1'b1, 1'b0, 1'b0}: DispPCXReq = "I";
{5'h1, 1'bX, 1'bX, 1'b0, 1'b0}: DispPCXReq = "ST";
{5'h1, 1'bX, 1'bX, 1'b1, 1'b1}: DispPCXReq = "BLKST";
{5'h1, 1'bX, 1'bX, 1'b0, 1'b1}: DispPCXReq = "BIS";
{5'h2, 1'b1, 1'bX, 1'b0, 1'b0}: DispPCXReq = "CASA1";
{5'h3, 1'b1, 1'bX, 1'b0, 1'b0}: DispPCXReq = "CASA2";
{5'h7, 1'b1, 1'bX, 1'b0, 1'b0}: DispPCXReq = "SWAP_LDSTUB";
{5'h4, 1'b1, 1'b0, 1'b0, 1'b0}: DispPCXReq = "STREAM_LD";
{5'h5, 1'b1, 1'b0, 1'b0, 1'bx}: DispPCXReq = "STREAM_ST";
{5'h8, 1'b1, 1'b0, 1'b0, 1'b0}: DispPCXReq = "MMU_LD";
//{5'h9, 1'b0, 1'b0, 1'b0, 1'b0}: DispPCXReq = "INT";
`PR_ERROR("lsu_mon", `ERROR, "<C%0h> <T%0h> <%0h> Can't recognise the PCX pkt type. rq_type = %h, nc_bit = %0b, inv_bit = %0b, pf_bit = %0b, bis_bit = %0b. pcx_pkt[129:0] = %h", core_id, pcx_pkt[`PCX_THR_ID], pcx_pkt[`PCX_ADDR], pcx_pkt[`PCX_RQTYP], pcx_pkt[`PCX_NC], pcx_pkt[`PCX_INV], pcx_pkt[`PCX_PF], pcx_pkt[`PCX_BIS], pcx_pkt);
if (`SPC4.lsu_align_b) DispExc = "Addr_not_aligned";
if (`SPC4.lsu_lddf_align_b) DispExc = "LDDF_Addr_not_aligned";
if (`SPC4.lsu_stdf_align_b) DispExc = "STDF_Addr_not_aligned";
if (`SPC4.lsu_priv_action_b) DispExc = "Priv_actio";
if (`SPC4.lsu_va_watchpoint_b) DispExc = "VA_watchpoint";
if (`SPC4.lsu_pa_watchpoint_b) DispExc = "PA_watchpoint";
//if (`SPC4.lsu_tlb_miss_b_) DispExc = "Tlb_miss";
if (`SPC4.lsu_illegal_inst_b) DispExc = "Illegal_inst";
if (`SPC4.lsu_daccess_prot_b) DispExc = "Data_access_prot_exc";
if (`SPC4.lsu_dae_invalid_asi_b) DispExc = "Dae_Invalid_asi";
if (`SPC4.lsu_dae_nc_page_b) DispExc = "Dae_nc_page";
if (`SPC4.lsu_dae_nfo_page_b) DispExc = "Dae_NFO_page";
if (`SPC4.lsu_dae_priv_viol_b) DispExc = "Dae_Priv_viol";
if (`SPC4.lsu_dae_so_page) DispExc = "Dae_so_page";
//if (`SPC4.lsu_perfmon_trap_b) DispExc = "Perf_mon_trap";
if (`SPC4.lsu_dtmh_err_b) DispExc = "DTLB_data_par_err";
if (`SPC4.lsu_dttp_err_b) DispExc = "DTLB_tag_par_err";
if (`SPC4.lsu_dtdp_err_b) DispExc = "DTLB_data_par_err";
`PR_INFO("lsu_mon", 23, "<C%0h> <T%0h> <%0h> B_stage: %s(VA=%0h) ASI = %0h. %s Exception.",core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b, asi_b, DispExc);
input [1:0] exu_lsu_va_error_b; // VA error requiring a flush
input [1:0] exu_ecc_b; // ECC error requiring a flush
err_b = dec_lsu_tid_b[2] ? (exu_ecc_b[1] | (exu_lsu_va_error_b[1] & ~`SPC4.lsu_tlb_bypass_b)):
(exu_ecc_b[0] | (exu_lsu_va_error_b[0] & ~`SPC4.lsu_tlb_bypass_b));
err_m = (dec_lsu_tid_b[2] ? `SPC4.exu_ecc_m[1] : `SPC4.exu_ecc_m[0]) & `SPC4.lsu.dcc.twocycle_b;
Is_exu_error = err_b | err_m;
task Insert_tlb_miss_info;
if (tlb_valid[dec_lsu_tid_b])
tmp = tlbmiss_pend_array[dec_lsu_tid_b];
Disp_tlbmiss_pend_array_entry(dec_lsu_tid_b);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <%0h> B_stage: %s(VA=%0h>) A new tlb miss request received while there is already a Tlb miss request pending from this thread as shown above.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b);
tlb_valid[dec_lsu_tid_b] <= 1'b1;
tmp[`INST_VA] = inst_pc_b;
tmp[`MEMOP_VA] = vaddr_b;
tlbmiss_pend_array[dec_lsu_tid_b] = tmp;
//problem with the signal.
always @ (negedge `SPC4.l2clk)
if (`SPC4.tlu_trap_pc_0_valid)
thid = {1'b0, `SPC4.tlu_trap_0_tid};
else if (`SPC4.tlu_trap_pc_1_valid)
thid = {1'b0, `SPC4.tlu_trap_1_tid};
`PR_ERROR("lsu_mon", `ERROR, "<C%h> mmu_dtlb_reload asserted but trap_pc_0_valid and trap_pc_1_valid are both 0", core_id);
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> mmu_dtlb_reload asserted while tlb_valid is 0.", core_id, thid);
tmp = tlbmiss_pend_array[dec_lsu_tid_b];
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> %s(VA=%0h> DTLB reloaded for VA = %0h.", core_id, thid, tb_top.intf0.xlate(tmp[`INST]), tmp[`INST_VA], tmp[`MEMOP_VA] );
task Insert_ld_miss_info;
reg [`LD_Pend_Width] tmp;
if (ld_valid[dec_lsu_tid_b])
tmp = ld_pend_array[dec_lsu_tid_b];
DispPendReq(dec_lsu_tid_b);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <%0h> B_stage: %s(VA=%0h>) A new request received while there is already a request pending from this thread as shown above.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b);
//ld_valid[dec_lsu_tid_b] <= 1'b1;
tmp[`INST_VA] = inst_pc_b;
tmp[`MEMOP_VA] = vaddr_b;
tmp[`MEMOP_PA] = {`SPC4.lsu.tlb_pgnum[39:13], vaddr_b[12:0]};
is_blkld[dec_lsu_tid_b] = 1'b1;
is_blkld[dec_lsu_tid_b] = 1'b0;
if (lsu_inst_b[`SWAP] || lsu_inst_b[`LDSTUB] || lsu_inst_b[`CASA])
tmp[`LSU_MON_INST] = lsu_inst_b;
ld_pend_array[dec_lsu_tid_b] = tmp;
task Insert_in_last_inst_array;
tmp[`INST_VA] = inst_pc_b;
tmp[`MEMOP_VA] = vaddr_b;
last_inst_array[dec_lsu_tid_b] = tmp;
reg [`LD_Pend_Width] tmp;
tmp = ld_pend_array[thid];
`PR_ALWAYS("lsu_mon", `ALWAYS, "LD_PEND_ARRAY[%0h] Data.", thid);
`PR_ALWAYS("lsu_mon", `ALWAYS, "<C%h> <T%0h> <%0h> %s(VA=%0h). PA = %0h. L2_ISS = %0h. L2_RESP = %0h, LSU_MON_INST=%h.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA], tmp[`MEMOP_PA], tmp[`L2_ISS], tmp[`L2_RESP], tmp[`LSU_MON_INST]);
`PR_ALWAYS("lsu_mon", `ALWAYS, "<C%h> <T%0h> STB[%0h] data.", core_id, thid, ptr);
`PR_ALWAYS("lsu_mon", `ALWAYS, "<C%h> <T%0h> <%0h> %s(VA=%0h). PA = %0h. L2_ISS = %0h. L2_ACK = %0h, LSU_MON_INST=%h. RMO = %0b", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA], tmp[`MEMOP_PA], tmp[`L2_ST_ISS], tmp[`L2_ACK], tmp[`LSU_MON_INST], tmp[`RMO]);
task Disp_tlbmiss_pend_array_entry;
tmp = tlbmiss_pend_array[thid];
`PR_INFO("lsu_mon", 23, "TLB_MISS_PEND_ARRAY[%0h] Data.", thid);
`PR_INFO("lsu_mon", 23, "<C%h> <T%0h> <%0h> %s(VA=%0h).", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA]);
`PR_ALWAYS("lsu_mon", `ALWAYS, "CPX_PKT data.");
`PR_ALWAYS("lsu_mon", `ALWAYS, "<C%0h> <T%0h> rtn_typ = %0h, err_bits = %0h, nc=%0b, atm = %0b, pf = %0b", core_id, cpx_pkt[`CPX_THR_ID], cpx_pkt[`CPX_RTNTYP], cpx_pkt[`CPX_ERR], cpx_pkt[`CPX_NC], cpx_pkt[`CPX_ATM], cpx_pkt[`CPX_PF]);
tmp[`INST_VA] = inst_pc_b;
tmp[`MEMOP_VA] = vaddr_b;
tmp[`MEMOP_PA] = {`SPC4.lsu.tlb_pgnum[39:13], vaddr_b[12:0]};
tmp[`LSU_MON_INST] = lsu_inst_b;
if (`SPC4.lsu.tlu_lsu_hpstate_hpriv[dec_lsu_tid_b])
else if (`SPC4.lsu.tlu_lsu_pstate_priv[dec_lsu_tid_b])
//bis_asi to io space is not rmo
tmp[`RMO] = lsu_inst_b[`BLKST] | (dec_altspace_b & Is_bis_asi(asi_b) & ~`SPC4.lsu.tlb_pgnum[39]);
input [195:0] store_data;
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> STB full and a new store received for insertion in STB.", core_id, thid);
stb[{thid, wrptr[thid]}] = store_data;
//Disp_STB_entry(thid, wrptr[thid]);
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> <%0h> %s(VA=%0h). STB[%0h] Inserted.", core_id, thid, store_data[`INST_VA], tb_top.intf0.xlate(store_data[`INST]), store_data[`MEMOP_VA], wrptr[thid]);
stb_valid[{thid, wrptr[thid]}] = 1'b1;
wrptr[thid] = wrptr[thid] + 1'b1;
//`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> wrptr = %0d.", core_id, thid, wrptr[thid]);
if ((wrptr[thid] == rdptr[thid]) && stb_valid[{thid, wrptr[thid]}])
//thid = decode_tid(`SPC4.lsu_stb_dealloc);
tmp = stb[{thid, rdptr[thid]}];
lsu_inst = tmp[`LSU_MON_INST];
if (~stb_valid[{thid, rdptr[thid]}])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> lsu_stb_dealloc = %0h asserted while the stb entry is invalid for that thid.", core_id, thid, `SPC4.lsu_stb_dealloc);
Disp_STB_entry(thid, rdptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> lsu_stb_dealloc = %0h asserted when we haven't received the response from the gasket.", core_id, thid, `SPC4.lsu_stb_dealloc);
else if (tmp[`ASI_ST_ISS])
ret_ptr[thid] = ret_ptr[thid] + 1'b1;
//blkst inst. is not issued anywhere, blkst helpers are issued.
//in case of bis stores, lsu issues the dealloc in P3, i.e when the req is issued to PCX.
//IF it is bis to cp sapce and there is an err then the store is issued to PCX with nd set
//However for ue onbis to IO space, dealloc is sent to IFU, issued on PCX with valid bit 0.
//The sbdiou signal is sent in next cycle. We need to take bis io stores in this equation.
else if (tmp[`ST_SQUASH] || lsu_inst[`BLKST] || (tmp[`RMO] & ~lsu_inst[`BLKST] & ~`SPC0.lsu.sbc.kill_store_p4_))
iss_ptr[thid] = iss_ptr[thid] + 1'b1;
ret_ptr[thid] = ret_ptr[thid] + 1'b1;
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> lsu_stb_dealloc = %0h asserted which is not issued to asi ring, or PCX or is not squashed.", core_id, thid, `SPC4.lsu_stb_dealloc);
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> <%0h>: %s(VA=%0h) PA = %0h. STB[%0d] Deallocated.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], tmp[`MEMOP_PA], rdptr[thid]);
stb_valid[{thid, rdptr[thid]}] = 1'b0;
rdptr[thid] = rdptr[thid] + 1'b1;
//`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> rd_ptr = %0d.", core_id, thid, rdptr[thid]);
st_rmo_cnt[thid] = st_rmo_cnt[thid] + 1'b1;
if (ret_ptr[thid] != iss_ptr[thid])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> lsu_block_store_kill asserted while the ret_ptr = %0h != iss_ptr = %0h.", core_id, thid, tmp[`MEMOP_PA], ret_ptr[thid], iss_ptr[thid]);
if (rdptr[thid] != iss_ptr[thid])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> lsu_block_store_kill asserted while the rdptr = %0h != iss_ptr = %0h.", core_id, thid, tmp[`MEMOP_PA], rdptr[thid], iss_ptr[thid]);
if (iss_ptr[thid] == wrptr[thid])
if (stb_valid[{thid, wrptr[thid]}])
/* Lsu can assert both dealloc and block_store_kill for a request.
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Lsu asserted block_store_kill while there are no valid entries in STB to be deallocated.", core_id, thid);
if (iss_ptr[thid] < wrptr[thid])
squash_cnt = wrptr[thid] - iss_ptr[thid];
else if (iss_ptr[thid] > wrptr[thid])
squash_cnt = wrptr[thid] + (8 - iss_ptr[thid]);
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> SQUASH_STB:iss_ptr = %0h, wrptr = %0h, squash_cnt = %0h.", core_id, thid, iss_ptr[thid], wrptr[thid], squash_cnt);
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> Block store kill changed issue_ptr:%0h->%0h. ret_ptr: %0h->%0h. rdptr:%0h->%0h.", core_id, thid, iss_ptr[thid], iss_ptr[thid]+squash_cnt, ret_ptr[thid], ret_ptr[thid]+squash_cnt, rdptr[thid], rdptr[thid]+squash_cnt);
ret_ptr[thid] = ret_ptr[thid] + squash_cnt;
rdptr[thid] = rdptr[thid] + squash_cnt;
iss_ptr[thid] = iss_ptr[thid] + squash_cnt;
if (~stb_valid[{thid, i}])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h><PA = %0h> lsu_block_store_kill asserted while the stb entry %0h is invalid.", core_id, thid, tmp[`MEMOP_PA], i);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h>st_issue bit is set when the block_store_kill is asserted for stb entry %0h.", core_id, thid, tmp[`MEMOP_PA], i);
//commenting out the chk below. Lsu can assert sbdiou and then in the next cycle insert a new entry into
//stb. LSU will squash this new entry and won't issue it to PCX/asi but its squash bit won't be
//set in the chkr which was causin it to fire.
//`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> lsu_block_store_kill asserted while the squash bit is 0 in the STB entry %0h.", core_id, thid, tmp[`MEMOP_PA], i);
stb_valid[{thid, i}] = 1'b0;
squash_cnt = squash_cnt - 1'b1;
if ((bst_cnt > 0) && (`SPC4.lsu_stb_alloc == 8'b0))
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Blk store entries are not allocated back to back in STB.", core_id, bst_active_thid);
//For bst the stb is still written even though we have errors.
//Stb is written in W stage. Howvere for first blk store helper
//the err will be flagged by FGU in b stage. We can miss the
// err signal if we don't sample in B.
//for the last helper err will be signalled in B stage of last helper and at
if (lsu_bst_active[bst_active_thid] & `SPC0.fgu_fst_ecc_error_fx2 & (bst_cnt < 7))
if (`SPC4.lsu_stb_alloc[7:0] != 8'b0)
thid = decode_tid(`SPC4.lsu_stb_alloc[7:0]);
if (thid != dec_lsu_tid_w)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> lsu_stb_alloc = %0h mismatches the thid %0h.", core_id, dec_lsu_tid_w, `SPC4.lsu_stb_alloc[7:0], dec_lsu_tid_w);
Insert_in_STB(stb_alloc_data, dec_lsu_tid_w);
if (lsu_bst_active[thid])
bst_data = bst_inst_data;
if (thid != bst_active_thid)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> lsu_stb_alloc = %0h mismatches the active blkstore thid = %0h.", core_id, bst_active_thid, `SPC4.lsu_stb_alloc[7:0], bst_active_thid);
addr = bst_data[`MEMOP_VA];
bst_data[`MEMOP_VA] = {addr[47:6], bst_cnt[2:0], 3'b0};
addr = bst_data[`MEMOP_PA];
bst_data[`MEMOP_PA] = {addr[39:6], bst_cnt[2:0], 3'b0};
Insert_in_STB(bst_data, bst_active_thid);
lsu_bst_active[thid] = 1'b0;
if (bst_fgu_err) //set the squash bit to 0 for all the stb entries
for (i = 0; i < 8; i=i+1)
tmp = stb[{thid, i[2:0]}];
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> Squash bit already set when trying to set it for a bst fgu errerr.", core_id, thid, tmp[`MEMOP_PA]);
stb[{thid, i[2:0]}] = tmp;
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> <PA = %0h> STB_entry[%0h] squashed due to FGU err.", core_id, thid, tmp[`MEMOP_PA], i);
`PR_ERROR("lsu_mon", `ERROR, "<C%h>: LSU asserted lsu_stb_alloc = %0h while no store pending to be written in STB.", core_id, `SPC4.lsu_stb_alloc[7:0]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <%0h> W_stage: LSU did not assert lsu_stb_alloc for the store.", core_id, dec_lsu_tid_w, inst_pc_w);
reg [47:0] addr, act_addr;
thid =`SPC4.lsu_rngl_cdbus[58:56];
thid =`SPC4.lsu_rngf_cdbus[58:56];
asi =`SPC4.lsu_rngl_cdbus[55:48];
asi =`SPC4.lsu_rngf_cdbus[55:48];
addr =`SPC4.lsu_rngl_cdbus[47:0];
addr =`SPC4.lsu_rngf_cdbus[47:0];
req_type =`SPC4.lsu_rngl_cdbus[61:60];
req_type =`SPC4.lsu_rngf_cdbus[61:60];
tmp = stb[{thid, iss_ptr[thid]}];
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> Store reissued on the ASI interface.", core_id, thid, addr);
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> Store issued on the ASI interface that has been squashed.", core_id, thid, addr);
act_addr = tmp[`MEMOP_PA];
act_addr = {act_addr[39:3], 3'b0};
//47 is D tag rd asi. LSU issues that on the ring but changes
if ((addr == act_addr) || (asi == 8'h47) || (asi == 8'h46))
stb[{thid, iss_ptr[thid]}] = tmp;
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) STB[%0d] Issued on local ring.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], iss_ptr[thid]);
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) STB[%0d] Issued on fast ring.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], iss_ptr[thid]);
iss_ptr[thid] = iss_ptr[thid] + 1'b1;
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <%0h>: %s(VA=%0h) STB[%0d] PA mismatch for asi req on local ring. Expected PA = %0h, actual PA = %0h", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], iss_ptr[thid], tmp[`MEMOP_PA], addr);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <%0h>: %s(VA=%0h) STB[%0d] PA mismatch for asi req on fast ring. Expected PA = %0h, actual PA = %0h", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], iss_ptr[thid], tmp[`MEMOP_PA], addr);
task chk_store_issue_to_pcx;
reg [39:0] pcx_pa, inst_pa;
thid = pcx_pkt[`PCX_THR_ID];
tmp = stb[{thid, iss_ptr[thid]}];
inst = tmp[`LSU_MON_INST];
pcx_pa = pcx_pkt[`PCX_ADDR];
inst_pa = tmp[`MEMOP_PA];
if (pcx_pkt[`PCX_RQTYP] == `PCX_STORE)
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) STB[%0d] Issued to gasket.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], iss_ptr[thid]);
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) STB[%0d] Issued to gasket with ND set.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], iss_ptr[thid]);
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> A store request made to gasket by LSU while the pending req is not store.", core_id, thid, pcx_pkt[`PCX_ADDR]);
if (pcx_pa[39:0] != inst_pa[39:0])
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> A store request made to gasket by LSU while the pending req has PA %0h.", core_id, thid, pcx_pkt[`PCX_ADDR], tmp[`MEMOP_PA]);
if ((tmp[`INST_ASI] == 8'h73) & (pcx_pa[39:0] != {8'h90, core_id, thid, tmp[`INST_ASI], 18'h0}))
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> pcx_pa is not correct for asi write to interrupt vector dispatch register.", core_id, thid, pcx_pkt[`PCX_ADDR]);
if (inst[`BLKST] && ~pcx_pkt[`PCX_BST])
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> Bst bit is not set in the PCX pkt by LSU for a blk st request.", core_id, thid, pcx_pkt[`PCX_ADDR]);
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> Store reissued on the PCX interface.", core_id, thid, pcx_pkt[`PCX_ADDR]);
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> Store issued on the PCX interface that has been squashed.", core_id, thid, pcx_pkt[`PCX_ADDR]);
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> BIS bit is not set in the PCX pkt by LSU for an RMO store.", core_id, thid, pcx_pkt[`PCX_ADDR]);
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> L2ack bit is set when the RMO store is issued to PCX.", core_id, thid, pcx_pkt[`PCX_ADDR]);
ret_ptr[thid] = ret_ptr[thid] + 1; //this will be deallocated before
//response seen from stub
st_rmo_cnt[thid] = st_rmo_cnt[thid] + 1'b1;
stb[{thid, iss_ptr[thid]}] = tmp;
iss_ptr[thid] = iss_ptr[thid] + 1;
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> iss_ptr = %0d. ret_ptr = %0d, st_rmo_cnt = %0d", core_id, thid, iss_ptr[thid], ret_ptr[thid], st_rmo_cnt[thid]);
`ifdef INJ_STB_ERR_IN_CMP
reg [2:0] err_tid, stb_err_tid_d1, stb_err_tid_d2;
reg [2:0] err_index, stb_err_index_d1, stb_err_index_d2;
reg stb_err_inj, stb_err_inj_d1, stb_err_inj_d2;
reg [1:0] err_priv, stb_err_priv_d1, stb_err_priv_d2;
if (("cmp_stb_err_inj_on"))
always @ (negedge (`SPC4.l2clk & enabled & cmp_stb_err_inj))
//valid stb ram rd for issue to pcx
if (`SPC4.lsu.sbc.ram_rptr_vld_2 & `SPC4.lsu.sbc.st_pcx_rq_p3 & `SPC4.lsu.pic.pic_st_sel_p3)
err_tid = decode_tid(`SPC4.lsu.sbc.st_rq_sel_p3[7:0]);
err_index = `SPC4.lsu.sbc.ram_rptr_d1;
err_tmp = stb[{err_tid, err_index}];
err_inst = err_tmp[`LSU_MON_INST];
cam_data = `SPC4.lsu.stb_cam.cam_array.stb_rdata[44:0];
err_priv = err_tmp[`ST_PRIV];
//if (err_inst[`SWAP] || err_inst[`CASA] || err_inst[`LDSTUB])
err_inj_cnt = err_inj_cnt + 1;
11, 12: err_bit = err_bit + 1;
force `SPC0.lsu.stb_cam.cam_array.stb_rdata[44:0] = cam_data ^ (1 << err_bit);
`PR_INFO("stb_err", 22, "<T%0h> <%0h> STB[%0h]: SBAPP forced for CASA. err_bit = %0h", err_tid, {cam_data[44:8], 3'b0}, err_index, err_bit);
release `SPC0.lsu.stb_cam.cam_array.stb_rdata[44:0];
if (~`SPC4.lsu_sbapp_err_g)
`PR_ERROR("lsu_mon", `ERROR, "<T%0h> sbapp err not asserted when err is injected for atomic.", stb_err_tid_d2);
if ((`SPC4.lsu_stberr_tid_g != stb_err_tid_d2) ||
(`SPC4.lsu_stberr_index_g != stb_err_index_d2) ||
(`SPC4.lsu_stberr_priv_g != stb_err_priv_d2))
`PR_ERROR("lsu_mon", `ERROR, "<T%0h> sbapp err parameters mismatch.", stb_err_tid_d2);
if (`SPC4.lsu_sbapp_err_g)
`PR_ERROR("lsu_mon", `ERROR, "<T%0h> sbapp err asserted when none expected.", `SPC4.lsu_stberr_tid_g);
always @ (posedge (`SPC4.l2clk & enabled & cmp_stb_err_inj))
stb_err_inj_d1 <= stb_err_inj;
stb_err_inj_d2 <= stb_err_inj_d1;
stb_err_tid_d1 <= err_tid;
stb_err_tid_d2 <= stb_err_tid_d1;
stb_err_index_d1 <= err_index;
stb_err_index_d2 <= stb_err_index_d1;
stb_err_priv_d1 <= err_priv;
stb_err_priv_d2 <= stb_err_priv_d1;
// If vcs_build_args NO_MONITORS, then module will be empty
reg [7:0] asi_e, imm_asi_e, asi_m, asi_b;
reg dec_altspace_e, dec_altspace_b, dec_altspace_m;
reg [1:0] exu_lsu_va_error_b;
reg [2:0] dec_lsu_tid_e, dec_lsu_tid_m, dec_lsu_tid_b, dec_lsu_tid_w;
reg [47:0] inst_pc_e, inst_pc_m, inst_pc_b, inst_pc_w;
reg [31:0] inst_e, inst_m, inst_b;
reg [47:0] vaddr_m, vaddr_b;
reg [63:0] int_st_data_m, int_st_data_b;
reg [63:0] fp_st_sata_fx2;
reg [20:0] lsu_inst_e, lsu_inst_m, lsu_inst_b;
reg mmu_dtlb_reload_d1, mmu_dtlb_reload_d2;
reg [`LD_Pend_Width] ld_pend_array[7:0];
reg [`LAST_INST_Pend_Width] last_inst_array[7:0];
reg [2:0] wrptr[7:0]; //Pts. to the STB entry into which data will be written next
reg [2:0] rdptr[7:0]; //Tracks the dealloc signal from STB
reg [2:0] iss_ptr[7:0]; //keeps track of when a store is issued from the STB to PCX
reg [2:0] ret_ptr[7:0]; //keeps track of when the response is received from
reg [`STB_Pend_Width] stb[63:0];
//reg [`TLB_MISS_Pend_Width] tlbmiss_pend_array[7:0];
reg [7:0] dcache_inv_cnt[7:0];
reg [7:0] st_rmo_cnt[7:0];
reg [31:0] dec_tg0_inst_d, dec_tg1_inst_d;
reg [7:0] lsu_bst_active;
reg [195:0] stb_alloc_data;
reg [195:0] bst_data, bst_inst_data;
reg [2:0] bst_active_thid;
reg [7:0] is_blkld; //reqd by lsu_ras_chkr to chk errors on blk ld.
reg [1:0] l2_blk_ld_errtype[7:0]; //Gives the type of err the ahd be reported by LSU if
//different types of err occur on blk ld helper returns
reg [1:0] st_priv[7:0]; //Gives the final priv level for an sbdiou/sbapp err that shd be
for (i = 0; i < 8; i = i+1)
l2_blk_ld_errtype[i] = 2'b0;
// avoid time zero ugliness. jp
//@(posedge `SPC0.l2clk);
//@(negedge `SPC0.l2clk);
//if (`PARGS.lsu_mon_on) enabled = 1;
3'h0: finish_mask = `PARGS.finish_mask[7:0];
3'h1: finish_mask = `PARGS.finish_mask[15:8];
3'h2: finish_mask = `PARGS.finish_mask[23:16];
3'h3: finish_mask = `PARGS.finish_mask[31:24];
3'h4: finish_mask = `PARGS.finish_mask[39:32];
3'h5: finish_mask = `PARGS.finish_mask[47:40];
3'h6: finish_mask = `PARGS.finish_mask[55:48];
3'h7: finish_mask = `PARGS.finish_mask[63:56];
if (~`TOP.in_reset & `PARGS.lsu_mon_on & ~reset_in_middle)
`PR_ALWAYS("lsu_mon", `ALWAYS, "Lsu_mon on, in_reset = 0.");
if (`TOP.in_reset & enabled)
`PR_ALWAYS("lsu_mon", `ALWAYS, "Reset asserted in the middle of the diag. Turned off Lsu_mon.");
always @ (posedge (tb_top.sim_status[0] & enabled))
if (|(ld_valid[7:0] & finish_mask[7:0]))
for (i = 0; i < 8; i=i+1)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> Ld requests pending at the end of simulation. ld_valid = %0h", core_id, ld_valid);
for (i = 0; i < 64; i=i+1)
if (stb_valid[i] & finish_mask[i[5:3]])
//chkr resets the stb valid bits when block_store_kill is asserted.
//in couple of failures block_store_kill was sampled asserted two cycles after
//lsu asserted stb_empty. The simulation ended the cycle stb_empty was sampled high
//causing moniotr firings with valid entries in stb at end of simulation. Now
//don't flag an error if squash bit is set and stb_valid is asserted at end
if (~is_squash_bit_set(i[5:0]))
Disp_STB_entry(i[5:3],i[2:0]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> Store requests pending at the end of simulation. stb_valid = %0h", core_id, stb_valid);
for (i = 0; i < 8; i=i+1)
if (finish_mask[i] & (pf_cnt[i] != 0))
`PR_ALWAYS("lsu_mon", `ALWAYS, "<C%h> <T%0h> Prefetches not finished. Pf_cnt = %0d", core_id, i, pf_cnt[i]);
if (finish_mask[i] & (dcache_inv_cnt[i] != 0))
`PR_ALWAYS("lsu_mon", `ALWAYS, "<C%h> <T%0h> D pkt not received for all invalidate reqs. issued by the thread. dcache_inv_cnt = %0d", core_id, i, dcache_inv_cnt[i]);
if (finish_mask[i] & (st_rmo_cnt[i] != 0))
`PR_ALWAYS("lsu_mon", `ALWAYS, "<C%h> <T%0h> rmo_cnt not zero. rmo_cnt = %0d", core_id, i, st_rmo_cnt[i]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> Prefetch/D/RMO_stores requests pending at the end of simulation.", core_id);
function is_squash_bit_set;
is_squash_bit_set = 1'b1;
is_squash_bit_set = 1'b0;
always @ (negedge (`SPC5.l2clk & enabled))
asi_e = `SPC5.lsu.dcc.dcc_asi_e[7:0];
lsu_inst_e[`LD] <= `SPC5.dec_ld_inst_e;
lsu_inst_e[`ST] <= `SPC5.dec_st_inst_e;
lsu_inst_e[`FP] <= `SPC5.dec_fpldst_inst_e;
lsu_inst_e[`PREF] <= `SPC5.dec_pref_inst_e;
lsu_inst_e[`SWAP] <= `SPC5.dec_swap_inst_e;
lsu_inst_e[`CASA] <= `SPC5.dec_casa_inst_e;
lsu_inst_e[`LDSTUB] <= `SPC5.dec_ldstub_inst_e;
lsu_inst_e[`FLUSH] <= `SPC5.dec_flush_inst_e;
lsu_inst_e[`MEMBAR] <= `SPC5.dec_memstbar_inst_e;
lsu_inst_e[`LDD] <= `SPC5.dec_ld_inst_e & `SPC5.dec_ldst_dbl_e & ~`SPC5.dec_fpldst_inst_e;
lsu_inst_e[`STD] <= `SPC5.dec_st_inst_e & `SPC5.dec_ldst_dbl_e & ~`SPC5.lsu.dec_fpldst_inst_e;
lsu_inst_e[`BLKLD] <= `SPC5.dec_ld_inst_e & `SPC5.dec_fpldst_inst_e & dec_altspace_e & Is_blk_asi(asi_e);
lsu_inst_e[`BLKST] <= `SPC5.dec_st_inst_e & `SPC5.dec_fpldst_inst_e & dec_altspace_e & Is_blk_asi(asi_e);
lsu_inst_e[`QLD] <= `SPC5.dec_ld_inst_e & dec_altspace_e & Is_qld_asi(asi_e);
lsu_inst_e[`ASR_RD_WR] <= `SPC5.dec_sr_inst_e & (`SPC5.dec_ld_inst_e | `SPC5.dec_st_inst_e);
lsu_inst_e[`PR_RD_WR] <= `SPC5.dec_pr_inst_e & (`SPC5.dec_ld_inst_e | `SPC5.dec_st_inst_e);
lsu_inst_e[`HPR_RD_WR] <= `SPC5.dec_hpr_inst_e & (`SPC5.dec_ld_inst_e | `SPC5.dec_st_inst_e);
lsu_inst_e[`FSR_RD_WR] <= `SPC5.dec_fsr_ldst_e & (`SPC5.dec_ld_inst_e | `SPC5.dec_st_inst_e);
always @ (posedge (`SPC5.l2clk & enabled))
dec_tg0_inst_d <= `SPC5.dec.ded0.decode_mux[31:0];
dec_tg1_inst_d <= `SPC5.dec.ded1.decode_mux[31:0];
imm_asi_vld_e <= `SPC5.lsu.dec_imm_asi_vld_d;
imm_asi_e <= `SPC5.lsu.dec_imm_asi_d;
dec_altspace_e <= `SPC5.dec_altspace_d;
dec_altspace_m <= dec_altspace_e;
dec_altspace_b <= dec_altspace_m;
exu_ecc_b <= `SPC5.exu_ecc_m;
exu_lsu_va_error_b <= `SPC5.exu_lsu_va_error_m;
dec_lsu_tid_e <= `SPC5.dec_lsu_tg_d ? {1'b1, `SPC5.dec_lsu_tid1_d} : {1'b0, `SPC5.dec_lsu_tid0_d};
dec_lsu_tid_m <= dec_lsu_tid_e;
dec_lsu_tid_b <= dec_lsu_tid_m;
dec_lsu_tid_w <= dec_lsu_tid_b;
inst_pc_e <= `SPC5.dec_lsu_tg_d ? {`SPC5.tlu.tlu_pc_1_d[47:2], 2'b0} : {`SPC5.tlu.tlu_pc_0_d[47:2], 2'b0};
inst_e <= `SPC5.dec_lsu_tg_d ? dec_tg1_inst_d : dec_tg0_inst_d;
vaddr_m <= `SPC5.exu_lsu_address_e;
int_st_data_m <= `SPC5.exu_lsu_store_data_e;
int_st_data_b <= int_st_data_m;
fp_st_sata_fx2 <= `SPC5.fgu_lsu_fst_data_fx1;
mmu_dtlb_reload_d1 <= `SPC5.mmu_dtlb_reload;
mmu_dtlb_reload_d2 <= mmu_dtlb_reload_d1;
//pcx_thid_d1 <= `SPC5.lsu.spc_pcx_data_pa[`PCX_THR_ID];
lsu_inst_m <= lsu_inst_e;
lsu_inst_b <= lsu_inst_m;
Is_blk_asi = (asi == `ASI_BLK_AIUP) | (asi == `ASI_BLK_AIUS) |
(asi == `ASI_BLK_AIUPL) | (asi == `ASI_BLK_AIUSL) |
(asi == `ASI_BLK_P) | (asi == `ASI_BLK_S) |
(asi == `ASI_BLK_PL) | (asi == `ASI_BLK_SL) |
(asi == `ASI_BLK_COMMIT_P) | (asi == `ASI_BLK_COMMIT_S);
Is_qld_asi = (asi == `ASI_AIU_BIS_QUAD_LDD_P) | (asi == `ASI_AIU_BIS_QUAD_LDD_S) |
(asi == `ASI_AIU_BIS_QUAD_LDD_P_LITTLE) | (asi == `ASI_AIU_BIS_QUAD_LDD_S_LITTLE) |
(asi == `ASI_NUCLEUS_BIS_QUAD_LDD) | (asi == `ASI_NUCLEUS_BIS_QUAD_LDD_LITTLE) |
(asi == `ASI_BIS_QUAD_LDD_P) | (asi == `ASI_BIS_QUAD_LDD_S) |
(asi == `ASI_BIS_QUAD_LDD_P_LITTLE) | (asi == `ASI_BIS_QUAD_LDD_S_LITTLE) |
(asi == `ASI_QUAD_LDD) | (asi == `ASI_QUAD_LDD_REAL) |
(asi == `ASI_QUAD_LDD_L) | (asi == `ASI_QUAD_LDD_REAL_L);
Is_bis_asi = (asi == `ASI_AIU_BIS_QUAD_LDD_P) | (asi == `ASI_AIU_BIS_QUAD_LDD_S) |
(asi == `ASI_AIU_BIS_QUAD_LDD_P_LITTLE) | (asi == `ASI_AIU_BIS_QUAD_LDD_S_LITTLE) |
(asi == `ASI_NUCLEUS_BIS_QUAD_LDD) | (asi == `ASI_NUCLEUS_BIS_QUAD_LDD_LITTLE) |
(asi == `ASI_BIS_QUAD_LDD_P) | (asi == `ASI_BIS_QUAD_LDD_S) |
(asi == `ASI_BIS_QUAD_LDD_P_LITTLE) | (asi == `ASI_BIS_QUAD_LDD_S_LITTLE);
always @ (negedge (`SPC5.l2clk & enabled))
`PR_INFO("lsu_mon", 21, "<C%0h> <T%0h> <%0h> M_stage: %s(VA=%0h) Flushed due to IFU Flush.", core_id, dec_lsu_tid_m, inst_pc_m, tb_top.intf0.xlate(inst_m),vaddr_m);
if (lsu_inst_b[`BLKLD]) print_inst = " BLKLD,";
else if (lsu_inst_b[`BLKST]) print_inst = " BLKST,";
else if (lsu_inst_b[`QLD]) print_inst = " QLD,";
`PR_INFO("lsu_mon", 21, "<C%0h> <T%0h> <%0h> B_stage: %s(VA=%0h) Flushed due to IFU Flush.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b);
else if (`SPC5.tlu_flush_lsu_b)
`PR_INFO("lsu_mon", 21, "<C%h> <T%0h> <%0h> B_stage: %s(VA=%0h) Flushed due to TLU Flush.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b);
//casa is a two cycle operation. If there is an err on the 2nd cycle of casa then also
//This function will also chk for errors on 2nd cycle.
else if (Is_exu_error(exu_lsu_va_error_b, exu_ecc_b))
`PR_INFO("lsu_mon", 21, "<C%h> <T%0h <%0h> B_stage: %s(VA=%0h) Flushed due to EXU error.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b);
else if ((`SPC5.fgu_cecc_fx2 || `SPC5.fgu_uecc_fx2) && lsu_inst_b[`ST] && lsu_inst_b[`FP])
`PR_INFO("lsu_mon", 21, "<C%h> <T%0h> <%0h> B_stage: %s(VA=%0h) Flushed due to FGU error.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b);
else if (!`SPC5.lsu_tlb_miss_b_)
`PR_INFO("lsu_mon", 23, "<C%h> <T%0h> <%0h> B_stage: %s(VA=%0h)%s ASI = %0h. DTLB miss.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b, print_inst, asi_b);
//Lsu doesn't assert lsu_sync for an exception or dtlb miss. Since for
//an exception tlu anyway tells the front end to flush itself there is
//no reason for LSU to flush the front end then TLU to flush it again.
//Lsu treats the dtlbmiss as an exception that it flushes the inst and
//handles it when it is reissued by the front end.
if (`SPC5.lsu_tlb_bypass_b)
if (`SPC5.lsu_sync != 8'b0)
`PR_INFO("lsu_mon", 23, "<C%h> <T%0h> <%0h>: %s(VA=%0h)%s PA = %0h, ASI = %0h. LSU_sync. DTLB Bypass.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b, print_inst, {`SPC5.lsu.tlb_pgnum[39:13], vaddr_b[12:0]}, asi_b);
`PR_INFO("lsu_mon", 23, "<C%h> <T%0h> <%0h>: %s(VA=%0h)%s PA = %0h, ASI = %0h. DTLB Bypass.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b, print_inst, {`SPC5.lsu.tlb_pgnum[39:13], vaddr_b[12:0]}, asi_b);
if (`SPC5.lsu_sync != 8'b0)
`PR_INFO("lsu_mon", 23, "<C%h> <T%0h> <%0h>: %s(VA=%0h)%s PA = %0h, ASI = %0h, Store_data = %0h. LSU_sync. DTLB hit.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b, print_inst, {`SPC5.lsu.tlb_pgnum[39:13], vaddr_b[12:0]}, asi_b,int_st_data_b);
`PR_INFO("lsu_mon", 23, "<C%h> <T%0h> <%0h>: %s(VA=%0h)%s PA = %0h, ASI = %0h. LSU_sync. DTLB hit.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b, print_inst, {`SPC5.lsu.tlb_pgnum[39:13], vaddr_b[12:0]}, asi_b);
`PR_INFO("lsu_mon", 23, "<C%h> <T%0h> <%0h>: %s(VA=%0h)%s PA = %0h, ASI = %0h, Store_data = %0h. DTLB hit.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b, print_inst, {`SPC5.lsu.tlb_pgnum[39:13], vaddr_b[12:0]}, asi_b, int_st_data_b);
`PR_INFO("lsu_mon", 23, "<C%h> <T%0h> <%0h>: %s(VA=%0h)%s PA = %0h, ASI = %0h. DTLB hit.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b, print_inst, {`SPC5.lsu.tlb_pgnum[39:13], vaddr_b[12:0]}, asi_b);
if (lsu_inst_b[`LD] || lsu_inst_b[`PREF] || lsu_inst_b[`SWAP] || lsu_inst_b[`CASA] || lsu_inst_b[`LDSTUB])
if (((lsu_inst_b == 16'h1) || (lsu_inst_b == 16'h5)) & `SPC5.lsu.stb_cam_hit)
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> <%0h>: LSU_sync asserted due to STB RAW.", core_id, dec_lsu_tid_b, inst_pc_b);
if (lsu_inst_b[`ST]) //for atomics both ld and store signals are asserted
Insert_in_last_inst_array;
if (`SPC5.lsu_trap_flush[7:0])
`PR_INFO("lsu_mon", 21, "<C%h> <T%0h> Trap Flush asserted.", core_id, decode_tid(`SPC5.lsu_trap_flush[7:0]));
//This is how we test squashing of stores by LSU_mon:
//Whenever lsu asserts err_sbdiou signal, the monitor sets the squash
//bit in the STB for the rest of the stores. If any of these squashed stores
//is issued on the asi ring or to the PCX interface the monitor complains.
//The squashed stores are deallocated when either a block_store_kill is
//asserted or dealloc signals are asserted by the LSU.
//When the block_store_kill is asserted, it tells the IFU to dealloc
//all the pending stores in the IFU. It means the when block_store_kill
//is asserted we have deallocated all the non-squashed requests from STB.
//The 0in_chkr ensures that LSU flags the correct index and priv with the
//the sbdiou signal to TLU.
always @ (negedge (`SPC5.l2clk & enabled))
if (`SPC5.lsu_l15_valid & `SPC5.lsu.spc_pcx_data_pa[129])
Chk_pcx_req_pkt(`SPC5.lsu.spc_pcx_data_pa[129:0]); //chk if we need .lsu here
if ((`SPC5.lsu_rngl_cdbus[64:63] == 2'b11) & ~`SPC5.lsu_rngl_cdbus[59])
Chk_st_on_ASI_ring(`LOCAL);
if ((`SPC5.lsu_rngf_cdbus[64:63] == 2'b11) & ~`SPC5.lsu_rngf_cdbus[59])
Chk_st_on_ASI_ring(`FAST);
//if (`SPC5.l15_lsu_valid)
//Chk_cpx_response_pkt({`SPC5.l15_lsu_valid, `SPC5.l15_lsu_cpkt[17:13],`SPC5.l15_lsu_cpkt[11:0],`SPC5.l15_spc_data1[127:0]});
if (`SPC5.cpx_spc_data_cx[145])
Chk_cpx_response_pkt(`SPC5.cpx_spc_data_cx);
if (`SPC5.lsu_complete[7:0] != 8'b0)
if (`SPC5.lsu_complete[0]) Chk_ld_complete(0);
if (`SPC5.lsu_complete[1]) Chk_ld_complete(1);
if (`SPC5.lsu_complete[2]) Chk_ld_complete(2);
if (`SPC5.lsu_complete[3]) Chk_ld_complete(3);
if (`SPC5.lsu_complete[4]) Chk_ld_complete(4);
if (`SPC5.lsu_complete[5]) Chk_ld_complete(5);
if (`SPC5.lsu_complete[6]) Chk_ld_complete(6);
if (`SPC5.lsu_complete[7]) Chk_ld_complete(7);
if (`SPC5.lsu_block_store_kill[7:0] != 8'b0)
if (`SPC5.lsu_block_store_kill[0]) Squash_STB(0);
if (`SPC5.lsu_block_store_kill[1]) Squash_STB(1);
if (`SPC5.lsu_block_store_kill[2]) Squash_STB(2);
if (`SPC5.lsu_block_store_kill[3]) Squash_STB(3);
if (`SPC5.lsu_block_store_kill[4]) Squash_STB(4);
if (`SPC5.lsu_block_store_kill[5]) Squash_STB(5);
if (`SPC5.lsu_block_store_kill[6]) Squash_STB(6);
if (`SPC5.lsu_block_store_kill[7]) Squash_STB(7);
if (`SPC5.lsu_stb_dealloc[7:0] != 8'b0)
if (`SPC5.lsu_stb_dealloc[0]) Dealloc_STB(0);
if (`SPC5.lsu_stb_dealloc[1]) Dealloc_STB(1);
if (`SPC5.lsu_stb_dealloc[2]) Dealloc_STB(2);
if (`SPC5.lsu_stb_dealloc[3]) Dealloc_STB(3);
if (`SPC5.lsu_stb_dealloc[4]) Dealloc_STB(4);
if (`SPC5.lsu_stb_dealloc[5]) Dealloc_STB(5);
if (`SPC5.lsu_stb_dealloc[6]) Dealloc_STB(6);
if (`SPC5.lsu_stb_dealloc[7]) Dealloc_STB(7);
if (`SPC5.lsu_block_store_stall)
if (`SPC5.lsu.lsu_block_store_alloc[7:0] != 8'b0)
Set_block_store_parameters;
if (`SPC5.lsu_sbdiou_err_g || `SPC5.lsu_sbapp_err_g)
if (`SPC5.lsu_stb_flush_g)
st_priv[`SPC5.lsu_stberr_tid_g] = get_priv_on_flush(`SPC5.lsu_stberr_tid_g);
function [1:0] get_priv_on_flush;
sq_index = `SPC5.lsu_stberr_index_g;
tmp = stb[{tid, sq_index}];
get_priv_on_flush = tmp[`ST_PRIV];
thid = `SPC5.lsu_block_store_tid;
bst_inst_data = stb[{thid, rdptr[thid]}];
inst = bst_inst_data[`LSU_MON_INST];
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> LSU asserted blk_store_stall while the req at the top of STB is not blkst as shown above", core_id, thid);
//lsu can assert block_store_stall for a new block store while it has not yet written
//the 8 stb entries from the previous blk store.
task Set_block_store_parameters;
thid = decode_tid(`SPC5.lsu.lsu_block_store_alloc[7:0]);
if (lsu_bst_active[thid])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> LSU asserted blk_store_alloc while the bst_active is already set for this thread.", core_id, thid);
lsu_bst_active[thid] = 1'b1;
if (`SPC5.lsu.fgu_fst_ecc_error_fx2)
thid = `SPC5.lsu_stberr_tid_g;
sq_index = `SPC5.lsu_stberr_index_g;
priv = `SPC5.lsu_stberr_priv_g;
tmp = stb[{thid, sq_index}];
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> Sbdiou/sbapp seen for index = %h and priv = %h.", core_id, thid, sq_index, priv);
st_priv[thid] = tmp[`ST_PRIV];
//lsu can assert deallocate before it asserts the sbdiou signal.
//In that case iss_ptr won't be equal to sbdiou index.
//if (sq_index != iss_ptr[thid])
// Disp_STB_entry(thid, iss_ptr[thid]);
// `PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> LSU asserted sbdiou/sbapp with index %0h while the next req to be issued is at index %0h.", core_id, thid, sq_index, iss_ptr[thid]);
//If there is only one store in the store buffer which gets an sbdiou error, then LSU can deallocate
//the store and then assert sbdiou. The deallocation will cause the stb issue_ptr to move
//forward to an inst. that has already been issued and completed and this chk can fire. So
// Disp_STB_entry(thid, iss_ptr[thid]);
// `PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> Store reissued on the PCX interface.", core_id, thid, tmp[`MEMOP_PA]);
if (iss_ptr[thid] == wrptr[thid])
if (stb_valid[{thid, wrptr[thid]}])
//changing it to an info message because if there is only one valid entry in store buffer that
//gets an sbdiou then LSU can deallocate the entry and then issue sbdiou.
//`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Lsu asserted sbdiou/sbapp while there are no valid entries in STB to be issued.", core_id, thid);
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> sbdiou/sbapp squashed only one entry in STB.", core_id, thid);
if (iss_ptr[thid] < wrptr[thid])
squash_cnt = wrptr[thid] - iss_ptr[thid];
else if (iss_ptr[thid] > wrptr[thid])
squash_cnt = wrptr[thid] + (8 - iss_ptr[thid]);
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> SQUASH_STORE:iss_ptr = %0h, wrptr = %0h, squash_cnt = %0h.", core_id, thid, iss_ptr[thid], wrptr[thid], squash_cnt);
if (priv < tmp[`ST_PRIV])
`PR_INFO("lsu_mon", `INFO, "<C%h> <T%0h> <PA = %0h> Sbdiou/sbapp signalled. Err in user/priv level store is squashing a higher priv level store.", core_id, thid, tmp[`MEMOP_PA]);
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> <PA = %0h> STB_entry[%0h] squashed.", core_id, thid, tmp[`MEMOP_PA], i);
squash_cnt = squash_cnt - 1'b1;
function [2:0] decode_tid;
8'h10: decode_tid = 3'h4;
8'h20: decode_tid = 3'h5;
8'h40: decode_tid = 3'h6;
8'h80: decode_tid = 3'h7;
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> decode_tid. Incorrect value of thid input = %0h.", core_id, thid_encode, thid_encode);
reg [`LD_Pend_Width] tmp;
tmp = ld_pend_array[thid];
if ((tmp[`L2_ISS] != 4'hf) || (tmp[`L2_RESP] != 4'hf))
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> LSU asserted lsu_complete while the l2_iss and l2_resp bits are not F.", core_id, thid);
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> <%0h> %s(VA=%0h) Complete. Setting ld_valid to 0.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA]);
tmp = last_inst_array[thid];
`PR_INFO("lsu_mon", 24, "<C%h> <T%0h> <%0h> %s(VA=%0h) Complete.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA]);
reg [`LD_Pend_Width] tmp, tmp1;
thid = pcx_pkt[`PCX_THR_ID];
tmp = ld_pend_array[thid];
inst = tmp[`LSU_MON_INST];
req = DispPCXReq(pcx_pkt);
addr = pcx_pkt[`PCX_ADDR];
if (pcx_pkt[`PCX_CPU_ID] != core_id)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> cpu_id (spc_pcx_data_pa[122:120]) = %h is not = %0h when the lsu made a %s req to gasket.", core_id, pcx_pkt[`PCX_THR_ID], addr, pcx_pkt[122:120], core_id, req);
if ((pcx_pkt[`PCX_RQTYP] == `PCX_LOAD) || (pcx_pkt[`PCX_RQTYP] == `PCX_CAS1) || (pcx_pkt[`PCX_RQTYP] == `PCX_CAS2) || (pcx_pkt[`PCX_RQTYP] == `PCX_SWAP_LDSTUB))
ld_valid[thid] = 1'b1; //we have sent a req to gasket and are waiting for response
`PR_INFO("lsu_mon", 22, "<C%0h> <T%0h> Setting ld_valid[%0h].", core_id, thid, thid);
if (tmp[`MEMOP_PA] != addr)
if ((tmp[`INST_ASI] == 8'h41) || (tmp[`INST_ASI] == 8'h73) || ((tmp[`INST_ASI] == 8'h45) && ((tmp[`MEMOP_PA] == 8'h10) || (tmp[`MEMOP_PA] == 8'h18))))
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <PA = %0h> PA mismatch on gasket for %s request. Ignoring the mismatch as inst. is issued with asi 41, 73 or 45 (with VA 0x10 or 18).", core_id, thid, addr, req);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> A %s request made to gasket by LSU while the pending req is with PA %0h.", core_id, thid, addr, req, tmp[`MEMOP_PA]);
case (pcx_pkt[`PCX_RQTYP])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> A prefetch request made to gasket by LSU which mismatches the pending request from the thread.", core_id, thid, addr);
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: PREF_ICE(VA=%0h) Issued. pf_cnt not updated.", core_id, thid, tmp[`INST_VA], tmp[`MEMOP_VA]);
pf_cnt[thid] = pf_cnt[thid] + 1'b1;
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) Issued. pf_cnt = %0d.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], pf_cnt[thid]);
tmp[`L2_RESP] = 4'hF; //we don't wait for a prefetch response from gasket
ld_pend_array[thid] = tmp;
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) Dcache invalidate pkt issued to CCX.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA]);
dcache_inv_cnt[thid] = dcache_inv_cnt[thid] + 1'b1;
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> CASA request made to gasket by LSU while no such request request is pending from this thread.", core_id, thid, addr);
if (pcx_pkt[`PCX_RQTYP] == `PCX_CAS1)
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) (CAS1) Issued to gasket.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA]);
ld_pend_array[thid] = tmp;
if (pcx_pkt[`PCX_RQTYP] == `PCX_CAS2)
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) (CAS2) Issued to gasket.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA]);
ld_pend_array[thid] = tmp;
chk_store_issue_to_pcx(pcx_pkt);
if (~inst[`SWAP] && ~inst[`LDSTUB])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> %s request made to gasket by LSU while no such request request is pending from this thread.", core_id, thid, addr, req);
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) Issued to gasket. store_data = %0h", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], pcx_pkt[`PCX_DATA]);
ld_pend_array[thid] = tmp;
chk_store_issue_to_pcx(pcx_pkt);
chk_store_issue_to_pcx(pcx_pkt);
default: `PR_INFO("lsu_mon", 21, "<C%h> <T%0h> <%0h>: %s Issued to gasket.", core_id, thid, addr, req);
task Chk_cpx_response_pkt;
thid = cpx_pkt[`CPX_THR_ID];
casex ({cpx_pkt[`CPX_RTNTYP], cpx_pkt[`CPX_ERR], cpx_pkt[`CPX_NC], cpx_pkt[`CPX_ATM], cpx_pkt[`CPX_PF]})
{4'b0, 2'bxx, 1'bx, 1'b0, 1'b0}:
chk_ccx_ld_response(cpx_pkt);
{4'b0, 2'bxx, 1'b1, 1'b0, 1'b1}:
if (pf_cnt[thid] == 8'b0)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Prefetch response received from gasket while the pf_cnt is 0 for this thread.", core_id, thid);
pf_cnt[thid] = pf_cnt[thid] - 1'b1;
`PR_INFO("lsu_mon", 26, "<C%h> <T%0h> Prefetch response received. pfcnt = %0d.", core_id, thid, pf_cnt[thid]);
{4'h8, 2'bxx, 1'b1, 1'b0, 1'b0}:
chk_ccx_ld_response(cpx_pkt);
{4'h4, 2'bxx, 1'bx, 1'b0, 1'b0}:
if (cpx_pkt[123]) //D pkt
if (cpx_pkt[120:118] != core_id)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> D response received from gasket with core_id =%h.", core_id, thid, cpx_pkt[120:118]);
if (dcache_inv_cnt[thid] == 8'b0)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> D response received from gasket while the Dcache_inv_cnt is 0 for this thread.", core_id, thid);
dcache_inv_cnt[thid] = dcache_inv_cnt[thid] - 1'b1;
`PR_INFO("lsu_mon", 26, "<C%h> <T%0h> D response received. Dcache_inv_cnt = %0d.", core_id, thid, dcache_inv_cnt[thid]);
else if (cpx_pkt[124]) //I pkt
if (cpx_pkt[120:118] != core_id)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> I response received from gasket with core_id =%h.", core_id, thid, cpx_pkt[120:118]);
//`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> I pkt.", core_id, thid);
else if (cpx_pkt[124:123] == 2'b0)
if (cpx_pkt[120:118] == core_id)
chk_ccx_st_response(cpx_pkt);
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> Store Ack pkt received from core %0h.", core_id, thid, cpx_pkt[120:118]);
{4'h1, 2'bxx, 1'bx, 1'b0, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> IFILL1 return.", core_id, thid);
{4'h1, 2'bxx, 1'bx, 1'b1, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> IFILL2 return.", core_id, thid);
{4'h9, 2'bxx, 1'b1, 1'b0, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> NCU IFILL return.", core_id, thid);
{4'b0, 2'bxx, 1'b1, 1'b1, 1'b0}:
chk_ccx_atm_response(cpx_pkt);
{4'h4, 2'bxx, 1'b1, 1'b1, 1'b0}:
if ((cpx_pkt[`CPX_RTNTYP] == 4'h4) & (cpx_pkt[120:118] == core_id))
chk_ccx_atm_response(cpx_pkt);
chk_ccx_st_response(cpx_pkt);
{4'h2, 2'bxx, 1'b1, 1'b0, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> Stream Ld return.", core_id, thid);
{4'h6, 2'bxx, 1'bx, 1'bx, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> Stream store Ack.", core_id, thid);
{4'h5, 2'bxx, 1'b1, 1'b0, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> MMU ld return.", core_id, thid);
{4'h7, 2'b00, 1'b0, 1'bx, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> Interrupt return.", core_id, thid);
{4'h3, 2'b00, 1'bx, 1'bx, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> Eviction Invalidation.", core_id, thid);
{4'hc, 2'bxx, 1'bx, 1'bx, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> L2 Indication.", core_id, thid);
{4'hd, 2'bxx, 1'bx, 1'bx, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> Soc Error Indication.", core_id, thid);
`PR_ALWAYS("lsu_mon", `ALWAYS, "CPX_PKT data.");
`PR_ALWAYS("lsu_mon", `ALWAYS, "<C%0h> <T%0h> rtn_typ = %0h, err_bits = %0h, nc=%0b, atm = %0b, pf = %0b", core_id, cpx_pkt[`CPX_THR_ID], cpx_pkt[`CPX_RTNTYP], cpx_pkt[`CPX_ERR], cpx_pkt[`CPX_NC], cpx_pkt[`CPX_ATM], cpx_pkt[`CPX_PF]);
`PR_ERROR("lsu_mon", `ERROR, "<C%0h> <T%0h> Can't recognise the CPX pkt.", core_id, thid);
task chk_ccx_ld_response;
reg [39:0] cpx_pa, inst_pa;
reg [`LD_Pend_Width] tmp;
thid = cpx_pkt[`CPX_THR_ID];
tmp = ld_pend_array[thid];
inst = tmp[`LSU_MON_INST];
inst_pa = tmp[`MEMOP_PA];
pkt_type = cpx_pkt[`CPX_RTNTYP];
`PR_INFO("lsu_mon", 26, "<C%0h> <T%0h> <%0h> %s(VA=%0h) L2 response.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA]);
if (inst_pa[39] != pkt_type[3])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> ccx pkt_type = %h mismatches the ld_pa bit 39. ld_pa = %0h.", core_id, thid, pkt_type, inst_pa);
if (tmp[`L2_RESP] == 4'h0)
tmp[`L2_ERR0] = cpx_pkt[`CPX_ERR];
if ((cpx_pkt[`CPX_ERR] == `ND) || (cpx_pkt[`CPX_ERR] == `UE))
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> UE/ND err on blk ld helper 1.", core_id, thid);
else if (tmp[`L2_RESP] == 4'h1)
tmp[`L2_ERR1] = cpx_pkt[`CPX_ERR];
if ((cpx_pkt[`CPX_ERR] == `ND) || (cpx_pkt[`CPX_ERR] == `UE))
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> UE/ND err on blk ld helper 2.", core_id, thid);
else if (tmp[`L2_RESP] == 4'h3)
tmp[`L2_ERR2] = cpx_pkt[`CPX_ERR];
if ((cpx_pkt[`CPX_ERR] == `ND) || (cpx_pkt[`CPX_ERR] == `UE))
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> UE/ND err on blk ld helper 3.", core_id, thid);
else if (tmp[`L2_RESP] == 4'h7)
tmp[`L2_ERR3] = cpx_pkt[`CPX_ERR];
if ((cpx_pkt[`CPX_ERR] == `ND) || (cpx_pkt[`CPX_ERR] == `UE))
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> UE/ND err on blk ld helper 4.", core_id, thid);
if ((tmp[`L2_ERR0] == `ND) || (tmp[`L2_ERR1] == `ND) || (tmp[`L2_ERR2] == `ND) || (tmp[`L2_ERR3] == `ND))
l2_blk_ld_errtype[thid] = `ND;
else if ((tmp[`L2_ERR0] == `UE) || (tmp[`L2_ERR1] == `UE) || (tmp[`L2_ERR2] == `UE) || (tmp[`L2_ERR3] == `UE))
l2_blk_ld_errtype[thid] = `UE;
else if ((tmp[`L2_ERR0] == `CE) || (tmp[`L2_ERR1] == `CE) || (tmp[`L2_ERR2] == `CE) || (tmp[`L2_ERR3] == `CE))
l2_blk_ld_errtype[thid] = `CE;
l2_blk_ld_errtype[thid] = `NE;
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Illegal value of l2_resp cnt when response pkt received from ccx.", core_id, thid);
else if (Is_single_pcx_req_ld(inst))
if (tmp[`L2_RESP] != 4'hE)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Illegal value of l2_resp cnt when response pkt received from ccx.", core_id, thid);
//`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> Setting L2_resp bits to F.", core_id, thid);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Load response received from gasket for thid %h while no load request pending from core for this thread.", core_id, thid, thid);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Load response received from gasket while no load request pending from core for this thread.", core_id, thid);
ld_pend_array[thid] = tmp;
task chk_ccx_atm_response;
reg [`LD_Pend_Width] tmp;
thid = cpx_pkt[`CPX_THR_ID];
tmp = ld_pend_array[thid];
inst = tmp[`LSU_MON_INST];
inst_pa = tmp[`MEMOP_PA];
if (cpx_pkt[`CPX_RTNTYP] == 4'b0)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Atomic ld response received from gasket while no request pending from core for this thread.", core_id, thid);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Atomic ack response received from gasket while no request pending from core for this thread.", core_id, thid);
if (~inst[`SWAP] && ~inst[`CASA] && ~inst[`LDSTUB])
if (cpx_pkt[`CPX_RTNTYP] == 4'b0)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Atomic ld response received from gasket which mismatches the request pending from this thread.", core_id, thid);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Atomic ack response received from gasket which mismatches the request pending from this thread.", core_id, thid);
if (cpx_pkt[`CPX_RTNTYP] == 4'b0)
`PR_INFO("lsu_mon", 26, "<C%0h> <T%0h> <%0h> %s(VA=%0h) Atomic ld response.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA]);
`PR_INFO("lsu_mon", 26, "<C%0h> <T%0h> <%0h> %s(VA=%0h) Atomic ack.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA]);
if (cpx_pkt[`CPX_RTNTYP] == 4'b0)
if (tmp[`L2_RESP] == 4'hC) tmp[`L2_RESP] = 4'hD;
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Illegal value of l2_resp cnt when atomic ld return pkt received from ccx.", core_id, thid);
if (tmp[`L2_RESP] == 4'hD) tmp[`L2_RESP] = 4'hF;
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Illegal value of l2_resp cnt when atomic ack pkt received from ccx.", core_id, thid);
ld_pend_array[thid] = tmp;
task chk_ccx_st_response;
reg [39:0] cpx_pa, inst_pa;
thid = cpx_pkt[`CPX_THR_ID];
tmp = stb[{thid, ret_ptr[thid]}];
inst = tmp[`LSU_MON_INST];
inst_pa = tmp[`MEMOP_PA];
pkt_type = cpx_pkt[`CPX_RTNTYP];
//is received. There could be some other store sitting in the STB at that time.
//Chk for squash bit only for non-bis responses.
if (cpx_pkt[`CPX_BIS]) //response to rmo store
if (st_rmo_cnt[thid] == 0)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> L2 response received for an rmo store while the st_rmo_cnt for this thread is 0.", core_id, thid);
st_rmo_cnt[thid] = st_rmo_cnt[thid] - 1'b1;
`PR_INFO("lsu_mon", 25, "<C%0h> <T%0h> Store ack received for RMO store. rmo_cnt = %0d", core_id, thid, st_rmo_cnt[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> L2 response received while the SQUASH bit is set in the STB entry %0h.", core_id, thid, ret_ptr[thid]);
if (~stb_valid[{thid, ret_ptr[thid]}])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Store ack received while that entry is invalid in STB.", core_id, thid);
if (~cpx_pkt[`CPX_ATM]) //don't print this message for atomic return
`PR_INFO("lsu_mon", 26, "<C%0h> <T%0h> <%0h> %s(VA=%0h) STB[%0d] Store ack.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA], ret_ptr[thid]);
stb[{thid, ret_ptr[thid]}] = tmp;
ret_ptr[thid] = ret_ptr[thid] + 1'b1;
//`PR_INFO("lsu_mon", 22, "<C%0h> <T%0h> ret_ptr = %0d.", core_id, thid, ret_ptr[thid]);
reg [`LD_Pend_Width] tmp;
reg [39:0] pcx_pa, inst_pa;
thid = pcx_pkt[`PCX_THR_ID];
tmp = ld_pend_array[thid];
inst = tmp[`LSU_MON_INST];
pcx_pa = pcx_pkt[`PCX_ADDR];
inst_pa = tmp[`MEMOP_PA];
req = DispPCXReq(pcx_pkt);
if (pcx_pa[39:6] != inst_pa[39:6])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> A load request made to gasket by LSU while the pending req has PA %0h.", core_id, thid, pcx_pa, tmp[`MEMOP_PA]);
if (tmp[`L2_ISS] != 4'h0 )
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> 1st load request (pa[5:0] = 6'b0) made to gasket by LSU for blkld while this request has already been issued to gasket.", core_id, thid, pcx_pa);
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) 1st blkld helper Issued to gasket.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA]);
if (pcx_pa[5:0] == 6'h10)
if (tmp[`L2_ISS] != 4'h1)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> 2nd load request (pa[5:0] = 6'h10) made to gasket by LSU for blkld while this request has already been issued to gasket.", core_id, thid, pcx_pa);
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) 2nd blkld helper Issued to gasket.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA]);
if (pcx_pa[5:0] == 6'h20)
if (tmp[`L2_ISS] != 4'h3)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> 3rd load request (pa[5:0] = 6'h20) made to gasket by LSU for blkld while this request has already been issued to gasket.", core_id, thid, pcx_pa);
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) 3rd blkld helper Issued to gasket.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA]);
if (pcx_pa[5:0] == 6'h30)
if (tmp[`L2_ISS] != 4'h7)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> 4th load request (pa[5:0] = 6'h30) made to gasket by LSU for blkld while this request has already been issued to gasket.", core_id, thid, pcx_pa);
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) 4th blkld helper Issued to gasket.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA]);
ld_pend_array[thid] = tmp;
else if (Is_single_pcx_req_ld(inst))
if (tmp[`L2_ISS] == 4'hF)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> Load request made to gasket by LSU while this request has already been issued to gasket.", core_id, thid, pcx_pa);
ld_pend_array[thid] = tmp;
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) Issued to gasket.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> A load request made to gasket by LSU while there is no such ld request pending from this thread.", core_id, thid, pcx_pa);
function Is_single_pcx_req_ld;
if (inst[`LDD] || inst[`QLD] || inst[`FSR_RD_WR] || (inst == 21'h1) || (inst == 21'h5))
Is_single_pcx_req_ld = 1'b1;
Is_single_pcx_req_ld = 1'b0;
//`PR_INFO("lsu_mon", 22, "<C%0h> Is_single_pcx_req_ld = %b. ", core_id, Is_single_pcx_req_ld);
case (`SPC5.lsu_trap_flush[7:0])
8'h01: if (tid == 3'h0) Is_trap = 1'b1;
8'h02: if (tid == 3'h1) Is_trap = 1'b1;
8'h04: if (tid == 3'h2) Is_trap = 1'b1;
8'h08: if (tid == 3'h3) Is_trap = 1'b1;
8'h10: if (tid == 3'h4) Is_trap = 1'b1;
8'h20: if (tid == 3'h5) Is_trap = 1'b1;
8'h40: if (tid == 3'h6) Is_trap = 1'b1;
8'h80: if (tid == 3'h7) Is_trap = 1'b1;
function [8*11:0] DispPCXReq;
casex ({pcx_pkt[`PCX_RQTYP], pcx_pkt[`PCX_NC], pcx_pkt[`PCX_INV], pcx_pkt[`PCX_PF], pcx_pkt[`PCX_BIS]})
{5'h0, 1'b1, 1'b0, 1'b1, 1'b0}: DispPCXReq = "PREF";
{5'h0, 1'b1, 1'b1, 1'b1, 1'b0}: DispPCXReq = "PREF_ICE";
{5'h0, 1'bx, 1'b0, 1'b0, 1'b0}: DispPCXReq = "LD";
{5'h0, 1'bx, 1'b1, 1'b0, 1'b0}: DispPCXReq = "D";
{5'h10, 1'bx, 1'b0, 1'b0, 1'b0}: DispPCXReq = "I";
{5'h10, 1'b0, 1'b1, 1'b0, 1'b0}: DispPCXReq = "I";
{5'h1, 1'bX, 1'bX, 1'b0, 1'b0}: DispPCXReq = "ST";
{5'h1, 1'bX, 1'bX, 1'b1, 1'b1}: DispPCXReq = "BLKST";
{5'h1, 1'bX, 1'bX, 1'b0, 1'b1}: DispPCXReq = "BIS";
{5'h2, 1'b1, 1'bX, 1'b0, 1'b0}: DispPCXReq = "CASA1";
{5'h3, 1'b1, 1'bX, 1'b0, 1'b0}: DispPCXReq = "CASA2";
{5'h7, 1'b1, 1'bX, 1'b0, 1'b0}: DispPCXReq = "SWAP_LDSTUB";
{5'h4, 1'b1, 1'b0, 1'b0, 1'b0}: DispPCXReq = "STREAM_LD";
{5'h5, 1'b1, 1'b0, 1'b0, 1'bx}: DispPCXReq = "STREAM_ST";
{5'h8, 1'b1, 1'b0, 1'b0, 1'b0}: DispPCXReq = "MMU_LD";
//{5'h9, 1'b0, 1'b0, 1'b0, 1'b0}: DispPCXReq = "INT";
`PR_ERROR("lsu_mon", `ERROR, "<C%0h> <T%0h> <%0h> Can't recognise the PCX pkt type. rq_type = %h, nc_bit = %0b, inv_bit = %0b, pf_bit = %0b, bis_bit = %0b. pcx_pkt[129:0] = %h", core_id, pcx_pkt[`PCX_THR_ID], pcx_pkt[`PCX_ADDR], pcx_pkt[`PCX_RQTYP], pcx_pkt[`PCX_NC], pcx_pkt[`PCX_INV], pcx_pkt[`PCX_PF], pcx_pkt[`PCX_BIS], pcx_pkt);
if (`SPC5.lsu_align_b) DispExc = "Addr_not_aligned";
if (`SPC5.lsu_lddf_align_b) DispExc = "LDDF_Addr_not_aligned";
if (`SPC5.lsu_stdf_align_b) DispExc = "STDF_Addr_not_aligned";
if (`SPC5.lsu_priv_action_b) DispExc = "Priv_actio";
if (`SPC5.lsu_va_watchpoint_b) DispExc = "VA_watchpoint";
if (`SPC5.lsu_pa_watchpoint_b) DispExc = "PA_watchpoint";
//if (`SPC5.lsu_tlb_miss_b_) DispExc = "Tlb_miss";
if (`SPC5.lsu_illegal_inst_b) DispExc = "Illegal_inst";
if (`SPC5.lsu_daccess_prot_b) DispExc = "Data_access_prot_exc";
if (`SPC5.lsu_dae_invalid_asi_b) DispExc = "Dae_Invalid_asi";
if (`SPC5.lsu_dae_nc_page_b) DispExc = "Dae_nc_page";
if (`SPC5.lsu_dae_nfo_page_b) DispExc = "Dae_NFO_page";
if (`SPC5.lsu_dae_priv_viol_b) DispExc = "Dae_Priv_viol";
if (`SPC5.lsu_dae_so_page) DispExc = "Dae_so_page";
//if (`SPC5.lsu_perfmon_trap_b) DispExc = "Perf_mon_trap";
if (`SPC5.lsu_dtmh_err_b) DispExc = "DTLB_data_par_err";
if (`SPC5.lsu_dttp_err_b) DispExc = "DTLB_tag_par_err";
if (`SPC5.lsu_dtdp_err_b) DispExc = "DTLB_data_par_err";
`PR_INFO("lsu_mon", 23, "<C%0h> <T%0h> <%0h> B_stage: %s(VA=%0h) ASI = %0h. %s Exception.",core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b, asi_b, DispExc);
input [1:0] exu_lsu_va_error_b; // VA error requiring a flush
input [1:0] exu_ecc_b; // ECC error requiring a flush
err_b = dec_lsu_tid_b[2] ? (exu_ecc_b[1] | (exu_lsu_va_error_b[1] & ~`SPC5.lsu_tlb_bypass_b)):
(exu_ecc_b[0] | (exu_lsu_va_error_b[0] & ~`SPC5.lsu_tlb_bypass_b));
err_m = (dec_lsu_tid_b[2] ? `SPC5.exu_ecc_m[1] : `SPC5.exu_ecc_m[0]) & `SPC5.lsu.dcc.twocycle_b;
Is_exu_error = err_b | err_m;
task Insert_tlb_miss_info;
if (tlb_valid[dec_lsu_tid_b])
tmp = tlbmiss_pend_array[dec_lsu_tid_b];
Disp_tlbmiss_pend_array_entry(dec_lsu_tid_b);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <%0h> B_stage: %s(VA=%0h>) A new tlb miss request received while there is already a Tlb miss request pending from this thread as shown above.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b);
tlb_valid[dec_lsu_tid_b] <= 1'b1;
tmp[`INST_VA] = inst_pc_b;
tmp[`MEMOP_VA] = vaddr_b;
tlbmiss_pend_array[dec_lsu_tid_b] = tmp;
//problem with the signal.
always @ (negedge `SPC5.l2clk)
if (`SPC5.tlu_trap_pc_0_valid)
thid = {1'b0, `SPC5.tlu_trap_0_tid};
else if (`SPC5.tlu_trap_pc_1_valid)
thid = {1'b0, `SPC5.tlu_trap_1_tid};
`PR_ERROR("lsu_mon", `ERROR, "<C%h> mmu_dtlb_reload asserted but trap_pc_0_valid and trap_pc_1_valid are both 0", core_id);
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> mmu_dtlb_reload asserted while tlb_valid is 0.", core_id, thid);
tmp = tlbmiss_pend_array[dec_lsu_tid_b];
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> %s(VA=%0h> DTLB reloaded for VA = %0h.", core_id, thid, tb_top.intf0.xlate(tmp[`INST]), tmp[`INST_VA], tmp[`MEMOP_VA] );
task Insert_ld_miss_info;
reg [`LD_Pend_Width] tmp;
if (ld_valid[dec_lsu_tid_b])
tmp = ld_pend_array[dec_lsu_tid_b];
DispPendReq(dec_lsu_tid_b);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <%0h> B_stage: %s(VA=%0h>) A new request received while there is already a request pending from this thread as shown above.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b);
//ld_valid[dec_lsu_tid_b] <= 1'b1;
tmp[`INST_VA] = inst_pc_b;
tmp[`MEMOP_VA] = vaddr_b;
tmp[`MEMOP_PA] = {`SPC5.lsu.tlb_pgnum[39:13], vaddr_b[12:0]};
is_blkld[dec_lsu_tid_b] = 1'b1;
is_blkld[dec_lsu_tid_b] = 1'b0;
if (lsu_inst_b[`SWAP] || lsu_inst_b[`LDSTUB] || lsu_inst_b[`CASA])
tmp[`LSU_MON_INST] = lsu_inst_b;
ld_pend_array[dec_lsu_tid_b] = tmp;
task Insert_in_last_inst_array;
tmp[`INST_VA] = inst_pc_b;
tmp[`MEMOP_VA] = vaddr_b;
last_inst_array[dec_lsu_tid_b] = tmp;
reg [`LD_Pend_Width] tmp;
tmp = ld_pend_array[thid];
`PR_ALWAYS("lsu_mon", `ALWAYS, "LD_PEND_ARRAY[%0h] Data.", thid);
`PR_ALWAYS("lsu_mon", `ALWAYS, "<C%h> <T%0h> <%0h> %s(VA=%0h). PA = %0h. L2_ISS = %0h. L2_RESP = %0h, LSU_MON_INST=%h.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA], tmp[`MEMOP_PA], tmp[`L2_ISS], tmp[`L2_RESP], tmp[`LSU_MON_INST]);
`PR_ALWAYS("lsu_mon", `ALWAYS, "<C%h> <T%0h> STB[%0h] data.", core_id, thid, ptr);
`PR_ALWAYS("lsu_mon", `ALWAYS, "<C%h> <T%0h> <%0h> %s(VA=%0h). PA = %0h. L2_ISS = %0h. L2_ACK = %0h, LSU_MON_INST=%h. RMO = %0b", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA], tmp[`MEMOP_PA], tmp[`L2_ST_ISS], tmp[`L2_ACK], tmp[`LSU_MON_INST], tmp[`RMO]);
task Disp_tlbmiss_pend_array_entry;
tmp = tlbmiss_pend_array[thid];
`PR_INFO("lsu_mon", 23, "TLB_MISS_PEND_ARRAY[%0h] Data.", thid);
`PR_INFO("lsu_mon", 23, "<C%h> <T%0h> <%0h> %s(VA=%0h).", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA]);
`PR_ALWAYS("lsu_mon", `ALWAYS, "CPX_PKT data.");
`PR_ALWAYS("lsu_mon", `ALWAYS, "<C%0h> <T%0h> rtn_typ = %0h, err_bits = %0h, nc=%0b, atm = %0b, pf = %0b", core_id, cpx_pkt[`CPX_THR_ID], cpx_pkt[`CPX_RTNTYP], cpx_pkt[`CPX_ERR], cpx_pkt[`CPX_NC], cpx_pkt[`CPX_ATM], cpx_pkt[`CPX_PF]);
tmp[`INST_VA] = inst_pc_b;
tmp[`MEMOP_VA] = vaddr_b;
tmp[`MEMOP_PA] = {`SPC5.lsu.tlb_pgnum[39:13], vaddr_b[12:0]};
tmp[`LSU_MON_INST] = lsu_inst_b;
if (`SPC5.lsu.tlu_lsu_hpstate_hpriv[dec_lsu_tid_b])
else if (`SPC5.lsu.tlu_lsu_pstate_priv[dec_lsu_tid_b])
//bis_asi to io space is not rmo
tmp[`RMO] = lsu_inst_b[`BLKST] | (dec_altspace_b & Is_bis_asi(asi_b) & ~`SPC5.lsu.tlb_pgnum[39]);
input [195:0] store_data;
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> STB full and a new store received for insertion in STB.", core_id, thid);
stb[{thid, wrptr[thid]}] = store_data;
//Disp_STB_entry(thid, wrptr[thid]);
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> <%0h> %s(VA=%0h). STB[%0h] Inserted.", core_id, thid, store_data[`INST_VA], tb_top.intf0.xlate(store_data[`INST]), store_data[`MEMOP_VA], wrptr[thid]);
stb_valid[{thid, wrptr[thid]}] = 1'b1;
wrptr[thid] = wrptr[thid] + 1'b1;
//`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> wrptr = %0d.", core_id, thid, wrptr[thid]);
if ((wrptr[thid] == rdptr[thid]) && stb_valid[{thid, wrptr[thid]}])
//thid = decode_tid(`SPC5.lsu_stb_dealloc);
tmp = stb[{thid, rdptr[thid]}];
lsu_inst = tmp[`LSU_MON_INST];
if (~stb_valid[{thid, rdptr[thid]}])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> lsu_stb_dealloc = %0h asserted while the stb entry is invalid for that thid.", core_id, thid, `SPC5.lsu_stb_dealloc);
Disp_STB_entry(thid, rdptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> lsu_stb_dealloc = %0h asserted when we haven't received the response from the gasket.", core_id, thid, `SPC5.lsu_stb_dealloc);
else if (tmp[`ASI_ST_ISS])
ret_ptr[thid] = ret_ptr[thid] + 1'b1;
//blkst inst. is not issued anywhere, blkst helpers are issued.
//in case of bis stores, lsu issues the dealloc in P3, i.e when the req is issued to PCX.
//IF it is bis to cp sapce and there is an err then the store is issued to PCX with nd set
//However for ue onbis to IO space, dealloc is sent to IFU, issued on PCX with valid bit 0.
//The sbdiou signal is sent in next cycle. We need to take bis io stores in this equation.
else if (tmp[`ST_SQUASH] || lsu_inst[`BLKST] || (tmp[`RMO] & ~lsu_inst[`BLKST] & ~`SPC0.lsu.sbc.kill_store_p4_))
iss_ptr[thid] = iss_ptr[thid] + 1'b1;
ret_ptr[thid] = ret_ptr[thid] + 1'b1;
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> lsu_stb_dealloc = %0h asserted which is not issued to asi ring, or PCX or is not squashed.", core_id, thid, `SPC5.lsu_stb_dealloc);
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> <%0h>: %s(VA=%0h) PA = %0h. STB[%0d] Deallocated.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], tmp[`MEMOP_PA], rdptr[thid]);
stb_valid[{thid, rdptr[thid]}] = 1'b0;
rdptr[thid] = rdptr[thid] + 1'b1;
//`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> rd_ptr = %0d.", core_id, thid, rdptr[thid]);
st_rmo_cnt[thid] = st_rmo_cnt[thid] + 1'b1;
if (ret_ptr[thid] != iss_ptr[thid])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> lsu_block_store_kill asserted while the ret_ptr = %0h != iss_ptr = %0h.", core_id, thid, tmp[`MEMOP_PA], ret_ptr[thid], iss_ptr[thid]);
if (rdptr[thid] != iss_ptr[thid])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> lsu_block_store_kill asserted while the rdptr = %0h != iss_ptr = %0h.", core_id, thid, tmp[`MEMOP_PA], rdptr[thid], iss_ptr[thid]);
if (iss_ptr[thid] == wrptr[thid])
if (stb_valid[{thid, wrptr[thid]}])
/* Lsu can assert both dealloc and block_store_kill for a request.
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Lsu asserted block_store_kill while there are no valid entries in STB to be deallocated.", core_id, thid);
if (iss_ptr[thid] < wrptr[thid])
squash_cnt = wrptr[thid] - iss_ptr[thid];
else if (iss_ptr[thid] > wrptr[thid])
squash_cnt = wrptr[thid] + (8 - iss_ptr[thid]);
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> SQUASH_STB:iss_ptr = %0h, wrptr = %0h, squash_cnt = %0h.", core_id, thid, iss_ptr[thid], wrptr[thid], squash_cnt);
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> Block store kill changed issue_ptr:%0h->%0h. ret_ptr: %0h->%0h. rdptr:%0h->%0h.", core_id, thid, iss_ptr[thid], iss_ptr[thid]+squash_cnt, ret_ptr[thid], ret_ptr[thid]+squash_cnt, rdptr[thid], rdptr[thid]+squash_cnt);
ret_ptr[thid] = ret_ptr[thid] + squash_cnt;
rdptr[thid] = rdptr[thid] + squash_cnt;
iss_ptr[thid] = iss_ptr[thid] + squash_cnt;
if (~stb_valid[{thid, i}])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h><PA = %0h> lsu_block_store_kill asserted while the stb entry %0h is invalid.", core_id, thid, tmp[`MEMOP_PA], i);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h>st_issue bit is set when the block_store_kill is asserted for stb entry %0h.", core_id, thid, tmp[`MEMOP_PA], i);
//commenting out the chk below. Lsu can assert sbdiou and then in the next cycle insert a new entry into
//stb. LSU will squash this new entry and won't issue it to PCX/asi but its squash bit won't be
//set in the chkr which was causin it to fire.
//`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> lsu_block_store_kill asserted while the squash bit is 0 in the STB entry %0h.", core_id, thid, tmp[`MEMOP_PA], i);
stb_valid[{thid, i}] = 1'b0;
squash_cnt = squash_cnt - 1'b1;
if ((bst_cnt > 0) && (`SPC5.lsu_stb_alloc == 8'b0))
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Blk store entries are not allocated back to back in STB.", core_id, bst_active_thid);
//For bst the stb is still written even though we have errors.
//Stb is written in W stage. Howvere for first blk store helper
//the err will be flagged by FGU in b stage. We can miss the
// err signal if we don't sample in B.
//for the last helper err will be signalled in B stage of last helper and at
if (lsu_bst_active[bst_active_thid] & `SPC0.fgu_fst_ecc_error_fx2 & (bst_cnt < 7))
if (`SPC5.lsu_stb_alloc[7:0] != 8'b0)
thid = decode_tid(`SPC5.lsu_stb_alloc[7:0]);
if (thid != dec_lsu_tid_w)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> lsu_stb_alloc = %0h mismatches the thid %0h.", core_id, dec_lsu_tid_w, `SPC5.lsu_stb_alloc[7:0], dec_lsu_tid_w);
Insert_in_STB(stb_alloc_data, dec_lsu_tid_w);
if (lsu_bst_active[thid])
bst_data = bst_inst_data;
if (thid != bst_active_thid)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> lsu_stb_alloc = %0h mismatches the active blkstore thid = %0h.", core_id, bst_active_thid, `SPC5.lsu_stb_alloc[7:0], bst_active_thid);
addr = bst_data[`MEMOP_VA];
bst_data[`MEMOP_VA] = {addr[47:6], bst_cnt[2:0], 3'b0};
addr = bst_data[`MEMOP_PA];
bst_data[`MEMOP_PA] = {addr[39:6], bst_cnt[2:0], 3'b0};
Insert_in_STB(bst_data, bst_active_thid);
lsu_bst_active[thid] = 1'b0;
if (bst_fgu_err) //set the squash bit to 0 for all the stb entries
for (i = 0; i < 8; i=i+1)
tmp = stb[{thid, i[2:0]}];
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> Squash bit already set when trying to set it for a bst fgu errerr.", core_id, thid, tmp[`MEMOP_PA]);
stb[{thid, i[2:0]}] = tmp;
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> <PA = %0h> STB_entry[%0h] squashed due to FGU err.", core_id, thid, tmp[`MEMOP_PA], i);
`PR_ERROR("lsu_mon", `ERROR, "<C%h>: LSU asserted lsu_stb_alloc = %0h while no store pending to be written in STB.", core_id, `SPC5.lsu_stb_alloc[7:0]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <%0h> W_stage: LSU did not assert lsu_stb_alloc for the store.", core_id, dec_lsu_tid_w, inst_pc_w);
reg [47:0] addr, act_addr;
thid =`SPC5.lsu_rngl_cdbus[58:56];
thid =`SPC5.lsu_rngf_cdbus[58:56];
asi =`SPC5.lsu_rngl_cdbus[55:48];
asi =`SPC5.lsu_rngf_cdbus[55:48];
addr =`SPC5.lsu_rngl_cdbus[47:0];
addr =`SPC5.lsu_rngf_cdbus[47:0];
req_type =`SPC5.lsu_rngl_cdbus[61:60];
req_type =`SPC5.lsu_rngf_cdbus[61:60];
tmp = stb[{thid, iss_ptr[thid]}];
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> Store reissued on the ASI interface.", core_id, thid, addr);
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> Store issued on the ASI interface that has been squashed.", core_id, thid, addr);
act_addr = tmp[`MEMOP_PA];
act_addr = {act_addr[39:3], 3'b0};
//47 is D tag rd asi. LSU issues that on the ring but changes
if ((addr == act_addr) || (asi == 8'h47) || (asi == 8'h46))
stb[{thid, iss_ptr[thid]}] = tmp;
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) STB[%0d] Issued on local ring.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], iss_ptr[thid]);
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) STB[%0d] Issued on fast ring.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], iss_ptr[thid]);
iss_ptr[thid] = iss_ptr[thid] + 1'b1;
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <%0h>: %s(VA=%0h) STB[%0d] PA mismatch for asi req on local ring. Expected PA = %0h, actual PA = %0h", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], iss_ptr[thid], tmp[`MEMOP_PA], addr);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <%0h>: %s(VA=%0h) STB[%0d] PA mismatch for asi req on fast ring. Expected PA = %0h, actual PA = %0h", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], iss_ptr[thid], tmp[`MEMOP_PA], addr);
task chk_store_issue_to_pcx;
reg [39:0] pcx_pa, inst_pa;
thid = pcx_pkt[`PCX_THR_ID];
tmp = stb[{thid, iss_ptr[thid]}];
inst = tmp[`LSU_MON_INST];
pcx_pa = pcx_pkt[`PCX_ADDR];
inst_pa = tmp[`MEMOP_PA];
if (pcx_pkt[`PCX_RQTYP] == `PCX_STORE)
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) STB[%0d] Issued to gasket.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], iss_ptr[thid]);
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) STB[%0d] Issued to gasket with ND set.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], iss_ptr[thid]);
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> A store request made to gasket by LSU while the pending req is not store.", core_id, thid, pcx_pkt[`PCX_ADDR]);
if (pcx_pa[39:0] != inst_pa[39:0])
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> A store request made to gasket by LSU while the pending req has PA %0h.", core_id, thid, pcx_pkt[`PCX_ADDR], tmp[`MEMOP_PA]);
if ((tmp[`INST_ASI] == 8'h73) & (pcx_pa[39:0] != {8'h90, core_id, thid, tmp[`INST_ASI], 18'h0}))
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> pcx_pa is not correct for asi write to interrupt vector dispatch register.", core_id, thid, pcx_pkt[`PCX_ADDR]);
if (inst[`BLKST] && ~pcx_pkt[`PCX_BST])
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> Bst bit is not set in the PCX pkt by LSU for a blk st request.", core_id, thid, pcx_pkt[`PCX_ADDR]);
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> Store reissued on the PCX interface.", core_id, thid, pcx_pkt[`PCX_ADDR]);
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> Store issued on the PCX interface that has been squashed.", core_id, thid, pcx_pkt[`PCX_ADDR]);
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> BIS bit is not set in the PCX pkt by LSU for an RMO store.", core_id, thid, pcx_pkt[`PCX_ADDR]);
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> L2ack bit is set when the RMO store is issued to PCX.", core_id, thid, pcx_pkt[`PCX_ADDR]);
ret_ptr[thid] = ret_ptr[thid] + 1; //this will be deallocated before
//response seen from stub
st_rmo_cnt[thid] = st_rmo_cnt[thid] + 1'b1;
stb[{thid, iss_ptr[thid]}] = tmp;
iss_ptr[thid] = iss_ptr[thid] + 1;
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> iss_ptr = %0d. ret_ptr = %0d, st_rmo_cnt = %0d", core_id, thid, iss_ptr[thid], ret_ptr[thid], st_rmo_cnt[thid]);
`ifdef INJ_STB_ERR_IN_CMP
reg [2:0] err_tid, stb_err_tid_d1, stb_err_tid_d2;
reg [2:0] err_index, stb_err_index_d1, stb_err_index_d2;
reg stb_err_inj, stb_err_inj_d1, stb_err_inj_d2;
reg [1:0] err_priv, stb_err_priv_d1, stb_err_priv_d2;
if (("cmp_stb_err_inj_on"))
always @ (negedge (`SPC5.l2clk & enabled & cmp_stb_err_inj))
//valid stb ram rd for issue to pcx
if (`SPC5.lsu.sbc.ram_rptr_vld_2 & `SPC5.lsu.sbc.st_pcx_rq_p3 & `SPC5.lsu.pic.pic_st_sel_p3)
err_tid = decode_tid(`SPC5.lsu.sbc.st_rq_sel_p3[7:0]);
err_index = `SPC5.lsu.sbc.ram_rptr_d1;
err_tmp = stb[{err_tid, err_index}];
err_inst = err_tmp[`LSU_MON_INST];
cam_data = `SPC5.lsu.stb_cam.cam_array.stb_rdata[44:0];
err_priv = err_tmp[`ST_PRIV];
//if (err_inst[`SWAP] || err_inst[`CASA] || err_inst[`LDSTUB])
err_inj_cnt = err_inj_cnt + 1;
11, 12: err_bit = err_bit + 1;
force `SPC0.lsu.stb_cam.cam_array.stb_rdata[44:0] = cam_data ^ (1 << err_bit);
`PR_INFO("stb_err", 22, "<T%0h> <%0h> STB[%0h]: SBAPP forced for CASA. err_bit = %0h", err_tid, {cam_data[44:8], 3'b0}, err_index, err_bit);
release `SPC0.lsu.stb_cam.cam_array.stb_rdata[44:0];
if (~`SPC5.lsu_sbapp_err_g)
`PR_ERROR("lsu_mon", `ERROR, "<T%0h> sbapp err not asserted when err is injected for atomic.", stb_err_tid_d2);
if ((`SPC5.lsu_stberr_tid_g != stb_err_tid_d2) ||
(`SPC5.lsu_stberr_index_g != stb_err_index_d2) ||
(`SPC5.lsu_stberr_priv_g != stb_err_priv_d2))
`PR_ERROR("lsu_mon", `ERROR, "<T%0h> sbapp err parameters mismatch.", stb_err_tid_d2);
if (`SPC5.lsu_sbapp_err_g)
`PR_ERROR("lsu_mon", `ERROR, "<T%0h> sbapp err asserted when none expected.", `SPC5.lsu_stberr_tid_g);
always @ (posedge (`SPC5.l2clk & enabled & cmp_stb_err_inj))
stb_err_inj_d1 <= stb_err_inj;
stb_err_inj_d2 <= stb_err_inj_d1;
stb_err_tid_d1 <= err_tid;
stb_err_tid_d2 <= stb_err_tid_d1;
stb_err_index_d1 <= err_index;
stb_err_index_d2 <= stb_err_index_d1;
stb_err_priv_d1 <= err_priv;
stb_err_priv_d2 <= stb_err_priv_d1;
// If vcs_build_args NO_MONITORS, then module will be empty
reg [7:0] asi_e, imm_asi_e, asi_m, asi_b;
reg dec_altspace_e, dec_altspace_b, dec_altspace_m;
reg [1:0] exu_lsu_va_error_b;
reg [2:0] dec_lsu_tid_e, dec_lsu_tid_m, dec_lsu_tid_b, dec_lsu_tid_w;
reg [47:0] inst_pc_e, inst_pc_m, inst_pc_b, inst_pc_w;
reg [31:0] inst_e, inst_m, inst_b;
reg [47:0] vaddr_m, vaddr_b;
reg [63:0] int_st_data_m, int_st_data_b;
reg [63:0] fp_st_sata_fx2;
reg [20:0] lsu_inst_e, lsu_inst_m, lsu_inst_b;
reg mmu_dtlb_reload_d1, mmu_dtlb_reload_d2;
reg [`LD_Pend_Width] ld_pend_array[7:0];
reg [`LAST_INST_Pend_Width] last_inst_array[7:0];
reg [2:0] wrptr[7:0]; //Pts. to the STB entry into which data will be written next
reg [2:0] rdptr[7:0]; //Tracks the dealloc signal from STB
reg [2:0] iss_ptr[7:0]; //keeps track of when a store is issued from the STB to PCX
reg [2:0] ret_ptr[7:0]; //keeps track of when the response is received from
reg [`STB_Pend_Width] stb[63:0];
//reg [`TLB_MISS_Pend_Width] tlbmiss_pend_array[7:0];
reg [7:0] dcache_inv_cnt[7:0];
reg [7:0] st_rmo_cnt[7:0];
reg [31:0] dec_tg0_inst_d, dec_tg1_inst_d;
reg [7:0] lsu_bst_active;
reg [195:0] stb_alloc_data;
reg [195:0] bst_data, bst_inst_data;
reg [2:0] bst_active_thid;
reg [7:0] is_blkld; //reqd by lsu_ras_chkr to chk errors on blk ld.
reg [1:0] l2_blk_ld_errtype[7:0]; //Gives the type of err the ahd be reported by LSU if
//different types of err occur on blk ld helper returns
reg [1:0] st_priv[7:0]; //Gives the final priv level for an sbdiou/sbapp err that shd be
for (i = 0; i < 8; i = i+1)
l2_blk_ld_errtype[i] = 2'b0;
// avoid time zero ugliness. jp
//@(posedge `SPC0.l2clk);
//@(negedge `SPC0.l2clk);
//if (`PARGS.lsu_mon_on) enabled = 1;
3'h0: finish_mask = `PARGS.finish_mask[7:0];
3'h1: finish_mask = `PARGS.finish_mask[15:8];
3'h2: finish_mask = `PARGS.finish_mask[23:16];
3'h3: finish_mask = `PARGS.finish_mask[31:24];
3'h4: finish_mask = `PARGS.finish_mask[39:32];
3'h5: finish_mask = `PARGS.finish_mask[47:40];
3'h6: finish_mask = `PARGS.finish_mask[55:48];
3'h7: finish_mask = `PARGS.finish_mask[63:56];
if (~`TOP.in_reset & `PARGS.lsu_mon_on & ~reset_in_middle)
`PR_ALWAYS("lsu_mon", `ALWAYS, "Lsu_mon on, in_reset = 0.");
if (`TOP.in_reset & enabled)
`PR_ALWAYS("lsu_mon", `ALWAYS, "Reset asserted in the middle of the diag. Turned off Lsu_mon.");
always @ (posedge (tb_top.sim_status[0] & enabled))
if (|(ld_valid[7:0] & finish_mask[7:0]))
for (i = 0; i < 8; i=i+1)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> Ld requests pending at the end of simulation. ld_valid = %0h", core_id, ld_valid);
for (i = 0; i < 64; i=i+1)
if (stb_valid[i] & finish_mask[i[5:3]])
//chkr resets the stb valid bits when block_store_kill is asserted.
//in couple of failures block_store_kill was sampled asserted two cycles after
//lsu asserted stb_empty. The simulation ended the cycle stb_empty was sampled high
//causing moniotr firings with valid entries in stb at end of simulation. Now
//don't flag an error if squash bit is set and stb_valid is asserted at end
if (~is_squash_bit_set(i[5:0]))
Disp_STB_entry(i[5:3],i[2:0]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> Store requests pending at the end of simulation. stb_valid = %0h", core_id, stb_valid);
for (i = 0; i < 8; i=i+1)
if (finish_mask[i] & (pf_cnt[i] != 0))
`PR_ALWAYS("lsu_mon", `ALWAYS, "<C%h> <T%0h> Prefetches not finished. Pf_cnt = %0d", core_id, i, pf_cnt[i]);
if (finish_mask[i] & (dcache_inv_cnt[i] != 0))
`PR_ALWAYS("lsu_mon", `ALWAYS, "<C%h> <T%0h> D pkt not received for all invalidate reqs. issued by the thread. dcache_inv_cnt = %0d", core_id, i, dcache_inv_cnt[i]);
if (finish_mask[i] & (st_rmo_cnt[i] != 0))
`PR_ALWAYS("lsu_mon", `ALWAYS, "<C%h> <T%0h> rmo_cnt not zero. rmo_cnt = %0d", core_id, i, st_rmo_cnt[i]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> Prefetch/D/RMO_stores requests pending at the end of simulation.", core_id);
function is_squash_bit_set;
is_squash_bit_set = 1'b1;
is_squash_bit_set = 1'b0;
always @ (negedge (`SPC6.l2clk & enabled))
asi_e = `SPC6.lsu.dcc.dcc_asi_e[7:0];
lsu_inst_e[`LD] <= `SPC6.dec_ld_inst_e;
lsu_inst_e[`ST] <= `SPC6.dec_st_inst_e;
lsu_inst_e[`FP] <= `SPC6.dec_fpldst_inst_e;
lsu_inst_e[`PREF] <= `SPC6.dec_pref_inst_e;
lsu_inst_e[`SWAP] <= `SPC6.dec_swap_inst_e;
lsu_inst_e[`CASA] <= `SPC6.dec_casa_inst_e;
lsu_inst_e[`LDSTUB] <= `SPC6.dec_ldstub_inst_e;
lsu_inst_e[`FLUSH] <= `SPC6.dec_flush_inst_e;
lsu_inst_e[`MEMBAR] <= `SPC6.dec_memstbar_inst_e;
lsu_inst_e[`LDD] <= `SPC6.dec_ld_inst_e & `SPC6.dec_ldst_dbl_e & ~`SPC6.dec_fpldst_inst_e;
lsu_inst_e[`STD] <= `SPC6.dec_st_inst_e & `SPC6.dec_ldst_dbl_e & ~`SPC6.lsu.dec_fpldst_inst_e;
lsu_inst_e[`BLKLD] <= `SPC6.dec_ld_inst_e & `SPC6.dec_fpldst_inst_e & dec_altspace_e & Is_blk_asi(asi_e);
lsu_inst_e[`BLKST] <= `SPC6.dec_st_inst_e & `SPC6.dec_fpldst_inst_e & dec_altspace_e & Is_blk_asi(asi_e);
lsu_inst_e[`QLD] <= `SPC6.dec_ld_inst_e & dec_altspace_e & Is_qld_asi(asi_e);
lsu_inst_e[`ASR_RD_WR] <= `SPC6.dec_sr_inst_e & (`SPC6.dec_ld_inst_e | `SPC6.dec_st_inst_e);
lsu_inst_e[`PR_RD_WR] <= `SPC6.dec_pr_inst_e & (`SPC6.dec_ld_inst_e | `SPC6.dec_st_inst_e);
lsu_inst_e[`HPR_RD_WR] <= `SPC6.dec_hpr_inst_e & (`SPC6.dec_ld_inst_e | `SPC6.dec_st_inst_e);
lsu_inst_e[`FSR_RD_WR] <= `SPC6.dec_fsr_ldst_e & (`SPC6.dec_ld_inst_e | `SPC6.dec_st_inst_e);
always @ (posedge (`SPC6.l2clk & enabled))
dec_tg0_inst_d <= `SPC6.dec.ded0.decode_mux[31:0];
dec_tg1_inst_d <= `SPC6.dec.ded1.decode_mux[31:0];
imm_asi_vld_e <= `SPC6.lsu.dec_imm_asi_vld_d;
imm_asi_e <= `SPC6.lsu.dec_imm_asi_d;
dec_altspace_e <= `SPC6.dec_altspace_d;
dec_altspace_m <= dec_altspace_e;
dec_altspace_b <= dec_altspace_m;
exu_ecc_b <= `SPC6.exu_ecc_m;
exu_lsu_va_error_b <= `SPC6.exu_lsu_va_error_m;
dec_lsu_tid_e <= `SPC6.dec_lsu_tg_d ? {1'b1, `SPC6.dec_lsu_tid1_d} : {1'b0, `SPC6.dec_lsu_tid0_d};
dec_lsu_tid_m <= dec_lsu_tid_e;
dec_lsu_tid_b <= dec_lsu_tid_m;
dec_lsu_tid_w <= dec_lsu_tid_b;
inst_pc_e <= `SPC6.dec_lsu_tg_d ? {`SPC6.tlu.tlu_pc_1_d[47:2], 2'b0} : {`SPC6.tlu.tlu_pc_0_d[47:2], 2'b0};
inst_e <= `SPC6.dec_lsu_tg_d ? dec_tg1_inst_d : dec_tg0_inst_d;
vaddr_m <= `SPC6.exu_lsu_address_e;
int_st_data_m <= `SPC6.exu_lsu_store_data_e;
int_st_data_b <= int_st_data_m;
fp_st_sata_fx2 <= `SPC6.fgu_lsu_fst_data_fx1;
mmu_dtlb_reload_d1 <= `SPC6.mmu_dtlb_reload;
mmu_dtlb_reload_d2 <= mmu_dtlb_reload_d1;
//pcx_thid_d1 <= `SPC6.lsu.spc_pcx_data_pa[`PCX_THR_ID];
lsu_inst_m <= lsu_inst_e;
lsu_inst_b <= lsu_inst_m;
Is_blk_asi = (asi == `ASI_BLK_AIUP) | (asi == `ASI_BLK_AIUS) |
(asi == `ASI_BLK_AIUPL) | (asi == `ASI_BLK_AIUSL) |
(asi == `ASI_BLK_P) | (asi == `ASI_BLK_S) |
(asi == `ASI_BLK_PL) | (asi == `ASI_BLK_SL) |
(asi == `ASI_BLK_COMMIT_P) | (asi == `ASI_BLK_COMMIT_S);
Is_qld_asi = (asi == `ASI_AIU_BIS_QUAD_LDD_P) | (asi == `ASI_AIU_BIS_QUAD_LDD_S) |
(asi == `ASI_AIU_BIS_QUAD_LDD_P_LITTLE) | (asi == `ASI_AIU_BIS_QUAD_LDD_S_LITTLE) |
(asi == `ASI_NUCLEUS_BIS_QUAD_LDD) | (asi == `ASI_NUCLEUS_BIS_QUAD_LDD_LITTLE) |
(asi == `ASI_BIS_QUAD_LDD_P) | (asi == `ASI_BIS_QUAD_LDD_S) |
(asi == `ASI_BIS_QUAD_LDD_P_LITTLE) | (asi == `ASI_BIS_QUAD_LDD_S_LITTLE) |
(asi == `ASI_QUAD_LDD) | (asi == `ASI_QUAD_LDD_REAL) |
(asi == `ASI_QUAD_LDD_L) | (asi == `ASI_QUAD_LDD_REAL_L);
Is_bis_asi = (asi == `ASI_AIU_BIS_QUAD_LDD_P) | (asi == `ASI_AIU_BIS_QUAD_LDD_S) |
(asi == `ASI_AIU_BIS_QUAD_LDD_P_LITTLE) | (asi == `ASI_AIU_BIS_QUAD_LDD_S_LITTLE) |
(asi == `ASI_NUCLEUS_BIS_QUAD_LDD) | (asi == `ASI_NUCLEUS_BIS_QUAD_LDD_LITTLE) |
(asi == `ASI_BIS_QUAD_LDD_P) | (asi == `ASI_BIS_QUAD_LDD_S) |
(asi == `ASI_BIS_QUAD_LDD_P_LITTLE) | (asi == `ASI_BIS_QUAD_LDD_S_LITTLE);
always @ (negedge (`SPC6.l2clk & enabled))
`PR_INFO("lsu_mon", 21, "<C%0h> <T%0h> <%0h> M_stage: %s(VA=%0h) Flushed due to IFU Flush.", core_id, dec_lsu_tid_m, inst_pc_m, tb_top.intf0.xlate(inst_m),vaddr_m);
if (lsu_inst_b[`BLKLD]) print_inst = " BLKLD,";
else if (lsu_inst_b[`BLKST]) print_inst = " BLKST,";
else if (lsu_inst_b[`QLD]) print_inst = " QLD,";
`PR_INFO("lsu_mon", 21, "<C%0h> <T%0h> <%0h> B_stage: %s(VA=%0h) Flushed due to IFU Flush.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b);
else if (`SPC6.tlu_flush_lsu_b)
`PR_INFO("lsu_mon", 21, "<C%h> <T%0h> <%0h> B_stage: %s(VA=%0h) Flushed due to TLU Flush.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b);
//casa is a two cycle operation. If there is an err on the 2nd cycle of casa then also
//This function will also chk for errors on 2nd cycle.
else if (Is_exu_error(exu_lsu_va_error_b, exu_ecc_b))
`PR_INFO("lsu_mon", 21, "<C%h> <T%0h <%0h> B_stage: %s(VA=%0h) Flushed due to EXU error.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b);
else if ((`SPC6.fgu_cecc_fx2 || `SPC6.fgu_uecc_fx2) && lsu_inst_b[`ST] && lsu_inst_b[`FP])
`PR_INFO("lsu_mon", 21, "<C%h> <T%0h> <%0h> B_stage: %s(VA=%0h) Flushed due to FGU error.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b);
else if (!`SPC6.lsu_tlb_miss_b_)
`PR_INFO("lsu_mon", 23, "<C%h> <T%0h> <%0h> B_stage: %s(VA=%0h)%s ASI = %0h. DTLB miss.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b, print_inst, asi_b);
//Lsu doesn't assert lsu_sync for an exception or dtlb miss. Since for
//an exception tlu anyway tells the front end to flush itself there is
//no reason for LSU to flush the front end then TLU to flush it again.
//Lsu treats the dtlbmiss as an exception that it flushes the inst and
//handles it when it is reissued by the front end.
if (`SPC6.lsu_tlb_bypass_b)
if (`SPC6.lsu_sync != 8'b0)
`PR_INFO("lsu_mon", 23, "<C%h> <T%0h> <%0h>: %s(VA=%0h)%s PA = %0h, ASI = %0h. LSU_sync. DTLB Bypass.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b, print_inst, {`SPC6.lsu.tlb_pgnum[39:13], vaddr_b[12:0]}, asi_b);
`PR_INFO("lsu_mon", 23, "<C%h> <T%0h> <%0h>: %s(VA=%0h)%s PA = %0h, ASI = %0h. DTLB Bypass.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b, print_inst, {`SPC6.lsu.tlb_pgnum[39:13], vaddr_b[12:0]}, asi_b);
if (`SPC6.lsu_sync != 8'b0)
`PR_INFO("lsu_mon", 23, "<C%h> <T%0h> <%0h>: %s(VA=%0h)%s PA = %0h, ASI = %0h, Store_data = %0h. LSU_sync. DTLB hit.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b, print_inst, {`SPC6.lsu.tlb_pgnum[39:13], vaddr_b[12:0]}, asi_b,int_st_data_b);
`PR_INFO("lsu_mon", 23, "<C%h> <T%0h> <%0h>: %s(VA=%0h)%s PA = %0h, ASI = %0h. LSU_sync. DTLB hit.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b, print_inst, {`SPC6.lsu.tlb_pgnum[39:13], vaddr_b[12:0]}, asi_b);
`PR_INFO("lsu_mon", 23, "<C%h> <T%0h> <%0h>: %s(VA=%0h)%s PA = %0h, ASI = %0h, Store_data = %0h. DTLB hit.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b, print_inst, {`SPC6.lsu.tlb_pgnum[39:13], vaddr_b[12:0]}, asi_b, int_st_data_b);
`PR_INFO("lsu_mon", 23, "<C%h> <T%0h> <%0h>: %s(VA=%0h)%s PA = %0h, ASI = %0h. DTLB hit.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b, print_inst, {`SPC6.lsu.tlb_pgnum[39:13], vaddr_b[12:0]}, asi_b);
if (lsu_inst_b[`LD] || lsu_inst_b[`PREF] || lsu_inst_b[`SWAP] || lsu_inst_b[`CASA] || lsu_inst_b[`LDSTUB])
if (((lsu_inst_b == 16'h1) || (lsu_inst_b == 16'h5)) & `SPC6.lsu.stb_cam_hit)
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> <%0h>: LSU_sync asserted due to STB RAW.", core_id, dec_lsu_tid_b, inst_pc_b);
if (lsu_inst_b[`ST]) //for atomics both ld and store signals are asserted
Insert_in_last_inst_array;
if (`SPC6.lsu_trap_flush[7:0])
`PR_INFO("lsu_mon", 21, "<C%h> <T%0h> Trap Flush asserted.", core_id, decode_tid(`SPC6.lsu_trap_flush[7:0]));
//This is how we test squashing of stores by LSU_mon:
//Whenever lsu asserts err_sbdiou signal, the monitor sets the squash
//bit in the STB for the rest of the stores. If any of these squashed stores
//is issued on the asi ring or to the PCX interface the monitor complains.
//The squashed stores are deallocated when either a block_store_kill is
//asserted or dealloc signals are asserted by the LSU.
//When the block_store_kill is asserted, it tells the IFU to dealloc
//all the pending stores in the IFU. It means the when block_store_kill
//is asserted we have deallocated all the non-squashed requests from STB.
//The 0in_chkr ensures that LSU flags the correct index and priv with the
//the sbdiou signal to TLU.
always @ (negedge (`SPC6.l2clk & enabled))
if (`SPC6.lsu_l15_valid & `SPC6.lsu.spc_pcx_data_pa[129])
Chk_pcx_req_pkt(`SPC6.lsu.spc_pcx_data_pa[129:0]); //chk if we need .lsu here
if ((`SPC6.lsu_rngl_cdbus[64:63] == 2'b11) & ~`SPC6.lsu_rngl_cdbus[59])
Chk_st_on_ASI_ring(`LOCAL);
if ((`SPC6.lsu_rngf_cdbus[64:63] == 2'b11) & ~`SPC6.lsu_rngf_cdbus[59])
Chk_st_on_ASI_ring(`FAST);
//if (`SPC6.l15_lsu_valid)
//Chk_cpx_response_pkt({`SPC6.l15_lsu_valid, `SPC6.l15_lsu_cpkt[17:13],`SPC6.l15_lsu_cpkt[11:0],`SPC6.l15_spc_data1[127:0]});
if (`SPC6.cpx_spc_data_cx[145])
Chk_cpx_response_pkt(`SPC6.cpx_spc_data_cx);
if (`SPC6.lsu_complete[7:0] != 8'b0)
if (`SPC6.lsu_complete[0]) Chk_ld_complete(0);
if (`SPC6.lsu_complete[1]) Chk_ld_complete(1);
if (`SPC6.lsu_complete[2]) Chk_ld_complete(2);
if (`SPC6.lsu_complete[3]) Chk_ld_complete(3);
if (`SPC6.lsu_complete[4]) Chk_ld_complete(4);
if (`SPC6.lsu_complete[5]) Chk_ld_complete(5);
if (`SPC6.lsu_complete[6]) Chk_ld_complete(6);
if (`SPC6.lsu_complete[7]) Chk_ld_complete(7);
if (`SPC6.lsu_block_store_kill[7:0] != 8'b0)
if (`SPC6.lsu_block_store_kill[0]) Squash_STB(0);
if (`SPC6.lsu_block_store_kill[1]) Squash_STB(1);
if (`SPC6.lsu_block_store_kill[2]) Squash_STB(2);
if (`SPC6.lsu_block_store_kill[3]) Squash_STB(3);
if (`SPC6.lsu_block_store_kill[4]) Squash_STB(4);
if (`SPC6.lsu_block_store_kill[5]) Squash_STB(5);
if (`SPC6.lsu_block_store_kill[6]) Squash_STB(6);
if (`SPC6.lsu_block_store_kill[7]) Squash_STB(7);
if (`SPC6.lsu_stb_dealloc[7:0] != 8'b0)
if (`SPC6.lsu_stb_dealloc[0]) Dealloc_STB(0);
if (`SPC6.lsu_stb_dealloc[1]) Dealloc_STB(1);
if (`SPC6.lsu_stb_dealloc[2]) Dealloc_STB(2);
if (`SPC6.lsu_stb_dealloc[3]) Dealloc_STB(3);
if (`SPC6.lsu_stb_dealloc[4]) Dealloc_STB(4);
if (`SPC6.lsu_stb_dealloc[5]) Dealloc_STB(5);
if (`SPC6.lsu_stb_dealloc[6]) Dealloc_STB(6);
if (`SPC6.lsu_stb_dealloc[7]) Dealloc_STB(7);
if (`SPC6.lsu_block_store_stall)
if (`SPC6.lsu.lsu_block_store_alloc[7:0] != 8'b0)
Set_block_store_parameters;
if (`SPC6.lsu_sbdiou_err_g || `SPC6.lsu_sbapp_err_g)
if (`SPC6.lsu_stb_flush_g)
st_priv[`SPC6.lsu_stberr_tid_g] = get_priv_on_flush(`SPC6.lsu_stberr_tid_g);
function [1:0] get_priv_on_flush;
sq_index = `SPC6.lsu_stberr_index_g;
tmp = stb[{tid, sq_index}];
get_priv_on_flush = tmp[`ST_PRIV];
thid = `SPC6.lsu_block_store_tid;
bst_inst_data = stb[{thid, rdptr[thid]}];
inst = bst_inst_data[`LSU_MON_INST];
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> LSU asserted blk_store_stall while the req at the top of STB is not blkst as shown above", core_id, thid);
//lsu can assert block_store_stall for a new block store while it has not yet written
//the 8 stb entries from the previous blk store.
task Set_block_store_parameters;
thid = decode_tid(`SPC6.lsu.lsu_block_store_alloc[7:0]);
if (lsu_bst_active[thid])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> LSU asserted blk_store_alloc while the bst_active is already set for this thread.", core_id, thid);
lsu_bst_active[thid] = 1'b1;
if (`SPC6.lsu.fgu_fst_ecc_error_fx2)
thid = `SPC6.lsu_stberr_tid_g;
sq_index = `SPC6.lsu_stberr_index_g;
priv = `SPC6.lsu_stberr_priv_g;
tmp = stb[{thid, sq_index}];
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> Sbdiou/sbapp seen for index = %h and priv = %h.", core_id, thid, sq_index, priv);
st_priv[thid] = tmp[`ST_PRIV];
//lsu can assert deallocate before it asserts the sbdiou signal.
//In that case iss_ptr won't be equal to sbdiou index.
//if (sq_index != iss_ptr[thid])
// Disp_STB_entry(thid, iss_ptr[thid]);
// `PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> LSU asserted sbdiou/sbapp with index %0h while the next req to be issued is at index %0h.", core_id, thid, sq_index, iss_ptr[thid]);
//If there is only one store in the store buffer which gets an sbdiou error, then LSU can deallocate
//the store and then assert sbdiou. The deallocation will cause the stb issue_ptr to move
//forward to an inst. that has already been issued and completed and this chk can fire. So
// Disp_STB_entry(thid, iss_ptr[thid]);
// `PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> Store reissued on the PCX interface.", core_id, thid, tmp[`MEMOP_PA]);
if (iss_ptr[thid] == wrptr[thid])
if (stb_valid[{thid, wrptr[thid]}])
//changing it to an info message because if there is only one valid entry in store buffer that
//gets an sbdiou then LSU can deallocate the entry and then issue sbdiou.
//`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Lsu asserted sbdiou/sbapp while there are no valid entries in STB to be issued.", core_id, thid);
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> sbdiou/sbapp squashed only one entry in STB.", core_id, thid);
if (iss_ptr[thid] < wrptr[thid])
squash_cnt = wrptr[thid] - iss_ptr[thid];
else if (iss_ptr[thid] > wrptr[thid])
squash_cnt = wrptr[thid] + (8 - iss_ptr[thid]);
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> SQUASH_STORE:iss_ptr = %0h, wrptr = %0h, squash_cnt = %0h.", core_id, thid, iss_ptr[thid], wrptr[thid], squash_cnt);
if (priv < tmp[`ST_PRIV])
`PR_INFO("lsu_mon", `INFO, "<C%h> <T%0h> <PA = %0h> Sbdiou/sbapp signalled. Err in user/priv level store is squashing a higher priv level store.", core_id, thid, tmp[`MEMOP_PA]);
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> <PA = %0h> STB_entry[%0h] squashed.", core_id, thid, tmp[`MEMOP_PA], i);
squash_cnt = squash_cnt - 1'b1;
function [2:0] decode_tid;
8'h10: decode_tid = 3'h4;
8'h20: decode_tid = 3'h5;
8'h40: decode_tid = 3'h6;
8'h80: decode_tid = 3'h7;
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> decode_tid. Incorrect value of thid input = %0h.", core_id, thid_encode, thid_encode);
reg [`LD_Pend_Width] tmp;
tmp = ld_pend_array[thid];
if ((tmp[`L2_ISS] != 4'hf) || (tmp[`L2_RESP] != 4'hf))
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> LSU asserted lsu_complete while the l2_iss and l2_resp bits are not F.", core_id, thid);
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> <%0h> %s(VA=%0h) Complete. Setting ld_valid to 0.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA]);
tmp = last_inst_array[thid];
`PR_INFO("lsu_mon", 24, "<C%h> <T%0h> <%0h> %s(VA=%0h) Complete.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA]);
reg [`LD_Pend_Width] tmp, tmp1;
thid = pcx_pkt[`PCX_THR_ID];
tmp = ld_pend_array[thid];
inst = tmp[`LSU_MON_INST];
req = DispPCXReq(pcx_pkt);
addr = pcx_pkt[`PCX_ADDR];
if (pcx_pkt[`PCX_CPU_ID] != core_id)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> cpu_id (spc_pcx_data_pa[122:120]) = %h is not = %0h when the lsu made a %s req to gasket.", core_id, pcx_pkt[`PCX_THR_ID], addr, pcx_pkt[122:120], core_id, req);
if ((pcx_pkt[`PCX_RQTYP] == `PCX_LOAD) || (pcx_pkt[`PCX_RQTYP] == `PCX_CAS1) || (pcx_pkt[`PCX_RQTYP] == `PCX_CAS2) || (pcx_pkt[`PCX_RQTYP] == `PCX_SWAP_LDSTUB))
ld_valid[thid] = 1'b1; //we have sent a req to gasket and are waiting for response
`PR_INFO("lsu_mon", 22, "<C%0h> <T%0h> Setting ld_valid[%0h].", core_id, thid, thid);
if (tmp[`MEMOP_PA] != addr)
if ((tmp[`INST_ASI] == 8'h41) || (tmp[`INST_ASI] == 8'h73) || ((tmp[`INST_ASI] == 8'h45) && ((tmp[`MEMOP_PA] == 8'h10) || (tmp[`MEMOP_PA] == 8'h18))))
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <PA = %0h> PA mismatch on gasket for %s request. Ignoring the mismatch as inst. is issued with asi 41, 73 or 45 (with VA 0x10 or 18).", core_id, thid, addr, req);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> A %s request made to gasket by LSU while the pending req is with PA %0h.", core_id, thid, addr, req, tmp[`MEMOP_PA]);
case (pcx_pkt[`PCX_RQTYP])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> A prefetch request made to gasket by LSU which mismatches the pending request from the thread.", core_id, thid, addr);
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: PREF_ICE(VA=%0h) Issued. pf_cnt not updated.", core_id, thid, tmp[`INST_VA], tmp[`MEMOP_VA]);
pf_cnt[thid] = pf_cnt[thid] + 1'b1;
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) Issued. pf_cnt = %0d.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], pf_cnt[thid]);
tmp[`L2_RESP] = 4'hF; //we don't wait for a prefetch response from gasket
ld_pend_array[thid] = tmp;
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) Dcache invalidate pkt issued to CCX.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA]);
dcache_inv_cnt[thid] = dcache_inv_cnt[thid] + 1'b1;
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> CASA request made to gasket by LSU while no such request request is pending from this thread.", core_id, thid, addr);
if (pcx_pkt[`PCX_RQTYP] == `PCX_CAS1)
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) (CAS1) Issued to gasket.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA]);
ld_pend_array[thid] = tmp;
if (pcx_pkt[`PCX_RQTYP] == `PCX_CAS2)
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) (CAS2) Issued to gasket.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA]);
ld_pend_array[thid] = tmp;
chk_store_issue_to_pcx(pcx_pkt);
if (~inst[`SWAP] && ~inst[`LDSTUB])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> %s request made to gasket by LSU while no such request request is pending from this thread.", core_id, thid, addr, req);
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) Issued to gasket. store_data = %0h", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], pcx_pkt[`PCX_DATA]);
ld_pend_array[thid] = tmp;
chk_store_issue_to_pcx(pcx_pkt);
chk_store_issue_to_pcx(pcx_pkt);
default: `PR_INFO("lsu_mon", 21, "<C%h> <T%0h> <%0h>: %s Issued to gasket.", core_id, thid, addr, req);
task Chk_cpx_response_pkt;
thid = cpx_pkt[`CPX_THR_ID];
casex ({cpx_pkt[`CPX_RTNTYP], cpx_pkt[`CPX_ERR], cpx_pkt[`CPX_NC], cpx_pkt[`CPX_ATM], cpx_pkt[`CPX_PF]})
{4'b0, 2'bxx, 1'bx, 1'b0, 1'b0}:
chk_ccx_ld_response(cpx_pkt);
{4'b0, 2'bxx, 1'b1, 1'b0, 1'b1}:
if (pf_cnt[thid] == 8'b0)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Prefetch response received from gasket while the pf_cnt is 0 for this thread.", core_id, thid);
pf_cnt[thid] = pf_cnt[thid] - 1'b1;
`PR_INFO("lsu_mon", 26, "<C%h> <T%0h> Prefetch response received. pfcnt = %0d.", core_id, thid, pf_cnt[thid]);
{4'h8, 2'bxx, 1'b1, 1'b0, 1'b0}:
chk_ccx_ld_response(cpx_pkt);
{4'h4, 2'bxx, 1'bx, 1'b0, 1'b0}:
if (cpx_pkt[123]) //D pkt
if (cpx_pkt[120:118] != core_id)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> D response received from gasket with core_id =%h.", core_id, thid, cpx_pkt[120:118]);
if (dcache_inv_cnt[thid] == 8'b0)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> D response received from gasket while the Dcache_inv_cnt is 0 for this thread.", core_id, thid);
dcache_inv_cnt[thid] = dcache_inv_cnt[thid] - 1'b1;
`PR_INFO("lsu_mon", 26, "<C%h> <T%0h> D response received. Dcache_inv_cnt = %0d.", core_id, thid, dcache_inv_cnt[thid]);
else if (cpx_pkt[124]) //I pkt
if (cpx_pkt[120:118] != core_id)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> I response received from gasket with core_id =%h.", core_id, thid, cpx_pkt[120:118]);
//`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> I pkt.", core_id, thid);
else if (cpx_pkt[124:123] == 2'b0)
if (cpx_pkt[120:118] == core_id)
chk_ccx_st_response(cpx_pkt);
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> Store Ack pkt received from core %0h.", core_id, thid, cpx_pkt[120:118]);
{4'h1, 2'bxx, 1'bx, 1'b0, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> IFILL1 return.", core_id, thid);
{4'h1, 2'bxx, 1'bx, 1'b1, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> IFILL2 return.", core_id, thid);
{4'h9, 2'bxx, 1'b1, 1'b0, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> NCU IFILL return.", core_id, thid);
{4'b0, 2'bxx, 1'b1, 1'b1, 1'b0}:
chk_ccx_atm_response(cpx_pkt);
{4'h4, 2'bxx, 1'b1, 1'b1, 1'b0}:
if ((cpx_pkt[`CPX_RTNTYP] == 4'h4) & (cpx_pkt[120:118] == core_id))
chk_ccx_atm_response(cpx_pkt);
chk_ccx_st_response(cpx_pkt);
{4'h2, 2'bxx, 1'b1, 1'b0, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> Stream Ld return.", core_id, thid);
{4'h6, 2'bxx, 1'bx, 1'bx, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> Stream store Ack.", core_id, thid);
{4'h5, 2'bxx, 1'b1, 1'b0, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> MMU ld return.", core_id, thid);
{4'h7, 2'b00, 1'b0, 1'bx, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> Interrupt return.", core_id, thid);
{4'h3, 2'b00, 1'bx, 1'bx, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> Eviction Invalidation.", core_id, thid);
{4'hc, 2'bxx, 1'bx, 1'bx, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> L2 Indication.", core_id, thid);
{4'hd, 2'bxx, 1'bx, 1'bx, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> Soc Error Indication.", core_id, thid);
`PR_ALWAYS("lsu_mon", `ALWAYS, "CPX_PKT data.");
`PR_ALWAYS("lsu_mon", `ALWAYS, "<C%0h> <T%0h> rtn_typ = %0h, err_bits = %0h, nc=%0b, atm = %0b, pf = %0b", core_id, cpx_pkt[`CPX_THR_ID], cpx_pkt[`CPX_RTNTYP], cpx_pkt[`CPX_ERR], cpx_pkt[`CPX_NC], cpx_pkt[`CPX_ATM], cpx_pkt[`CPX_PF]);
`PR_ERROR("lsu_mon", `ERROR, "<C%0h> <T%0h> Can't recognise the CPX pkt.", core_id, thid);
task chk_ccx_ld_response;
reg [39:0] cpx_pa, inst_pa;
reg [`LD_Pend_Width] tmp;
thid = cpx_pkt[`CPX_THR_ID];
tmp = ld_pend_array[thid];
inst = tmp[`LSU_MON_INST];
inst_pa = tmp[`MEMOP_PA];
pkt_type = cpx_pkt[`CPX_RTNTYP];
`PR_INFO("lsu_mon", 26, "<C%0h> <T%0h> <%0h> %s(VA=%0h) L2 response.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA]);
if (inst_pa[39] != pkt_type[3])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> ccx pkt_type = %h mismatches the ld_pa bit 39. ld_pa = %0h.", core_id, thid, pkt_type, inst_pa);
if (tmp[`L2_RESP] == 4'h0)
tmp[`L2_ERR0] = cpx_pkt[`CPX_ERR];
if ((cpx_pkt[`CPX_ERR] == `ND) || (cpx_pkt[`CPX_ERR] == `UE))
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> UE/ND err on blk ld helper 1.", core_id, thid);
else if (tmp[`L2_RESP] == 4'h1)
tmp[`L2_ERR1] = cpx_pkt[`CPX_ERR];
if ((cpx_pkt[`CPX_ERR] == `ND) || (cpx_pkt[`CPX_ERR] == `UE))
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> UE/ND err on blk ld helper 2.", core_id, thid);
else if (tmp[`L2_RESP] == 4'h3)
tmp[`L2_ERR2] = cpx_pkt[`CPX_ERR];
if ((cpx_pkt[`CPX_ERR] == `ND) || (cpx_pkt[`CPX_ERR] == `UE))
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> UE/ND err on blk ld helper 3.", core_id, thid);
else if (tmp[`L2_RESP] == 4'h7)
tmp[`L2_ERR3] = cpx_pkt[`CPX_ERR];
if ((cpx_pkt[`CPX_ERR] == `ND) || (cpx_pkt[`CPX_ERR] == `UE))
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> UE/ND err on blk ld helper 4.", core_id, thid);
if ((tmp[`L2_ERR0] == `ND) || (tmp[`L2_ERR1] == `ND) || (tmp[`L2_ERR2] == `ND) || (tmp[`L2_ERR3] == `ND))
l2_blk_ld_errtype[thid] = `ND;
else if ((tmp[`L2_ERR0] == `UE) || (tmp[`L2_ERR1] == `UE) || (tmp[`L2_ERR2] == `UE) || (tmp[`L2_ERR3] == `UE))
l2_blk_ld_errtype[thid] = `UE;
else if ((tmp[`L2_ERR0] == `CE) || (tmp[`L2_ERR1] == `CE) || (tmp[`L2_ERR2] == `CE) || (tmp[`L2_ERR3] == `CE))
l2_blk_ld_errtype[thid] = `CE;
l2_blk_ld_errtype[thid] = `NE;
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Illegal value of l2_resp cnt when response pkt received from ccx.", core_id, thid);
else if (Is_single_pcx_req_ld(inst))
if (tmp[`L2_RESP] != 4'hE)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Illegal value of l2_resp cnt when response pkt received from ccx.", core_id, thid);
//`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> Setting L2_resp bits to F.", core_id, thid);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Load response received from gasket for thid %h while no load request pending from core for this thread.", core_id, thid, thid);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Load response received from gasket while no load request pending from core for this thread.", core_id, thid);
ld_pend_array[thid] = tmp;
task chk_ccx_atm_response;
reg [`LD_Pend_Width] tmp;
thid = cpx_pkt[`CPX_THR_ID];
tmp = ld_pend_array[thid];
inst = tmp[`LSU_MON_INST];
inst_pa = tmp[`MEMOP_PA];
if (cpx_pkt[`CPX_RTNTYP] == 4'b0)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Atomic ld response received from gasket while no request pending from core for this thread.", core_id, thid);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Atomic ack response received from gasket while no request pending from core for this thread.", core_id, thid);
if (~inst[`SWAP] && ~inst[`CASA] && ~inst[`LDSTUB])
if (cpx_pkt[`CPX_RTNTYP] == 4'b0)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Atomic ld response received from gasket which mismatches the request pending from this thread.", core_id, thid);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Atomic ack response received from gasket which mismatches the request pending from this thread.", core_id, thid);
if (cpx_pkt[`CPX_RTNTYP] == 4'b0)
`PR_INFO("lsu_mon", 26, "<C%0h> <T%0h> <%0h> %s(VA=%0h) Atomic ld response.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA]);
`PR_INFO("lsu_mon", 26, "<C%0h> <T%0h> <%0h> %s(VA=%0h) Atomic ack.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA]);
if (cpx_pkt[`CPX_RTNTYP] == 4'b0)
if (tmp[`L2_RESP] == 4'hC) tmp[`L2_RESP] = 4'hD;
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Illegal value of l2_resp cnt when atomic ld return pkt received from ccx.", core_id, thid);
if (tmp[`L2_RESP] == 4'hD) tmp[`L2_RESP] = 4'hF;
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Illegal value of l2_resp cnt when atomic ack pkt received from ccx.", core_id, thid);
ld_pend_array[thid] = tmp;
task chk_ccx_st_response;
reg [39:0] cpx_pa, inst_pa;
thid = cpx_pkt[`CPX_THR_ID];
tmp = stb[{thid, ret_ptr[thid]}];
inst = tmp[`LSU_MON_INST];
inst_pa = tmp[`MEMOP_PA];
pkt_type = cpx_pkt[`CPX_RTNTYP];
//is received. There could be some other store sitting in the STB at that time.
//Chk for squash bit only for non-bis responses.
if (cpx_pkt[`CPX_BIS]) //response to rmo store
if (st_rmo_cnt[thid] == 0)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> L2 response received for an rmo store while the st_rmo_cnt for this thread is 0.", core_id, thid);
st_rmo_cnt[thid] = st_rmo_cnt[thid] - 1'b1;
`PR_INFO("lsu_mon", 25, "<C%0h> <T%0h> Store ack received for RMO store. rmo_cnt = %0d", core_id, thid, st_rmo_cnt[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> L2 response received while the SQUASH bit is set in the STB entry %0h.", core_id, thid, ret_ptr[thid]);
if (~stb_valid[{thid, ret_ptr[thid]}])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Store ack received while that entry is invalid in STB.", core_id, thid);
if (~cpx_pkt[`CPX_ATM]) //don't print this message for atomic return
`PR_INFO("lsu_mon", 26, "<C%0h> <T%0h> <%0h> %s(VA=%0h) STB[%0d] Store ack.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA], ret_ptr[thid]);
stb[{thid, ret_ptr[thid]}] = tmp;
ret_ptr[thid] = ret_ptr[thid] + 1'b1;
//`PR_INFO("lsu_mon", 22, "<C%0h> <T%0h> ret_ptr = %0d.", core_id, thid, ret_ptr[thid]);
reg [`LD_Pend_Width] tmp;
reg [39:0] pcx_pa, inst_pa;
thid = pcx_pkt[`PCX_THR_ID];
tmp = ld_pend_array[thid];
inst = tmp[`LSU_MON_INST];
pcx_pa = pcx_pkt[`PCX_ADDR];
inst_pa = tmp[`MEMOP_PA];
req = DispPCXReq(pcx_pkt);
if (pcx_pa[39:6] != inst_pa[39:6])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> A load request made to gasket by LSU while the pending req has PA %0h.", core_id, thid, pcx_pa, tmp[`MEMOP_PA]);
if (tmp[`L2_ISS] != 4'h0 )
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> 1st load request (pa[5:0] = 6'b0) made to gasket by LSU for blkld while this request has already been issued to gasket.", core_id, thid, pcx_pa);
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) 1st blkld helper Issued to gasket.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA]);
if (pcx_pa[5:0] == 6'h10)
if (tmp[`L2_ISS] != 4'h1)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> 2nd load request (pa[5:0] = 6'h10) made to gasket by LSU for blkld while this request has already been issued to gasket.", core_id, thid, pcx_pa);
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) 2nd blkld helper Issued to gasket.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA]);
if (pcx_pa[5:0] == 6'h20)
if (tmp[`L2_ISS] != 4'h3)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> 3rd load request (pa[5:0] = 6'h20) made to gasket by LSU for blkld while this request has already been issued to gasket.", core_id, thid, pcx_pa);
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) 3rd blkld helper Issued to gasket.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA]);
if (pcx_pa[5:0] == 6'h30)
if (tmp[`L2_ISS] != 4'h7)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> 4th load request (pa[5:0] = 6'h30) made to gasket by LSU for blkld while this request has already been issued to gasket.", core_id, thid, pcx_pa);
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) 4th blkld helper Issued to gasket.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA]);
ld_pend_array[thid] = tmp;
else if (Is_single_pcx_req_ld(inst))
if (tmp[`L2_ISS] == 4'hF)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> Load request made to gasket by LSU while this request has already been issued to gasket.", core_id, thid, pcx_pa);
ld_pend_array[thid] = tmp;
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) Issued to gasket.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> A load request made to gasket by LSU while there is no such ld request pending from this thread.", core_id, thid, pcx_pa);
function Is_single_pcx_req_ld;
if (inst[`LDD] || inst[`QLD] || inst[`FSR_RD_WR] || (inst == 21'h1) || (inst == 21'h5))
Is_single_pcx_req_ld = 1'b1;
Is_single_pcx_req_ld = 1'b0;
//`PR_INFO("lsu_mon", 22, "<C%0h> Is_single_pcx_req_ld = %b. ", core_id, Is_single_pcx_req_ld);
case (`SPC6.lsu_trap_flush[7:0])
8'h01: if (tid == 3'h0) Is_trap = 1'b1;
8'h02: if (tid == 3'h1) Is_trap = 1'b1;
8'h04: if (tid == 3'h2) Is_trap = 1'b1;
8'h08: if (tid == 3'h3) Is_trap = 1'b1;
8'h10: if (tid == 3'h4) Is_trap = 1'b1;
8'h20: if (tid == 3'h5) Is_trap = 1'b1;
8'h40: if (tid == 3'h6) Is_trap = 1'b1;
8'h80: if (tid == 3'h7) Is_trap = 1'b1;
function [8*11:0] DispPCXReq;
casex ({pcx_pkt[`PCX_RQTYP], pcx_pkt[`PCX_NC], pcx_pkt[`PCX_INV], pcx_pkt[`PCX_PF], pcx_pkt[`PCX_BIS]})
{5'h0, 1'b1, 1'b0, 1'b1, 1'b0}: DispPCXReq = "PREF";
{5'h0, 1'b1, 1'b1, 1'b1, 1'b0}: DispPCXReq = "PREF_ICE";
{5'h0, 1'bx, 1'b0, 1'b0, 1'b0}: DispPCXReq = "LD";
{5'h0, 1'bx, 1'b1, 1'b0, 1'b0}: DispPCXReq = "D";
{5'h10, 1'bx, 1'b0, 1'b0, 1'b0}: DispPCXReq = "I";
{5'h10, 1'b0, 1'b1, 1'b0, 1'b0}: DispPCXReq = "I";
{5'h1, 1'bX, 1'bX, 1'b0, 1'b0}: DispPCXReq = "ST";
{5'h1, 1'bX, 1'bX, 1'b1, 1'b1}: DispPCXReq = "BLKST";
{5'h1, 1'bX, 1'bX, 1'b0, 1'b1}: DispPCXReq = "BIS";
{5'h2, 1'b1, 1'bX, 1'b0, 1'b0}: DispPCXReq = "CASA1";
{5'h3, 1'b1, 1'bX, 1'b0, 1'b0}: DispPCXReq = "CASA2";
{5'h7, 1'b1, 1'bX, 1'b0, 1'b0}: DispPCXReq = "SWAP_LDSTUB";
{5'h4, 1'b1, 1'b0, 1'b0, 1'b0}: DispPCXReq = "STREAM_LD";
{5'h5, 1'b1, 1'b0, 1'b0, 1'bx}: DispPCXReq = "STREAM_ST";
{5'h8, 1'b1, 1'b0, 1'b0, 1'b0}: DispPCXReq = "MMU_LD";
//{5'h9, 1'b0, 1'b0, 1'b0, 1'b0}: DispPCXReq = "INT";
`PR_ERROR("lsu_mon", `ERROR, "<C%0h> <T%0h> <%0h> Can't recognise the PCX pkt type. rq_type = %h, nc_bit = %0b, inv_bit = %0b, pf_bit = %0b, bis_bit = %0b. pcx_pkt[129:0] = %h", core_id, pcx_pkt[`PCX_THR_ID], pcx_pkt[`PCX_ADDR], pcx_pkt[`PCX_RQTYP], pcx_pkt[`PCX_NC], pcx_pkt[`PCX_INV], pcx_pkt[`PCX_PF], pcx_pkt[`PCX_BIS], pcx_pkt);
if (`SPC6.lsu_align_b) DispExc = "Addr_not_aligned";
if (`SPC6.lsu_lddf_align_b) DispExc = "LDDF_Addr_not_aligned";
if (`SPC6.lsu_stdf_align_b) DispExc = "STDF_Addr_not_aligned";
if (`SPC6.lsu_priv_action_b) DispExc = "Priv_actio";
if (`SPC6.lsu_va_watchpoint_b) DispExc = "VA_watchpoint";
if (`SPC6.lsu_pa_watchpoint_b) DispExc = "PA_watchpoint";
//if (`SPC6.lsu_tlb_miss_b_) DispExc = "Tlb_miss";
if (`SPC6.lsu_illegal_inst_b) DispExc = "Illegal_inst";
if (`SPC6.lsu_daccess_prot_b) DispExc = "Data_access_prot_exc";
if (`SPC6.lsu_dae_invalid_asi_b) DispExc = "Dae_Invalid_asi";
if (`SPC6.lsu_dae_nc_page_b) DispExc = "Dae_nc_page";
if (`SPC6.lsu_dae_nfo_page_b) DispExc = "Dae_NFO_page";
if (`SPC6.lsu_dae_priv_viol_b) DispExc = "Dae_Priv_viol";
if (`SPC6.lsu_dae_so_page) DispExc = "Dae_so_page";
//if (`SPC6.lsu_perfmon_trap_b) DispExc = "Perf_mon_trap";
if (`SPC6.lsu_dtmh_err_b) DispExc = "DTLB_data_par_err";
if (`SPC6.lsu_dttp_err_b) DispExc = "DTLB_tag_par_err";
if (`SPC6.lsu_dtdp_err_b) DispExc = "DTLB_data_par_err";
`PR_INFO("lsu_mon", 23, "<C%0h> <T%0h> <%0h> B_stage: %s(VA=%0h) ASI = %0h. %s Exception.",core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b, asi_b, DispExc);
input [1:0] exu_lsu_va_error_b; // VA error requiring a flush
input [1:0] exu_ecc_b; // ECC error requiring a flush
err_b = dec_lsu_tid_b[2] ? (exu_ecc_b[1] | (exu_lsu_va_error_b[1] & ~`SPC6.lsu_tlb_bypass_b)):
(exu_ecc_b[0] | (exu_lsu_va_error_b[0] & ~`SPC6.lsu_tlb_bypass_b));
err_m = (dec_lsu_tid_b[2] ? `SPC6.exu_ecc_m[1] : `SPC6.exu_ecc_m[0]) & `SPC6.lsu.dcc.twocycle_b;
Is_exu_error = err_b | err_m;
task Insert_tlb_miss_info;
if (tlb_valid[dec_lsu_tid_b])
tmp = tlbmiss_pend_array[dec_lsu_tid_b];
Disp_tlbmiss_pend_array_entry(dec_lsu_tid_b);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <%0h> B_stage: %s(VA=%0h>) A new tlb miss request received while there is already a Tlb miss request pending from this thread as shown above.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b);
tlb_valid[dec_lsu_tid_b] <= 1'b1;
tmp[`INST_VA] = inst_pc_b;
tmp[`MEMOP_VA] = vaddr_b;
tlbmiss_pend_array[dec_lsu_tid_b] = tmp;
//problem with the signal.
always @ (negedge `SPC6.l2clk)
if (`SPC6.tlu_trap_pc_0_valid)
thid = {1'b0, `SPC6.tlu_trap_0_tid};
else if (`SPC6.tlu_trap_pc_1_valid)
thid = {1'b0, `SPC6.tlu_trap_1_tid};
`PR_ERROR("lsu_mon", `ERROR, "<C%h> mmu_dtlb_reload asserted but trap_pc_0_valid and trap_pc_1_valid are both 0", core_id);
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> mmu_dtlb_reload asserted while tlb_valid is 0.", core_id, thid);
tmp = tlbmiss_pend_array[dec_lsu_tid_b];
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> %s(VA=%0h> DTLB reloaded for VA = %0h.", core_id, thid, tb_top.intf0.xlate(tmp[`INST]), tmp[`INST_VA], tmp[`MEMOP_VA] );
task Insert_ld_miss_info;
reg [`LD_Pend_Width] tmp;
if (ld_valid[dec_lsu_tid_b])
tmp = ld_pend_array[dec_lsu_tid_b];
DispPendReq(dec_lsu_tid_b);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <%0h> B_stage: %s(VA=%0h>) A new request received while there is already a request pending from this thread as shown above.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b);
//ld_valid[dec_lsu_tid_b] <= 1'b1;
tmp[`INST_VA] = inst_pc_b;
tmp[`MEMOP_VA] = vaddr_b;
tmp[`MEMOP_PA] = {`SPC6.lsu.tlb_pgnum[39:13], vaddr_b[12:0]};
is_blkld[dec_lsu_tid_b] = 1'b1;
is_blkld[dec_lsu_tid_b] = 1'b0;
if (lsu_inst_b[`SWAP] || lsu_inst_b[`LDSTUB] || lsu_inst_b[`CASA])
tmp[`LSU_MON_INST] = lsu_inst_b;
ld_pend_array[dec_lsu_tid_b] = tmp;
task Insert_in_last_inst_array;
tmp[`INST_VA] = inst_pc_b;
tmp[`MEMOP_VA] = vaddr_b;
last_inst_array[dec_lsu_tid_b] = tmp;
reg [`LD_Pend_Width] tmp;
tmp = ld_pend_array[thid];
`PR_ALWAYS("lsu_mon", `ALWAYS, "LD_PEND_ARRAY[%0h] Data.", thid);
`PR_ALWAYS("lsu_mon", `ALWAYS, "<C%h> <T%0h> <%0h> %s(VA=%0h). PA = %0h. L2_ISS = %0h. L2_RESP = %0h, LSU_MON_INST=%h.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA], tmp[`MEMOP_PA], tmp[`L2_ISS], tmp[`L2_RESP], tmp[`LSU_MON_INST]);
`PR_ALWAYS("lsu_mon", `ALWAYS, "<C%h> <T%0h> STB[%0h] data.", core_id, thid, ptr);
`PR_ALWAYS("lsu_mon", `ALWAYS, "<C%h> <T%0h> <%0h> %s(VA=%0h). PA = %0h. L2_ISS = %0h. L2_ACK = %0h, LSU_MON_INST=%h. RMO = %0b", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA], tmp[`MEMOP_PA], tmp[`L2_ST_ISS], tmp[`L2_ACK], tmp[`LSU_MON_INST], tmp[`RMO]);
task Disp_tlbmiss_pend_array_entry;
tmp = tlbmiss_pend_array[thid];
`PR_INFO("lsu_mon", 23, "TLB_MISS_PEND_ARRAY[%0h] Data.", thid);
`PR_INFO("lsu_mon", 23, "<C%h> <T%0h> <%0h> %s(VA=%0h).", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA]);
`PR_ALWAYS("lsu_mon", `ALWAYS, "CPX_PKT data.");
`PR_ALWAYS("lsu_mon", `ALWAYS, "<C%0h> <T%0h> rtn_typ = %0h, err_bits = %0h, nc=%0b, atm = %0b, pf = %0b", core_id, cpx_pkt[`CPX_THR_ID], cpx_pkt[`CPX_RTNTYP], cpx_pkt[`CPX_ERR], cpx_pkt[`CPX_NC], cpx_pkt[`CPX_ATM], cpx_pkt[`CPX_PF]);
tmp[`INST_VA] = inst_pc_b;
tmp[`MEMOP_VA] = vaddr_b;
tmp[`MEMOP_PA] = {`SPC6.lsu.tlb_pgnum[39:13], vaddr_b[12:0]};
tmp[`LSU_MON_INST] = lsu_inst_b;
if (`SPC6.lsu.tlu_lsu_hpstate_hpriv[dec_lsu_tid_b])
else if (`SPC6.lsu.tlu_lsu_pstate_priv[dec_lsu_tid_b])
//bis_asi to io space is not rmo
tmp[`RMO] = lsu_inst_b[`BLKST] | (dec_altspace_b & Is_bis_asi(asi_b) & ~`SPC6.lsu.tlb_pgnum[39]);
input [195:0] store_data;
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> STB full and a new store received for insertion in STB.", core_id, thid);
stb[{thid, wrptr[thid]}] = store_data;
//Disp_STB_entry(thid, wrptr[thid]);
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> <%0h> %s(VA=%0h). STB[%0h] Inserted.", core_id, thid, store_data[`INST_VA], tb_top.intf0.xlate(store_data[`INST]), store_data[`MEMOP_VA], wrptr[thid]);
stb_valid[{thid, wrptr[thid]}] = 1'b1;
wrptr[thid] = wrptr[thid] + 1'b1;
//`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> wrptr = %0d.", core_id, thid, wrptr[thid]);
if ((wrptr[thid] == rdptr[thid]) && stb_valid[{thid, wrptr[thid]}])
//thid = decode_tid(`SPC6.lsu_stb_dealloc);
tmp = stb[{thid, rdptr[thid]}];
lsu_inst = tmp[`LSU_MON_INST];
if (~stb_valid[{thid, rdptr[thid]}])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> lsu_stb_dealloc = %0h asserted while the stb entry is invalid for that thid.", core_id, thid, `SPC6.lsu_stb_dealloc);
Disp_STB_entry(thid, rdptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> lsu_stb_dealloc = %0h asserted when we haven't received the response from the gasket.", core_id, thid, `SPC6.lsu_stb_dealloc);
else if (tmp[`ASI_ST_ISS])
ret_ptr[thid] = ret_ptr[thid] + 1'b1;
//blkst inst. is not issued anywhere, blkst helpers are issued.
//in case of bis stores, lsu issues the dealloc in P3, i.e when the req is issued to PCX.
//IF it is bis to cp sapce and there is an err then the store is issued to PCX with nd set
//However for ue onbis to IO space, dealloc is sent to IFU, issued on PCX with valid bit 0.
//The sbdiou signal is sent in next cycle. We need to take bis io stores in this equation.
else if (tmp[`ST_SQUASH] || lsu_inst[`BLKST] || (tmp[`RMO] & ~lsu_inst[`BLKST] & ~`SPC0.lsu.sbc.kill_store_p4_))
iss_ptr[thid] = iss_ptr[thid] + 1'b1;
ret_ptr[thid] = ret_ptr[thid] + 1'b1;
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> lsu_stb_dealloc = %0h asserted which is not issued to asi ring, or PCX or is not squashed.", core_id, thid, `SPC6.lsu_stb_dealloc);
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> <%0h>: %s(VA=%0h) PA = %0h. STB[%0d] Deallocated.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], tmp[`MEMOP_PA], rdptr[thid]);
stb_valid[{thid, rdptr[thid]}] = 1'b0;
rdptr[thid] = rdptr[thid] + 1'b1;
//`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> rd_ptr = %0d.", core_id, thid, rdptr[thid]);
st_rmo_cnt[thid] = st_rmo_cnt[thid] + 1'b1;
if (ret_ptr[thid] != iss_ptr[thid])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> lsu_block_store_kill asserted while the ret_ptr = %0h != iss_ptr = %0h.", core_id, thid, tmp[`MEMOP_PA], ret_ptr[thid], iss_ptr[thid]);
if (rdptr[thid] != iss_ptr[thid])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> lsu_block_store_kill asserted while the rdptr = %0h != iss_ptr = %0h.", core_id, thid, tmp[`MEMOP_PA], rdptr[thid], iss_ptr[thid]);
if (iss_ptr[thid] == wrptr[thid])
if (stb_valid[{thid, wrptr[thid]}])
/* Lsu can assert both dealloc and block_store_kill for a request.
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Lsu asserted block_store_kill while there are no valid entries in STB to be deallocated.", core_id, thid);
if (iss_ptr[thid] < wrptr[thid])
squash_cnt = wrptr[thid] - iss_ptr[thid];
else if (iss_ptr[thid] > wrptr[thid])
squash_cnt = wrptr[thid] + (8 - iss_ptr[thid]);
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> SQUASH_STB:iss_ptr = %0h, wrptr = %0h, squash_cnt = %0h.", core_id, thid, iss_ptr[thid], wrptr[thid], squash_cnt);
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> Block store kill changed issue_ptr:%0h->%0h. ret_ptr: %0h->%0h. rdptr:%0h->%0h.", core_id, thid, iss_ptr[thid], iss_ptr[thid]+squash_cnt, ret_ptr[thid], ret_ptr[thid]+squash_cnt, rdptr[thid], rdptr[thid]+squash_cnt);
ret_ptr[thid] = ret_ptr[thid] + squash_cnt;
rdptr[thid] = rdptr[thid] + squash_cnt;
iss_ptr[thid] = iss_ptr[thid] + squash_cnt;
if (~stb_valid[{thid, i}])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h><PA = %0h> lsu_block_store_kill asserted while the stb entry %0h is invalid.", core_id, thid, tmp[`MEMOP_PA], i);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h>st_issue bit is set when the block_store_kill is asserted for stb entry %0h.", core_id, thid, tmp[`MEMOP_PA], i);
//commenting out the chk below. Lsu can assert sbdiou and then in the next cycle insert a new entry into
//stb. LSU will squash this new entry and won't issue it to PCX/asi but its squash bit won't be
//set in the chkr which was causin it to fire.
//`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> lsu_block_store_kill asserted while the squash bit is 0 in the STB entry %0h.", core_id, thid, tmp[`MEMOP_PA], i);
stb_valid[{thid, i}] = 1'b0;
squash_cnt = squash_cnt - 1'b1;
if ((bst_cnt > 0) && (`SPC6.lsu_stb_alloc == 8'b0))
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Blk store entries are not allocated back to back in STB.", core_id, bst_active_thid);
//For bst the stb is still written even though we have errors.
//Stb is written in W stage. Howvere for first blk store helper
//the err will be flagged by FGU in b stage. We can miss the
// err signal if we don't sample in B.
//for the last helper err will be signalled in B stage of last helper and at
if (lsu_bst_active[bst_active_thid] & `SPC0.fgu_fst_ecc_error_fx2 & (bst_cnt < 7))
if (`SPC6.lsu_stb_alloc[7:0] != 8'b0)
thid = decode_tid(`SPC6.lsu_stb_alloc[7:0]);
if (thid != dec_lsu_tid_w)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> lsu_stb_alloc = %0h mismatches the thid %0h.", core_id, dec_lsu_tid_w, `SPC6.lsu_stb_alloc[7:0], dec_lsu_tid_w);
Insert_in_STB(stb_alloc_data, dec_lsu_tid_w);
if (lsu_bst_active[thid])
bst_data = bst_inst_data;
if (thid != bst_active_thid)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> lsu_stb_alloc = %0h mismatches the active blkstore thid = %0h.", core_id, bst_active_thid, `SPC6.lsu_stb_alloc[7:0], bst_active_thid);
addr = bst_data[`MEMOP_VA];
bst_data[`MEMOP_VA] = {addr[47:6], bst_cnt[2:0], 3'b0};
addr = bst_data[`MEMOP_PA];
bst_data[`MEMOP_PA] = {addr[39:6], bst_cnt[2:0], 3'b0};
Insert_in_STB(bst_data, bst_active_thid);
lsu_bst_active[thid] = 1'b0;
if (bst_fgu_err) //set the squash bit to 0 for all the stb entries
for (i = 0; i < 8; i=i+1)
tmp = stb[{thid, i[2:0]}];
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> Squash bit already set when trying to set it for a bst fgu errerr.", core_id, thid, tmp[`MEMOP_PA]);
stb[{thid, i[2:0]}] = tmp;
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> <PA = %0h> STB_entry[%0h] squashed due to FGU err.", core_id, thid, tmp[`MEMOP_PA], i);
`PR_ERROR("lsu_mon", `ERROR, "<C%h>: LSU asserted lsu_stb_alloc = %0h while no store pending to be written in STB.", core_id, `SPC6.lsu_stb_alloc[7:0]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <%0h> W_stage: LSU did not assert lsu_stb_alloc for the store.", core_id, dec_lsu_tid_w, inst_pc_w);
reg [47:0] addr, act_addr;
thid =`SPC6.lsu_rngl_cdbus[58:56];
thid =`SPC6.lsu_rngf_cdbus[58:56];
asi =`SPC6.lsu_rngl_cdbus[55:48];
asi =`SPC6.lsu_rngf_cdbus[55:48];
addr =`SPC6.lsu_rngl_cdbus[47:0];
addr =`SPC6.lsu_rngf_cdbus[47:0];
req_type =`SPC6.lsu_rngl_cdbus[61:60];
req_type =`SPC6.lsu_rngf_cdbus[61:60];
tmp = stb[{thid, iss_ptr[thid]}];
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> Store reissued on the ASI interface.", core_id, thid, addr);
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> Store issued on the ASI interface that has been squashed.", core_id, thid, addr);
act_addr = tmp[`MEMOP_PA];
act_addr = {act_addr[39:3], 3'b0};
//47 is D tag rd asi. LSU issues that on the ring but changes
if ((addr == act_addr) || (asi == 8'h47) || (asi == 8'h46))
stb[{thid, iss_ptr[thid]}] = tmp;
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) STB[%0d] Issued on local ring.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], iss_ptr[thid]);
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) STB[%0d] Issued on fast ring.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], iss_ptr[thid]);
iss_ptr[thid] = iss_ptr[thid] + 1'b1;
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <%0h>: %s(VA=%0h) STB[%0d] PA mismatch for asi req on local ring. Expected PA = %0h, actual PA = %0h", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], iss_ptr[thid], tmp[`MEMOP_PA], addr);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <%0h>: %s(VA=%0h) STB[%0d] PA mismatch for asi req on fast ring. Expected PA = %0h, actual PA = %0h", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], iss_ptr[thid], tmp[`MEMOP_PA], addr);
task chk_store_issue_to_pcx;
reg [39:0] pcx_pa, inst_pa;
thid = pcx_pkt[`PCX_THR_ID];
tmp = stb[{thid, iss_ptr[thid]}];
inst = tmp[`LSU_MON_INST];
pcx_pa = pcx_pkt[`PCX_ADDR];
inst_pa = tmp[`MEMOP_PA];
if (pcx_pkt[`PCX_RQTYP] == `PCX_STORE)
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) STB[%0d] Issued to gasket.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], iss_ptr[thid]);
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) STB[%0d] Issued to gasket with ND set.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], iss_ptr[thid]);
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> A store request made to gasket by LSU while the pending req is not store.", core_id, thid, pcx_pkt[`PCX_ADDR]);
if (pcx_pa[39:0] != inst_pa[39:0])
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> A store request made to gasket by LSU while the pending req has PA %0h.", core_id, thid, pcx_pkt[`PCX_ADDR], tmp[`MEMOP_PA]);
if ((tmp[`INST_ASI] == 8'h73) & (pcx_pa[39:0] != {8'h90, core_id, thid, tmp[`INST_ASI], 18'h0}))
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> pcx_pa is not correct for asi write to interrupt vector dispatch register.", core_id, thid, pcx_pkt[`PCX_ADDR]);
if (inst[`BLKST] && ~pcx_pkt[`PCX_BST])
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> Bst bit is not set in the PCX pkt by LSU for a blk st request.", core_id, thid, pcx_pkt[`PCX_ADDR]);
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> Store reissued on the PCX interface.", core_id, thid, pcx_pkt[`PCX_ADDR]);
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> Store issued on the PCX interface that has been squashed.", core_id, thid, pcx_pkt[`PCX_ADDR]);
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> BIS bit is not set in the PCX pkt by LSU for an RMO store.", core_id, thid, pcx_pkt[`PCX_ADDR]);
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> L2ack bit is set when the RMO store is issued to PCX.", core_id, thid, pcx_pkt[`PCX_ADDR]);
ret_ptr[thid] = ret_ptr[thid] + 1; //this will be deallocated before
//response seen from stub
st_rmo_cnt[thid] = st_rmo_cnt[thid] + 1'b1;
stb[{thid, iss_ptr[thid]}] = tmp;
iss_ptr[thid] = iss_ptr[thid] + 1;
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> iss_ptr = %0d. ret_ptr = %0d, st_rmo_cnt = %0d", core_id, thid, iss_ptr[thid], ret_ptr[thid], st_rmo_cnt[thid]);
`ifdef INJ_STB_ERR_IN_CMP
reg [2:0] err_tid, stb_err_tid_d1, stb_err_tid_d2;
reg [2:0] err_index, stb_err_index_d1, stb_err_index_d2;
reg stb_err_inj, stb_err_inj_d1, stb_err_inj_d2;
reg [1:0] err_priv, stb_err_priv_d1, stb_err_priv_d2;
if (("cmp_stb_err_inj_on"))
always @ (negedge (`SPC6.l2clk & enabled & cmp_stb_err_inj))
//valid stb ram rd for issue to pcx
if (`SPC6.lsu.sbc.ram_rptr_vld_2 & `SPC6.lsu.sbc.st_pcx_rq_p3 & `SPC6.lsu.pic.pic_st_sel_p3)
err_tid = decode_tid(`SPC6.lsu.sbc.st_rq_sel_p3[7:0]);
err_index = `SPC6.lsu.sbc.ram_rptr_d1;
err_tmp = stb[{err_tid, err_index}];
err_inst = err_tmp[`LSU_MON_INST];
cam_data = `SPC6.lsu.stb_cam.cam_array.stb_rdata[44:0];
err_priv = err_tmp[`ST_PRIV];
//if (err_inst[`SWAP] || err_inst[`CASA] || err_inst[`LDSTUB])
err_inj_cnt = err_inj_cnt + 1;
11, 12: err_bit = err_bit + 1;
force `SPC0.lsu.stb_cam.cam_array.stb_rdata[44:0] = cam_data ^ (1 << err_bit);
`PR_INFO("stb_err", 22, "<T%0h> <%0h> STB[%0h]: SBAPP forced for CASA. err_bit = %0h", err_tid, {cam_data[44:8], 3'b0}, err_index, err_bit);
release `SPC0.lsu.stb_cam.cam_array.stb_rdata[44:0];
if (~`SPC6.lsu_sbapp_err_g)
`PR_ERROR("lsu_mon", `ERROR, "<T%0h> sbapp err not asserted when err is injected for atomic.", stb_err_tid_d2);
if ((`SPC6.lsu_stberr_tid_g != stb_err_tid_d2) ||
(`SPC6.lsu_stberr_index_g != stb_err_index_d2) ||
(`SPC6.lsu_stberr_priv_g != stb_err_priv_d2))
`PR_ERROR("lsu_mon", `ERROR, "<T%0h> sbapp err parameters mismatch.", stb_err_tid_d2);
if (`SPC6.lsu_sbapp_err_g)
`PR_ERROR("lsu_mon", `ERROR, "<T%0h> sbapp err asserted when none expected.", `SPC6.lsu_stberr_tid_g);
always @ (posedge (`SPC6.l2clk & enabled & cmp_stb_err_inj))
stb_err_inj_d1 <= stb_err_inj;
stb_err_inj_d2 <= stb_err_inj_d1;
stb_err_tid_d1 <= err_tid;
stb_err_tid_d2 <= stb_err_tid_d1;
stb_err_index_d1 <= err_index;
stb_err_index_d2 <= stb_err_index_d1;
stb_err_priv_d1 <= err_priv;
stb_err_priv_d2 <= stb_err_priv_d1;
// If vcs_build_args NO_MONITORS, then module will be empty
reg [7:0] asi_e, imm_asi_e, asi_m, asi_b;
reg dec_altspace_e, dec_altspace_b, dec_altspace_m;
reg [1:0] exu_lsu_va_error_b;
reg [2:0] dec_lsu_tid_e, dec_lsu_tid_m, dec_lsu_tid_b, dec_lsu_tid_w;
reg [47:0] inst_pc_e, inst_pc_m, inst_pc_b, inst_pc_w;
reg [31:0] inst_e, inst_m, inst_b;
reg [47:0] vaddr_m, vaddr_b;
reg [63:0] int_st_data_m, int_st_data_b;
reg [63:0] fp_st_sata_fx2;
reg [20:0] lsu_inst_e, lsu_inst_m, lsu_inst_b;
reg mmu_dtlb_reload_d1, mmu_dtlb_reload_d2;
reg [`LD_Pend_Width] ld_pend_array[7:0];
reg [`LAST_INST_Pend_Width] last_inst_array[7:0];
reg [2:0] wrptr[7:0]; //Pts. to the STB entry into which data will be written next
reg [2:0] rdptr[7:0]; //Tracks the dealloc signal from STB
reg [2:0] iss_ptr[7:0]; //keeps track of when a store is issued from the STB to PCX
reg [2:0] ret_ptr[7:0]; //keeps track of when the response is received from
reg [`STB_Pend_Width] stb[63:0];
//reg [`TLB_MISS_Pend_Width] tlbmiss_pend_array[7:0];
reg [7:0] dcache_inv_cnt[7:0];
reg [7:0] st_rmo_cnt[7:0];
reg [31:0] dec_tg0_inst_d, dec_tg1_inst_d;
reg [7:0] lsu_bst_active;
reg [195:0] stb_alloc_data;
reg [195:0] bst_data, bst_inst_data;
reg [2:0] bst_active_thid;
reg [7:0] is_blkld; //reqd by lsu_ras_chkr to chk errors on blk ld.
reg [1:0] l2_blk_ld_errtype[7:0]; //Gives the type of err the ahd be reported by LSU if
//different types of err occur on blk ld helper returns
reg [1:0] st_priv[7:0]; //Gives the final priv level for an sbdiou/sbapp err that shd be
for (i = 0; i < 8; i = i+1)
l2_blk_ld_errtype[i] = 2'b0;
// avoid time zero ugliness. jp
//@(posedge `SPC0.l2clk);
//@(negedge `SPC0.l2clk);
//if (`PARGS.lsu_mon_on) enabled = 1;
3'h0: finish_mask = `PARGS.finish_mask[7:0];
3'h1: finish_mask = `PARGS.finish_mask[15:8];
3'h2: finish_mask = `PARGS.finish_mask[23:16];
3'h3: finish_mask = `PARGS.finish_mask[31:24];
3'h4: finish_mask = `PARGS.finish_mask[39:32];
3'h5: finish_mask = `PARGS.finish_mask[47:40];
3'h6: finish_mask = `PARGS.finish_mask[55:48];
3'h7: finish_mask = `PARGS.finish_mask[63:56];
if (~`TOP.in_reset & `PARGS.lsu_mon_on & ~reset_in_middle)
`PR_ALWAYS("lsu_mon", `ALWAYS, "Lsu_mon on, in_reset = 0.");
if (`TOP.in_reset & enabled)
`PR_ALWAYS("lsu_mon", `ALWAYS, "Reset asserted in the middle of the diag. Turned off Lsu_mon.");
always @ (posedge (tb_top.sim_status[0] & enabled))
if (|(ld_valid[7:0] & finish_mask[7:0]))
for (i = 0; i < 8; i=i+1)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> Ld requests pending at the end of simulation. ld_valid = %0h", core_id, ld_valid);
for (i = 0; i < 64; i=i+1)
if (stb_valid[i] & finish_mask[i[5:3]])
//chkr resets the stb valid bits when block_store_kill is asserted.
//in couple of failures block_store_kill was sampled asserted two cycles after
//lsu asserted stb_empty. The simulation ended the cycle stb_empty was sampled high
//causing moniotr firings with valid entries in stb at end of simulation. Now
//don't flag an error if squash bit is set and stb_valid is asserted at end
if (~is_squash_bit_set(i[5:0]))
Disp_STB_entry(i[5:3],i[2:0]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> Store requests pending at the end of simulation. stb_valid = %0h", core_id, stb_valid);
for (i = 0; i < 8; i=i+1)
if (finish_mask[i] & (pf_cnt[i] != 0))
`PR_ALWAYS("lsu_mon", `ALWAYS, "<C%h> <T%0h> Prefetches not finished. Pf_cnt = %0d", core_id, i, pf_cnt[i]);
if (finish_mask[i] & (dcache_inv_cnt[i] != 0))
`PR_ALWAYS("lsu_mon", `ALWAYS, "<C%h> <T%0h> D pkt not received for all invalidate reqs. issued by the thread. dcache_inv_cnt = %0d", core_id, i, dcache_inv_cnt[i]);
if (finish_mask[i] & (st_rmo_cnt[i] != 0))
`PR_ALWAYS("lsu_mon", `ALWAYS, "<C%h> <T%0h> rmo_cnt not zero. rmo_cnt = %0d", core_id, i, st_rmo_cnt[i]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> Prefetch/D/RMO_stores requests pending at the end of simulation.", core_id);
function is_squash_bit_set;
is_squash_bit_set = 1'b1;
is_squash_bit_set = 1'b0;
always @ (negedge (`SPC7.l2clk & enabled))
asi_e = `SPC7.lsu.dcc.dcc_asi_e[7:0];
lsu_inst_e[`LD] <= `SPC7.dec_ld_inst_e;
lsu_inst_e[`ST] <= `SPC7.dec_st_inst_e;
lsu_inst_e[`FP] <= `SPC7.dec_fpldst_inst_e;
lsu_inst_e[`PREF] <= `SPC7.dec_pref_inst_e;
lsu_inst_e[`SWAP] <= `SPC7.dec_swap_inst_e;
lsu_inst_e[`CASA] <= `SPC7.dec_casa_inst_e;
lsu_inst_e[`LDSTUB] <= `SPC7.dec_ldstub_inst_e;
lsu_inst_e[`FLUSH] <= `SPC7.dec_flush_inst_e;
lsu_inst_e[`MEMBAR] <= `SPC7.dec_memstbar_inst_e;
lsu_inst_e[`LDD] <= `SPC7.dec_ld_inst_e & `SPC7.dec_ldst_dbl_e & ~`SPC7.dec_fpldst_inst_e;
lsu_inst_e[`STD] <= `SPC7.dec_st_inst_e & `SPC7.dec_ldst_dbl_e & ~`SPC7.lsu.dec_fpldst_inst_e;
lsu_inst_e[`BLKLD] <= `SPC7.dec_ld_inst_e & `SPC7.dec_fpldst_inst_e & dec_altspace_e & Is_blk_asi(asi_e);
lsu_inst_e[`BLKST] <= `SPC7.dec_st_inst_e & `SPC7.dec_fpldst_inst_e & dec_altspace_e & Is_blk_asi(asi_e);
lsu_inst_e[`QLD] <= `SPC7.dec_ld_inst_e & dec_altspace_e & Is_qld_asi(asi_e);
lsu_inst_e[`ASR_RD_WR] <= `SPC7.dec_sr_inst_e & (`SPC7.dec_ld_inst_e | `SPC7.dec_st_inst_e);
lsu_inst_e[`PR_RD_WR] <= `SPC7.dec_pr_inst_e & (`SPC7.dec_ld_inst_e | `SPC7.dec_st_inst_e);
lsu_inst_e[`HPR_RD_WR] <= `SPC7.dec_hpr_inst_e & (`SPC7.dec_ld_inst_e | `SPC7.dec_st_inst_e);
lsu_inst_e[`FSR_RD_WR] <= `SPC7.dec_fsr_ldst_e & (`SPC7.dec_ld_inst_e | `SPC7.dec_st_inst_e);
always @ (posedge (`SPC7.l2clk & enabled))
dec_tg0_inst_d <= `SPC7.dec.ded0.decode_mux[31:0];
dec_tg1_inst_d <= `SPC7.dec.ded1.decode_mux[31:0];
imm_asi_vld_e <= `SPC7.lsu.dec_imm_asi_vld_d;
imm_asi_e <= `SPC7.lsu.dec_imm_asi_d;
dec_altspace_e <= `SPC7.dec_altspace_d;
dec_altspace_m <= dec_altspace_e;
dec_altspace_b <= dec_altspace_m;
exu_ecc_b <= `SPC7.exu_ecc_m;
exu_lsu_va_error_b <= `SPC7.exu_lsu_va_error_m;
dec_lsu_tid_e <= `SPC7.dec_lsu_tg_d ? {1'b1, `SPC7.dec_lsu_tid1_d} : {1'b0, `SPC7.dec_lsu_tid0_d};
dec_lsu_tid_m <= dec_lsu_tid_e;
dec_lsu_tid_b <= dec_lsu_tid_m;
dec_lsu_tid_w <= dec_lsu_tid_b;
inst_pc_e <= `SPC7.dec_lsu_tg_d ? {`SPC7.tlu.tlu_pc_1_d[47:2], 2'b0} : {`SPC7.tlu.tlu_pc_0_d[47:2], 2'b0};
inst_e <= `SPC7.dec_lsu_tg_d ? dec_tg1_inst_d : dec_tg0_inst_d;
vaddr_m <= `SPC7.exu_lsu_address_e;
int_st_data_m <= `SPC7.exu_lsu_store_data_e;
int_st_data_b <= int_st_data_m;
fp_st_sata_fx2 <= `SPC7.fgu_lsu_fst_data_fx1;
mmu_dtlb_reload_d1 <= `SPC7.mmu_dtlb_reload;
mmu_dtlb_reload_d2 <= mmu_dtlb_reload_d1;
//pcx_thid_d1 <= `SPC7.lsu.spc_pcx_data_pa[`PCX_THR_ID];
lsu_inst_m <= lsu_inst_e;
lsu_inst_b <= lsu_inst_m;
Is_blk_asi = (asi == `ASI_BLK_AIUP) | (asi == `ASI_BLK_AIUS) |
(asi == `ASI_BLK_AIUPL) | (asi == `ASI_BLK_AIUSL) |
(asi == `ASI_BLK_P) | (asi == `ASI_BLK_S) |
(asi == `ASI_BLK_PL) | (asi == `ASI_BLK_SL) |
(asi == `ASI_BLK_COMMIT_P) | (asi == `ASI_BLK_COMMIT_S);
Is_qld_asi = (asi == `ASI_AIU_BIS_QUAD_LDD_P) | (asi == `ASI_AIU_BIS_QUAD_LDD_S) |
(asi == `ASI_AIU_BIS_QUAD_LDD_P_LITTLE) | (asi == `ASI_AIU_BIS_QUAD_LDD_S_LITTLE) |
(asi == `ASI_NUCLEUS_BIS_QUAD_LDD) | (asi == `ASI_NUCLEUS_BIS_QUAD_LDD_LITTLE) |
(asi == `ASI_BIS_QUAD_LDD_P) | (asi == `ASI_BIS_QUAD_LDD_S) |
(asi == `ASI_BIS_QUAD_LDD_P_LITTLE) | (asi == `ASI_BIS_QUAD_LDD_S_LITTLE) |
(asi == `ASI_QUAD_LDD) | (asi == `ASI_QUAD_LDD_REAL) |
(asi == `ASI_QUAD_LDD_L) | (asi == `ASI_QUAD_LDD_REAL_L);
Is_bis_asi = (asi == `ASI_AIU_BIS_QUAD_LDD_P) | (asi == `ASI_AIU_BIS_QUAD_LDD_S) |
(asi == `ASI_AIU_BIS_QUAD_LDD_P_LITTLE) | (asi == `ASI_AIU_BIS_QUAD_LDD_S_LITTLE) |
(asi == `ASI_NUCLEUS_BIS_QUAD_LDD) | (asi == `ASI_NUCLEUS_BIS_QUAD_LDD_LITTLE) |
(asi == `ASI_BIS_QUAD_LDD_P) | (asi == `ASI_BIS_QUAD_LDD_S) |
(asi == `ASI_BIS_QUAD_LDD_P_LITTLE) | (asi == `ASI_BIS_QUAD_LDD_S_LITTLE);
always @ (negedge (`SPC7.l2clk & enabled))
`PR_INFO("lsu_mon", 21, "<C%0h> <T%0h> <%0h> M_stage: %s(VA=%0h) Flushed due to IFU Flush.", core_id, dec_lsu_tid_m, inst_pc_m, tb_top.intf0.xlate(inst_m),vaddr_m);
if (lsu_inst_b[`BLKLD]) print_inst = " BLKLD,";
else if (lsu_inst_b[`BLKST]) print_inst = " BLKST,";
else if (lsu_inst_b[`QLD]) print_inst = " QLD,";
`PR_INFO("lsu_mon", 21, "<C%0h> <T%0h> <%0h> B_stage: %s(VA=%0h) Flushed due to IFU Flush.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b);
else if (`SPC7.tlu_flush_lsu_b)
`PR_INFO("lsu_mon", 21, "<C%h> <T%0h> <%0h> B_stage: %s(VA=%0h) Flushed due to TLU Flush.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b);
//casa is a two cycle operation. If there is an err on the 2nd cycle of casa then also
//This function will also chk for errors on 2nd cycle.
else if (Is_exu_error(exu_lsu_va_error_b, exu_ecc_b))
`PR_INFO("lsu_mon", 21, "<C%h> <T%0h <%0h> B_stage: %s(VA=%0h) Flushed due to EXU error.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b);
else if ((`SPC7.fgu_cecc_fx2 || `SPC7.fgu_uecc_fx2) && lsu_inst_b[`ST] && lsu_inst_b[`FP])
`PR_INFO("lsu_mon", 21, "<C%h> <T%0h> <%0h> B_stage: %s(VA=%0h) Flushed due to FGU error.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b);
else if (!`SPC7.lsu_tlb_miss_b_)
`PR_INFO("lsu_mon", 23, "<C%h> <T%0h> <%0h> B_stage: %s(VA=%0h)%s ASI = %0h. DTLB miss.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b, print_inst, asi_b);
//Lsu doesn't assert lsu_sync for an exception or dtlb miss. Since for
//an exception tlu anyway tells the front end to flush itself there is
//no reason for LSU to flush the front end then TLU to flush it again.
//Lsu treats the dtlbmiss as an exception that it flushes the inst and
//handles it when it is reissued by the front end.
if (`SPC7.lsu_tlb_bypass_b)
if (`SPC7.lsu_sync != 8'b0)
`PR_INFO("lsu_mon", 23, "<C%h> <T%0h> <%0h>: %s(VA=%0h)%s PA = %0h, ASI = %0h. LSU_sync. DTLB Bypass.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b, print_inst, {`SPC7.lsu.tlb_pgnum[39:13], vaddr_b[12:0]}, asi_b);
`PR_INFO("lsu_mon", 23, "<C%h> <T%0h> <%0h>: %s(VA=%0h)%s PA = %0h, ASI = %0h. DTLB Bypass.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b, print_inst, {`SPC7.lsu.tlb_pgnum[39:13], vaddr_b[12:0]}, asi_b);
if (`SPC7.lsu_sync != 8'b0)
`PR_INFO("lsu_mon", 23, "<C%h> <T%0h> <%0h>: %s(VA=%0h)%s PA = %0h, ASI = %0h, Store_data = %0h. LSU_sync. DTLB hit.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b, print_inst, {`SPC7.lsu.tlb_pgnum[39:13], vaddr_b[12:0]}, asi_b,int_st_data_b);
`PR_INFO("lsu_mon", 23, "<C%h> <T%0h> <%0h>: %s(VA=%0h)%s PA = %0h, ASI = %0h. LSU_sync. DTLB hit.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b, print_inst, {`SPC7.lsu.tlb_pgnum[39:13], vaddr_b[12:0]}, asi_b);
`PR_INFO("lsu_mon", 23, "<C%h> <T%0h> <%0h>: %s(VA=%0h)%s PA = %0h, ASI = %0h, Store_data = %0h. DTLB hit.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b, print_inst, {`SPC7.lsu.tlb_pgnum[39:13], vaddr_b[12:0]}, asi_b, int_st_data_b);
`PR_INFO("lsu_mon", 23, "<C%h> <T%0h> <%0h>: %s(VA=%0h)%s PA = %0h, ASI = %0h. DTLB hit.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b, print_inst, {`SPC7.lsu.tlb_pgnum[39:13], vaddr_b[12:0]}, asi_b);
if (lsu_inst_b[`LD] || lsu_inst_b[`PREF] || lsu_inst_b[`SWAP] || lsu_inst_b[`CASA] || lsu_inst_b[`LDSTUB])
if (((lsu_inst_b == 16'h1) || (lsu_inst_b == 16'h5)) & `SPC7.lsu.stb_cam_hit)
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> <%0h>: LSU_sync asserted due to STB RAW.", core_id, dec_lsu_tid_b, inst_pc_b);
if (lsu_inst_b[`ST]) //for atomics both ld and store signals are asserted
Insert_in_last_inst_array;
if (`SPC7.lsu_trap_flush[7:0])
`PR_INFO("lsu_mon", 21, "<C%h> <T%0h> Trap Flush asserted.", core_id, decode_tid(`SPC7.lsu_trap_flush[7:0]));
//This is how we test squashing of stores by LSU_mon:
//Whenever lsu asserts err_sbdiou signal, the monitor sets the squash
//bit in the STB for the rest of the stores. If any of these squashed stores
//is issued on the asi ring or to the PCX interface the monitor complains.
//The squashed stores are deallocated when either a block_store_kill is
//asserted or dealloc signals are asserted by the LSU.
//When the block_store_kill is asserted, it tells the IFU to dealloc
//all the pending stores in the IFU. It means the when block_store_kill
//is asserted we have deallocated all the non-squashed requests from STB.
//The 0in_chkr ensures that LSU flags the correct index and priv with the
//the sbdiou signal to TLU.
always @ (negedge (`SPC7.l2clk & enabled))
if (`SPC7.lsu_l15_valid & `SPC7.lsu.spc_pcx_data_pa[129])
Chk_pcx_req_pkt(`SPC7.lsu.spc_pcx_data_pa[129:0]); //chk if we need .lsu here
if ((`SPC7.lsu_rngl_cdbus[64:63] == 2'b11) & ~`SPC7.lsu_rngl_cdbus[59])
Chk_st_on_ASI_ring(`LOCAL);
if ((`SPC7.lsu_rngf_cdbus[64:63] == 2'b11) & ~`SPC7.lsu_rngf_cdbus[59])
Chk_st_on_ASI_ring(`FAST);
//if (`SPC7.l15_lsu_valid)
//Chk_cpx_response_pkt({`SPC7.l15_lsu_valid, `SPC7.l15_lsu_cpkt[17:13],`SPC7.l15_lsu_cpkt[11:0],`SPC7.l15_spc_data1[127:0]});
if (`SPC7.cpx_spc_data_cx[145])
Chk_cpx_response_pkt(`SPC7.cpx_spc_data_cx);
if (`SPC7.lsu_complete[7:0] != 8'b0)
if (`SPC7.lsu_complete[0]) Chk_ld_complete(0);
if (`SPC7.lsu_complete[1]) Chk_ld_complete(1);
if (`SPC7.lsu_complete[2]) Chk_ld_complete(2);
if (`SPC7.lsu_complete[3]) Chk_ld_complete(3);
if (`SPC7.lsu_complete[4]) Chk_ld_complete(4);
if (`SPC7.lsu_complete[5]) Chk_ld_complete(5);
if (`SPC7.lsu_complete[6]) Chk_ld_complete(6);
if (`SPC7.lsu_complete[7]) Chk_ld_complete(7);
if (`SPC7.lsu_block_store_kill[7:0] != 8'b0)
if (`SPC7.lsu_block_store_kill[0]) Squash_STB(0);
if (`SPC7.lsu_block_store_kill[1]) Squash_STB(1);
if (`SPC7.lsu_block_store_kill[2]) Squash_STB(2);
if (`SPC7.lsu_block_store_kill[3]) Squash_STB(3);
if (`SPC7.lsu_block_store_kill[4]) Squash_STB(4);
if (`SPC7.lsu_block_store_kill[5]) Squash_STB(5);
if (`SPC7.lsu_block_store_kill[6]) Squash_STB(6);
if (`SPC7.lsu_block_store_kill[7]) Squash_STB(7);
if (`SPC7.lsu_stb_dealloc[7:0] != 8'b0)
if (`SPC7.lsu_stb_dealloc[0]) Dealloc_STB(0);
if (`SPC7.lsu_stb_dealloc[1]) Dealloc_STB(1);
if (`SPC7.lsu_stb_dealloc[2]) Dealloc_STB(2);
if (`SPC7.lsu_stb_dealloc[3]) Dealloc_STB(3);
if (`SPC7.lsu_stb_dealloc[4]) Dealloc_STB(4);
if (`SPC7.lsu_stb_dealloc[5]) Dealloc_STB(5);
if (`SPC7.lsu_stb_dealloc[6]) Dealloc_STB(6);
if (`SPC7.lsu_stb_dealloc[7]) Dealloc_STB(7);
if (`SPC7.lsu_block_store_stall)
if (`SPC7.lsu.lsu_block_store_alloc[7:0] != 8'b0)
Set_block_store_parameters;
if (`SPC7.lsu_sbdiou_err_g || `SPC7.lsu_sbapp_err_g)
if (`SPC7.lsu_stb_flush_g)
st_priv[`SPC7.lsu_stberr_tid_g] = get_priv_on_flush(`SPC7.lsu_stberr_tid_g);
function [1:0] get_priv_on_flush;
sq_index = `SPC7.lsu_stberr_index_g;
tmp = stb[{tid, sq_index}];
get_priv_on_flush = tmp[`ST_PRIV];
thid = `SPC7.lsu_block_store_tid;
bst_inst_data = stb[{thid, rdptr[thid]}];
inst = bst_inst_data[`LSU_MON_INST];
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> LSU asserted blk_store_stall while the req at the top of STB is not blkst as shown above", core_id, thid);
//lsu can assert block_store_stall for a new block store while it has not yet written
//the 8 stb entries from the previous blk store.
task Set_block_store_parameters;
thid = decode_tid(`SPC7.lsu.lsu_block_store_alloc[7:0]);
if (lsu_bst_active[thid])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> LSU asserted blk_store_alloc while the bst_active is already set for this thread.", core_id, thid);
lsu_bst_active[thid] = 1'b1;
if (`SPC7.lsu.fgu_fst_ecc_error_fx2)
thid = `SPC7.lsu_stberr_tid_g;
sq_index = `SPC7.lsu_stberr_index_g;
priv = `SPC7.lsu_stberr_priv_g;
tmp = stb[{thid, sq_index}];
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> Sbdiou/sbapp seen for index = %h and priv = %h.", core_id, thid, sq_index, priv);
st_priv[thid] = tmp[`ST_PRIV];
//lsu can assert deallocate before it asserts the sbdiou signal.
//In that case iss_ptr won't be equal to sbdiou index.
//if (sq_index != iss_ptr[thid])
// Disp_STB_entry(thid, iss_ptr[thid]);
// `PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> LSU asserted sbdiou/sbapp with index %0h while the next req to be issued is at index %0h.", core_id, thid, sq_index, iss_ptr[thid]);
//If there is only one store in the store buffer which gets an sbdiou error, then LSU can deallocate
//the store and then assert sbdiou. The deallocation will cause the stb issue_ptr to move
//forward to an inst. that has already been issued and completed and this chk can fire. So
// Disp_STB_entry(thid, iss_ptr[thid]);
// `PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> Store reissued on the PCX interface.", core_id, thid, tmp[`MEMOP_PA]);
if (iss_ptr[thid] == wrptr[thid])
if (stb_valid[{thid, wrptr[thid]}])
//changing it to an info message because if there is only one valid entry in store buffer that
//gets an sbdiou then LSU can deallocate the entry and then issue sbdiou.
//`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Lsu asserted sbdiou/sbapp while there are no valid entries in STB to be issued.", core_id, thid);
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> sbdiou/sbapp squashed only one entry in STB.", core_id, thid);
if (iss_ptr[thid] < wrptr[thid])
squash_cnt = wrptr[thid] - iss_ptr[thid];
else if (iss_ptr[thid] > wrptr[thid])
squash_cnt = wrptr[thid] + (8 - iss_ptr[thid]);
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> SQUASH_STORE:iss_ptr = %0h, wrptr = %0h, squash_cnt = %0h.", core_id, thid, iss_ptr[thid], wrptr[thid], squash_cnt);
if (priv < tmp[`ST_PRIV])
`PR_INFO("lsu_mon", `INFO, "<C%h> <T%0h> <PA = %0h> Sbdiou/sbapp signalled. Err in user/priv level store is squashing a higher priv level store.", core_id, thid, tmp[`MEMOP_PA]);
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> <PA = %0h> STB_entry[%0h] squashed.", core_id, thid, tmp[`MEMOP_PA], i);
squash_cnt = squash_cnt - 1'b1;
function [2:0] decode_tid;
8'h10: decode_tid = 3'h4;
8'h20: decode_tid = 3'h5;
8'h40: decode_tid = 3'h6;
8'h80: decode_tid = 3'h7;
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> decode_tid. Incorrect value of thid input = %0h.", core_id, thid_encode, thid_encode);
reg [`LD_Pend_Width] tmp;
tmp = ld_pend_array[thid];
if ((tmp[`L2_ISS] != 4'hf) || (tmp[`L2_RESP] != 4'hf))
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> LSU asserted lsu_complete while the l2_iss and l2_resp bits are not F.", core_id, thid);
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> <%0h> %s(VA=%0h) Complete. Setting ld_valid to 0.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA]);
tmp = last_inst_array[thid];
`PR_INFO("lsu_mon", 24, "<C%h> <T%0h> <%0h> %s(VA=%0h) Complete.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA]);
reg [`LD_Pend_Width] tmp, tmp1;
thid = pcx_pkt[`PCX_THR_ID];
tmp = ld_pend_array[thid];
inst = tmp[`LSU_MON_INST];
req = DispPCXReq(pcx_pkt);
addr = pcx_pkt[`PCX_ADDR];
if (pcx_pkt[`PCX_CPU_ID] != core_id)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> cpu_id (spc_pcx_data_pa[122:120]) = %h is not = %0h when the lsu made a %s req to gasket.", core_id, pcx_pkt[`PCX_THR_ID], addr, pcx_pkt[122:120], core_id, req);
if ((pcx_pkt[`PCX_RQTYP] == `PCX_LOAD) || (pcx_pkt[`PCX_RQTYP] == `PCX_CAS1) || (pcx_pkt[`PCX_RQTYP] == `PCX_CAS2) || (pcx_pkt[`PCX_RQTYP] == `PCX_SWAP_LDSTUB))
ld_valid[thid] = 1'b1; //we have sent a req to gasket and are waiting for response
`PR_INFO("lsu_mon", 22, "<C%0h> <T%0h> Setting ld_valid[%0h].", core_id, thid, thid);
if (tmp[`MEMOP_PA] != addr)
if ((tmp[`INST_ASI] == 8'h41) || (tmp[`INST_ASI] == 8'h73) || ((tmp[`INST_ASI] == 8'h45) && ((tmp[`MEMOP_PA] == 8'h10) || (tmp[`MEMOP_PA] == 8'h18))))
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <PA = %0h> PA mismatch on gasket for %s request. Ignoring the mismatch as inst. is issued with asi 41, 73 or 45 (with VA 0x10 or 18).", core_id, thid, addr, req);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> A %s request made to gasket by LSU while the pending req is with PA %0h.", core_id, thid, addr, req, tmp[`MEMOP_PA]);
case (pcx_pkt[`PCX_RQTYP])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> A prefetch request made to gasket by LSU which mismatches the pending request from the thread.", core_id, thid, addr);
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: PREF_ICE(VA=%0h) Issued. pf_cnt not updated.", core_id, thid, tmp[`INST_VA], tmp[`MEMOP_VA]);
pf_cnt[thid] = pf_cnt[thid] + 1'b1;
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) Issued. pf_cnt = %0d.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], pf_cnt[thid]);
tmp[`L2_RESP] = 4'hF; //we don't wait for a prefetch response from gasket
ld_pend_array[thid] = tmp;
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) Dcache invalidate pkt issued to CCX.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA]);
dcache_inv_cnt[thid] = dcache_inv_cnt[thid] + 1'b1;
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> CASA request made to gasket by LSU while no such request request is pending from this thread.", core_id, thid, addr);
if (pcx_pkt[`PCX_RQTYP] == `PCX_CAS1)
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) (CAS1) Issued to gasket.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA]);
ld_pend_array[thid] = tmp;
if (pcx_pkt[`PCX_RQTYP] == `PCX_CAS2)
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) (CAS2) Issued to gasket.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA]);
ld_pend_array[thid] = tmp;
chk_store_issue_to_pcx(pcx_pkt);
if (~inst[`SWAP] && ~inst[`LDSTUB])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> %s request made to gasket by LSU while no such request request is pending from this thread.", core_id, thid, addr, req);
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) Issued to gasket. store_data = %0h", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], pcx_pkt[`PCX_DATA]);
ld_pend_array[thid] = tmp;
chk_store_issue_to_pcx(pcx_pkt);
chk_store_issue_to_pcx(pcx_pkt);
default: `PR_INFO("lsu_mon", 21, "<C%h> <T%0h> <%0h>: %s Issued to gasket.", core_id, thid, addr, req);
task Chk_cpx_response_pkt;
thid = cpx_pkt[`CPX_THR_ID];
casex ({cpx_pkt[`CPX_RTNTYP], cpx_pkt[`CPX_ERR], cpx_pkt[`CPX_NC], cpx_pkt[`CPX_ATM], cpx_pkt[`CPX_PF]})
{4'b0, 2'bxx, 1'bx, 1'b0, 1'b0}:
chk_ccx_ld_response(cpx_pkt);
{4'b0, 2'bxx, 1'b1, 1'b0, 1'b1}:
if (pf_cnt[thid] == 8'b0)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Prefetch response received from gasket while the pf_cnt is 0 for this thread.", core_id, thid);
pf_cnt[thid] = pf_cnt[thid] - 1'b1;
`PR_INFO("lsu_mon", 26, "<C%h> <T%0h> Prefetch response received. pfcnt = %0d.", core_id, thid, pf_cnt[thid]);
{4'h8, 2'bxx, 1'b1, 1'b0, 1'b0}:
chk_ccx_ld_response(cpx_pkt);
{4'h4, 2'bxx, 1'bx, 1'b0, 1'b0}:
if (cpx_pkt[123]) //D pkt
if (cpx_pkt[120:118] != core_id)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> D response received from gasket with core_id =%h.", core_id, thid, cpx_pkt[120:118]);
if (dcache_inv_cnt[thid] == 8'b0)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> D response received from gasket while the Dcache_inv_cnt is 0 for this thread.", core_id, thid);
dcache_inv_cnt[thid] = dcache_inv_cnt[thid] - 1'b1;
`PR_INFO("lsu_mon", 26, "<C%h> <T%0h> D response received. Dcache_inv_cnt = %0d.", core_id, thid, dcache_inv_cnt[thid]);
else if (cpx_pkt[124]) //I pkt
if (cpx_pkt[120:118] != core_id)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> I response received from gasket with core_id =%h.", core_id, thid, cpx_pkt[120:118]);
//`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> I pkt.", core_id, thid);
else if (cpx_pkt[124:123] == 2'b0)
if (cpx_pkt[120:118] == core_id)
chk_ccx_st_response(cpx_pkt);
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> Store Ack pkt received from core %0h.", core_id, thid, cpx_pkt[120:118]);
{4'h1, 2'bxx, 1'bx, 1'b0, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> IFILL1 return.", core_id, thid);
{4'h1, 2'bxx, 1'bx, 1'b1, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> IFILL2 return.", core_id, thid);
{4'h9, 2'bxx, 1'b1, 1'b0, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> NCU IFILL return.", core_id, thid);
{4'b0, 2'bxx, 1'b1, 1'b1, 1'b0}:
chk_ccx_atm_response(cpx_pkt);
{4'h4, 2'bxx, 1'b1, 1'b1, 1'b0}:
if ((cpx_pkt[`CPX_RTNTYP] == 4'h4) & (cpx_pkt[120:118] == core_id))
chk_ccx_atm_response(cpx_pkt);
chk_ccx_st_response(cpx_pkt);
{4'h2, 2'bxx, 1'b1, 1'b0, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> Stream Ld return.", core_id, thid);
{4'h6, 2'bxx, 1'bx, 1'bx, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> Stream store Ack.", core_id, thid);
{4'h5, 2'bxx, 1'b1, 1'b0, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> MMU ld return.", core_id, thid);
{4'h7, 2'b00, 1'b0, 1'bx, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> Interrupt return.", core_id, thid);
{4'h3, 2'b00, 1'bx, 1'bx, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> Eviction Invalidation.", core_id, thid);
{4'hc, 2'bxx, 1'bx, 1'bx, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> L2 Indication.", core_id, thid);
{4'hd, 2'bxx, 1'bx, 1'bx, 1'b0}:
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> Soc Error Indication.", core_id, thid);
`PR_ALWAYS("lsu_mon", `ALWAYS, "CPX_PKT data.");
`PR_ALWAYS("lsu_mon", `ALWAYS, "<C%0h> <T%0h> rtn_typ = %0h, err_bits = %0h, nc=%0b, atm = %0b, pf = %0b", core_id, cpx_pkt[`CPX_THR_ID], cpx_pkt[`CPX_RTNTYP], cpx_pkt[`CPX_ERR], cpx_pkt[`CPX_NC], cpx_pkt[`CPX_ATM], cpx_pkt[`CPX_PF]);
`PR_ERROR("lsu_mon", `ERROR, "<C%0h> <T%0h> Can't recognise the CPX pkt.", core_id, thid);
task chk_ccx_ld_response;
reg [39:0] cpx_pa, inst_pa;
reg [`LD_Pend_Width] tmp;
thid = cpx_pkt[`CPX_THR_ID];
tmp = ld_pend_array[thid];
inst = tmp[`LSU_MON_INST];
inst_pa = tmp[`MEMOP_PA];
pkt_type = cpx_pkt[`CPX_RTNTYP];
`PR_INFO("lsu_mon", 26, "<C%0h> <T%0h> <%0h> %s(VA=%0h) L2 response.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA]);
if (inst_pa[39] != pkt_type[3])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> ccx pkt_type = %h mismatches the ld_pa bit 39. ld_pa = %0h.", core_id, thid, pkt_type, inst_pa);
if (tmp[`L2_RESP] == 4'h0)
tmp[`L2_ERR0] = cpx_pkt[`CPX_ERR];
if ((cpx_pkt[`CPX_ERR] == `ND) || (cpx_pkt[`CPX_ERR] == `UE))
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> UE/ND err on blk ld helper 1.", core_id, thid);
else if (tmp[`L2_RESP] == 4'h1)
tmp[`L2_ERR1] = cpx_pkt[`CPX_ERR];
if ((cpx_pkt[`CPX_ERR] == `ND) || (cpx_pkt[`CPX_ERR] == `UE))
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> UE/ND err on blk ld helper 2.", core_id, thid);
else if (tmp[`L2_RESP] == 4'h3)
tmp[`L2_ERR2] = cpx_pkt[`CPX_ERR];
if ((cpx_pkt[`CPX_ERR] == `ND) || (cpx_pkt[`CPX_ERR] == `UE))
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> UE/ND err on blk ld helper 3.", core_id, thid);
else if (tmp[`L2_RESP] == 4'h7)
tmp[`L2_ERR3] = cpx_pkt[`CPX_ERR];
if ((cpx_pkt[`CPX_ERR] == `ND) || (cpx_pkt[`CPX_ERR] == `UE))
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> UE/ND err on blk ld helper 4.", core_id, thid);
if ((tmp[`L2_ERR0] == `ND) || (tmp[`L2_ERR1] == `ND) || (tmp[`L2_ERR2] == `ND) || (tmp[`L2_ERR3] == `ND))
l2_blk_ld_errtype[thid] = `ND;
else if ((tmp[`L2_ERR0] == `UE) || (tmp[`L2_ERR1] == `UE) || (tmp[`L2_ERR2] == `UE) || (tmp[`L2_ERR3] == `UE))
l2_blk_ld_errtype[thid] = `UE;
else if ((tmp[`L2_ERR0] == `CE) || (tmp[`L2_ERR1] == `CE) || (tmp[`L2_ERR2] == `CE) || (tmp[`L2_ERR3] == `CE))
l2_blk_ld_errtype[thid] = `CE;
l2_blk_ld_errtype[thid] = `NE;
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Illegal value of l2_resp cnt when response pkt received from ccx.", core_id, thid);
else if (Is_single_pcx_req_ld(inst))
if (tmp[`L2_RESP] != 4'hE)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Illegal value of l2_resp cnt when response pkt received from ccx.", core_id, thid);
//`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> Setting L2_resp bits to F.", core_id, thid);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Load response received from gasket for thid %h while no load request pending from core for this thread.", core_id, thid, thid);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Load response received from gasket while no load request pending from core for this thread.", core_id, thid);
ld_pend_array[thid] = tmp;
task chk_ccx_atm_response;
reg [`LD_Pend_Width] tmp;
thid = cpx_pkt[`CPX_THR_ID];
tmp = ld_pend_array[thid];
inst = tmp[`LSU_MON_INST];
inst_pa = tmp[`MEMOP_PA];
if (cpx_pkt[`CPX_RTNTYP] == 4'b0)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Atomic ld response received from gasket while no request pending from core for this thread.", core_id, thid);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Atomic ack response received from gasket while no request pending from core for this thread.", core_id, thid);
if (~inst[`SWAP] && ~inst[`CASA] && ~inst[`LDSTUB])
if (cpx_pkt[`CPX_RTNTYP] == 4'b0)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Atomic ld response received from gasket which mismatches the request pending from this thread.", core_id, thid);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Atomic ack response received from gasket which mismatches the request pending from this thread.", core_id, thid);
if (cpx_pkt[`CPX_RTNTYP] == 4'b0)
`PR_INFO("lsu_mon", 26, "<C%0h> <T%0h> <%0h> %s(VA=%0h) Atomic ld response.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA]);
`PR_INFO("lsu_mon", 26, "<C%0h> <T%0h> <%0h> %s(VA=%0h) Atomic ack.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA]);
if (cpx_pkt[`CPX_RTNTYP] == 4'b0)
if (tmp[`L2_RESP] == 4'hC) tmp[`L2_RESP] = 4'hD;
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Illegal value of l2_resp cnt when atomic ld return pkt received from ccx.", core_id, thid);
if (tmp[`L2_RESP] == 4'hD) tmp[`L2_RESP] = 4'hF;
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Illegal value of l2_resp cnt when atomic ack pkt received from ccx.", core_id, thid);
ld_pend_array[thid] = tmp;
task chk_ccx_st_response;
reg [39:0] cpx_pa, inst_pa;
thid = cpx_pkt[`CPX_THR_ID];
tmp = stb[{thid, ret_ptr[thid]}];
inst = tmp[`LSU_MON_INST];
inst_pa = tmp[`MEMOP_PA];
pkt_type = cpx_pkt[`CPX_RTNTYP];
//is received. There could be some other store sitting in the STB at that time.
//Chk for squash bit only for non-bis responses.
if (cpx_pkt[`CPX_BIS]) //response to rmo store
if (st_rmo_cnt[thid] == 0)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> L2 response received for an rmo store while the st_rmo_cnt for this thread is 0.", core_id, thid);
st_rmo_cnt[thid] = st_rmo_cnt[thid] - 1'b1;
`PR_INFO("lsu_mon", 25, "<C%0h> <T%0h> Store ack received for RMO store. rmo_cnt = %0d", core_id, thid, st_rmo_cnt[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> L2 response received while the SQUASH bit is set in the STB entry %0h.", core_id, thid, ret_ptr[thid]);
if (~stb_valid[{thid, ret_ptr[thid]}])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Store ack received while that entry is invalid in STB.", core_id, thid);
if (~cpx_pkt[`CPX_ATM]) //don't print this message for atomic return
`PR_INFO("lsu_mon", 26, "<C%0h> <T%0h> <%0h> %s(VA=%0h) STB[%0d] Store ack.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA], ret_ptr[thid]);
stb[{thid, ret_ptr[thid]}] = tmp;
ret_ptr[thid] = ret_ptr[thid] + 1'b1;
//`PR_INFO("lsu_mon", 22, "<C%0h> <T%0h> ret_ptr = %0d.", core_id, thid, ret_ptr[thid]);
reg [`LD_Pend_Width] tmp;
reg [39:0] pcx_pa, inst_pa;
thid = pcx_pkt[`PCX_THR_ID];
tmp = ld_pend_array[thid];
inst = tmp[`LSU_MON_INST];
pcx_pa = pcx_pkt[`PCX_ADDR];
inst_pa = tmp[`MEMOP_PA];
req = DispPCXReq(pcx_pkt);
if (pcx_pa[39:6] != inst_pa[39:6])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> A load request made to gasket by LSU while the pending req has PA %0h.", core_id, thid, pcx_pa, tmp[`MEMOP_PA]);
if (tmp[`L2_ISS] != 4'h0 )
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> 1st load request (pa[5:0] = 6'b0) made to gasket by LSU for blkld while this request has already been issued to gasket.", core_id, thid, pcx_pa);
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) 1st blkld helper Issued to gasket.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA]);
if (pcx_pa[5:0] == 6'h10)
if (tmp[`L2_ISS] != 4'h1)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> 2nd load request (pa[5:0] = 6'h10) made to gasket by LSU for blkld while this request has already been issued to gasket.", core_id, thid, pcx_pa);
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) 2nd blkld helper Issued to gasket.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA]);
if (pcx_pa[5:0] == 6'h20)
if (tmp[`L2_ISS] != 4'h3)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> 3rd load request (pa[5:0] = 6'h20) made to gasket by LSU for blkld while this request has already been issued to gasket.", core_id, thid, pcx_pa);
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) 3rd blkld helper Issued to gasket.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA]);
if (pcx_pa[5:0] == 6'h30)
if (tmp[`L2_ISS] != 4'h7)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> 4th load request (pa[5:0] = 6'h30) made to gasket by LSU for blkld while this request has already been issued to gasket.", core_id, thid, pcx_pa);
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) 4th blkld helper Issued to gasket.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA]);
ld_pend_array[thid] = tmp;
else if (Is_single_pcx_req_ld(inst))
if (tmp[`L2_ISS] == 4'hF)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> Load request made to gasket by LSU while this request has already been issued to gasket.", core_id, thid, pcx_pa);
ld_pend_array[thid] = tmp;
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) Issued to gasket.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> A load request made to gasket by LSU while there is no such ld request pending from this thread.", core_id, thid, pcx_pa);
function Is_single_pcx_req_ld;
if (inst[`LDD] || inst[`QLD] || inst[`FSR_RD_WR] || (inst == 21'h1) || (inst == 21'h5))
Is_single_pcx_req_ld = 1'b1;
Is_single_pcx_req_ld = 1'b0;
//`PR_INFO("lsu_mon", 22, "<C%0h> Is_single_pcx_req_ld = %b. ", core_id, Is_single_pcx_req_ld);
case (`SPC7.lsu_trap_flush[7:0])
8'h01: if (tid == 3'h0) Is_trap = 1'b1;
8'h02: if (tid == 3'h1) Is_trap = 1'b1;
8'h04: if (tid == 3'h2) Is_trap = 1'b1;
8'h08: if (tid == 3'h3) Is_trap = 1'b1;
8'h10: if (tid == 3'h4) Is_trap = 1'b1;
8'h20: if (tid == 3'h5) Is_trap = 1'b1;
8'h40: if (tid == 3'h6) Is_trap = 1'b1;
8'h80: if (tid == 3'h7) Is_trap = 1'b1;
function [8*11:0] DispPCXReq;
casex ({pcx_pkt[`PCX_RQTYP], pcx_pkt[`PCX_NC], pcx_pkt[`PCX_INV], pcx_pkt[`PCX_PF], pcx_pkt[`PCX_BIS]})
{5'h0, 1'b1, 1'b0, 1'b1, 1'b0}: DispPCXReq = "PREF";
{5'h0, 1'b1, 1'b1, 1'b1, 1'b0}: DispPCXReq = "PREF_ICE";
{5'h0, 1'bx, 1'b0, 1'b0, 1'b0}: DispPCXReq = "LD";
{5'h0, 1'bx, 1'b1, 1'b0, 1'b0}: DispPCXReq = "D";
{5'h10, 1'bx, 1'b0, 1'b0, 1'b0}: DispPCXReq = "I";
{5'h10, 1'b0, 1'b1, 1'b0, 1'b0}: DispPCXReq = "I";
{5'h1, 1'bX, 1'bX, 1'b0, 1'b0}: DispPCXReq = "ST";
{5'h1, 1'bX, 1'bX, 1'b1, 1'b1}: DispPCXReq = "BLKST";
{5'h1, 1'bX, 1'bX, 1'b0, 1'b1}: DispPCXReq = "BIS";
{5'h2, 1'b1, 1'bX, 1'b0, 1'b0}: DispPCXReq = "CASA1";
{5'h3, 1'b1, 1'bX, 1'b0, 1'b0}: DispPCXReq = "CASA2";
{5'h7, 1'b1, 1'bX, 1'b0, 1'b0}: DispPCXReq = "SWAP_LDSTUB";
{5'h4, 1'b1, 1'b0, 1'b0, 1'b0}: DispPCXReq = "STREAM_LD";
{5'h5, 1'b1, 1'b0, 1'b0, 1'bx}: DispPCXReq = "STREAM_ST";
{5'h8, 1'b1, 1'b0, 1'b0, 1'b0}: DispPCXReq = "MMU_LD";
//{5'h9, 1'b0, 1'b0, 1'b0, 1'b0}: DispPCXReq = "INT";
`PR_ERROR("lsu_mon", `ERROR, "<C%0h> <T%0h> <%0h> Can't recognise the PCX pkt type. rq_type = %h, nc_bit = %0b, inv_bit = %0b, pf_bit = %0b, bis_bit = %0b. pcx_pkt[129:0] = %h", core_id, pcx_pkt[`PCX_THR_ID], pcx_pkt[`PCX_ADDR], pcx_pkt[`PCX_RQTYP], pcx_pkt[`PCX_NC], pcx_pkt[`PCX_INV], pcx_pkt[`PCX_PF], pcx_pkt[`PCX_BIS], pcx_pkt);
if (`SPC7.lsu_align_b) DispExc = "Addr_not_aligned";
if (`SPC7.lsu_lddf_align_b) DispExc = "LDDF_Addr_not_aligned";
if (`SPC7.lsu_stdf_align_b) DispExc = "STDF_Addr_not_aligned";
if (`SPC7.lsu_priv_action_b) DispExc = "Priv_actio";
if (`SPC7.lsu_va_watchpoint_b) DispExc = "VA_watchpoint";
if (`SPC7.lsu_pa_watchpoint_b) DispExc = "PA_watchpoint";
//if (`SPC7.lsu_tlb_miss_b_) DispExc = "Tlb_miss";
if (`SPC7.lsu_illegal_inst_b) DispExc = "Illegal_inst";
if (`SPC7.lsu_daccess_prot_b) DispExc = "Data_access_prot_exc";
if (`SPC7.lsu_dae_invalid_asi_b) DispExc = "Dae_Invalid_asi";
if (`SPC7.lsu_dae_nc_page_b) DispExc = "Dae_nc_page";
if (`SPC7.lsu_dae_nfo_page_b) DispExc = "Dae_NFO_page";
if (`SPC7.lsu_dae_priv_viol_b) DispExc = "Dae_Priv_viol";
if (`SPC7.lsu_dae_so_page) DispExc = "Dae_so_page";
//if (`SPC7.lsu_perfmon_trap_b) DispExc = "Perf_mon_trap";
if (`SPC7.lsu_dtmh_err_b) DispExc = "DTLB_data_par_err";
if (`SPC7.lsu_dttp_err_b) DispExc = "DTLB_tag_par_err";
if (`SPC7.lsu_dtdp_err_b) DispExc = "DTLB_data_par_err";
`PR_INFO("lsu_mon", 23, "<C%0h> <T%0h> <%0h> B_stage: %s(VA=%0h) ASI = %0h. %s Exception.",core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b, asi_b, DispExc);
input [1:0] exu_lsu_va_error_b; // VA error requiring a flush
input [1:0] exu_ecc_b; // ECC error requiring a flush
err_b = dec_lsu_tid_b[2] ? (exu_ecc_b[1] | (exu_lsu_va_error_b[1] & ~`SPC7.lsu_tlb_bypass_b)):
(exu_ecc_b[0] | (exu_lsu_va_error_b[0] & ~`SPC7.lsu_tlb_bypass_b));
err_m = (dec_lsu_tid_b[2] ? `SPC7.exu_ecc_m[1] : `SPC7.exu_ecc_m[0]) & `SPC7.lsu.dcc.twocycle_b;
Is_exu_error = err_b | err_m;
task Insert_tlb_miss_info;
if (tlb_valid[dec_lsu_tid_b])
tmp = tlbmiss_pend_array[dec_lsu_tid_b];
Disp_tlbmiss_pend_array_entry(dec_lsu_tid_b);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <%0h> B_stage: %s(VA=%0h>) A new tlb miss request received while there is already a Tlb miss request pending from this thread as shown above.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b);
tlb_valid[dec_lsu_tid_b] <= 1'b1;
tmp[`INST_VA] = inst_pc_b;
tmp[`MEMOP_VA] = vaddr_b;
tlbmiss_pend_array[dec_lsu_tid_b] = tmp;
//problem with the signal.
always @ (negedge `SPC7.l2clk)
if (`SPC7.tlu_trap_pc_0_valid)
thid = {1'b0, `SPC7.tlu_trap_0_tid};
else if (`SPC7.tlu_trap_pc_1_valid)
thid = {1'b0, `SPC7.tlu_trap_1_tid};
`PR_ERROR("lsu_mon", `ERROR, "<C%h> mmu_dtlb_reload asserted but trap_pc_0_valid and trap_pc_1_valid are both 0", core_id);
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> mmu_dtlb_reload asserted while tlb_valid is 0.", core_id, thid);
tmp = tlbmiss_pend_array[dec_lsu_tid_b];
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> %s(VA=%0h> DTLB reloaded for VA = %0h.", core_id, thid, tb_top.intf0.xlate(tmp[`INST]), tmp[`INST_VA], tmp[`MEMOP_VA] );
task Insert_ld_miss_info;
reg [`LD_Pend_Width] tmp;
if (ld_valid[dec_lsu_tid_b])
tmp = ld_pend_array[dec_lsu_tid_b];
DispPendReq(dec_lsu_tid_b);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <%0h> B_stage: %s(VA=%0h>) A new request received while there is already a request pending from this thread as shown above.", core_id, dec_lsu_tid_b, inst_pc_b, tb_top.intf0.xlate(inst_b),vaddr_b);
//ld_valid[dec_lsu_tid_b] <= 1'b1;
tmp[`INST_VA] = inst_pc_b;
tmp[`MEMOP_VA] = vaddr_b;
tmp[`MEMOP_PA] = {`SPC7.lsu.tlb_pgnum[39:13], vaddr_b[12:0]};
is_blkld[dec_lsu_tid_b] = 1'b1;
is_blkld[dec_lsu_tid_b] = 1'b0;
if (lsu_inst_b[`SWAP] || lsu_inst_b[`LDSTUB] || lsu_inst_b[`CASA])
tmp[`LSU_MON_INST] = lsu_inst_b;
ld_pend_array[dec_lsu_tid_b] = tmp;
task Insert_in_last_inst_array;
tmp[`INST_VA] = inst_pc_b;
tmp[`MEMOP_VA] = vaddr_b;
last_inst_array[dec_lsu_tid_b] = tmp;
reg [`LD_Pend_Width] tmp;
tmp = ld_pend_array[thid];
`PR_ALWAYS("lsu_mon", `ALWAYS, "LD_PEND_ARRAY[%0h] Data.", thid);
`PR_ALWAYS("lsu_mon", `ALWAYS, "<C%h> <T%0h> <%0h> %s(VA=%0h). PA = %0h. L2_ISS = %0h. L2_RESP = %0h, LSU_MON_INST=%h.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA], tmp[`MEMOP_PA], tmp[`L2_ISS], tmp[`L2_RESP], tmp[`LSU_MON_INST]);
`PR_ALWAYS("lsu_mon", `ALWAYS, "<C%h> <T%0h> STB[%0h] data.", core_id, thid, ptr);
`PR_ALWAYS("lsu_mon", `ALWAYS, "<C%h> <T%0h> <%0h> %s(VA=%0h). PA = %0h. L2_ISS = %0h. L2_ACK = %0h, LSU_MON_INST=%h. RMO = %0b", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA], tmp[`MEMOP_PA], tmp[`L2_ST_ISS], tmp[`L2_ACK], tmp[`LSU_MON_INST], tmp[`RMO]);
task Disp_tlbmiss_pend_array_entry;
tmp = tlbmiss_pend_array[thid];
`PR_INFO("lsu_mon", 23, "TLB_MISS_PEND_ARRAY[%0h] Data.", thid);
`PR_INFO("lsu_mon", 23, "<C%h> <T%0h> <%0h> %s(VA=%0h).", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]), tmp[`MEMOP_VA]);
`PR_ALWAYS("lsu_mon", `ALWAYS, "CPX_PKT data.");
`PR_ALWAYS("lsu_mon", `ALWAYS, "<C%0h> <T%0h> rtn_typ = %0h, err_bits = %0h, nc=%0b, atm = %0b, pf = %0b", core_id, cpx_pkt[`CPX_THR_ID], cpx_pkt[`CPX_RTNTYP], cpx_pkt[`CPX_ERR], cpx_pkt[`CPX_NC], cpx_pkt[`CPX_ATM], cpx_pkt[`CPX_PF]);
tmp[`INST_VA] = inst_pc_b;
tmp[`MEMOP_VA] = vaddr_b;
tmp[`MEMOP_PA] = {`SPC7.lsu.tlb_pgnum[39:13], vaddr_b[12:0]};
tmp[`LSU_MON_INST] = lsu_inst_b;
if (`SPC7.lsu.tlu_lsu_hpstate_hpriv[dec_lsu_tid_b])
else if (`SPC7.lsu.tlu_lsu_pstate_priv[dec_lsu_tid_b])
//bis_asi to io space is not rmo
tmp[`RMO] = lsu_inst_b[`BLKST] | (dec_altspace_b & Is_bis_asi(asi_b) & ~`SPC7.lsu.tlb_pgnum[39]);
input [195:0] store_data;
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> STB full and a new store received for insertion in STB.", core_id, thid);
stb[{thid, wrptr[thid]}] = store_data;
//Disp_STB_entry(thid, wrptr[thid]);
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> <%0h> %s(VA=%0h). STB[%0h] Inserted.", core_id, thid, store_data[`INST_VA], tb_top.intf0.xlate(store_data[`INST]), store_data[`MEMOP_VA], wrptr[thid]);
stb_valid[{thid, wrptr[thid]}] = 1'b1;
wrptr[thid] = wrptr[thid] + 1'b1;
//`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> wrptr = %0d.", core_id, thid, wrptr[thid]);
if ((wrptr[thid] == rdptr[thid]) && stb_valid[{thid, wrptr[thid]}])
//thid = decode_tid(`SPC7.lsu_stb_dealloc);
tmp = stb[{thid, rdptr[thid]}];
lsu_inst = tmp[`LSU_MON_INST];
if (~stb_valid[{thid, rdptr[thid]}])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> lsu_stb_dealloc = %0h asserted while the stb entry is invalid for that thid.", core_id, thid, `SPC7.lsu_stb_dealloc);
Disp_STB_entry(thid, rdptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> lsu_stb_dealloc = %0h asserted when we haven't received the response from the gasket.", core_id, thid, `SPC7.lsu_stb_dealloc);
else if (tmp[`ASI_ST_ISS])
ret_ptr[thid] = ret_ptr[thid] + 1'b1;
//blkst inst. is not issued anywhere, blkst helpers are issued.
//in case of bis stores, lsu issues the dealloc in P3, i.e when the req is issued to PCX.
//IF it is bis to cp sapce and there is an err then the store is issued to PCX with nd set
//However for ue onbis to IO space, dealloc is sent to IFU, issued on PCX with valid bit 0.
//The sbdiou signal is sent in next cycle. We need to take bis io stores in this equation.
else if (tmp[`ST_SQUASH] || lsu_inst[`BLKST] || (tmp[`RMO] & ~lsu_inst[`BLKST] & ~`SPC0.lsu.sbc.kill_store_p4_))
iss_ptr[thid] = iss_ptr[thid] + 1'b1;
ret_ptr[thid] = ret_ptr[thid] + 1'b1;
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> lsu_stb_dealloc = %0h asserted which is not issued to asi ring, or PCX or is not squashed.", core_id, thid, `SPC7.lsu_stb_dealloc);
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> <%0h>: %s(VA=%0h) PA = %0h. STB[%0d] Deallocated.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], tmp[`MEMOP_PA], rdptr[thid]);
stb_valid[{thid, rdptr[thid]}] = 1'b0;
rdptr[thid] = rdptr[thid] + 1'b1;
//`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> rd_ptr = %0d.", core_id, thid, rdptr[thid]);
st_rmo_cnt[thid] = st_rmo_cnt[thid] + 1'b1;
if (ret_ptr[thid] != iss_ptr[thid])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> lsu_block_store_kill asserted while the ret_ptr = %0h != iss_ptr = %0h.", core_id, thid, tmp[`MEMOP_PA], ret_ptr[thid], iss_ptr[thid]);
if (rdptr[thid] != iss_ptr[thid])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> lsu_block_store_kill asserted while the rdptr = %0h != iss_ptr = %0h.", core_id, thid, tmp[`MEMOP_PA], rdptr[thid], iss_ptr[thid]);
if (iss_ptr[thid] == wrptr[thid])
if (stb_valid[{thid, wrptr[thid]}])
/* Lsu can assert both dealloc and block_store_kill for a request.
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Lsu asserted block_store_kill while there are no valid entries in STB to be deallocated.", core_id, thid);
if (iss_ptr[thid] < wrptr[thid])
squash_cnt = wrptr[thid] - iss_ptr[thid];
else if (iss_ptr[thid] > wrptr[thid])
squash_cnt = wrptr[thid] + (8 - iss_ptr[thid]);
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> SQUASH_STB:iss_ptr = %0h, wrptr = %0h, squash_cnt = %0h.", core_id, thid, iss_ptr[thid], wrptr[thid], squash_cnt);
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> Block store kill changed issue_ptr:%0h->%0h. ret_ptr: %0h->%0h. rdptr:%0h->%0h.", core_id, thid, iss_ptr[thid], iss_ptr[thid]+squash_cnt, ret_ptr[thid], ret_ptr[thid]+squash_cnt, rdptr[thid], rdptr[thid]+squash_cnt);
ret_ptr[thid] = ret_ptr[thid] + squash_cnt;
rdptr[thid] = rdptr[thid] + squash_cnt;
iss_ptr[thid] = iss_ptr[thid] + squash_cnt;
if (~stb_valid[{thid, i}])
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h><PA = %0h> lsu_block_store_kill asserted while the stb entry %0h is invalid.", core_id, thid, tmp[`MEMOP_PA], i);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h>st_issue bit is set when the block_store_kill is asserted for stb entry %0h.", core_id, thid, tmp[`MEMOP_PA], i);
//commenting out the chk below. Lsu can assert sbdiou and then in the next cycle insert a new entry into
//stb. LSU will squash this new entry and won't issue it to PCX/asi but its squash bit won't be
//set in the chkr which was causin it to fire.
//`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> lsu_block_store_kill asserted while the squash bit is 0 in the STB entry %0h.", core_id, thid, tmp[`MEMOP_PA], i);
stb_valid[{thid, i}] = 1'b0;
squash_cnt = squash_cnt - 1'b1;
if ((bst_cnt > 0) && (`SPC7.lsu_stb_alloc == 8'b0))
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> Blk store entries are not allocated back to back in STB.", core_id, bst_active_thid);
//For bst the stb is still written even though we have errors.
//Stb is written in W stage. Howvere for first blk store helper
//the err will be flagged by FGU in b stage. We can miss the
// err signal if we don't sample in B.
//for the last helper err will be signalled in B stage of last helper and at
if (lsu_bst_active[bst_active_thid] & `SPC0.fgu_fst_ecc_error_fx2 & (bst_cnt < 7))
if (`SPC7.lsu_stb_alloc[7:0] != 8'b0)
thid = decode_tid(`SPC7.lsu_stb_alloc[7:0]);
if (thid != dec_lsu_tid_w)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> lsu_stb_alloc = %0h mismatches the thid %0h.", core_id, dec_lsu_tid_w, `SPC7.lsu_stb_alloc[7:0], dec_lsu_tid_w);
Insert_in_STB(stb_alloc_data, dec_lsu_tid_w);
if (lsu_bst_active[thid])
bst_data = bst_inst_data;
if (thid != bst_active_thid)
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> lsu_stb_alloc = %0h mismatches the active blkstore thid = %0h.", core_id, bst_active_thid, `SPC7.lsu_stb_alloc[7:0], bst_active_thid);
addr = bst_data[`MEMOP_VA];
bst_data[`MEMOP_VA] = {addr[47:6], bst_cnt[2:0], 3'b0};
addr = bst_data[`MEMOP_PA];
bst_data[`MEMOP_PA] = {addr[39:6], bst_cnt[2:0], 3'b0};
Insert_in_STB(bst_data, bst_active_thid);
lsu_bst_active[thid] = 1'b0;
if (bst_fgu_err) //set the squash bit to 0 for all the stb entries
for (i = 0; i < 8; i=i+1)
tmp = stb[{thid, i[2:0]}];
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> Squash bit already set when trying to set it for a bst fgu errerr.", core_id, thid, tmp[`MEMOP_PA]);
stb[{thid, i[2:0]}] = tmp;
`PR_INFO("lsu_mon", 22, "<C%h> <T%0h> <PA = %0h> STB_entry[%0h] squashed due to FGU err.", core_id, thid, tmp[`MEMOP_PA], i);
`PR_ERROR("lsu_mon", `ERROR, "<C%h>: LSU asserted lsu_stb_alloc = %0h while no store pending to be written in STB.", core_id, `SPC7.lsu_stb_alloc[7:0]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <%0h> W_stage: LSU did not assert lsu_stb_alloc for the store.", core_id, dec_lsu_tid_w, inst_pc_w);
reg [47:0] addr, act_addr;
thid =`SPC7.lsu_rngl_cdbus[58:56];
thid =`SPC7.lsu_rngf_cdbus[58:56];
asi =`SPC7.lsu_rngl_cdbus[55:48];
asi =`SPC7.lsu_rngf_cdbus[55:48];
addr =`SPC7.lsu_rngl_cdbus[47:0];
addr =`SPC7.lsu_rngf_cdbus[47:0];
req_type =`SPC7.lsu_rngl_cdbus[61:60];
req_type =`SPC7.lsu_rngf_cdbus[61:60];
tmp = stb[{thid, iss_ptr[thid]}];
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> Store reissued on the ASI interface.", core_id, thid, addr);
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> Store issued on the ASI interface that has been squashed.", core_id, thid, addr);
act_addr = tmp[`MEMOP_PA];
act_addr = {act_addr[39:3], 3'b0};
//47 is D tag rd asi. LSU issues that on the ring but changes
if ((addr == act_addr) || (asi == 8'h47) || (asi == 8'h46))
stb[{thid, iss_ptr[thid]}] = tmp;
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) STB[%0d] Issued on local ring.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], iss_ptr[thid]);
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) STB[%0d] Issued on fast ring.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], iss_ptr[thid]);
iss_ptr[thid] = iss_ptr[thid] + 1'b1;
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <%0h>: %s(VA=%0h) STB[%0d] PA mismatch for asi req on local ring. Expected PA = %0h, actual PA = %0h", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], iss_ptr[thid], tmp[`MEMOP_PA], addr);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <%0h>: %s(VA=%0h) STB[%0d] PA mismatch for asi req on fast ring. Expected PA = %0h, actual PA = %0h", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], iss_ptr[thid], tmp[`MEMOP_PA], addr);
task chk_store_issue_to_pcx;
reg [39:0] pcx_pa, inst_pa;
thid = pcx_pkt[`PCX_THR_ID];
tmp = stb[{thid, iss_ptr[thid]}];
inst = tmp[`LSU_MON_INST];
pcx_pa = pcx_pkt[`PCX_ADDR];
inst_pa = tmp[`MEMOP_PA];
if (pcx_pkt[`PCX_RQTYP] == `PCX_STORE)
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) STB[%0d] Issued to gasket.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], iss_ptr[thid]);
`PR_INFO("lsu_mon", 25, "<C%h> <T%0h> <%0h>: %s(VA=%0h) STB[%0d] Issued to gasket with ND set.", core_id, thid, tmp[`INST_VA], tb_top.intf0.xlate(tmp[`INST]),tmp[`MEMOP_VA], iss_ptr[thid]);
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> A store request made to gasket by LSU while the pending req is not store.", core_id, thid, pcx_pkt[`PCX_ADDR]);
if (pcx_pa[39:0] != inst_pa[39:0])
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> A store request made to gasket by LSU while the pending req has PA %0h.", core_id, thid, pcx_pkt[`PCX_ADDR], tmp[`MEMOP_PA]);
if ((tmp[`INST_ASI] == 8'h73) & (pcx_pa[39:0] != {8'h90, core_id, thid, tmp[`INST_ASI], 18'h0}))
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> pcx_pa is not correct for asi write to interrupt vector dispatch register.", core_id, thid, pcx_pkt[`PCX_ADDR]);
if (inst[`BLKST] && ~pcx_pkt[`PCX_BST])
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> Bst bit is not set in the PCX pkt by LSU for a blk st request.", core_id, thid, pcx_pkt[`PCX_ADDR]);
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> Store reissued on the PCX interface.", core_id, thid, pcx_pkt[`PCX_ADDR]);
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> Store issued on the PCX interface that has been squashed.", core_id, thid, pcx_pkt[`PCX_ADDR]);
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> BIS bit is not set in the PCX pkt by LSU for an RMO store.", core_id, thid, pcx_pkt[`PCX_ADDR]);
Disp_STB_entry(thid, iss_ptr[thid]);
`PR_ERROR("lsu_mon", `ERROR, "<C%h> <T%0h> <PA = %0h> L2ack bit is set when the RMO store is issued to PCX.", core_id, thid, pcx_pkt[`PCX_ADDR]);
ret_ptr[thid] = ret_ptr[thid] + 1; //this will be deallocated before
//response seen from stub
st_rmo_cnt[thid] = st_rmo_cnt[thid] + 1'b1;
stb[{thid, iss_ptr[thid]}] = tmp;
iss_ptr[thid] = iss_ptr[thid] + 1;
`PR_INFO("lsu_mon", 20, "<C%h> <T%0h> iss_ptr = %0d. ret_ptr = %0d, st_rmo_cnt = %0d", core_id, thid, iss_ptr[thid], ret_ptr[thid], st_rmo_cnt[thid]);
`ifdef INJ_STB_ERR_IN_CMP
reg [2:0] err_tid, stb_err_tid_d1, stb_err_tid_d2;
reg [2:0] err_index, stb_err_index_d1, stb_err_index_d2;
reg stb_err_inj, stb_err_inj_d1, stb_err_inj_d2;
reg [1:0] err_priv, stb_err_priv_d1, stb_err_priv_d2;
if (("cmp_stb_err_inj_on"))
always @ (negedge (`SPC7.l2clk & enabled & cmp_stb_err_inj))
//valid stb ram rd for issue to pcx
if (`SPC7.lsu.sbc.ram_rptr_vld_2 & `SPC7.lsu.sbc.st_pcx_rq_p3 & `SPC7.lsu.pic.pic_st_sel_p3)
err_tid = decode_tid(`SPC7.lsu.sbc.st_rq_sel_p3[7:0]);
err_index = `SPC7.lsu.sbc.ram_rptr_d1;
err_tmp = stb[{err_tid, err_index}];
err_inst = err_tmp[`LSU_MON_INST];
cam_data = `SPC7.lsu.stb_cam.cam_array.stb_rdata[44:0];
err_priv = err_tmp[`ST_PRIV];
//if (err_inst[`SWAP] || err_inst[`CASA] || err_inst[`LDSTUB])
err_inj_cnt = err_inj_cnt + 1;
11, 12: err_bit = err_bit + 1;
force `SPC0.lsu.stb_cam.cam_array.stb_rdata[44:0] = cam_data ^ (1 << err_bit);
`PR_INFO("stb_err", 22, "<T%0h> <%0h> STB[%0h]: SBAPP forced for CASA. err_bit = %0h", err_tid, {cam_data[44:8], 3'b0}, err_index, err_bit);
release `SPC0.lsu.stb_cam.cam_array.stb_rdata[44:0];
if (~`SPC7.lsu_sbapp_err_g)
`PR_ERROR("lsu_mon", `ERROR, "<T%0h> sbapp err not asserted when err is injected for atomic.", stb_err_tid_d2);
if ((`SPC7.lsu_stberr_tid_g != stb_err_tid_d2) ||
(`SPC7.lsu_stberr_index_g != stb_err_index_d2) ||
(`SPC7.lsu_stberr_priv_g != stb_err_priv_d2))
`PR_ERROR("lsu_mon", `ERROR, "<T%0h> sbapp err parameters mismatch.", stb_err_tid_d2);
if (`SPC7.lsu_sbapp_err_g)
`PR_ERROR("lsu_mon", `ERROR, "<T%0h> sbapp err asserted when none expected.", `SPC7.lsu_stberr_tid_g);
always @ (posedge (`SPC7.l2clk & enabled & cmp_stb_err_inj))
stb_err_inj_d1 <= stb_err_inj;
stb_err_inj_d2 <= stb_err_inj_d1;
stb_err_tid_d1 <= err_tid;
stb_err_tid_d2 <= stb_err_tid_d1;
stb_err_index_d1 <= err_index;
stb_err_index_d2 <= stb_err_index_d1;
stb_err_priv_d1 <= err_priv;
stb_err_priv_d2 <= stb_err_priv_d1;
//----------------------------------------------------------
//----------------------------------------------------------