You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2488 lines
97 KiB
Verilog

// © IBM Corp. 2020
// Licensed under the Apache License, Version 2.0 (the "License"), as modified by
// the terms below; you may not use the files in this repository except in
// compliance with the License as modified.
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
//
// Modified Terms:
//
// 1) For the purpose of the patent license granted to you in Section 3 of the
// License, the "Work" hereby includes implementations of the work of authorship
// in physical form.
//
// 2) Notwithstanding any terms to the contrary in the License, any licenses
// necessary for implementation of the Work that are available from OpenPOWER
// via the Power ISA End User License Agreement (EULA) are explicitly excluded
// hereunder, and may be obtained from OpenPOWER under the terms and conditions
// of the EULA.
//
// Unless required by applicable law or agreed to in writing, the reference design
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
// for the specific language governing permissions and limitations under the License.
//
// Additional rights, including the ability to physically implement a softcore that
// is compliant with the required sections of the Power ISA Specification, are
// available at no cost under the terms of the OpenPOWER Power ISA EULA, which can be
// obtained (along with the Power ISA) here: https://openpowerfoundation.org.
`timescale 1 ns / 1 ns
//********************************************************************
//*
//* TITLE:
//*
//* NAME: iuq_ic_dir.v
//*
//*********************************************************************
`include "tri_a2o.vh"
module iuq_ic_dir(
inout vcs,
inout vdd,
inout gnd,
(* pin_data ="PIN_FUNCTION=/G_CLK/" *)
input [0:`NCLK_WIDTH-1] nclk,
input pc_iu_func_sl_thold_0_b,
input pc_iu_func_slp_sl_thold_0_b,
input pc_iu_time_sl_thold_0,
input pc_iu_repr_sl_thold_0,
input pc_iu_abst_sl_thold_0,
input pc_iu_abst_sl_thold_0_b,
input pc_iu_abst_slp_sl_thold_0,
input pc_iu_ary_nsl_thold_0,
input pc_iu_ary_slp_nsl_thold_0,
input pc_iu_bolt_sl_thold_0,
input pc_iu_sg_0,
input pc_iu_sg_1,
input force_t,
input funcslp_force,
input abst_force,
input d_mode,
input delay_lclkr,
input mpw1_b,
input mpw2_b,
input clkoff_b,
input act_dis,
input g8t_clkoff_b,
input g8t_d_mode,
input [0:4] g8t_delay_lclkr,
input [0:4] g8t_mpw1_b,
input g8t_mpw2_b,
input g6t_clkoff_b,
input g6t_act_dis,
input g6t_d_mode,
input [0:3] g6t_delay_lclkr,
input [0:4] g6t_mpw1_b,
input g6t_mpw2_b,
input tc_ac_ccflush_dc,
input tc_ac_scan_dis_dc_b,
input tc_ac_scan_diag_dc,
(* pin_data ="PIN_FUNCTION=/SCAN_IN/" *)
input func_scan_in,
(* pin_data ="PIN_FUNCTION=/SCAN_IN/" *)
input time_scan_in,
(* pin_data ="PIN_FUNCTION=/SCAN_IN/" *)
input repr_scan_in,
(* pin_data ="PIN_FUNCTION=/SCAN_IN/" *)
input [0:2] abst_scan_in,
(* pin_data ="PIN_FUNCTION=/SCAN_OUT/" *)
output func_scan_out,
(* pin_data ="PIN_FUNCTION=/SCAN_OUT/" *)
output time_scan_out,
(* pin_data ="PIN_FUNCTION=/SCAN_OUT/" *)
output repr_scan_out,
(* pin_data ="PIN_FUNCTION=/SCAN_OUT/" *)
output [0:2] abst_scan_out,
input spr_ic_cls, // (0): 64B cacheline, (1): 128B cacheline
input spr_ic_ierat_byp_dis,
input [0:1] spr_ic_idir_way,
output ic_spr_idir_done,
output [0:2] ic_spr_idir_lru,
output [0:3] ic_spr_idir_parity,
output ic_spr_idir_endian,
output ic_spr_idir_valid,
output [0:28] ic_spr_idir_tag,
output [9:11] ic_perf_t0_event,
`ifndef THREADS1
output [9:11] ic_perf_t1_event,
`endif
output [0:1] ic_perf_event,
output iu_pc_err_icache_parity,
output iu_pc_err_icachedir_parity,
output iu_pc_err_icachedir_multihit,
input pc_iu_inj_icache_parity,
input pc_iu_inj_icachedir_parity,
input pc_iu_inj_icachedir_multihit,
input pc_iu_abist_g8t_wenb,
input pc_iu_abist_g8t1p_renb_0,
input [0:3] pc_iu_abist_di_0,
input pc_iu_abist_g8t_bw_1,
input pc_iu_abist_g8t_bw_0,
input [3:9] pc_iu_abist_waddr_0,
input [1:9] pc_iu_abist_raddr_0,
input pc_iu_abist_ena_dc,
input pc_iu_abist_wl128_comp_ena,
input pc_iu_abist_raw_dc_b,
input [0:3] pc_iu_abist_g8t_dcomp,
input [0:1] pc_iu_abist_g6t_bw,
input [0:3] pc_iu_abist_di_g6t_2r,
input pc_iu_abist_wl512_comp_ena,
input [0:3] pc_iu_abist_dcomp_g6t_2r,
input pc_iu_abist_g6t_r_wb,
input an_ac_lbist_ary_wrt_thru_dc,
input pc_iu_bo_enable_2, // bolt-on ABIST
input pc_iu_bo_reset,
input pc_iu_bo_unload,
input pc_iu_bo_repair,
input pc_iu_bo_shdata,
input [0:3] pc_iu_bo_select,
output [0:3] iu_pc_bo_fail,
output [0:3] iu_pc_bo_diagout,
output [0:51] iu_mm_ierat_epn,
output iu_ierat_iu1_back_inv,
input [64-`REAL_IFAR_WIDTH:51] ierat_iu_iu2_rpn,
input [0:4] ierat_iu_iu2_wimge,
input [0:3] ierat_iu_iu2_u,
input [0:2] ierat_iu_iu2_error,
input ierat_iu_iu2_miss,
input ierat_iu_iu2_multihit,
input ierat_iu_iu2_isi,
input [0:`THREADS-1] ierat_iu_iu2_flush_req,
input ierat_iu_cam_change,
// Cache invalidate
input lq_iu_ici_val,
// IU IC Select
input ics_icd_dir_rd_act,
input [0:1] ics_icd_data_rd_act,
input ics_icd_iu0_valid,
input [0:`THREADS-1] ics_icd_iu0_tid,
input [62-`EFF_IFAR_ARCH:61] ics_icd_iu0_ifar,
input ics_icd_iu0_index51,
input ics_icd_iu0_inval,
input ics_icd_iu0_2ucode,
input ics_icd_iu0_2ucode_type,
input ics_icd_iu0_prefetch,
input ics_icd_iu0_read_erat,
input ics_icd_iu0_spr_idir_read,
input [0:`THREADS-1] ics_icd_iu1_flush,
input [0:`THREADS-1] ics_icd_iu2_flush,
output icd_ics_iu1_valid,
output [0:`THREADS-1] icd_ics_iu1_tid,
output [62-`EFF_IFAR_WIDTH:61] icd_ics_iu1_ifar,
output icd_ics_iu1_2ucode,
output icd_ics_iu1_2ucode_type,
output [0:`THREADS-1] icd_ics_iu1_read_erat,
output [0:`THREADS-1] icd_ics_iu2_wrong_ra_flush,
output [0:`THREADS-1] icd_ics_iu2_cam_etc_flush,
output [62-`EFF_IFAR_WIDTH:61] icd_ics_iu2_ifar_eff,
output icd_ics_iu2_2ucode,
output icd_ics_iu2_2ucode_type,
output icd_ics_iu2_valid,
output [0:`THREADS-1] icd_ics_iu2_read_erat_error,
output [0:`THREADS-1] icd_ics_iu3_miss_flush,
output [0:`THREADS-1] icd_ics_iu3_parity_flush,
output [62-`EFF_IFAR_WIDTH:61] icd_ics_iu3_ifar,
output icd_ics_iu3_2ucode,
output icd_ics_iu3_2ucode_type,
// IU IC Miss
input [51:57] icm_icd_lru_addr,
input icm_icd_dir_inval,
input icm_icd_dir_val,
input icm_icd_data_write,
input [51:59] icm_icd_reload_addr,
input [0:143] icm_icd_reload_data,
input [0:3] icm_icd_reload_way,
input [0:`THREADS-1] icm_icd_load,
input [62-`EFF_IFAR_WIDTH:61] icm_icd_load_addr,
input icm_icd_load_2ucode,
input icm_icd_load_2ucode_type,
input icm_icd_dir_write,
input [64-`REAL_IFAR_WIDTH:57] icm_icd_dir_write_addr,
input icm_icd_dir_write_endian,
input [0:3] icm_icd_dir_write_way,
input icm_icd_lru_write,
input [51:57] icm_icd_lru_write_addr,
input [0:3] icm_icd_lru_write_way,
input icm_icd_ecc_inval,
input [51:57] icm_icd_ecc_addr,
input [0:3] icm_icd_ecc_way,
input icm_icd_iu3_ecc_fp_cancel,
input icm_icd_any_reld_r2,
output icd_icm_miss,
output icd_icm_prefetch,
output [0:`THREADS-1] icd_icm_tid,
output [64-`REAL_IFAR_WIDTH:61] icd_icm_addr_real,
output [62-`EFF_IFAR_WIDTH:51] icd_icm_addr_eff,
output [0:4] icd_icm_wimge, // (1): CI
output [0:3] icd_icm_userdef,
output icd_icm_2ucode,
output icd_icm_2ucode_type,
output icd_icm_iu2_inval,
output icd_icm_any_iu2_valid,
output [0:2] icd_icm_row_lru,
output [0:3] icd_icm_row_val,
//Branch Predict
// iu3
output [0:3] ic_bp_iu2_t0_val,
`ifndef THREADS1
output [0:3] ic_bp_iu2_t1_val,
`endif
output [62-`EFF_IFAR_WIDTH:61] ic_bp_iu2_ifar,
output ic_bp_iu2_2ucode,
output ic_bp_iu2_2ucode_type,
output [0:2] ic_bp_iu2_error,
output [0:`THREADS-1] ic_bp_iu3_flush,
// iu3 instruction(0:31) + predecode(32:35)
output [0:35] ic_bp_iu2_0_instr,
output [0:35] ic_bp_iu2_1_instr,
output [0:35] ic_bp_iu2_2_instr,
output [0:35] ic_bp_iu2_3_instr,
input event_bus_enable
);
parameter ways = 4;
parameter dir_way_width = 34;
parameter dir_ext_bits = 8 - ((52 - (64 - `REAL_IFAR_WIDTH)) % 8);
parameter dir_parity_width = (52 - (64 - `REAL_IFAR_WIDTH) + dir_ext_bits)/8;
parameter iu1_valid_offset = 0;
parameter iu1_tid_offset = iu1_valid_offset + 1;
parameter iu1_ifar_offset = iu1_tid_offset + `THREADS;
parameter iu1_index51_offset = iu1_ifar_offset + `EFF_IFAR_ARCH;
parameter iu1_inval_offset = iu1_index51_offset + 1;
parameter iu1_prefetch_offset = iu1_inval_offset + 1;
parameter iu1_read_erat_offset = iu1_prefetch_offset + 1;
parameter iu1_2ucode_offset = iu1_read_erat_offset + 1;
parameter iu1_2ucode_type_offset = iu1_2ucode_offset + 1;
parameter iu2_valid_offset = iu1_2ucode_type_offset + 1;
parameter iu2_tid_offset = iu2_valid_offset + 1;
parameter iu2_ifar_eff_offset = iu2_tid_offset + `THREADS;
parameter iu2_index51_offset = iu2_ifar_eff_offset + `EFF_IFAR_ARCH;
parameter iu2_2ucode_offset = iu2_index51_offset + 1;
parameter iu2_2ucode_type_offset = iu2_2ucode_offset + 1;
parameter iu2_inval_offset = iu2_2ucode_type_offset + 1;
parameter iu2_prefetch_offset = iu2_inval_offset + 1;
parameter iu2_read_erat_offset = iu2_prefetch_offset + 1;
parameter iu2_cam_change_etc_offset = iu2_read_erat_offset + 1;
parameter iu2_stored_rpn_offset = iu2_cam_change_etc_offset + 1;
parameter iu2_dir_rd_val_offset = iu2_stored_rpn_offset + `REAL_IFAR_WIDTH-12;
parameter iu2_dir_dataout_offset = iu2_dir_rd_val_offset + 4;
parameter iu3_dir_parity_err_way_offset = iu2_dir_dataout_offset + 1; //handled in tri
parameter iu2_data_dataout_offset = iu3_dir_parity_err_way_offset + 4;
parameter dir_val_offset = iu2_data_dataout_offset + 1; //handled in tri
parameter dir_lru_offset = dir_val_offset + (128 * 4);
parameter iu3_miss_flush_offset = dir_lru_offset + (128 * 3);
parameter iu3_tid_offset = iu3_miss_flush_offset + 1;
parameter iu3_ifar_offset = iu3_tid_offset + `THREADS;
parameter iu3_2ucode_offset = iu3_ifar_offset + `EFF_IFAR_WIDTH;
parameter iu3_2ucode_type_offset = iu3_2ucode_offset + 1;
parameter iu3_erat_err_offset = iu3_2ucode_type_offset + 1;
parameter iu3_multihit_err_way_offset = iu3_erat_err_offset + 1;
parameter iu3_multihit_flush_offset = iu3_multihit_err_way_offset + 4;
parameter iu3_data_parity_err_way_offset = iu3_multihit_flush_offset + 1;
parameter iu3_parity_needs_flush_offset = iu3_data_parity_err_way_offset + 4;
parameter iu3_parity_tag_offset = iu3_parity_needs_flush_offset + 1;
parameter ici_val_offset = iu3_parity_tag_offset + 7;
parameter spr_ic_cls_offset = ici_val_offset + 1;
parameter spr_ic_idir_way_offset = spr_ic_cls_offset + 1;
parameter iu1_spr_idir_read_offset = spr_ic_idir_way_offset + 2;
parameter iu2_spr_idir_read_offset = iu1_spr_idir_read_offset + 1;
parameter iu2_spr_idir_lru_offset = iu2_spr_idir_read_offset + 1;
parameter stored_erat_rpn_offset = iu2_spr_idir_lru_offset + 3;
parameter stored_erat_wimge_offset = stored_erat_rpn_offset + (`REAL_IFAR_WIDTH - 12) * `THREADS;
parameter stored_erat_u_offset = stored_erat_wimge_offset + 5 * `THREADS;
parameter perf_instr_count_offset = stored_erat_u_offset + 4 * `THREADS;
parameter perf_t_event_offset = perf_instr_count_offset + 2 * `THREADS;
parameter perf_event_offset = perf_t_event_offset + 3 * `THREADS;
parameter pc_iu_inj_offset = perf_event_offset + 2;
parameter scan_right = pc_iu_inj_offset + 3 - 1;
wire tidn;
wire tiup;
// Latch inputs
// IU1 pipeline
wire iu1_valid_d;
wire iu1_valid_l2;
wire [0:`THREADS-1] iu1_tid_d;
wire [0:`THREADS-1] iu1_tid_l2;
wire [62-`EFF_IFAR_ARCH:61] iu1_ifar_d;
wire [62-`EFF_IFAR_ARCH:61] iu1_ifar_l2;
wire iu1_index51_d;
wire iu1_index51_l2;
wire iu1_inval_d;
wire iu1_inval_l2;
wire iu1_prefetch_d;
wire iu1_prefetch_l2;
wire iu1_read_erat_d;
wire iu1_read_erat_l2;
wire iu1_2ucode_d;
wire iu1_2ucode_l2;
wire iu1_2ucode_type_d;
wire iu1_2ucode_type_l2;
// IU2 pipeline
wire iu2_valid_d;
wire iu2_valid_l2;
wire [0:`THREADS-1] iu2_tid_d;
wire [0:`THREADS-1] iu2_tid_l2;
wire [62-`EFF_IFAR_ARCH:61] iu2_ifar_eff_d;
wire [62-`EFF_IFAR_ARCH:61] iu2_ifar_eff_l2;
wire iu2_index51_d;
wire iu2_index51_l2;
wire iu2_2ucode_d;
wire iu2_2ucode_l2;
wire iu2_2ucode_type_d;
wire iu2_2ucode_type_l2;
wire iu2_inval_d;
wire iu2_inval_l2;
wire iu2_prefetch_d;
wire iu2_prefetch_l2;
wire iu2_read_erat_d;
wire iu2_read_erat_l2;
wire iu2_cam_change_etc_d;
wire iu2_cam_change_etc_l2;
reg [64-`REAL_IFAR_WIDTH:51] iu2_stored_rpn_d;
wire [64-`REAL_IFAR_WIDTH:51] iu2_stored_rpn_l2;
wire [0:3] iu2_dir_rd_val_d;
wire [0:3] iu2_dir_rd_val_l2;
wire [0:3] iu3_dir_parity_err_way_d;
wire [0:3] iu3_dir_parity_err_way_l2;
// Dir val & LRU
wire [0:3] dir_val_d[0:127];
wire [0:3] dir_val_l2[0:127];
wire [0:2] dir_lru_d[0:127];
wire [0:2] dir_lru_l2[0:127];
// IU3 pipeline
wire iu3_miss_flush_d;
wire iu3_miss_flush_l2;
wire [0:3] iu3_instr_valid_d;
wire [0:`THREADS-1] iu3_tid_d;
wire [0:`THREADS-1] iu3_tid_l2;
wire [62-`EFF_IFAR_WIDTH:61] iu3_ifar_d;
wire [62-`EFF_IFAR_WIDTH:61] iu3_ifar_l2; //20
wire iu3_2ucode_d;
wire iu3_2ucode_l2;
wire iu3_2ucode_type_d;
wire iu3_2ucode_type_l2;
wire [0:2] iu3_erat_err_d;
wire [0:0] iu3_erat_err_l2; // Only latch 1 bit
wire [0:3] iu3_multihit_err_way_d;
wire [0:3] iu3_multihit_err_way_l2;
wire iu3_multihit_flush_d;
wire iu3_multihit_flush_l2;
wire [0:3] iu3_data_parity_err_way_d;
wire [0:3] iu3_data_parity_err_way_l2;
wire iu3_parity_needs_flush_d;
wire iu3_parity_needs_flush_l2;
wire [51:57] iu3_parity_tag_d;
wire [51:57] iu3_parity_tag_l2;
// ICI
wire ici_val_d;
wire ici_val_l2;
wire spr_ic_cls_d;
wire spr_ic_cls_l2;
wire [0:1] spr_ic_idir_way_d;
wire [0:1] spr_ic_idir_way_l2;
wire iu1_spr_idir_read_d;
wire iu1_spr_idir_read_l2;
wire iu2_spr_idir_read_d;
wire iu2_spr_idir_read_l2;
wire [0:2] iu2_spr_idir_lru_d;
wire [0:2] iu2_spr_idir_lru_l2;
// IERAT Storing
wire [64-`REAL_IFAR_WIDTH:51] stored_erat_rpn_d[0:`THREADS-1];
wire [64-`REAL_IFAR_WIDTH:51] stored_erat_rpn_l2[0:`THREADS-1];
wire [0:4] stored_erat_wimge_d[0:`THREADS-1];
wire [0:4] stored_erat_wimge_l2[0:`THREADS-1];
wire [0:3] stored_erat_u_d[0:`THREADS-1];
wire [0:3] stored_erat_u_l2[0:`THREADS-1];
wire [0:1] perf_instr_count_d[0:`THREADS-1];
wire [0:1] perf_instr_count_l2[0:`THREADS-1];
wire [9:11] perf_t_event_d[0:`THREADS-1];
wire [9:11] perf_t_event_l2[0:`THREADS-1];
wire [0:1] perf_event_d;
wire [0:1] perf_event_l2;
wire pc_iu_inj_icache_parity_l2;
wire pc_iu_inj_icachedir_parity_l2;
wire pc_iu_inj_icachedir_multihit_l2;
// Stored IERAT
wire iu2_valid_erat_read;
wire [0:`THREADS-1] stored_erat_act;
wire iu1_stored_erat_updating;
reg [0:4] iu2_stored_wimge;
reg [0:3] iu2_stored_u;
wire [64-`REAL_IFAR_WIDTH:51] iu2_rpn;
wire [0:4] iu2_wimge;
wire [0:3] iu2_u;
wire [0:2] iu2_ierat_error;
wire iu2_ci;
wire iu2_endian;
// IDIR
wire dir_rd_act;
wire dir_write;
wire [0:ways-1] dir_way;
wire [0:6] dir_wr_addr;
wire [0:6] dir_rd_addr;
wire [0:dir_parity_width*8-1] ext_dir_datain;
wire [0:dir_parity_width-1] dir_parity_in;
wire [0:dir_way_width-1] way_datain;
wire [0:dir_way_width*ways-1] dir_datain;
wire [0:dir_way_width*ways-1] iu2_dir_dataout;
wire dir_dataout_act;
wire [51:57] iu1_ifar_cacheline;
reg [0:3] dir_rd_val;
reg [0:2] iu1_spr_idir_lru;
// IDATA
wire [0:1] data_read;
wire data_write;
wire [0:3] data_write_act;
wire [0:ways-1] data_way;
wire [0:8] data_addr;
wire [0:17] data_parity_in;
wire [0:161] data_datain;
wire [0:162*ways-1] data_dataout;
wire [0:162*ways-1] iu2_data_dataout;
// Compare
wire [0:3] iu2_rd_tag_hit;
wire [0:3] iu2_rd_hit;
wire [0:3] iu2_rd_tag_hit_erat;
wire [0:3] iu2_rd_hit_erat;
wire [0:3] iu2_rd_tag_hit_stored;
wire [0:3] iu2_rd_hit_stored;
wire iu2_dir_miss;
wire iu2_wrong_ra;
wire iu2_cam_change_etc_flush;
wire [51:57] iu2_ifar_eff_cacheline;
wire [51:57] reload_cacheline;
wire [51:57] ecc_inval_cacheline;
wire [51:57] lru_write_cacheline;
wire [0:3] iu3_any_parity_err_way;
wire dir_val_act;
wire iu2_erat_err_lite;
wire iu2_lru_rd_update;
reg [0:2] dir_lru_read[0:127];
reg [0:2] dir_lru_write[0:127];
wire [0:15] dir_lru_act;
// Check multihit
wire iu2_multihit_err;
wire iu3_multihit_err;
wire iu2_pc_inj_icachedir_multihit;
// Check parity
wire [0:dir_parity_width*8-1] ext_dir_dataout[0:3];
wire [0:dir_parity_width-1] dir_parity_out[0:3];
wire [0:dir_parity_width-1] dir_parity_err_byte[0:3];
wire [0:dir_parity_width-1] gen_dir_parity_out[0:3];
wire [0:3] iu2_dir_parity_err_way;
wire iu2_rd_parity_err;
wire iu3_dir_parity_err;
wire [0:17] data_parity_out[0:3];
wire [0:17] data_parity_err_byte[0:3];
wire [0:17] gen_data_parity_out[0:3];
wire data_parity_err;
// Update Valid Bit
reg [0:2] return_lru;
reg [0:3] return_val;
// IU2
wire iu2_rd_miss;
wire iu2_valid_or_load;
wire [0:35] iu2_instr0_cache_rot[0:3]; // 4 ways
wire [0:35] iu2_instr1_cache_rot[0:3];
wire [0:35] iu2_instr2_cache_rot[0:3];
wire [0:35] iu2_instr3_cache_rot[0:3];
wire [0:35] iu2_reload_rot[0:3]; // instructions 0-3
wire [0:35] iu2_hit_rot[0:3];
wire [0:35] iu2_instr[0:3];
wire [0:3] iu2_uc_illegal_cache_rot;
wire iu2_uc_illegal_reload;
wire iu2_uc_illegal_cache;
wire iu2_uc_illegal;
// performance events
wire [0:2] iu2_instr_count;
wire [0:2] perf_instr_count_new[0:`THREADS-1];
// abist
wire stage_abist_g8t_wenb;
wire stage_abist_g8t1p_renb_0;
wire [0:3] stage_abist_di_0;
wire stage_abist_g8t_bw_1;
wire stage_abist_g8t_bw_0;
wire [3:9] stage_abist_waddr_0;
wire [1:9] stage_abist_raddr_0;
wire stage_abist_wl128_comp_ena;
wire [0:3] stage_abist_g8t_dcomp;
wire [0:1] stage_abist_g6t_bw;
wire [0:3] stage_abist_di_g6t_2r;
wire stage_abist_wl512_comp_ena;
wire [0:3] stage_abist_dcomp_g6t_2r;
wire stage_abist_g6t_r_wb;
// scan
wire [0:scan_right] siv /*verilator split_var*/;
wire [0:scan_right] sov;
wire [0:44] abst_siv;
wire [0:44] abst_sov;
wire [0:1] time_siv;
wire [0:1] time_sov;
wire [0:1] repr_siv;
wire [0:1] repr_sov;
assign tidn = 1'b0;
assign tiup = 1'b1;
assign spr_ic_cls_d = spr_ic_cls;
assign spr_ic_idir_way_d = spr_ic_idir_way;
//---------------------------------------------------------------------
// IU1 Latches
//---------------------------------------------------------------------
assign iu1_valid_d = ics_icd_iu0_valid;
assign iu1_tid_d = ics_icd_iu0_tid;
assign iu1_ifar_d = ics_icd_iu0_ifar;
assign iu1_index51_d = ics_icd_iu0_index51;
assign iu1_inval_d = ics_icd_iu0_inval;
assign iu1_2ucode_d = ics_icd_iu0_2ucode;
assign iu1_2ucode_type_d = ics_icd_iu0_2ucode_type;
assign iu1_prefetch_d = ics_icd_iu0_prefetch;
assign iu1_read_erat_d = ics_icd_iu0_read_erat;
assign iu1_spr_idir_read_d = ics_icd_iu0_spr_idir_read;
assign iu_ierat_iu1_back_inv = iu1_inval_l2;
assign icd_ics_iu1_valid = iu1_valid_l2;
assign icd_ics_iu1_tid = iu1_tid_l2;
assign icd_ics_iu1_ifar = iu1_ifar_l2[62-`EFF_IFAR_WIDTH:61];
assign icd_ics_iu1_2ucode = iu1_2ucode_l2;
assign icd_ics_iu1_2ucode_type = iu1_2ucode_type_l2;
//---------------------------------------------------------------------
// Stored IERAT
//---------------------------------------------------------------------
// Keep copy of IERAT output so it is not necessary to read IERAT each time, for power savings
assign iu2_valid_erat_read = (iu2_valid_l2 | iu2_prefetch_l2) & iu2_read_erat_l2;
assign stored_erat_act = {`THREADS{iu2_valid_erat_read & (~spr_ic_ierat_byp_dis)}} & iu2_tid_l2;
assign iu1_stored_erat_updating = |(stored_erat_act & iu1_tid_l2); //'1' if stored erat is updating in IU2 for same thread that is in IU1
generate
begin : xhdl1
genvar i;
for (i = 0; i < `THREADS; i = i + 1)
begin : erat_val_gen
assign stored_erat_rpn_d[i] = ierat_iu_iu2_rpn;
assign stored_erat_wimge_d[i] = ierat_iu_iu2_wimge;
assign stored_erat_u_d[i] = ierat_iu_iu2_u;
end
end
endgenerate
//---------------------------------------------------------------------
// ERAT Output
//---------------------------------------------------------------------
// Need to mux between threads
// Need to mux between stored & non-stored
//always @(iu2_tid_l2 or stored_erat_rpn_l2 or stored_erat_wimge_l2 or stored_erat_u_l2)
always @ (*)
begin: stored_erat_proc
reg [64-`REAL_IFAR_WIDTH:51] iu1_stored_rpn_calc;
reg [0:4] iu2_stored_wimge_calc;
reg [0:3] iu2_stored_u_calc;
//(* analysis_not_referenced="true" *)
integer i;
iu1_stored_rpn_calc = {`REAL_IFAR_WIDTH-12{1'b0}};
iu2_stored_wimge_calc = 5'b0;
iu2_stored_u_calc = 4'b0;
for (i = 0; i < `THREADS; i = i + 1)
begin
iu1_stored_rpn_calc = iu1_stored_rpn_calc | ({`REAL_IFAR_WIDTH-12{iu1_tid_l2[i]}} & stored_erat_rpn_l2[i]);
iu2_stored_wimge_calc = iu2_stored_wimge_calc | ({5{iu2_tid_l2[i]}} & stored_erat_wimge_l2[i]);
iu2_stored_u_calc = iu2_stored_u_calc | ({4{iu2_tid_l2[i]}} & stored_erat_u_l2[i]);
end
iu2_stored_rpn_d = iu1_stored_erat_updating ? ierat_iu_iu2_rpn : iu1_stored_rpn_calc;
iu2_stored_wimge = iu2_stored_wimge_calc;
iu2_stored_u = iu2_stored_u_calc;
end
assign iu2_rpn = ((iu2_read_erat_l2 | iu2_inval_l2) == 1'b1) ? ierat_iu_iu2_rpn :
iu2_stored_rpn_l2;
assign iu2_rd_tag_hit = ((iu2_read_erat_l2 | iu2_inval_l2) == 1'b1) ? iu2_rd_tag_hit_erat :
iu2_rd_tag_hit_stored;
assign iu2_rd_hit = ((iu2_read_erat_l2 | iu2_inval_l2) == 1'b1) ? iu2_rd_hit_erat :
iu2_rd_hit_stored;
assign iu2_wimge = ((iu2_read_erat_l2 | iu2_inval_l2) == 1'b1) ? ierat_iu_iu2_wimge :
iu2_stored_wimge;
assign iu2_u = ((iu2_read_erat_l2 | iu2_inval_l2) == 1'b1) ? ierat_iu_iu2_u :
iu2_stored_u;
assign iu2_ierat_error = {3{iu2_read_erat_l2}} & ierat_iu_iu2_error;
assign iu2_ci = iu2_wimge[1]; // Note: Must check iu2_valid everywhere this is used. Otherwise, set to 0 if iu2_inval_l2
assign iu2_endian = iu2_wimge[4];
// Timing: Moved muxing to ierat, since similar mux exists there
assign iu2_ifar_eff_d = iu1_ifar_l2;
assign iu2_index51_d = iu1_index51_l2;
//---------------------------------------------------------------------
// Access IDIR, Valid, & LRU
//---------------------------------------------------------------------
assign dir_rd_act = ics_icd_dir_rd_act;
assign dir_write = icm_icd_dir_write;
assign dir_way = icm_icd_dir_write_way;
assign dir_wr_addr = {icm_icd_dir_write_addr[51:56], (icm_icd_dir_write_addr[57] & (~spr_ic_cls_l2))}; // Use even row for 128B mode
assign dir_rd_addr = {ics_icd_iu0_index51, ics_icd_iu0_ifar[52:56], (ics_icd_iu0_ifar[57] & (~(spr_ic_cls_l2 & (~ics_icd_iu0_spr_idir_read))))};
generate
begin : xhdl2
genvar i;
for (i = 0; i < dir_parity_width*8; i = i + 1)
begin : calc_ext_dir_data
if (i < 51 - (64 - `REAL_IFAR_WIDTH))
assign ext_dir_datain[i] = icm_icd_dir_write_addr[(64 - `REAL_IFAR_WIDTH) + i];
if (i == 51 - (64 - `REAL_IFAR_WIDTH))
assign ext_dir_datain[i] = icm_icd_dir_write_endian;
if (i > 51 - (64 - `REAL_IFAR_WIDTH))
assign ext_dir_datain[i] = 1'b0;
end
//genvar i;
for (i = 0; i < dir_parity_width; i = i + 1)
begin : gen_dir_parity
assign dir_parity_in[i] = ^(ext_dir_datain[i * 8:i * 8 + 7]);
end
end
endgenerate
assign way_datain[0:50 - (64 - `REAL_IFAR_WIDTH)] = icm_icd_dir_write_addr[(64 - `REAL_IFAR_WIDTH):50];
assign way_datain[51 - (64 - `REAL_IFAR_WIDTH)] = icm_icd_dir_write_endian;
assign way_datain[52 - (64 - `REAL_IFAR_WIDTH):52 - (64 - `REAL_IFAR_WIDTH) + dir_parity_width - 1] = dir_parity_in;
generate
if (52 - (64 - `REAL_IFAR_WIDTH) + dir_parity_width < dir_way_width)
assign way_datain[52 - (64 - `REAL_IFAR_WIDTH) + dir_parity_width:dir_way_width-1] = {dir_way_width-52+64-`REAL_IFAR_WIDTH-dir_parity_width{1'b0}};
endgenerate
assign dir_datain = {way_datain, way_datain, way_datain, way_datain};
// 0:28 - tag, 29 - endianness, 30:33 - parity
tri_128x34_4w_1r1w idir(
.gnd(gnd),
.vdd(vdd),
.vcs(vdd),
.nclk(nclk),
.rd_act(dir_rd_act),
.wr_act(dir_write),
.sg_0(pc_iu_sg_0),
.abst_sl_thold_0(pc_iu_abst_slp_sl_thold_0),
.ary_nsl_thold_0(pc_iu_ary_slp_nsl_thold_0),
.time_sl_thold_0(pc_iu_time_sl_thold_0),
.repr_sl_thold_0(pc_iu_repr_sl_thold_0),
.func_sl_thold_0_b(pc_iu_func_slp_sl_thold_0_b),
.func_force(funcslp_force),
.clkoff_dc_b(g8t_clkoff_b),
.ccflush_dc(tc_ac_ccflush_dc),
.scan_dis_dc_b(tc_ac_scan_dis_dc_b),
.scan_diag_dc(tc_ac_scan_diag_dc),
.d_mode_dc(g8t_d_mode),
.mpw1_dc_b(g8t_mpw1_b),
.mpw2_dc_b(g8t_mpw2_b),
.delay_lclkr_dc(g8t_delay_lclkr),
.wr_abst_act(stage_abist_g8t_wenb),
.rd0_abst_act(stage_abist_g8t1p_renb_0),
.abist_di(stage_abist_di_0),
.abist_bw_odd(stage_abist_g8t_bw_1),
.abist_bw_even(stage_abist_g8t_bw_0),
.abist_wr_adr(stage_abist_waddr_0[3:9]),
.abist_rd0_adr(stage_abist_raddr_0[3:9]),
.tc_lbist_ary_wrt_thru_dc(an_ac_lbist_ary_wrt_thru_dc),
.abist_ena_1(pc_iu_abist_ena_dc),
.abist_g8t_rd0_comp_ena(stage_abist_wl128_comp_ena),
.abist_raw_dc_b(pc_iu_abist_raw_dc_b),
.obs0_abist_cmp(stage_abist_g8t_dcomp),
.abst_scan_in({abst_siv[0], abst_siv[2]}),
.time_scan_in(time_siv[0]),
.repr_scan_in(repr_siv[0]),
.func_scan_in(siv[iu2_dir_dataout_offset]),
.abst_scan_out({abst_sov[0], abst_sov[2]}),
.time_scan_out(time_sov[0]),
.repr_scan_out(repr_sov[0]),
.func_scan_out(sov[iu2_dir_dataout_offset]),
.lcb_bolt_sl_thold_0(pc_iu_bolt_sl_thold_0),
.pc_bo_enable_2(pc_iu_bo_enable_2),
.pc_bo_reset(pc_iu_bo_reset),
.pc_bo_unload(pc_iu_bo_unload),
.pc_bo_repair(pc_iu_bo_repair),
.pc_bo_shdata(pc_iu_bo_shdata),
.pc_bo_select(pc_iu_bo_select[0:1]),
.bo_pc_failout(iu_pc_bo_fail[0:1]),
.bo_pc_diagloop(iu_pc_bo_diagout[0:1]),
.tri_lcb_mpw1_dc_b(mpw1_b),
.tri_lcb_mpw2_dc_b(mpw2_b),
.tri_lcb_delay_lclkr_dc(delay_lclkr),
.tri_lcb_clkoff_dc_b(clkoff_b),
.tri_lcb_act_dis_dc(act_dis),
.wr_way(dir_way),
.wr_addr(dir_wr_addr),
.data_in(dir_datain),
.rd_addr(dir_rd_addr),
.data_out(iu2_dir_dataout)
);
assign dir_dataout_act = iu1_valid_l2 | iu1_inval_l2 | iu1_spr_idir_read_l2 | iu1_prefetch_l2;
// Muxing the val for directory access
assign iu1_ifar_cacheline = {iu1_index51_l2, iu1_ifar_l2[52:56],
(iu1_ifar_l2[57] & (~(spr_ic_cls_l2 & (~iu1_spr_idir_read_l2))))};
//always @(iu1_ifar_cacheline or dir_val_l2)
always @(*)
begin: dir_rd_val_proc
//(* analysis_not_referenced="true" *)
integer i;
dir_rd_val = 4'b0000;
for (i = 0; i < 128; i = i + 1)
if (iu1_ifar_cacheline == i[6:0])
dir_rd_val = dir_val_l2[i];
end
assign iu2_dir_rd_val_d = dir_rd_val;
assign ic_spr_idir_valid = (spr_ic_idir_way_l2 == 2'b00) ? iu2_dir_rd_val_l2[0] :
(spr_ic_idir_way_l2 == 2'b01) ? iu2_dir_rd_val_l2[1] :
(spr_ic_idir_way_l2 == 2'b10) ? iu2_dir_rd_val_l2[2] :
iu2_dir_rd_val_l2[3];
//always @(iu1_index51_l2 or iu1_ifar_l2 or dir_lru_l2)
always @ (*)
begin: iu2_spr_idir_lru_proc
//(* analysis_not_referenced="true" *)
integer i;
iu1_spr_idir_lru = 3'b000;
for (i = 0; i < 128; i = i + 1)
if ({iu1_index51_l2, iu1_ifar_l2[52:57]} == i[6:0])
iu1_spr_idir_lru = dir_lru_l2[i];
end
assign iu2_spr_idir_lru_d = {3{iu1_spr_idir_read_l2}} & iu1_spr_idir_lru; // gate to reduce switching/power
assign ic_spr_idir_lru = iu2_spr_idir_lru_l2;
assign ic_spr_idir_tag = (spr_ic_idir_way_l2 == 2'b00) ? iu2_dir_dataout[0:28] :
(spr_ic_idir_way_l2 == 2'b01) ? iu2_dir_dataout[ dir_way_width: dir_way_width + 28] :
(spr_ic_idir_way_l2 == 2'b10) ? iu2_dir_dataout[2 * dir_way_width:2 * dir_way_width + 28] :
iu2_dir_dataout[3 * dir_way_width:3 * dir_way_width + 28];
assign ic_spr_idir_endian = (spr_ic_idir_way_l2 == 2'b00) ? iu2_dir_dataout[29] :
(spr_ic_idir_way_l2 == 2'b01) ? iu2_dir_dataout[ dir_way_width + 29] :
(spr_ic_idir_way_l2 == 2'b10) ? iu2_dir_dataout[2 * dir_way_width + 29] :
iu2_dir_dataout[3 * dir_way_width + 29];
assign ic_spr_idir_parity = (spr_ic_idir_way_l2 == 2'b00) ? iu2_dir_dataout[30:33] :
(spr_ic_idir_way_l2 == 2'b01) ? iu2_dir_dataout[ dir_way_width + 30:2 * dir_way_width - 1] :
(spr_ic_idir_way_l2 == 2'b10) ? iu2_dir_dataout[2 * dir_way_width + 30:3 * dir_way_width - 1] :
iu2_dir_dataout[3 * dir_way_width + 30:4 * dir_way_width - 1];
assign ic_spr_idir_done = iu2_spr_idir_read_l2;
//---------------------------------------------------------------------
// Access IData
//---------------------------------------------------------------------
assign data_read = ics_icd_data_rd_act;
assign data_write = icm_icd_data_write;
assign data_way = icm_icd_reload_way; // write
assign data_addr = (data_write == 1'b1) ? icm_icd_reload_addr[51:59] :
{ics_icd_iu0_index51, ics_icd_iu0_ifar[52:59]};
assign data_write_act[0] = (data_way[0] | data_way[1]) & (~icm_icd_reload_addr[51]);
assign data_write_act[1] = (data_way[2] | data_way[3]) & (~icm_icd_reload_addr[51]);
assign data_write_act[2] = (data_way[0] | data_way[1]) & icm_icd_reload_addr[51];
assign data_write_act[3] = (data_way[2] | data_way[3]) & icm_icd_reload_addr[51];
generate
begin : xhdl4
genvar i;
for (i = 0; i < 18; i = i + 1)
begin : gen_data_parity
assign data_parity_in[i] = ^(icm_icd_reload_data[i * 8:i * 8 + 7]);
end
end
endgenerate
assign data_datain = {icm_icd_reload_data, data_parity_in};
tri_512x162_4w_0 idata(
.gnd(gnd),
.vdd(vdd),
.vcs(vdd),
.nclk(nclk),
.ccflush_dc(tc_ac_ccflush_dc),
.lcb_clkoff_dc_b(g6t_clkoff_b),
.lcb_d_mode_dc(g6t_d_mode),
.lcb_act_dis_dc(g6t_act_dis),
.lcb_ary_nsl_thold_0(pc_iu_ary_nsl_thold_0),
.lcb_sg_1(pc_iu_sg_1),
.lcb_abst_sl_thold_0(pc_iu_abst_sl_thold_0),
.lcb_func_sl_thold_0_b(pc_iu_func_sl_thold_0_b),
.func_force(force_t),
.scan_diag_dc(tc_ac_scan_diag_dc),
.scan_dis_dc_b(tc_ac_scan_dis_dc_b),
.func_scan_in(siv[iu2_data_dataout_offset]),
.func_scan_out(sov[iu2_data_dataout_offset]),
.abst_scan_in({abst_siv[1], abst_siv[3]}),
.abst_scan_out({abst_sov[1], abst_sov[3]}),
.lcb_delay_lclkr_np_dc(g6t_delay_lclkr[0]),
.ctrl_lcb_delay_lclkr_np_dc(g6t_delay_lclkr[1]),
.dibw_lcb_delay_lclkr_np_dc(g6t_delay_lclkr[2]),
.ctrl_lcb_mpw1_np_dc_b(g6t_mpw1_b[0]),
.dibw_lcb_mpw1_np_dc_b(g6t_mpw1_b[1]),
.lcb_mpw1_pp_dc_b(g6t_mpw1_b[2]),
.lcb_mpw1_2_pp_dc_b(g6t_mpw1_b[3]),
.aodo_lcb_delay_lclkr_dc(g6t_delay_lclkr[3]),
.aodo_lcb_mpw1_dc_b(g6t_mpw1_b[4]),
.aodo_lcb_mpw2_dc_b(g6t_mpw2_b),
.lcb_time_sg_0(pc_iu_sg_0),
.lcb_time_sl_thold_0(pc_iu_time_sl_thold_0),
.time_scan_in(time_siv[1]),
.time_scan_out(time_sov[1]),
.bitw_abist(stage_abist_g6t_bw),
.lcb_repr_sl_thold_0(pc_iu_repr_sl_thold_0),
.lcb_repr_sg_0(pc_iu_sg_0),
.repr_scan_in(repr_siv[1]),
.repr_scan_out(repr_sov[1]),
.tc_lbist_ary_wrt_thru_dc(an_ac_lbist_ary_wrt_thru_dc),
.abist_en_1(pc_iu_abist_ena_dc),
.din_abist(stage_abist_di_g6t_2r),
.abist_cmp_en(stage_abist_wl512_comp_ena),
.abist_raw_b_dc(pc_iu_abist_raw_dc_b),
.data_cmp_abist(stage_abist_dcomp_g6t_2r),
.addr_abist(stage_abist_raddr_0[1:9]),
.r_wb_abist(stage_abist_g6t_r_wb),
.write_thru_en_dc(tidn),
.lcb_bolt_sl_thold_0(pc_iu_bolt_sl_thold_0),
.pc_bo_enable_2(pc_iu_bo_enable_2),
.pc_bo_reset(pc_iu_bo_reset),
.pc_bo_unload(pc_iu_bo_unload),
.pc_bo_repair(pc_iu_bo_repair),
.pc_bo_shdata(pc_iu_bo_shdata),
.pc_bo_select(pc_iu_bo_select[2:3]),
.bo_pc_failout(iu_pc_bo_fail[2:3]),
.bo_pc_diagloop(iu_pc_bo_diagout[2:3]),
.tri_lcb_mpw1_dc_b(mpw1_b),
.tri_lcb_mpw2_dc_b(mpw2_b),
.tri_lcb_delay_lclkr_dc(delay_lclkr),
.tri_lcb_clkoff_dc_b(clkoff_b),
.tri_lcb_act_dis_dc(act_dis),
.read_act(data_read),
.write_act(data_write_act),
.write_enable(data_write),
.write_way(data_way),
.addr(data_addr),
.data_in(data_datain),
.data_out(data_dataout)
);
assign iu2_data_dataout[0] = data_dataout[0] ^ pc_iu_inj_icache_parity_l2;
assign iu2_data_dataout[1:162*ways-1] = data_dataout[1:162*ways-1];
//---------------------------------------------------------------------
// Compare Tag
//---------------------------------------------------------------------
generate
begin : xhdl5
genvar i;
for (i = 0; i < 4; i = i + 1)
begin : rd_tag_hit0
assign iu2_rd_tag_hit_erat[i] = ierat_iu_iu2_rpn[(64 - `REAL_IFAR_WIDTH):50] == iu2_dir_dataout[i * dir_way_width:i * dir_way_width + 50 - (64 - `REAL_IFAR_WIDTH)];
assign iu2_rd_hit_erat[i] = iu2_dir_rd_val_l2[i] & iu2_rd_tag_hit_erat[i] & (ierat_iu_iu2_rpn[51] == iu2_index51_l2) & (iu2_endian == iu2_dir_dataout[i * dir_way_width + 51 - (64 - `REAL_IFAR_WIDTH)]);
assign iu2_rd_tag_hit_stored[i] = iu2_stored_rpn_l2[(64 - `REAL_IFAR_WIDTH):50] == iu2_dir_dataout[i * dir_way_width:i * dir_way_width + 50 - (64 - `REAL_IFAR_WIDTH)];
assign iu2_rd_hit_stored[i] = iu2_dir_rd_val_l2[i] & iu2_rd_tag_hit_stored[i] & (iu2_stored_rpn_l2[51] == iu2_index51_l2) & (iu2_endian == iu2_dir_dataout[i * dir_way_width + 51 - (64 - `REAL_IFAR_WIDTH)]);
end
end
endgenerate
assign iu2_dir_miss = (~|(iu2_rd_hit));
assign iu2_wrong_ra = (iu2_rpn[51] != iu2_index51_l2) & (~iu2_ierat_error[0]) & (~iu2_cam_change_etc_flush);
assign icd_ics_iu2_wrong_ra_flush = {`THREADS{iu2_valid_l2 & iu2_wrong_ra}} & iu2_tid_l2;
// Cam change is IU1 phase. Need to flush if cam changes and we didn't read erat.
// Latch IU1 flushes and do flush in IU2 (less muxing for IU0 ifar). Flush if cam changes & didn't read erat
assign iu2_cam_change_etc_d = (ierat_iu_cam_change & (~iu1_read_erat_l2)) |
(ierat_iu_iu2_error[0] & iu2_valid_erat_read & (~iu1_read_erat_l2) & (iu1_tid_l2 == iu2_tid_l2)) | // Flush next command (IU1) if IU2 error
(|(ierat_iu_iu2_flush_req & iu1_tid_l2) & (iu1_tid_l2 == iu2_tid_l2)); // Flush next command (IU1) if ierat flush and iu2_prefetch, in order to get the correct iu0_ifar
assign iu2_cam_change_etc_flush = iu2_cam_change_etc_l2 & (iu2_valid_l2 | iu2_prefetch_l2);
assign icd_ics_iu2_cam_etc_flush = {`THREADS{iu2_cam_change_etc_flush}} & iu2_tid_l2;
assign iu2_valid_d = iu1_valid_l2 & (|(iu1_tid_l2 & (~ics_icd_iu1_flush)));
assign iu2_tid_d = iu1_tid_l2;
assign iu2_2ucode_d = iu1_2ucode_l2;
assign iu2_2ucode_type_d = iu1_2ucode_type_l2;
assign iu2_inval_d = iu1_inval_l2;
assign iu2_prefetch_d = iu1_prefetch_l2 & (|(iu1_tid_l2 & (~ics_icd_iu1_flush)));
assign iu2_read_erat_d = iu1_read_erat_l2;
assign iu2_spr_idir_read_d = iu1_spr_idir_read_l2;
assign icd_ics_iu1_read_erat = {`THREADS{(iu1_valid_l2 | iu1_prefetch_l2) & iu1_read_erat_l2}} & iu1_tid_l2;
assign icd_ics_iu2_read_erat_error = {`THREADS{(iu2_valid_l2 | iu2_prefetch_l2) & iu2_read_erat_l2 & ierat_iu_iu2_error[0]}} & iu2_tid_l2;
//---------------------------------------------------------------------
// Check Multihit
//---------------------------------------------------------------------
// Set if more than 1 way matches (not 0000, 0001, 0010, 0100, 1000)
assign iu2_multihit_err = (iu2_valid_l2 | iu2_inval_l2 | iu2_spr_idir_read_l2 | iu2_prefetch_l2) & // Don't want to set error if array not read this cycle
(~((iu2_rd_hit[0:2] == 3'b000) |
(({iu2_rd_hit[0:1], iu2_rd_hit[3]}) == 3'b000) |
(({iu2_rd_hit[0], iu2_rd_hit[2:3]}) == 3'b000) |
(iu2_rd_hit[1:3] == 3'b000)));
assign iu2_pc_inj_icachedir_multihit = (iu2_valid_l2 | iu2_inval_l2 | iu2_spr_idir_read_l2 | iu2_prefetch_l2) & pc_iu_inj_icachedir_multihit_l2 & (~iu2_dir_miss);
assign iu3_multihit_err_way_d = ({4{iu2_multihit_err}} & iu2_rd_hit) |
{4{iu2_pc_inj_icachedir_multihit}};
assign iu3_multihit_err = |(iu3_multihit_err_way_l2);
assign iu3_multihit_flush_d = (iu2_multihit_err | (pc_iu_inj_icachedir_multihit_l2 & (~iu2_dir_miss))) & (iu2_valid_l2 & (|(iu2_tid_l2 & (~ics_icd_iu2_flush))) & (~iu2_ci));
tri_direct_err_rpt #(.WIDTH(1)) err_icachedir_multihit(
.vd(vdd),
.gd(gnd),
.err_in(iu3_multihit_err),
.err_out(iu_pc_err_icachedir_multihit)
);
//---------------------------------------------------------------------
// Check Parity
//---------------------------------------------------------------------
// Dir
generate
begin : xhdl9
genvar w;
for (w = 0; w < 4; w = w + 1)
begin : calc_ext_dir_0
genvar i;
for (i = 0; i < dir_parity_width*8; i = i + 1)
begin : calc_ext_dir_dataout0
if (i < 52 - (64 - `REAL_IFAR_WIDTH))
assign ext_dir_dataout[w][i] = iu2_dir_dataout[i + w * dir_way_width];
if (i >= 52 - (64 - `REAL_IFAR_WIDTH))
assign ext_dir_dataout[w][i] = 1'b0;
end
assign dir_parity_out[w] = iu2_dir_dataout[w * dir_way_width + 52 - (64 - `REAL_IFAR_WIDTH):w * dir_way_width + 52 - (64 - `REAL_IFAR_WIDTH) + dir_parity_width - 1];
//genvar i;
for (i = 0; i < dir_parity_width; i = i + 1)
begin : chk_dir_parity
assign gen_dir_parity_out[w][i] = ^(ext_dir_dataout[w][i * 8:i * 8 + 7]) ^ pc_iu_inj_icachedir_parity_l2;
end
assign dir_parity_err_byte[w] = dir_parity_out[w] ^ gen_dir_parity_out[w];
assign iu2_dir_parity_err_way[w] = (|(dir_parity_err_byte[w])) & iu2_dir_rd_val_l2[w] & (iu2_valid_l2 | iu2_inval_l2 | iu2_spr_idir_read_l2 | iu2_prefetch_l2); // Don't want to set error if array not read this cycle
end
end
endgenerate
assign iu2_rd_parity_err = |(iu2_dir_parity_err_way & iu2_rd_hit);
assign iu3_dir_parity_err_way_d = iu2_dir_parity_err_way;
assign iu3_dir_parity_err = |(iu3_dir_parity_err_way_l2);
tri_direct_err_rpt #(.WIDTH(1)) err_icachedir_parity(
.vd(vdd),
.gd(gnd),
.err_in(iu3_dir_parity_err),
.err_out(iu_pc_err_icachedir_parity)
);
//Data
generate
begin : xhdl11
genvar w;
for (w = 0; w < 4; w = w + 1)
begin : data_parity_out_gen
assign data_parity_out[w] = iu2_data_dataout[w * 162 + 144:w * 162 + 144 + 18 - 1];
genvar i;
for (i = 0; i < 18; i = i + 1)
begin : chk_data_parity
assign gen_data_parity_out[w][i] = ^(iu2_data_dataout[w * 162 + i * 8:w * 162 + i * 8 + 7]);
end
assign data_parity_err_byte[w] = data_parity_out[w] ^ gen_data_parity_out[w];
assign iu3_data_parity_err_way_d[w] = (|(data_parity_err_byte[w])) & iu2_dir_rd_val_l2[w] & iu2_valid_l2;
end
end
endgenerate
assign data_parity_err = |(iu3_data_parity_err_way_l2);
tri_direct_err_rpt #(.WIDTH(1)) err_icache_parity(
.vd(vdd),
.gd(gnd),
.err_in(data_parity_err),
.err_out(iu_pc_err_icache_parity)
);
assign iu3_parity_needs_flush_d = iu2_valid_l2 & (|(iu2_tid_l2 & (~ics_icd_iu2_flush))) & (~iu2_rd_miss) & (|(iu3_data_parity_err_way_d & iu2_rd_hit));
assign icd_ics_iu3_parity_flush = {`THREADS{iu3_parity_needs_flush_l2 | iu3_multihit_flush_l2}} & iu3_tid_l2;
assign iu3_parity_tag_d = {iu2_index51_l2, iu2_ifar_eff_l2[52:56], (iu2_ifar_eff_l2[57] & (~(spr_ic_cls_l2 & (~iu2_spr_idir_read_l2))))};
//---------------------------------------------------------------------
// Update LRU
//---------------------------------------------------------------------
// For 128B cacheline mode, use even dir rows
assign iu2_ifar_eff_cacheline = {iu2_index51_l2, iu2_ifar_eff_l2[52:56], (iu2_ifar_eff_l2[57] & (~(spr_ic_cls_l2 & (~iu2_spr_idir_read_l2))))};
assign reload_cacheline = {icm_icd_reload_addr[51:56], (icm_icd_reload_addr[57] & (~spr_ic_cls_l2))};
assign ecc_inval_cacheline = {icm_icd_ecc_addr[51:56], (icm_icd_ecc_addr[57] & (~spr_ic_cls_l2))};
assign lru_write_cacheline = {icm_icd_lru_write_addr[51:56], (icm_icd_lru_write_addr[57] & (~spr_ic_cls_l2))};
assign iu3_any_parity_err_way = iu3_multihit_err_way_l2 | iu3_dir_parity_err_way_l2 | iu3_data_parity_err_way_l2;
// ICI Latches
assign ici_val_d = lq_iu_ici_val;
// update LRU in IU2 on read hit or dir_write
generate
begin : xhdl12
genvar a;
for (a = 0; a < 128; a = a + 1)
begin : dir_lru_gen
wire [0:6] index_v7 = a;
assign dir_lru_d[a] = (icm_icd_lru_write == 1'b0) ? dir_lru_read[a] :
dir_lru_write[a];
//always @(dir_lru_l2 or iu2_lru_rd_update or iu2_ifar_eff_cacheline or iu2_way_select_no_par_err or icm_icd_lru_write or lru_write_cacheline or icm_icd_lru_write_way)
always @ (*)
begin: lru_proc
dir_lru_read[a] = dir_lru_l2[a];
dir_lru_write[a] = dir_lru_l2[a];
if (iu2_lru_rd_update == 1'b1 & (iu2_ifar_eff_cacheline == index_v7))
dir_lru_read[a] = ({3{iu2_rd_hit[0]}} & {2'b11, dir_lru_l2[a][2]}) |
({3{iu2_rd_hit[1]}} & {2'b10, dir_lru_l2[a][2]}) |
({3{iu2_rd_hit[2]}} & {1'b0, dir_lru_l2[a][1], 1'b1}) |
({3{iu2_rd_hit[3]}} & {1'b0, dir_lru_l2[a][1], 1'b0});
if (icm_icd_lru_write == 1'b1 & (lru_write_cacheline == index_v7))
dir_lru_write[a] = ({3{icm_icd_lru_write_way[0]}} & {2'b11, dir_lru_l2[a][2]}) |
({3{icm_icd_lru_write_way[1]}} & {2'b10, dir_lru_l2[a][2]}) |
({3{icm_icd_lru_write_way[2]}} & {1'b0, dir_lru_l2[a][1], 1'b1}) |
({3{icm_icd_lru_write_way[3]}} & {1'b0, dir_lru_l2[a][1], 1'b0});
end
//---------------------------------------------------------------------
// Update Valid Bits
//---------------------------------------------------------------------
assign dir_val_d[a] =
((dir_val_l2[a] &
(~({4{iu3_parity_tag_l2[51:57] == index_v7}} & iu3_any_parity_err_way))) | // clear on dir parity, data parity, or multihit error
({4{icm_icd_dir_val & (reload_cacheline[51:57] == index_v7)}} & icm_icd_reload_way)) & // set when writing to this entry
(~({4{icm_icd_dir_inval & (reload_cacheline[51:57] == index_v7)}} & icm_icd_reload_way)) & // clear when invalidating way for new reload
(~({4{icm_icd_ecc_inval & (ecc_inval_cacheline[51:57] == index_v7)}} & icm_icd_ecc_way)) & // clear when bad ecc on data written last cycle
(~(({4{iu2_inval_l2 & (iu2_ifar_eff_cacheline[51:57] == index_v7)}} & dir_val_l2[a]) & iu2_rd_tag_hit)) & // clear on back_invalidate
(~({4{ici_val_l2}})); // clear on ICI
end
end
endgenerate
generate
begin : xhdl13
genvar a;
for (a = 0; a < 16; a = a + 1)
begin : dir_lru_act_gen
wire [0:3] index_v4 = a;
assign dir_lru_act[a] = (icm_icd_lru_write & (lru_write_cacheline[51:54] == index_v4)) |
(iu2_valid_l2 & (iu2_ifar_eff_cacheline[51:54] == index_v4));
end
end
endgenerate
assign dir_val_act = ici_val_l2 | (|(iu3_any_parity_err_way)) | icm_icd_any_reld_r2 | icm_icd_ecc_inval | iu2_inval_l2;
// All erat errors except for erat parity error, for timing
assign iu2_erat_err_lite = (ierat_iu_iu2_miss | ierat_iu_iu2_multihit | ierat_iu_iu2_isi) & iu2_read_erat_l2;
// Note: if timing is bad, can remove parity err check
assign iu2_lru_rd_update = iu2_valid_l2 & (~iu2_erat_err_lite) & (|(iu2_rd_hit)) & (~iu2_rd_parity_err) & (~iu2_multihit_err) & (~pc_iu_inj_icachedir_multihit_l2);
// ic miss latches the location for data write to prevent data from moving around in Data cache
//always @(icm_icd_lru_addr or dir_lru_l2)
always @ (*)
begin: return_lru_proc
//(* analysis_not_referenced="true" *)
integer i;
return_lru = 3'b000;
for (i = 0; i < 128; i = i + 1)
if (icm_icd_lru_addr[51:57] == i[6:0])
return_lru = dir_lru_l2[i];
end
assign icd_icm_row_lru = return_lru;
//always @(icm_icd_lru_addr or dir_val_l2)
always @ (*)
begin: return_val_proc
//(* analysis_not_referenced="true" *)
integer i;
return_val = 4'b0000;
for (i = 0; i < 128; i = i + 1)
if (icm_icd_lru_addr[51:57] == i[6:0])
return_val = dir_val_l2[i];
end
assign icd_icm_row_val = return_val;
//---------------------------------------------------------------------
// IU2
//---------------------------------------------------------------------
// IU2 Output
generate
begin : xhdl14
genvar i;
for (i = 0; i < 52; i = i + 1)
begin : mm_epn
if (i < (62 - `EFF_IFAR_ARCH))
assign iu_mm_ierat_epn[i] = 1'b0;
if (i >= (62 - `EFF_IFAR_ARCH))
assign iu_mm_ierat_epn[i] = iu2_ifar_eff_l2[i];
end
end
endgenerate
// Handle Miss
assign iu2_rd_miss = (iu2_valid_l2 | iu2_prefetch_l2) & (~|(ierat_iu_iu2_flush_req)) &
(iu2_dir_miss | iu2_ci | iu2_rd_parity_err) &
(~iu2_ierat_error[0]) & (~iu2_cam_change_etc_flush) & (~iu2_wrong_ra) &
(~(iu3_miss_flush_l2 & |(iu3_tid_l2 & iu2_tid_l2)));
assign iu3_miss_flush_d = iu2_rd_miss & (~iu2_prefetch_l2) & (|(iu2_tid_l2 & (~ics_icd_iu2_flush)));
assign icd_icm_miss = iu2_rd_miss;
assign icd_icm_prefetch = iu2_prefetch_l2;
assign icd_icm_tid = iu2_tid_l2;
assign icd_icm_addr_real = {iu2_rpn[64 - `REAL_IFAR_WIDTH:51], iu2_ifar_eff_l2[52:61]}; // ???? Could use iu2_index51
assign icd_icm_addr_eff = iu2_ifar_eff_l2[62 - `EFF_IFAR_WIDTH:51];
assign icd_icm_wimge = iu2_wimge;
assign icd_icm_userdef = iu2_u;
assign icd_icm_2ucode = iu2_2ucode_l2;
assign icd_icm_2ucode_type = iu2_2ucode_type_l2;
assign icd_icm_iu2_inval = iu2_inval_l2;
assign icd_icm_any_iu2_valid = iu2_valid_l2 | iu2_prefetch_l2; // for act's in ic_miss
assign icd_ics_iu3_miss_flush = {`THREADS{iu3_miss_flush_l2}} & iu3_tid_l2 ;
assign icd_ics_iu2_ifar_eff = iu2_ifar_eff_l2[62 - `EFF_IFAR_WIDTH:61];
assign icd_ics_iu2_2ucode = iu2_2ucode_l2;
assign icd_ics_iu2_2ucode_type = iu2_2ucode_type_l2;
assign icd_ics_iu2_valid = iu2_valid_l2;
// Moved flushes to ic_bp_iu2_flush
// Note: iu2_valid_l2 and icm_icd_load must never be on at same time
assign iu2_valid_or_load = iu2_valid_l2 | (|(icm_icd_load));
assign iu3_instr_valid_d[0:3] = ({iu2_valid_or_load, iu3_ifar_d[60:61]} == 3'b100) ? 4'b1111 :
({iu2_valid_or_load, iu3_ifar_d[60:61]} == 3'b101) ? 4'b1110 :
({iu2_valid_or_load, iu3_ifar_d[60:61]} == 3'b110) ? 4'b1100 :
({iu2_valid_or_load, iu3_ifar_d[60:61]} == 3'b111) ? 4'b1000 :
4'b0000;
assign iu3_tid_d = (iu2_valid_l2 == 1'b1) ? iu2_tid_l2 :
icm_icd_load;
assign iu3_ifar_d = (iu2_valid_l2 == 1'b1) ? iu2_ifar_eff_l2[62 - `EFF_IFAR_WIDTH:61] :
icm_icd_load_addr;
assign iu3_2ucode_d = (iu2_valid_l2 == 1'b1) ? iu2_2ucode_l2 :
icm_icd_load_2ucode;
assign iu3_2ucode_type_d = (iu2_valid_l2 == 1'b1) ? iu2_2ucode_type_l2 :
icm_icd_load_2ucode_type;
assign iu3_erat_err_d = iu2_ierat_error[0:2] & {3{iu2_valid_l2}};
// Rotate instructions
generate
begin : xhdl15
genvar w;
for (w = 0; w < 4; w = w + 1)
begin : iu2_instr_rot0
assign iu2_instr0_cache_rot[w] =
(iu2_ifar_eff_l2[60:61] == 2'b00) ? iu2_data_dataout[w * 162 :w * 162 + 35] :
(iu2_ifar_eff_l2[60:61] == 2'b01) ? iu2_data_dataout[w * 162 + 36 :w * 162 + 71] :
(iu2_ifar_eff_l2[60:61] == 2'b10) ? iu2_data_dataout[w * 162 + 72 :w * 162 + 107] :
iu2_data_dataout[w * 162 + 108:w * 162 + 143];
assign iu2_instr1_cache_rot[w] =
(iu2_ifar_eff_l2[60:61] == 2'b00) ? iu2_data_dataout[w * 162 + 36 :w * 162 + 71] :
(iu2_ifar_eff_l2[60:61] == 2'b01) ? iu2_data_dataout[w * 162 + 72 :w * 162 + 107] :
iu2_data_dataout[w * 162 + 108:w * 162 + 143];
assign iu2_instr2_cache_rot[w] =
(iu2_ifar_eff_l2[61] == 1'b0) ? iu2_data_dataout[w * 162 + 72 :w * 162 + 107] :
iu2_data_dataout[w * 162 + 108:w * 162 + 143];
assign iu2_instr3_cache_rot[w] = iu2_data_dataout[w * 162 + 108:w * 162 + 143];
// Force 2ucode to 0 if branch instructions or no-op. No other
// instructions are legal when dynamically changing code.
// Note: This signal does not include all non-ucode ops - just the ones
// that will cause problems with flush_2ucode.
assign iu2_uc_illegal_cache_rot[w] = iu2_instr0_cache_rot[w][32] | (iu2_instr0_cache_rot[w][0:5] == 6'b011000);
end
end
endgenerate
assign iu2_reload_rot[0] = (icm_icd_load_addr[60:61] == 2'b00) ? icm_icd_reload_data[0:35] :
(icm_icd_load_addr[60:61] == 2'b01) ? icm_icd_reload_data[36:71] :
(icm_icd_load_addr[60:61] == 2'b10) ? icm_icd_reload_data[72:107] :
icm_icd_reload_data[108:143];
assign iu2_reload_rot[1] = (icm_icd_load_addr[60:61] == 2'b00) ? icm_icd_reload_data[36:71] :
(icm_icd_load_addr[60:61] == 2'b01) ? icm_icd_reload_data[72:107] :
icm_icd_reload_data[108:143];
assign iu2_reload_rot[2] = (icm_icd_load_addr[61] == 1'b0) ? icm_icd_reload_data[72:107] :
icm_icd_reload_data[108:143];
assign iu2_reload_rot[3] = icm_icd_reload_data[108:143];
assign iu2_uc_illegal_reload = iu2_reload_rot[0][32] | (iu2_reload_rot[0][0:5] == 6'b011000);
// Select way hit
assign iu2_hit_rot[0] = ({36{iu2_rd_hit[0]}} & iu2_instr0_cache_rot[0]) |
({36{iu2_rd_hit[1]}} & iu2_instr0_cache_rot[1]) |
({36{iu2_rd_hit[2]}} & iu2_instr0_cache_rot[2]) |
({36{iu2_rd_hit[3]}} & iu2_instr0_cache_rot[3]);
assign iu2_hit_rot[1] = ({36{iu2_rd_hit[0]}} & iu2_instr1_cache_rot[0]) |
({36{iu2_rd_hit[1]}} & iu2_instr1_cache_rot[1]) |
({36{iu2_rd_hit[2]}} & iu2_instr1_cache_rot[2]) |
({36{iu2_rd_hit[3]}} & iu2_instr1_cache_rot[3]);
assign iu2_hit_rot[2] = ({36{iu2_rd_hit[0]}} & iu2_instr2_cache_rot[0]) |
({36{iu2_rd_hit[1]}} & iu2_instr2_cache_rot[1]) |
({36{iu2_rd_hit[2]}} & iu2_instr2_cache_rot[2]) |
({36{iu2_rd_hit[3]}} & iu2_instr2_cache_rot[3]);
assign iu2_hit_rot[3] = ({36{iu2_rd_hit[0]}} & iu2_instr3_cache_rot[0]) |
({36{iu2_rd_hit[1]}} & iu2_instr3_cache_rot[1]) |
({36{iu2_rd_hit[2]}} & iu2_instr3_cache_rot[2]) |
({36{iu2_rd_hit[3]}} & iu2_instr3_cache_rot[3]);
assign iu2_uc_illegal_cache = |(iu2_rd_hit & iu2_uc_illegal_cache_rot);
// Timing: moved xnop to bp
// Using xori 0,0,0 (xnop) when erat error
//xnop <= "011010" & ZEROS(6 to 35);
generate
begin : xhdl16
genvar i;
for (i = 0; i < 4; i = i + 1)
begin : gen_instr
assign iu2_instr[i] = (iu2_valid_l2 == 1'b1) ? iu2_hit_rot[i] :
iu2_reload_rot[i];
end
end
endgenerate
assign iu2_uc_illegal = (iu2_valid_l2 == 1'b1) ? iu2_uc_illegal_cache :
iu2_uc_illegal_reload;
//---------------------------------------------------------------------
// IU3
//---------------------------------------------------------------------
assign ic_bp_iu2_t0_val = {4{iu3_tid_d[0]}} & iu3_instr_valid_d;
`ifndef THREADS1
assign ic_bp_iu2_t1_val = {4{iu3_tid_d[1]}} & iu3_instr_valid_d;
`endif
assign ic_bp_iu2_ifar = iu3_ifar_d;
assign ic_bp_iu2_2ucode = iu3_2ucode_d & (~iu2_uc_illegal);
assign ic_bp_iu2_2ucode_type = iu3_2ucode_type_d;
// Moved ecc_err muxing to BP IU3
assign ic_bp_iu2_error = iu3_erat_err_d;
assign ic_bp_iu2_0_instr = iu2_instr[0];
assign ic_bp_iu2_1_instr = iu2_instr[1];
assign ic_bp_iu2_2_instr = iu2_instr[2];
assign ic_bp_iu2_3_instr = iu2_instr[3];
// Moved ic_bp_iu2_flush to iuq_ic_select
assign ic_bp_iu3_flush = {`THREADS{iu3_miss_flush_l2 | icm_icd_iu3_ecc_fp_cancel | ((iu3_parity_needs_flush_l2 | iu3_multihit_flush_l2) & (~iu3_erat_err_l2[0]))}} & iu3_tid_l2;
assign icd_ics_iu3_ifar = iu3_ifar_l2;
assign icd_ics_iu3_2ucode = iu3_2ucode_l2;
assign icd_ics_iu3_2ucode_type = iu3_2ucode_type_l2;
//---------------------------------------------------------------------
// Performance Events
//---------------------------------------------------------------------
generate
begin : xhdl10
genvar i;
for (i = 0; i < `THREADS; i = i + 1)
begin : gen_perf
// IERAT Miss
// - IU2 ierat miss
assign perf_t_event_d[i][9] = iu2_valid_l2 & iu2_tid_l2[i] & iu2_read_erat_l2 & ierat_iu_iu2_miss;
// I-Cache Fetch
// - Number of times ICache is read for instruction
assign perf_t_event_d[i][10] = iu2_valid_l2 & iu2_tid_l2[i];
// Instructions Fetched
// - Number of instructions fetched, divided by 4.
assign perf_instr_count_new[i][0:2] = {1'b0, perf_instr_count_l2[i][0:1]} + iu2_instr_count;
assign perf_instr_count_d[i][0:1] = (iu2_valid_l2 & iu2_tid_l2[i]) ? perf_instr_count_new[i][1:2] :
perf_instr_count_l2[i];
assign perf_t_event_d[i][11] = iu2_valid_l2 & iu2_tid_l2[i] & perf_instr_count_new[i][0];
end
end
endgenerate
assign iu2_instr_count = (iu2_ifar_eff_l2[60:61] == 2'b00) ? 3'b100 :
(iu2_ifar_eff_l2[60:61] == 2'b01) ? 3'b011 :
(iu2_ifar_eff_l2[60:61] == 2'b10) ? 3'b010 :
3'b001;
// Events not per thread
// L2 Back Invalidates I-Cache
assign perf_event_d[0] = iu2_inval_l2;
// L2 Back Invalidates I-Cache - Hits
assign perf_event_d[1] = iu2_inval_l2 & |(iu2_rd_tag_hit & iu2_dir_rd_val_l2);
assign ic_perf_t0_event = perf_t_event_l2[0];
`ifndef THREADS1
assign ic_perf_t1_event = perf_t_event_l2[1];
`endif
assign ic_perf_event = perf_event_l2;
//---------------------------------------------------------------------
// Latches
//---------------------------------------------------------------------
// IU1
tri_rlmlatch_p #(.INIT(0)) iu1_valid_latch(
.vd(vdd),
.gd(gnd),
.nclk(nclk),
.act(tiup),
.thold_b(pc_iu_func_sl_thold_0_b),
.sg(pc_iu_sg_0),
.force_t(force_t),
.delay_lclkr(delay_lclkr),
.mpw1_b(mpw1_b),
.mpw2_b(mpw2_b),
.d_mode(d_mode),
.scin(siv[iu1_valid_offset]),
.scout(sov[iu1_valid_offset]),
.din(iu1_valid_d),
.dout(iu1_valid_l2)
);
generate
if (`THREADS == 1)
begin : iu1_tid1
assign iu1_tid_l2 = iu1_tid_d | 1'b1; // Need to always be '1' when single thread since we aren't latching.
// 'iu1_tid_d' part is to get rid of unused warnings
assign sov[iu1_tid_offset] = siv[iu1_tid_offset];
end
endgenerate
generate
if (`THREADS != 1)
begin : iu1_tid2
tri_rlmreg_p #(.WIDTH(`THREADS), .INIT(0)) iu1_tid_latch(
.vd(vdd),
.gd(gnd),
.nclk(nclk),
.act(dir_rd_act), // ??? Is this act worth it? Only tid, 2ucode, & 2ucode_type use for non-slp
.thold_b(pc_iu_func_sl_thold_0_b),
.sg(pc_iu_sg_0),
.force_t(force_t),
.delay_lclkr(delay_lclkr),
.mpw1_b(mpw1_b),
.mpw2_b(mpw2_b),
.d_mode(d_mode),
.scin(siv[iu1_tid_offset:iu1_tid_offset + `THREADS - 1]),
.scout(sov[iu1_tid_offset:iu1_tid_offset + `THREADS - 1]),
.din(iu1_tid_d),
.dout(iu1_tid_l2)
);
end
endgenerate
// Note: Technically, only need REAL_IFAR range during sleep mode
tri_rlmreg_p #(.WIDTH(`EFF_IFAR_ARCH), .INIT(0), .NEEDS_SRESET(0)) iu1_ifar_latch(
.vd(vdd),
.gd(gnd),
.nclk(nclk),
.act(dir_rd_act),
.thold_b(pc_iu_func_slp_sl_thold_0_b),
.sg(pc_iu_sg_0),
.force_t(funcslp_force),
.delay_lclkr(delay_lclkr),
.mpw1_b(mpw1_b),
.mpw2_b(mpw2_b),
.d_mode(d_mode),
.scin(siv[iu1_ifar_offset:iu1_ifar_offset + `EFF_IFAR_ARCH - 1]),
.scout(sov[iu1_ifar_offset:iu1_ifar_offset + `EFF_IFAR_ARCH - 1]),
.din(iu1_ifar_d),
.dout(iu1_ifar_l2)
);
tri_rlmlatch_p #(.INIT(0)) iu1_index51_latch(
.vd(vdd),
.gd(gnd),
.nclk(nclk),
.act(dir_rd_act),
.thold_b(pc_iu_func_slp_sl_thold_0_b),
.sg(pc_iu_sg_0),
.force_t(funcslp_force),
.delay_lclkr(delay_lclkr),
.mpw1_b(mpw1_b),
.mpw2_b(mpw2_b),
.d_mode(d_mode),
.scin(siv[iu1_index51_offset]),
.scout(sov[iu1_index51_offset]),
.din(iu1_index51_d),
.dout(iu1_index51_l2)
);
tri_rlmlatch_p #(.INIT(0)) iu1_inval_latch(
.vd(vdd),
.gd(gnd),
.nclk(nclk),
.act(tiup),
.thold_b(pc_iu_func_slp_sl_thold_0_b),
.sg(pc_iu_sg_0),
.force_t(funcslp_force),
.delay_lclkr(delay_lclkr),
.mpw1_b(mpw1_b),
.mpw2_b(mpw2_b),
.d_mode(d_mode),
.scin(siv[iu1_inval_offset]),
.scout(sov[iu1_inval_offset]),
.din(iu1_inval_d),
.dout(iu1_inval_l2)
);
tri_rlmlatch_p #(.INIT(0)) iu1_prefetch_latch(
.vd(vdd),
.gd(gnd),
.nclk(nclk),
.act(tiup),
.thold_b(pc_iu_func_sl_thold_0_b),
.sg(pc_iu_sg_0),
.force_t(force_t),
.delay_lclkr(delay_lclkr),
.mpw1_b(mpw1_b),
.mpw2_b(mpw2_b),
.d_mode(d_mode),
.scin(siv[iu1_prefetch_offset]),
.scout(sov[iu1_prefetch_offset]),
.din(iu1_prefetch_d),
.dout(iu1_prefetch_l2)
);
generate
if (`INCLUDE_IERAT_BYPASS == 0)
begin : gen_iu1_read_erat0
assign iu1_read_erat_l2 = 1'b1 | iu1_read_erat_d;
assign sov[iu1_read_erat_offset] = siv[iu1_read_erat_offset];
end
endgenerate
generate
if (`INCLUDE_IERAT_BYPASS == 1)
begin : gen_iu1_read_erat1
tri_rlmlatch_p #(.INIT(0)) iu1_read_erat_latch(
.vd(vdd),
.gd(gnd),
.nclk(nclk),
.act(dir_rd_act),
.thold_b(pc_iu_func_sl_thold_0_b),
.sg(pc_iu_sg_0),
.force_t(force_t),
.delay_lclkr(delay_lclkr),
.mpw1_b(mpw1_b),
.mpw2_b(mpw2_b),
.d_mode(d_mode),
.scin(siv[iu1_read_erat_offset]),
.scout(sov[iu1_read_erat_offset]),
.din(iu1_read_erat_d),
.dout(iu1_read_erat_l2)
);
end
endgenerate
tri_rlmlatch_p #(.INIT(0)) iu1_2ucode_latch(
.vd(vdd),
.gd(gnd),
.nclk(nclk),
.act(dir_rd_act),
.thold_b(pc_iu_func_sl_thold_0_b),
.sg(pc_iu_sg_0),
.force_t(force_t),
.delay_lclkr(delay_lclkr),
.mpw1_b(mpw1_b),
.mpw2_b(mpw2_b),
.d_mode(d_mode),
.scin(siv[iu1_2ucode_offset]),
.scout(sov[iu1_2ucode_offset]),
.din(iu1_2ucode_d),
.dout(iu1_2ucode_l2)
);
tri_rlmlatch_p #(.INIT(0)) iu1_2ucode_type_latch(
.vd(vdd),
.gd(gnd),
.nclk(nclk),
.act(dir_rd_act),
.thold_b(pc_iu_func_sl_thold_0_b),
.sg(pc_iu_sg_0),
.force_t(force_t),
.delay_lclkr(delay_lclkr),
.mpw1_b(mpw1_b),
.mpw2_b(mpw2_b),
.d_mode(d_mode),
.scin(siv[iu1_2ucode_type_offset]),
.scout(sov[iu1_2ucode_type_offset]),
.din(iu1_2ucode_type_d),
.dout(iu1_2ucode_type_l2)
);
// IU2
tri_rlmlatch_p #(.INIT(0)) iu2_valid_latch(
.vd(vdd),
.gd(gnd),
.nclk(nclk),
.act(tiup),
.thold_b(pc_iu_func_sl_thold_0_b),
.sg(pc_iu_sg_0),
.force_t(force_t),
.delay_lclkr(delay_lclkr),
.mpw1_b(mpw1_b),
.mpw2_b(mpw2_b),
.d_mode(d_mode),
.scin(siv[iu2_valid_offset]),
.scout(sov[iu2_valid_offset]),
.din(iu2_valid_d),
.dout(iu2_valid_l2)
);
generate
if (`THREADS == 1)
begin : iu2_tid1
assign iu2_tid_l2 = iu2_tid_d;
assign sov[iu2_tid_offset] = siv[iu2_tid_offset];
end
endgenerate
generate
if (`THREADS != 1)
begin : iu2_tid2
tri_rlmreg_p #(.WIDTH(`THREADS), .INIT(0)) iu2_tid_latch(
.vd(vdd),
.gd(gnd),
.nclk(nclk),
.act(dir_dataout_act),
.thold_b(pc_iu_func_sl_thold_0_b),
.sg(pc_iu_sg_0),
.force_t(force_t),
.delay_lclkr(delay_lclkr),
.mpw1_b(mpw1_b),
.mpw2_b(mpw2_b),
.d_mode(d_mode),
.scin(siv[iu2_tid_offset:iu2_tid_offset + `THREADS - 1]),
.scout(sov[iu2_tid_offset:iu2_tid_offset + `THREADS - 1]),
.din(iu2_tid_d),
.dout(iu2_tid_l2)
);
end
endgenerate
tri_rlmreg_p #(.WIDTH(`EFF_IFAR_ARCH-10), .INIT(0), .NEEDS_SRESET(0)) iu2_ifar_eff_latch(
.vd(vdd),
.gd(gnd),
.nclk(nclk),
.act(dir_dataout_act),
.thold_b(pc_iu_func_sl_thold_0_b),
.sg(pc_iu_sg_0),
.force_t(force_t),
.delay_lclkr(delay_lclkr),
.mpw1_b(mpw1_b),
.mpw2_b(mpw2_b),
.d_mode(d_mode),
.scin(siv[iu2_ifar_eff_offset:iu2_ifar_eff_offset + `EFF_IFAR_ARCH-10 - 1]),
.scout(sov[iu2_ifar_eff_offset:iu2_ifar_eff_offset + `EFF_IFAR_ARCH-10 - 1]),
.din(iu2_ifar_eff_d[62 - `EFF_IFAR_ARCH:51]),
.dout(iu2_ifar_eff_l2[62 - `EFF_IFAR_ARCH:51])
);
// Only need 52:57 in sleep mode
tri_rlmreg_p #(.WIDTH(10), .INIT(0), .NEEDS_SRESET(0)) iu2_ifar_eff_slp_latch(
.vd(vdd),
.gd(gnd),
.nclk(nclk),
.act(dir_dataout_act),
.thold_b(pc_iu_func_slp_sl_thold_0_b),
.sg(pc_iu_sg_0),
.force_t(funcslp_force),
.delay_lclkr(delay_lclkr),
.mpw1_b(mpw1_b),
.mpw2_b(mpw2_b),
.d_mode(d_mode),
.scin(siv[iu2_ifar_eff_offset + `EFF_IFAR_ARCH-10:iu2_ifar_eff_offset + `EFF_IFAR_ARCH - 1]),
.scout(sov[iu2_ifar_eff_offset + `EFF_IFAR_ARCH-10:iu2_ifar_eff_offset + `EFF_IFAR_ARCH - 1]),
.din(iu2_ifar_eff_d[52:61]),
.dout(iu2_ifar_eff_l2[52:61])
);
tri_rlmlatch_p #(.INIT(0)) iu2_2ucode_latch(
.vd(vdd),
.gd(gnd),
.nclk(nclk),
.act(iu1_valid_l2),
.thold_b(pc_iu_func_sl_thold_0_b),
.sg(pc_iu_sg_0),
.force_t(force_t),
.delay_lclkr(delay_lclkr),
.mpw1_b(mpw1_b),
.mpw2_b(mpw2_b),
.d_mode(d_mode),
.scin(siv[iu2_2ucode_offset]),
.scout(sov[iu2_2ucode_offset]),
.din(iu2_2ucode_d),
.dout(iu2_2ucode_l2)
);
tri_rlmlatch_p #(.INIT(0)) iu2_2ucode_type_latch(
.vd(vdd),
.gd(gnd),
.nclk(nclk),
.act(iu1_valid_l2),
.thold_b(pc_iu_func_sl_thold_0_b),
.sg(pc_iu_sg_0),
.force_t(force_t),
.delay_lclkr(delay_lclkr),
.mpw1_b(mpw1_b),
.mpw2_b(mpw2_b),
.d_mode(d_mode),
.scin(siv[iu2_2ucode_type_offset]),
.scout(sov[iu2_2ucode_type_offset]),
.din(iu2_2ucode_type_d),
.dout(iu2_2ucode_type_l2)
);
tri_rlmlatch_p #(.INIT(0)) iu2_index51_latch(
.vd(vdd),
.gd(gnd),
.nclk(nclk),
.act(dir_dataout_act),
.thold_b(pc_iu_func_slp_sl_thold_0_b),
.sg(pc_iu_sg_0),
.force_t(funcslp_force),
.delay_lclkr(delay_lclkr),
.mpw1_b(mpw1_b),
.mpw2_b(mpw2_b),
.d_mode(d_mode),
.scin(siv[iu2_index51_offset]),
.scout(sov[iu2_index51_offset]),
.din(iu2_index51_d),
.dout(iu2_index51_l2)
);
tri_rlmlatch_p #(.INIT(0)) iu2_inval_latch(
.vd(vdd),
.gd(gnd),
.nclk(nclk),
.act(tiup),
.thold_b(pc_iu_func_slp_sl_thold_0_b),
.sg(pc_iu_sg_0),
.force_t(funcslp_force),
.delay_lclkr(delay_lclkr),
.mpw1_b(mpw1_b),
.mpw2_b(mpw2_b),
.d_mode(d_mode),
.scin(siv[iu2_inval_offset]),
.scout(sov[iu2_inval_offset]),
.din(iu2_inval_d),
.dout(iu2_inval_l2)
);
tri_rlmlatch_p #(.INIT(0)) iu2_prefetch_latch(
.vd(vdd),
.gd(gnd),
.nclk(nclk),
.act(tiup),
.thold_b(pc_iu_func_sl_thold_0_b),
.sg(pc_iu_sg_0),
.force_t(force_t),
.delay_lclkr(delay_lclkr),
.mpw1_b(mpw1_b),
.mpw2_b(mpw2_b),
.d_mode(d_mode),
.scin(siv[iu2_prefetch_offset]),
.scout(sov[iu2_prefetch_offset]),
.din(iu2_prefetch_d),
.dout(iu2_prefetch_l2)
);
generate
if (`INCLUDE_IERAT_BYPASS == 0)
begin : gen_iu2_read_erat0
assign iu2_read_erat_l2 = 1'b1 | iu2_read_erat_d;
assign iu2_cam_change_etc_l2 = 1'b0 & iu2_cam_change_etc_d;
assign sov[iu2_read_erat_offset] = siv[iu2_read_erat_offset];
assign sov[iu2_cam_change_etc_offset] = siv[iu2_cam_change_etc_offset];
end
endgenerate
generate
if (`INCLUDE_IERAT_BYPASS == 1)
begin : gen_iu2_read_erat1
tri_rlmlatch_p #(.INIT(0)) iu2_read_erat_latch(
.vd(vdd),
.gd(gnd),
.nclk(nclk),
.act(dir_dataout_act),
.thold_b(pc_iu_func_sl_thold_0_b),
.sg(pc_iu_sg_0),
.force_t(force_t),
.delay_lclkr(delay_lclkr),
.mpw1_b(mpw1_b),
.mpw2_b(mpw2_b),
.d_mode(d_mode),
.scin(siv[iu2_read_erat_offset]),
.scout(sov[iu2_read_erat_offset]),
.din(iu2_read_erat_d),
.dout(iu2_read_erat_l2)
);
tri_rlmlatch_p #(.INIT(0)) iu2_cam_change_etc_latch(
.vd(vdd),
.gd(gnd),
.nclk(nclk),
.act(tiup),
.thold_b(pc_iu_func_sl_thold_0_b),
.sg(pc_iu_sg_0),
.force_t(force_t),
.delay_lclkr(delay_lclkr),
.mpw1_b(mpw1_b),
.mpw2_b(mpw2_b),
.d_mode(d_mode),
.scin(siv[iu2_cam_change_etc_offset]),
.scout(sov[iu2_cam_change_etc_offset]),
.din(iu2_cam_change_etc_d),
.dout(iu2_cam_change_etc_l2)
);
end
endgenerate
tri_rlmreg_p #(.WIDTH(`REAL_IFAR_WIDTH-12), .INIT(0), .NEEDS_SRESET(0)) iu2_stored_rpn_latch(
.vd(vdd),
.gd(gnd),
.nclk(nclk),
.act(dir_dataout_act),
.thold_b(pc_iu_func_sl_thold_0_b),
.sg(pc_iu_sg_0),
.force_t(force_t),
.delay_lclkr(delay_lclkr),
.mpw1_b(mpw1_b),
.mpw2_b(mpw2_b),
.d_mode(d_mode),
.scin(siv[iu2_stored_rpn_offset:iu2_stored_rpn_offset + `REAL_IFAR_WIDTH-12 - 1]),
.scout(sov[iu2_stored_rpn_offset:iu2_stored_rpn_offset + `REAL_IFAR_WIDTH-12 - 1]),
.din(iu2_stored_rpn_d),
.dout(iu2_stored_rpn_l2)
);
tri_rlmreg_p #(.WIDTH(4), .INIT(0)) iu2_dir_rd_val_latch(
.vd(vdd),
.gd(gnd),
.nclk(nclk),
.act(dir_dataout_act),
.thold_b(pc_iu_func_slp_sl_thold_0_b),
.sg(pc_iu_sg_0),
.force_t(funcslp_force),
.delay_lclkr(delay_lclkr),
.mpw1_b(mpw1_b),
.mpw2_b(mpw2_b),
.d_mode(d_mode),
.scin(siv[iu2_dir_rd_val_offset:iu2_dir_rd_val_offset + 4 - 1]),
.scout(sov[iu2_dir_rd_val_offset:iu2_dir_rd_val_offset + 4 - 1]),
.din(iu2_dir_rd_val_d),
.dout(iu2_dir_rd_val_l2)
);
tri_rlmreg_p #(.WIDTH(4), .INIT(0)) iu3_dir_parity_err_way_latch(
.vd(vdd),
.gd(gnd),
.nclk(nclk),
.act(tiup),
.thold_b(pc_iu_func_slp_sl_thold_0_b),
.sg(pc_iu_sg_0),
.force_t(funcslp_force),
.delay_lclkr(delay_lclkr),
.mpw1_b(mpw1_b),
.mpw2_b(mpw2_b),
.d_mode(d_mode),
.scin(siv[iu3_dir_parity_err_way_offset:iu3_dir_parity_err_way_offset + 4 - 1]),
.scout(sov[iu3_dir_parity_err_way_offset:iu3_dir_parity_err_way_offset + 4 - 1]),
.din(iu3_dir_parity_err_way_d),
.dout(iu3_dir_parity_err_way_l2)
);
// Dir
generate
begin : xhdl17
genvar a;
for (a = 0; a < 128; a = a + 1)
begin : dir_val_latch_gen
tri_rlmreg_p #(.WIDTH(4), .INIT(0)) dir_val_latch(
.vd(vdd),
.gd(gnd),
.nclk(nclk),
.act(dir_val_act),
.thold_b(pc_iu_func_slp_sl_thold_0_b),
.sg(pc_iu_sg_0),
.force_t(funcslp_force),
.delay_lclkr(delay_lclkr),
.mpw1_b(mpw1_b),
.mpw2_b(mpw2_b),
.d_mode(d_mode),
.scin(siv[dir_val_offset + 4 * a:(dir_val_offset + 4 * (a + 1)) - 1]),
.scout(sov[dir_val_offset + 4 * a:(dir_val_offset + 4 * (a + 1)) - 1]),
.din(dir_val_d[a]),
.dout(dir_val_l2[a])
);
tri_rlmreg_p #(.WIDTH(3), .INIT(0)) dir_lru_latch(
.vd(vdd),
.gd(gnd),
.nclk(nclk),
.act(dir_lru_act[a/8]),
.thold_b(pc_iu_func_sl_thold_0_b),
.sg(pc_iu_sg_0),
.force_t(force_t),
.delay_lclkr(delay_lclkr),
.mpw1_b(mpw1_b),
.mpw2_b(mpw2_b),
.d_mode(d_mode),
.scin(siv[dir_lru_offset + 3 * a:(dir_lru_offset + 3 * (a + 1)) - 1]),
.scout(sov[dir_lru_offset + 3 * a:(dir_lru_offset + 3 * (a + 1)) - 1]),
.din(dir_lru_d[a]),
.dout(dir_lru_l2[a])
);
end
end
endgenerate
tri_rlmlatch_p #(.INIT(0)) iu3_miss_flush(
.vd(vdd),
.gd(gnd),
.nclk(nclk),
.act(tiup),
.thold_b(pc_iu_func_sl_thold_0_b),
.sg(pc_iu_sg_0),
.force_t(force_t),
.delay_lclkr(delay_lclkr),
.mpw1_b(mpw1_b),
.mpw2_b(mpw2_b),
.d_mode(d_mode),
.scin(siv[iu3_miss_flush_offset]),
.scout(sov[iu3_miss_flush_offset]),
.din(iu3_miss_flush_d),
.dout(iu3_miss_flush_l2)
);
generate
if (`THREADS == 1)
begin : iu3_tid1
assign iu3_tid_l2 = iu3_tid_d | 1'b1; // Need to always be '1' when single thread since we aren't latching.
// 'iu3_tid_d' part is to get rid of unused warnings
assign sov[iu3_tid_offset] = siv[iu3_tid_offset];
end
endgenerate
generate
if (`THREADS != 1)
begin : iu3_tid2
tri_rlmreg_p #(.WIDTH(`THREADS), .INIT(0)) iu3_tid_latch(
.vd(vdd),
.gd(gnd),
.nclk(nclk),
.act(tiup),
.thold_b(pc_iu_func_sl_thold_0_b),
.sg(pc_iu_sg_0),
.force_t(force_t),
.delay_lclkr(delay_lclkr),
.mpw1_b(mpw1_b),
.mpw2_b(mpw2_b),
.d_mode(d_mode),
.scin(siv[iu3_tid_offset:iu3_tid_offset + `THREADS - 1]),
.scout(sov[iu3_tid_offset:iu3_tid_offset + `THREADS - 1]),
.din(iu3_tid_d),
.dout(iu3_tid_l2)
);
end
endgenerate
tri_rlmreg_p #(.WIDTH(`EFF_IFAR_WIDTH), .INIT(0), .NEEDS_SRESET(0)) iu3_ifar_latch(
.vd(vdd),
.gd(gnd),
.nclk(nclk),
.act(iu2_valid_l2),
.thold_b(pc_iu_func_sl_thold_0_b),
.sg(pc_iu_sg_0),
.force_t(force_t),
.delay_lclkr(delay_lclkr),
.mpw1_b(mpw1_b),
.mpw2_b(mpw2_b),
.d_mode(d_mode),
.scin(siv[iu3_ifar_offset:iu3_ifar_offset + `EFF_IFAR_WIDTH - 1]),
.scout(sov[iu3_ifar_offset:iu3_ifar_offset + `EFF_IFAR_WIDTH - 1]),
.din(iu3_ifar_d),
.dout(iu3_ifar_l2)
);
tri_rlmlatch_p #(.INIT(0)) iu3_2ucode_latch(
.vd(vdd),
.gd(gnd),
.nclk(nclk),
.act(iu2_valid_l2),
.thold_b(pc_iu_func_sl_thold_0_b),
.sg(pc_iu_sg_0),
.force_t(force_t),
.delay_lclkr(delay_lclkr),
.mpw1_b(mpw1_b),
.mpw2_b(mpw2_b),
.d_mode(d_mode),
.scin(siv[iu3_2ucode_offset]),
.scout(sov[iu3_2ucode_offset]),
.din(iu3_2ucode_d),
.dout(iu3_2ucode_l2)
);
tri_rlmlatch_p #(.INIT(0)) iu3_2ucode_type_latch(
.vd(vdd),
.gd(gnd),
.nclk(nclk),
.act(iu2_valid_l2),
.thold_b(pc_iu_func_sl_thold_0_b),
.sg(pc_iu_sg_0),
.force_t(force_t),
.delay_lclkr(delay_lclkr),
.mpw1_b(mpw1_b),
.mpw2_b(mpw2_b),
.d_mode(d_mode),
.scin(siv[iu3_2ucode_type_offset]),
.scout(sov[iu3_2ucode_type_offset]),
.din(iu3_2ucode_type_d),
.dout(iu3_2ucode_type_l2)
);
tri_rlmreg_p #(.WIDTH(1), .INIT(0)) iu3_erat_err_latch(
.vd(vdd),
.gd(gnd),
.nclk(nclk),
.act(tiup),
.thold_b(pc_iu_func_sl_thold_0_b),
.sg(pc_iu_sg_0),
.force_t(force_t),
.delay_lclkr(delay_lclkr),
.mpw1_b(mpw1_b),
.mpw2_b(mpw2_b),
.d_mode(d_mode),
.scin(siv[iu3_erat_err_offset:iu3_erat_err_offset + 1 - 1]),
.scout(sov[iu3_erat_err_offset:iu3_erat_err_offset + 1 - 1]),
.din(iu3_erat_err_d[0:0]),
.dout(iu3_erat_err_l2)
);
tri_rlmreg_p #(.WIDTH(4), .INIT(0)) iu3_multihit_err_way_latch(
.vd(vdd),
.gd(gnd),
.nclk(nclk),
.act(tiup),
.thold_b(pc_iu_func_slp_sl_thold_0_b),
.sg(pc_iu_sg_0),
.force_t(funcslp_force),
.delay_lclkr(delay_lclkr),
.mpw1_b(mpw1_b),
.mpw2_b(mpw2_b),
.d_mode(d_mode),
.scin(siv[iu3_multihit_err_way_offset:iu3_multihit_err_way_offset + 4 - 1]),
.scout(sov[iu3_multihit_err_way_offset:iu3_multihit_err_way_offset + 4 - 1]),
.din(iu3_multihit_err_way_d),
.dout(iu3_multihit_err_way_l2)
);
tri_rlmlatch_p #(.INIT(0)) iu3_multihit_flush_latch(
.vd(vdd),
.gd(gnd),
.nclk(nclk),
.act(tiup),
.thold_b(pc_iu_func_sl_thold_0_b),
.sg(pc_iu_sg_0),
.force_t(force_t),
.delay_lclkr(delay_lclkr),
.mpw1_b(mpw1_b),
.mpw2_b(mpw2_b),
.d_mode(d_mode),
.scin(siv[iu3_multihit_flush_offset]),
.scout(sov[iu3_multihit_flush_offset]),
.din(iu3_multihit_flush_d),
.dout(iu3_multihit_flush_l2)
);
tri_rlmreg_p #(.WIDTH(4), .INIT(0)) iu3_data_parity_err_way_latch(
.vd(vdd),
.gd(gnd),
.nclk(nclk),
.act(tiup),
.thold_b(pc_iu_func_sl_thold_0_b),
.sg(pc_iu_sg_0),
.force_t(force_t),
.delay_lclkr(delay_lclkr),
.mpw1_b(mpw1_b),
.mpw2_b(mpw2_b),
.d_mode(d_mode),
.scin(siv[iu3_data_parity_err_way_offset:iu3_data_parity_err_way_offset + 4 - 1]),
.scout(sov[iu3_data_parity_err_way_offset:iu3_data_parity_err_way_offset + 4 - 1]),
.din(iu3_data_parity_err_way_d),
.dout(iu3_data_parity_err_way_l2)
);
tri_rlmlatch_p #(.INIT(0)) iu3_parity_needs_flush_latch(
.vd(vdd),
.gd(gnd),
.nclk(nclk),
.act(tiup),
.thold_b(pc_iu_func_sl_thold_0_b),
.sg(pc_iu_sg_0),
.force_t(force_t),
.delay_lclkr(delay_lclkr),
.mpw1_b(mpw1_b),
.mpw2_b(mpw2_b),
.d_mode(d_mode),
.scin(siv[iu3_parity_needs_flush_offset]),
.scout(sov[iu3_parity_needs_flush_offset]),
.din(iu3_parity_needs_flush_d),
.dout(iu3_parity_needs_flush_l2)
);
tri_rlmreg_p #(.WIDTH(7), .INIT(0), .NEEDS_SRESET(0)) iu3_parity_tag_latch(
.vd(vdd),
.gd(gnd),
.nclk(nclk),
.act(tiup),
.thold_b(pc_iu_func_slp_sl_thold_0_b),
.sg(pc_iu_sg_0),
.force_t(funcslp_force),
.delay_lclkr(delay_lclkr),
.mpw1_b(mpw1_b),
.mpw2_b(mpw2_b),
.d_mode(d_mode),
.scin(siv[iu3_parity_tag_offset:iu3_parity_tag_offset + 7 - 1]),
.scout(sov[iu3_parity_tag_offset:iu3_parity_tag_offset + 7 - 1]),
.din(iu3_parity_tag_d),
.dout(iu3_parity_tag_l2)
);
tri_rlmlatch_p #(.INIT(0)) ici_val_latch(
.vd(vdd),
.gd(gnd),
.nclk(nclk),
.act(tiup),
.thold_b(pc_iu_func_sl_thold_0_b),
.sg(pc_iu_sg_0),
.force_t(force_t),
.delay_lclkr(delay_lclkr),
.mpw1_b(mpw1_b),
.mpw2_b(mpw2_b),
.d_mode(d_mode),
.scin(siv[ici_val_offset]),
.scout(sov[ici_val_offset]),
.din(ici_val_d),
.dout(ici_val_l2)
);
tri_rlmlatch_p #(.INIT(0)) spr_ic_cls_latch(
.vd(vdd),
.gd(gnd),
.nclk(nclk),
.act(tiup),
.thold_b(pc_iu_func_sl_thold_0_b),
.sg(pc_iu_sg_0),
.force_t(force_t),
.delay_lclkr(delay_lclkr),
.mpw1_b(mpw1_b),
.mpw2_b(mpw2_b),
.d_mode(d_mode),
.scin(siv[spr_ic_cls_offset]),
.scout(sov[spr_ic_cls_offset]),
.din(spr_ic_cls_d),
.dout(spr_ic_cls_l2)
);
tri_rlmreg_p #(.WIDTH(2), .INIT(0)) spr_ic_idir_way_latch(
.vd(vdd),
.gd(gnd),
.nclk(nclk),
.act(dir_dataout_act),
.thold_b(pc_iu_func_sl_thold_0_b),
.sg(pc_iu_sg_0),
.force_t(force_t),
.delay_lclkr(delay_lclkr),
.mpw1_b(mpw1_b),
.mpw2_b(mpw2_b),
.d_mode(d_mode),
.scin(siv[spr_ic_idir_way_offset:spr_ic_idir_way_offset + 2 - 1]),
.scout(sov[spr_ic_idir_way_offset:spr_ic_idir_way_offset + 2 - 1]),
.din(spr_ic_idir_way_d),
.dout(spr_ic_idir_way_l2)
);
tri_rlmlatch_p #(.INIT(0)) iu1_spr_idir_read_latch(
.vd(vdd),
.gd(gnd),
.nclk(nclk),
.act(tiup),
.thold_b(pc_iu_func_sl_thold_0_b),
.sg(pc_iu_sg_0),
.force_t(force_t),
.delay_lclkr(delay_lclkr),
.mpw1_b(mpw1_b),
.mpw2_b(mpw2_b),
.d_mode(d_mode),
.scin(siv[iu1_spr_idir_read_offset]),
.scout(sov[iu1_spr_idir_read_offset]),
.din(iu1_spr_idir_read_d),
.dout(iu1_spr_idir_read_l2)
);
tri_rlmlatch_p #(.INIT(0)) iu2_spr_idir_read_latch(
.vd(vdd),
.gd(gnd),
.nclk(nclk),
.act(tiup),
.thold_b(pc_iu_func_sl_thold_0_b),
.sg(pc_iu_sg_0),
.force_t(force_t),
.delay_lclkr(delay_lclkr),
.mpw1_b(mpw1_b),
.mpw2_b(mpw2_b),
.d_mode(d_mode),
.scin(siv[iu2_spr_idir_read_offset]),
.scout(sov[iu2_spr_idir_read_offset]),
.din(iu2_spr_idir_read_d),
.dout(iu2_spr_idir_read_l2)
);
tri_rlmreg_p #(.WIDTH(3), .INIT(0)) iu2_spr_idir_lru_latch(
.vd(vdd),
.gd(gnd),
.nclk(nclk),
.act(dir_dataout_act),
.thold_b(pc_iu_func_sl_thold_0_b),
.sg(pc_iu_sg_0),
.force_t(force_t),
.delay_lclkr(delay_lclkr),
.mpw1_b(mpw1_b),
.mpw2_b(mpw2_b),
.d_mode(d_mode),
.scin(siv[iu2_spr_idir_lru_offset:iu2_spr_idir_lru_offset + 3 - 1]),
.scout(sov[iu2_spr_idir_lru_offset:iu2_spr_idir_lru_offset + 3 - 1]),
.din(iu2_spr_idir_lru_d),
.dout(iu2_spr_idir_lru_l2)
);
generate
begin : xhdl19
if (`INCLUDE_IERAT_BYPASS == 0)
begin : gen0
genvar i;
for (i = 0; i < `THREADS; i = i + 1)
begin : thr0
assign stored_erat_rpn_l2[i] = {`REAL_IFAR_WIDTH-12{1'b0}} & stored_erat_rpn_d[i]; // ..._d part is to get rid of unused warnings
assign stored_erat_wimge_l2[i] = 5'b0 & stored_erat_wimge_d[i];
assign stored_erat_u_l2[i] = 4'b0 & stored_erat_u_d[i];
end
assign sov[stored_erat_rpn_offset:stored_erat_u_offset + 4 * `THREADS - 1] = siv[stored_erat_rpn_offset:stored_erat_u_offset + 4 * `THREADS - 1];
end
if (`INCLUDE_IERAT_BYPASS == 1)
begin : gen1
genvar i;
for (i = 0; i < `THREADS; i = i + 1)
begin : thr
tri_rlmreg_p #(.WIDTH(`REAL_IFAR_WIDTH-12), .INIT(0)) stored_erat_rpn_latch(
.vd(vdd),
.gd(gnd),
.nclk(nclk),
.act(stored_erat_act[i]),
.thold_b(pc_iu_func_sl_thold_0_b),
.sg(pc_iu_sg_0),
.force_t(force_t),
.delay_lclkr(delay_lclkr),
.mpw1_b(mpw1_b),
.mpw2_b(mpw2_b),
.d_mode(d_mode),
.scin(siv[stored_erat_rpn_offset + i * (`REAL_IFAR_WIDTH-12):stored_erat_rpn_offset + (i + 1) * (`REAL_IFAR_WIDTH-12) - 1]),
.scout(sov[stored_erat_rpn_offset + i * (`REAL_IFAR_WIDTH-12):stored_erat_rpn_offset + (i + 1) * (`REAL_IFAR_WIDTH-12) - 1]),
.din(stored_erat_rpn_d[i]),
.dout(stored_erat_rpn_l2[i])
);
tri_rlmreg_p #(.WIDTH(5), .INIT(0)) stored_erat_wimge_latch(
.vd(vdd),
.gd(gnd),
.nclk(nclk),
.act(stored_erat_act[i]),
.thold_b(pc_iu_func_sl_thold_0_b),
.sg(pc_iu_sg_0),
.force_t(force_t),
.delay_lclkr(delay_lclkr),
.mpw1_b(mpw1_b),
.mpw2_b(mpw2_b),
.d_mode(d_mode),
.scin(siv[stored_erat_wimge_offset + i * 5:stored_erat_wimge_offset + (i + 1) * 5 - 1]),
.scout(sov[stored_erat_wimge_offset + i * 5:stored_erat_wimge_offset + (i + 1) * 5 - 1]),
.din(stored_erat_wimge_d[i]),
.dout(stored_erat_wimge_l2[i])
);
tri_rlmreg_p #(.WIDTH(4), .INIT(0)) stored_erat_u_latch(
.vd(vdd),
.gd(gnd),
.nclk(nclk),
.act(stored_erat_act[i]),
.thold_b(pc_iu_func_sl_thold_0_b),
.sg(pc_iu_sg_0),
.force_t(force_t),
.delay_lclkr(delay_lclkr),
.mpw1_b(mpw1_b),
.mpw2_b(mpw2_b),
.d_mode(d_mode),
.scin(siv[stored_erat_u_offset + i * 4:stored_erat_u_offset + (i + 1) * 4 - 1]),
.scout(sov[stored_erat_u_offset + i * 4:stored_erat_u_offset + (i + 1) * 4 - 1]),
.din(stored_erat_u_d[i]),
.dout(stored_erat_u_l2[i])
);
end
end
end
endgenerate
generate
begin : xhdl18
genvar i;
for (i = 0; i < `THREADS; i = i + 1)
begin : gen_perf_reg
tri_rlmreg_p #(.WIDTH(2), .INIT(0)) perf_instr_count_latch(
.vd(vdd),
.gd(gnd),
.nclk(nclk),
.act(event_bus_enable),
.thold_b(pc_iu_func_sl_thold_0_b),
.sg(pc_iu_sg_0),
.force_t(force_t),
.delay_lclkr(delay_lclkr),
.mpw1_b(mpw1_b),
.mpw2_b(mpw2_b),
.d_mode(d_mode),
.scin(siv[perf_instr_count_offset + i * 2:perf_instr_count_offset + (i + 1) * 2 - 1]),
.scout(sov[perf_instr_count_offset + i * 2:perf_instr_count_offset + (i + 1) * 2 - 1]),
.din(perf_instr_count_d[i]),
.dout(perf_instr_count_l2[i])
);
tri_rlmreg_p #(.WIDTH(3), .INIT(0)) perf_t_event_latch(
.vd(vdd),
.gd(gnd),
.nclk(nclk),
.act(event_bus_enable),
.thold_b(pc_iu_func_sl_thold_0_b),
.sg(pc_iu_sg_0),
.force_t(force_t),
.delay_lclkr(delay_lclkr),
.mpw1_b(mpw1_b),
.mpw2_b(mpw2_b),
.d_mode(d_mode),
.scin(siv[perf_t_event_offset + i * 3:perf_t_event_offset + (i + 1) * 3 - 1]),
.scout(sov[perf_t_event_offset + i * 3:perf_t_event_offset + (i + 1) * 3 - 1]),
.din(perf_t_event_d[i]),
.dout(perf_t_event_l2[i])
);
end
end
endgenerate
tri_rlmreg_p #(.WIDTH(2), .INIT(0)) perf_event_latch(
.vd(vdd),
.gd(gnd),
.nclk(nclk),
.act(event_bus_enable),
.thold_b(pc_iu_func_sl_thold_0_b),
.sg(pc_iu_sg_0),
.force_t(force_t),
.delay_lclkr(delay_lclkr),
.mpw1_b(mpw1_b),
.mpw2_b(mpw2_b),
.d_mode(d_mode),
.scin(siv[perf_event_offset:perf_event_offset + 2 - 1]),
.scout(sov[perf_event_offset:perf_event_offset + 2 - 1]),
.din(perf_event_d),
.dout(perf_event_l2)
);
tri_rlmreg_p #(.WIDTH(3), .INIT(0)) pc_iu_inj_latch(
.vd(vdd),
.gd(gnd),
.nclk(nclk),
.act(tiup),
.thold_b(pc_iu_func_sl_thold_0_b),
.sg(pc_iu_sg_0),
.force_t(force_t),
.delay_lclkr(delay_lclkr),
.mpw1_b(mpw1_b),
.mpw2_b(mpw2_b),
.d_mode(d_mode),
.scin(siv[pc_iu_inj_offset:pc_iu_inj_offset + 3 - 1]),
.scout(sov[pc_iu_inj_offset:pc_iu_inj_offset + 3 - 1]),
.din({pc_iu_inj_icache_parity,
pc_iu_inj_icachedir_parity,
pc_iu_inj_icachedir_multihit}),
.dout({pc_iu_inj_icache_parity_l2,
pc_iu_inj_icachedir_parity_l2,
pc_iu_inj_icachedir_multihit_l2})
);
//---------------------------------------------------------------------
// abist latches
//---------------------------------------------------------------------
tri_rlmreg_p #(.INIT(0), .WIDTH(41), .NEEDS_SRESET(0)) ab_reg(
.vd(vdd),
.gd(gnd),
.nclk(nclk),
.act(pc_iu_abist_ena_dc),
.thold_b(pc_iu_abst_sl_thold_0_b),
.sg(pc_iu_sg_0),
.force_t(abst_force),
.delay_lclkr(delay_lclkr),
.mpw1_b(mpw1_b),
.mpw2_b(mpw2_b),
.d_mode(d_mode),
.scin(abst_siv[4:44]),
.scout(abst_sov[4:44]),
.din({pc_iu_abist_g8t_wenb, pc_iu_abist_g8t1p_renb_0, pc_iu_abist_di_0,
pc_iu_abist_g8t_bw_1, pc_iu_abist_g8t_bw_0, pc_iu_abist_waddr_0,
pc_iu_abist_wl128_comp_ena, pc_iu_abist_g8t_dcomp, pc_iu_abist_raddr_0,
pc_iu_abist_g6t_bw, pc_iu_abist_di_g6t_2r, pc_iu_abist_wl512_comp_ena,
pc_iu_abist_dcomp_g6t_2r, pc_iu_abist_g6t_r_wb}),
.dout({stage_abist_g8t_wenb, stage_abist_g8t1p_renb_0, stage_abist_di_0,
stage_abist_g8t_bw_1, stage_abist_g8t_bw_0, stage_abist_waddr_0,
stage_abist_wl128_comp_ena, stage_abist_g8t_dcomp, stage_abist_raddr_0,
stage_abist_g6t_bw, stage_abist_di_g6t_2r, stage_abist_wl512_comp_ena,
stage_abist_dcomp_g6t_2r, stage_abist_g6t_r_wb})
);
//---------------------------------------------------------------------
// Scan
//---------------------------------------------------------------------
assign siv[0:scan_right] = {sov[1:scan_right], func_scan_in};
assign func_scan_out = sov[0] & tc_ac_scan_dis_dc_b;
// Chain 0: WAY01 IDIR & IDATA
assign abst_siv[0:1] = {abst_sov[1], abst_scan_in[0]};
assign abst_scan_out[0] = abst_sov[0] & tc_ac_scan_dis_dc_b;
// Chain 1: WAY23 IDIR & IDATA
assign abst_siv[2:3] = {abst_sov[3], abst_scan_in[1]};
assign abst_scan_out[1] = abst_sov[2] & tc_ac_scan_dis_dc_b;
// Chain 2: AB_REG - tack on to BHT's scan chain
assign abst_siv[4:44] = {abst_sov[5:44], abst_scan_in[2]};
assign abst_scan_out[2] = abst_sov[4] & tc_ac_scan_dis_dc_b;
assign time_siv = {time_sov[1:1], time_scan_in};
assign time_scan_out = time_sov[0] & tc_ac_scan_dis_dc_b;
assign repr_siv = {repr_sov[1:1], repr_scan_in};
assign repr_scan_out = repr_sov[0] & tc_ac_scan_dis_dc_b;
endmodule