//******************************************************************************** // SPDX-License-Identifier: Apache-2.0 // Copyright 2020 Western Digital Corporation or it's affiliates. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // 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. //******************************************************************************** //******************************************************************************** // Function: Icache , iccm control // BFF -> F1 -> F2 -> A //******************************************************************************** module el2_ifu_mem_ctl import el2_pkg::*; #( `include "el2_param.vh" ) ( input logic clk, input logic free_clk, // free clock always except during pause input logic active_clk, // Active always except during pause input logic rst_l, input logic exu_flush_final, // Flush from the pipeline., includes flush lower input logic dec_tlu_flush_lower_wb, // Flush lower from the pipeline. input logic dec_tlu_flush_err_wb, // Flush from the pipeline due to perr. input logic dec_tlu_i0_commit_cmt, // committed i0 instruction input logic dec_tlu_force_halt, // force halt. input logic [31:1] ifc_fetch_addr_bf, // Fetch Address byte aligned always. F1 stage. input logic ifc_fetch_uncacheable_bf, // The fetch request is uncacheable space. F1 stage input logic ifc_fetch_req_bf, // Fetch request. Comes with the address. F1 stage input logic ifc_fetch_req_bf_raw, // Fetch request without some qualifications. Used for clock-gating. F1 stage input logic ifc_iccm_access_bf, // This request is to the ICCM. Do not generate misses to the bus. input logic ifc_region_acc_fault_bf, // Access fault. in ICCM region but offset is outside defined ICCM. input logic ifc_dma_access_ok, // It is OK to give dma access to the ICCM. (ICCM is not busy this cycle). input logic dec_tlu_fence_i_wb, // Fence.i instruction is committing. Clear all Icache valids. input logic ifu_bp_hit_taken_f, // Branch is predicted taken. Kill the fetch next cycle. input logic ifu_bp_inst_mask_f, // tell ic which valids to kill because of a taken branch, right justified output logic ifu_miss_state_idle, // No icache misses are outstanding. output logic ifu_ic_mb_empty, // Continue with normal fetching. This does not mean that miss is finished. output logic ic_dma_active , // In the middle of servicing dma request to ICCM. Do not make any new requests. output logic ic_write_stall, // Stall fetch the cycle we are writing the cache. /// PMU signals output logic ifu_pmu_ic_miss, // IC miss event output logic ifu_pmu_ic_hit, // IC hit event output logic ifu_pmu_bus_error, // Bus error event output logic ifu_pmu_bus_busy, // Bus busy event output logic ifu_pmu_bus_trxn, // Bus transaction //-------------------------- IFU AXI signals-------------------------- // AXI Write Channels output logic ifu_axi_awvalid, output logic [pt.IFU_BUS_TAG-1:0] ifu_axi_awid, output logic [31:0] ifu_axi_awaddr, output logic [3:0] ifu_axi_awregion, output logic [7:0] ifu_axi_awlen, output logic [2:0] ifu_axi_awsize, output logic [1:0] ifu_axi_awburst, output logic ifu_axi_awlock, output logic [3:0] ifu_axi_awcache, output logic [2:0] ifu_axi_awprot, output logic [3:0] ifu_axi_awqos, output logic ifu_axi_wvalid, output logic [63:0] ifu_axi_wdata, output logic [7:0] ifu_axi_wstrb, output logic ifu_axi_wlast, output logic ifu_axi_bready, // AXI Read Channels output logic ifu_axi_arvalid, input logic ifu_axi_arready, output logic [pt.IFU_BUS_TAG-1:0] ifu_axi_arid, output logic [31:0] ifu_axi_araddr, output logic [3:0] ifu_axi_arregion, output logic [7:0] ifu_axi_arlen, output logic [2:0] ifu_axi_arsize, output logic [1:0] ifu_axi_arburst, output logic ifu_axi_arlock, output logic [3:0] ifu_axi_arcache, output logic [2:0] ifu_axi_arprot, output logic [3:0] ifu_axi_arqos, input logic ifu_axi_rvalid, output logic ifu_axi_rready, input logic [pt.IFU_BUS_TAG-1:0] ifu_axi_rid, input logic [63:0] ifu_axi_rdata, input logic [1:0] ifu_axi_rresp, input logic ifu_bus_clk_en, input logic dma_iccm_req, // dma iccm command (read or write) input logic [31:0] dma_mem_addr, // dma address input logic [2:0] dma_mem_sz, // size input logic dma_mem_write, // write input logic [63:0] dma_mem_wdata, // write data input logic [2:0] dma_mem_tag, // DMA Buffer entry number output logic iccm_dma_ecc_error,// Data read from iccm has an ecc error output logic iccm_dma_rvalid, // Data read from iccm is valid output logic [63:0] iccm_dma_rdata, // dma data read from iccm output logic [2:0] iccm_dma_rtag, // Tag of the DMA req output logic iccm_ready, // iccm ready to accept new command. // I$ & ITAG Ports output logic [31:1] ic_rw_addr, // Read/Write addresss to the Icache. output logic [pt.ICACHE_NUM_WAYS-1:0] ic_wr_en, // Icache write enable, when filling the Icache. output logic ic_rd_en, // Icache read enable. output logic [pt.ICACHE_BANKS_WAY-1:0] [70:0] ic_wr_data, // Data to fill to the Icache. With ECC input logic [63:0] ic_rd_data , // Data read from Icache. 2x64bits + parity bits. F2 stage. With ECC input logic [70:0] ic_debug_rd_data , // Data read from Icache. 2x64bits + parity bits. F2 stage. With ECC input logic [25:0] ictag_debug_rd_data, // Debug icache tag. output logic [70:0] ic_debug_wr_data, // Debug wr cache. output logic [70:0] ifu_ic_debug_rd_data, // debug data read input logic [pt.ICACHE_BANKS_WAY-1:0] ic_eccerr, // input logic [pt.ICACHE_BANKS_WAY-1:0] ic_parerr, output logic [pt.ICACHE_INDEX_HI:3] ic_debug_addr, // Read/Write addresss to the Icache. output logic ic_debug_rd_en, // Icache debug rd output logic ic_debug_wr_en, // Icache debug wr output logic ic_debug_tag_array, // Debug tag array output logic [pt.ICACHE_NUM_WAYS-1:0] ic_debug_way, // Debug way. Rd or Wr. output logic [pt.ICACHE_NUM_WAYS-1:0] ic_tag_valid, // Valid bits when accessing the Icache. One valid bit per way. F2 stage input logic [pt.ICACHE_NUM_WAYS-1:0] ic_rd_hit, // Compare hits from Icache tags. Per way. F2 stage input logic ic_tag_perr, // Icache Tag parity error // ICCM ports output logic [pt.ICCM_BITS-1:1] iccm_rw_addr, // ICCM read/write address. output logic iccm_wren, // ICCM write enable (through the DMA) output logic iccm_rden, // ICCM read enable. output logic [77:0] iccm_wr_data, // ICCM write data. output logic [2:0] iccm_wr_size, // ICCM write location within DW. input logic [63:0] iccm_rd_data, // Data read from ICCM. input logic [77:0] iccm_rd_data_ecc, // Data + ECC read from ICCM. input logic [1:0] ifu_fetch_val, // IFU control signals output logic ic_hit_f, // Hit in Icache(if Icache access) or ICCM access( ICCM always has ic_hit_f) output logic ic_access_fault_f, // Access fault (bus error or ICCM access in region but out of offset range). output logic [1:0] ic_access_fault_type_f, // Access fault types output logic iccm_rd_ecc_single_err, // This fetch has a single ICCM ecc error. output logic iccm_rd_ecc_double_err, // This fetch has a double ICCM ecc error. output logic ic_error_start, // This has any I$ errors ( data/tag/ecc/parity ) output logic ifu_async_error_start, // Or of the sb iccm, and all the icache errors sent to aligner to stop output logic iccm_dma_sb_error, // Single Bit ECC error from a DMA access output logic [1:0] ic_fetch_val_f, // valid bytes for fetch. To the Aligner. output logic [31:0] ic_data_f, // Data read from Icache or ICCM. To the Aligner. output logic [63:0] ic_premux_data, // Premuxed data to be muxed with Icache data output logic ic_sel_premux_data, // Select premux data. ///// Debug input el2_cache_debug_pkt_t dec_tlu_ic_diag_pkt , // Icache/tag debug read/write packet input logic dec_tlu_core_ecc_disable, // disable the ecc checking and flagging output logic ifu_ic_debug_rd_data_valid, // debug data valid. output logic iccm_buf_correct_ecc, output logic iccm_correction_state, input logic scan_mode ); // Create different defines for ICACHE and ICCM enable combinations localparam NUM_OF_BEATS = 8 ; logic [31:3] ifu_ic_req_addr_f; logic uncacheable_miss_in ; logic uncacheable_miss_ff; logic bus_ifu_wr_en ; logic bus_ifu_wr_en_ff ; logic bus_ifu_wr_en_ff_q ; logic bus_ifu_wr_en_ff_wo_err ; logic [pt.ICACHE_NUM_WAYS-1:0] bus_ic_wr_en ; logic reset_tag_valid_for_miss ; logic [pt.ICACHE_STATUS_BITS-1:0] way_status; logic [pt.ICACHE_STATUS_BITS-1:0] way_status_mb_in; logic [pt.ICACHE_STATUS_BITS-1:0] way_status_rep_new; logic [pt.ICACHE_STATUS_BITS-1:0] way_status_mb_ff; logic [pt.ICACHE_STATUS_BITS-1:0] way_status_new; logic [pt.ICACHE_STATUS_BITS-1:0] way_status_hit_new; logic [pt.ICACHE_STATUS_BITS-1:0] way_status_new_w_debug; logic [pt.ICACHE_NUM_WAYS-1:0] tagv_mb_in; logic [pt.ICACHE_NUM_WAYS-1:0] tagv_mb_ff; logic ifu_wr_data_comb_err ; logic ifu_byp_data_err_new; logic ifu_wr_cumulative_err_data; logic ifu_wr_cumulative_err; logic ifu_wr_data_comb_err_ff; logic scnd_miss_index_match ; logic ifc_dma_access_q_ok; logic ifc_iccm_access_f ; logic ifc_region_acc_fault_f; logic ifc_region_acc_fault_final_f; logic ifc_bus_acc_fault_f; logic ic_act_miss_f; logic ic_miss_under_miss_f; logic ic_ignore_2nd_miss_f; logic ic_act_hit_f; logic miss_pending; logic [31:1] imb_in , imb_ff ; logic [31:pt.ICACHE_BEAT_ADDR_HI+1] miss_addr_in , miss_addr ; logic miss_wrap_f ; logic flush_final_f; logic ifc_fetch_req_f; logic ifc_fetch_req_f_raw; logic fetch_req_f_qual ; logic ifc_fetch_req_qual_bf ; logic [pt.ICACHE_NUM_WAYS-1:0] replace_way_mb_any; logic last_beat; logic reset_beat_cnt ; logic [pt.ICACHE_BEAT_ADDR_HI:3] ic_req_addr_bits_hi_3 ; logic [pt.ICACHE_BEAT_ADDR_HI:3] ic_wr_addr_bits_hi_3 ; logic [31:1] ifu_fetch_addr_int_f ; logic [31:1] ifu_ic_rw_int_addr ; logic crit_wd_byp_ok_ff ; logic ic_crit_wd_rdy_new_ff; logic [79:0] ic_byp_data_only_pre_new; logic [79:0] ic_byp_data_only_new; logic ic_byp_hit_f ; logic ic_valid ; logic ic_valid_ff; logic reset_all_tags; logic ic_valid_w_debug; logic [pt.ICACHE_NUM_WAYS-1:0] ifu_tag_wren,ifu_tag_wren_ff; logic [pt.ICACHE_NUM_WAYS-1:0] ic_debug_tag_wr_en; logic [pt.ICACHE_NUM_WAYS-1:0] ifu_tag_wren_w_debug; logic [pt.ICACHE_NUM_WAYS-1:0] ic_debug_way_ff; logic ic_debug_rd_en_ff ; logic fetch_bf_f_c1_clken ; logic fetch_bf_f_c1_clk; logic debug_c1_clken; logic debug_c1_clk; logic reset_ic_in ; logic reset_ic_ff ; logic [pt.ICACHE_BEAT_ADDR_HI:1] vaddr_f ; logic [31:1] ifu_status_wr_addr; logic sel_mb_addr ; logic sel_mb_addr_ff ; logic sel_mb_status_addr ; logic [63:0] ic_final_data; logic [pt.ICACHE_INDEX_HI:pt.ICACHE_TAG_INDEX_LO] ifu_ic_rw_int_addr_ff ; logic [pt.ICACHE_INDEX_HI:pt.ICACHE_TAG_INDEX_LO] ifu_status_wr_addr_ff ; logic [pt.ICACHE_INDEX_HI:pt.ICACHE_TAG_INDEX_LO] ifu_ic_rw_int_addr_w_debug ; logic [pt.ICACHE_INDEX_HI:pt.ICACHE_TAG_INDEX_LO] ifu_status_wr_addr_w_debug ; logic [pt.ICACHE_STATUS_BITS-1:0] way_status_new_ff ; logic way_status_wr_en_ff ; logic [pt.ICACHE_TAG_DEPTH-1:0][pt.ICACHE_STATUS_BITS-1:0] way_status_out ; logic [1:0] ic_debug_way_enc; logic [pt.IFU_BUS_TAG-1:0] ifu_bus_rid_ff; logic fetch_req_icache_f; logic fetch_req_iccm_f; logic ic_iccm_hit_f; logic fetch_uncacheable_ff; logic way_status_wr_en; logic sel_byp_data; logic sel_ic_data; logic sel_iccm_data; logic ic_rd_parity_final_err; logic ic_act_miss_f_delayed; logic bus_ifu_wr_data_error; logic bus_ifu_wr_data_error_ff; logic way_status_wr_en_w_debug; logic ic_debug_tag_val_rd_out; logic ifu_pmu_ic_miss_in; logic ifu_pmu_ic_hit_in; logic ifu_pmu_bus_error_in; logic ifu_pmu_bus_trxn_in; logic ifu_pmu_bus_busy_in; logic ic_debug_ict_array_sel_in; logic ic_debug_ict_array_sel_ff; logic debug_data_clk; logic debug_data_clken; logic last_data_recieved_in ; logic last_data_recieved_ff ; logic ifu_bus_rvalid ; logic ifu_bus_rvalid_ff ; logic ifu_bus_rvalid_unq ; logic ifu_bus_rvalid_unq_ff ; logic ifu_bus_arready_unq ; logic ifu_bus_arready_unq_ff ; logic ifu_bus_arvalid ; logic ifu_bus_arvalid_ff ; logic ifu_bus_arready ; logic ifu_bus_arready_ff ; logic [63:0] ifu_bus_rdata_ff ; logic [1:0] ifu_bus_rresp_ff ; logic ifu_bus_rsp_valid ; logic ifu_bus_rsp_ready ; logic [pt.IFU_BUS_TAG-1:0] ifu_bus_rsp_tag; logic [63:0] ifu_bus_rsp_rdata; logic [1:0] ifu_bus_rsp_opc; logic [pt.ICACHE_NUM_BEATS-1:0] write_fill_data; logic [pt.ICACHE_NUM_BEATS-1:0] wr_data_c1_clk; logic [pt.ICACHE_NUM_BEATS-1:0] ic_miss_buff_data_valid_in; logic [pt.ICACHE_NUM_BEATS-1:0] ic_miss_buff_data_valid; logic [pt.ICACHE_NUM_BEATS-1:0] ic_miss_buff_data_error_in; logic [pt.ICACHE_NUM_BEATS-1:0] ic_miss_buff_data_error; logic [pt.ICACHE_BEAT_ADDR_HI:1] byp_fetch_index; logic [pt.ICACHE_BEAT_ADDR_HI:2] byp_fetch_index_0; logic [pt.ICACHE_BEAT_ADDR_HI:2] byp_fetch_index_1; logic [pt.ICACHE_BEAT_ADDR_HI:3] byp_fetch_index_inc; logic [pt.ICACHE_BEAT_ADDR_HI:2] byp_fetch_index_inc_0; logic [pt.ICACHE_BEAT_ADDR_HI:2] byp_fetch_index_inc_1; logic miss_buff_hit_unq_f ; logic stream_hit_f ; logic stream_miss_f ; logic stream_eol_f ; logic crit_byp_hit_f ; logic [pt.IFU_BUS_TAG-1:0] other_tag ; logic [(2*pt.ICACHE_NUM_BEATS)-1:0] [31:0] ic_miss_buff_data; logic [63:0] ic_miss_buff_half; logic scnd_miss_req, scnd_miss_req_q, scnd_miss_req_ff2; logic scnd_miss_req_in; logic [pt.ICCM_BITS-1:2] iccm_ecc_corr_index_ff; logic [pt.ICCM_BITS-1:2] iccm_ecc_corr_index_in; logic [38:0] iccm_ecc_corr_data_ff; logic iccm_ecc_write_status ; logic iccm_rd_ecc_single_err_ff ; logic iccm_error_start; // start the error fsm logic perr_state_en; logic miss_state_en; logic busclk; logic busclk_force; logic busclk_reset; logic bus_ifu_bus_clk_en_ff; logic bus_ifu_bus_clk_en ; logic ifc_bus_ic_req_ff_in; logic ifu_bus_cmd_valid ; logic ifu_bus_cmd_ready ; logic bus_inc_data_beat_cnt ; logic bus_reset_data_beat_cnt ; logic bus_hold_data_beat_cnt ; logic bus_inc_cmd_beat_cnt ; logic bus_reset_cmd_beat_cnt_0 ; logic bus_reset_cmd_beat_cnt_secondlast ; logic bus_hold_cmd_beat_cnt ; logic [pt.ICACHE_BEAT_BITS-1:0] bus_new_data_beat_count ; logic [pt.ICACHE_BEAT_BITS-1:0] bus_data_beat_count ; logic [pt.ICACHE_BEAT_BITS-1:0] bus_new_cmd_beat_count ; logic [pt.ICACHE_BEAT_BITS-1:0] bus_cmd_beat_count ; logic [pt.ICACHE_BEAT_BITS-1:0] bus_new_rd_addr_count; logic [pt.ICACHE_BEAT_BITS-1:0] bus_rd_addr_count; logic bus_cmd_sent ; logic bus_last_data_beat ; logic [pt.ICACHE_NUM_WAYS-1:0] bus_wren ; logic [pt.ICACHE_NUM_WAYS-1:0] bus_wren_last ; logic [pt.ICACHE_NUM_WAYS-1:0] wren_reset_miss ; logic ifc_dma_access_ok_d; logic ifc_dma_access_ok_prev; logic bus_cmd_req_in ; logic bus_cmd_req_hold ; logic second_half_available ; logic write_ic_16_bytes ; logic ifc_region_acc_fault_final_bf; logic ifc_region_acc_fault_memory_bf; logic ifc_region_acc_fault_memory_f; logic ifc_region_acc_okay; logic iccm_correct_ecc; logic dma_sb_err_state, dma_sb_err_state_ff; logic two_byte_instr; typedef enum logic [2:0] {IDLE=3'b000, CRIT_BYP_OK=3'b001, HIT_U_MISS=3'b010, MISS_WAIT=3'b011,CRIT_WRD_RDY=3'b100,SCND_MISS=3'b101,STREAM=3'b110 , STALL_SCND_MISS=3'b111} miss_state_t; miss_state_t miss_state, miss_nxtstate; typedef enum logic [1:0] {ERR_STOP_IDLE=2'b00, ERR_FETCH1=2'b01 , ERR_FETCH2=2'b10 , ERR_STOP_FETCH=2'b11} err_stop_state_t; err_stop_state_t err_stop_state, err_stop_nxtstate; logic err_stop_state_en ; logic err_stop_fetch ; logic ic_crit_wd_rdy; // Critical fetch is ready to be bypassed. logic ifu_bp_hit_taken_q_f; logic bus_cmd_beat_en; // ---- Clock gating section ----- // c1 clock enables assign fetch_bf_f_c1_clken = ifc_fetch_req_bf_raw | ifc_fetch_req_f | miss_pending | exu_flush_final | scnd_miss_req; assign debug_c1_clken = ic_debug_rd_en | ic_debug_wr_en ; // C1 - 1 clock pulse for data rvclkhdr fetch_bf_f_c1_cgc ( .en(fetch_bf_f_c1_clken), .l1clk(fetch_bf_f_c1_clk), .* ); rvclkhdr debug_c1_cgc ( .en(debug_c1_clken), .l1clk(debug_c1_clk), .* ); // ------ end clock gating section ------------------------ logic [1:0] iccm_single_ecc_error; logic dma_iccm_req_f ; assign iccm_dma_sb_error = (|iccm_single_ecc_error[1:0] ) & dma_iccm_req_f ; assign ifu_async_error_start = iccm_rd_ecc_single_err | ic_error_start; typedef enum logic [2:0] {ERR_IDLE=3'b000, IC_WFF=3'b001 , ECC_WFF=3'b010 , ECC_CORR=3'b011, DMA_SB_ERR=3'b100} perr_state_t; perr_state_t perr_state, perr_nxtstate; assign ic_dma_active = iccm_correct_ecc | (perr_state == DMA_SB_ERR) | (err_stop_state == ERR_STOP_FETCH) | err_stop_fetch | dec_tlu_flush_err_wb; // The last term is to give a error-correction a chance to finish before refetch starts assign scnd_miss_req_in = ifu_bus_rsp_valid & bus_ifu_bus_clk_en & ifu_bus_rsp_ready & (&bus_new_data_beat_count[pt.ICACHE_BEAT_BITS-1:0]) & ~uncacheable_miss_ff & ((miss_state == SCND_MISS) | (miss_nxtstate == SCND_MISS)) & ~exu_flush_final; assign ifu_bp_hit_taken_q_f = ifu_bp_hit_taken_f & ic_hit_f ; //////////////////////////////////// Create Miss State Machine /////////////////////// // Create Miss State Machine // // Create Miss State Machine // // Create Miss State Machine // //////////////////////////////////// Create Miss State Machine /////////////////////// // FIFO state machine always_comb begin : MISS_SM miss_nxtstate = IDLE; miss_state_en = 1'b0; case (miss_state) IDLE: begin : idle miss_nxtstate = (ic_act_miss_f & ~exu_flush_final) ? CRIT_BYP_OK : HIT_U_MISS ; miss_state_en = ic_act_miss_f & ~dec_tlu_force_halt ; end CRIT_BYP_OK: begin : crit_byp_ok miss_nxtstate = (dec_tlu_force_halt ) ? IDLE : ( ic_byp_hit_f & (last_data_recieved_ff | (bus_ifu_wr_en_ff & last_beat)) & uncacheable_miss_ff) ? IDLE : ( ic_byp_hit_f & ~last_data_recieved_ff & uncacheable_miss_ff) ? MISS_WAIT : (~ic_byp_hit_f & ~exu_flush_final & (bus_ifu_wr_en_ff & last_beat) & uncacheable_miss_ff) ? CRIT_WRD_RDY : ( (bus_ifu_wr_en_ff & last_beat) & ~uncacheable_miss_ff) ? IDLE : ( ic_byp_hit_f & ~exu_flush_final & ~(bus_ifu_wr_en_ff & last_beat) & ~ifu_bp_hit_taken_q_f & ~uncacheable_miss_ff) ? STREAM : ( bus_ifu_wr_en_ff & ~exu_flush_final & ~(bus_ifu_wr_en_ff & last_beat) & ~ifu_bp_hit_taken_q_f & ~uncacheable_miss_ff) ? STREAM : (~ic_byp_hit_f & ~exu_flush_final & (bus_ifu_wr_en_ff & last_beat) & ~uncacheable_miss_ff) ? IDLE : ( (exu_flush_final | ifu_bp_hit_taken_q_f) & ~(bus_ifu_wr_en_ff & last_beat) ) ? HIT_U_MISS : IDLE; miss_state_en = dec_tlu_force_halt | exu_flush_final | ic_byp_hit_f | ifu_bp_hit_taken_q_f | (bus_ifu_wr_en_ff & last_beat) | (bus_ifu_wr_en_ff & ~uncacheable_miss_ff) ; end CRIT_WRD_RDY: begin : crit_wrd_rdy miss_nxtstate = IDLE ; miss_state_en = exu_flush_final | flush_final_f | ic_byp_hit_f | dec_tlu_force_halt ; end STREAM: begin : stream miss_nxtstate = ((exu_flush_final | ifu_bp_hit_taken_q_f | stream_eol_f ) & ~(bus_ifu_wr_en_ff & last_beat) & ~dec_tlu_force_halt) ? HIT_U_MISS : IDLE ; miss_state_en = exu_flush_final | ifu_bp_hit_taken_q_f | stream_eol_f | (bus_ifu_wr_en_ff & last_beat) | dec_tlu_force_halt ; end MISS_WAIT: begin : miss_wait miss_nxtstate = (exu_flush_final & ~(bus_ifu_wr_en_ff & last_beat) & ~dec_tlu_force_halt) ? HIT_U_MISS : IDLE ; miss_state_en = exu_flush_final | (bus_ifu_wr_en_ff & last_beat) | dec_tlu_force_halt ; end HIT_U_MISS: begin : hit_u_miss miss_nxtstate = ic_miss_under_miss_f & ~(bus_ifu_wr_en_ff & last_beat) & ~dec_tlu_force_halt ? SCND_MISS : ic_ignore_2nd_miss_f & ~(bus_ifu_wr_en_ff & last_beat) & ~dec_tlu_force_halt ? STALL_SCND_MISS : IDLE ; miss_state_en = (bus_ifu_wr_en_ff & last_beat) | ic_miss_under_miss_f | ic_ignore_2nd_miss_f | dec_tlu_force_halt; end SCND_MISS: begin : scnd_miss miss_nxtstate = dec_tlu_force_halt ? IDLE : exu_flush_final ? ((bus_ifu_wr_en_ff & last_beat) ? IDLE : HIT_U_MISS) : CRIT_BYP_OK; miss_state_en = (bus_ifu_wr_en_ff & last_beat) | exu_flush_final | dec_tlu_force_halt; end STALL_SCND_MISS: begin : stall_scnd_miss miss_nxtstate = dec_tlu_force_halt ? IDLE : exu_flush_final ? ((bus_ifu_wr_en_ff & last_beat) ? IDLE : HIT_U_MISS) : IDLE; miss_state_en = (bus_ifu_wr_en_ff & last_beat) | exu_flush_final | dec_tlu_force_halt; end default: begin : def_case miss_nxtstate = IDLE; miss_state_en = 1'b0; end endcase end rvdffs #(($bits(miss_state_t))) miss_state_ff (.clk(free_clk), .din(miss_nxtstate), .dout({miss_state}), .en(miss_state_en), .*); logic sel_hold_imb ; assign miss_pending = (miss_state != IDLE) ; assign crit_wd_byp_ok_ff = (miss_state == CRIT_BYP_OK) | ((miss_state == CRIT_WRD_RDY) & ~flush_final_f); assign sel_hold_imb = (miss_pending & ~(bus_ifu_wr_en_ff & last_beat) & ~((miss_state == CRIT_WRD_RDY) & exu_flush_final) & ~((miss_state == CRIT_WRD_RDY) & crit_byp_hit_f) ) | ic_act_miss_f | (miss_pending & (miss_nxtstate == CRIT_WRD_RDY)) ; logic sel_hold_imb_scnd; logic [31:1] imb_scnd_in; logic [31:1] imb_scnd_ff; logic uncacheable_miss_scnd_in ; logic uncacheable_miss_scnd_ff ; logic [pt.ICACHE_NUM_WAYS-1:0] tagv_mb_scnd_in; logic [pt.ICACHE_NUM_WAYS-1:0] tagv_mb_scnd_ff; logic [pt.ICACHE_STATUS_BITS-1:0] way_status_mb_scnd_in; logic [pt.ICACHE_STATUS_BITS-1:0] way_status_mb_scnd_ff; assign sel_hold_imb_scnd =((miss_state == SCND_MISS) | ic_miss_under_miss_f) & ~flush_final_f ; assign way_status_mb_scnd_in[pt.ICACHE_STATUS_BITS-1:0] = (miss_state == SCND_MISS) ? way_status_mb_scnd_ff[pt.ICACHE_STATUS_BITS-1:0] : {way_status[pt.ICACHE_STATUS_BITS-1:0]} ; assign tagv_mb_scnd_in[pt.ICACHE_NUM_WAYS-1:0] = (miss_state == SCND_MISS) ? tagv_mb_scnd_ff[pt.ICACHE_NUM_WAYS-1:0] : ({ic_tag_valid[pt.ICACHE_NUM_WAYS-1:0]} & {pt.ICACHE_NUM_WAYS{~reset_all_tags}}); assign uncacheable_miss_scnd_in = sel_hold_imb_scnd ? uncacheable_miss_scnd_ff : ifc_fetch_uncacheable_bf ; rvdff #(1) unc_miss_scnd_ff (.*, .clk(fetch_bf_f_c1_clk), .din (uncacheable_miss_scnd_in), .dout(uncacheable_miss_scnd_ff)); rvdff #(31) imb_f_scnd_ff (.*, .clk(fetch_bf_f_c1_clk), .din ({imb_scnd_in[31:1]}), .dout({imb_scnd_ff[31:1]})); rvdff #(pt.ICACHE_STATUS_BITS) mb_rep_wayf2_scnd_ff (.*, .clk(fetch_bf_f_c1_clk), .din ({way_status_mb_scnd_in[pt.ICACHE_STATUS_BITS-1:0]}), .dout({way_status_mb_scnd_ff[pt.ICACHE_STATUS_BITS-1:0]})); rvdff #(pt.ICACHE_NUM_WAYS) mb_tagv_scnd_ff (.*, .clk(fetch_bf_f_c1_clk), .din ({tagv_mb_scnd_in[pt.ICACHE_NUM_WAYS-1:0]}), .dout({tagv_mb_scnd_ff[pt.ICACHE_NUM_WAYS-1:0]})); assign ic_req_addr_bits_hi_3[pt.ICACHE_BEAT_ADDR_HI:3] = bus_rd_addr_count[pt.ICACHE_BEAT_BITS-1:0] ; assign ic_wr_addr_bits_hi_3[pt.ICACHE_BEAT_ADDR_HI:3] = ifu_bus_rid_ff[pt.ICACHE_BEAT_BITS-1:0] & {pt.ICACHE_BEAT_BITS{bus_ifu_wr_en_ff}}; // NOTE: Cacheline size is 16 bytes in this example. // Tag Index Bank Offset // [31:16] [15:5] [4] [3:0] assign fetch_req_icache_f = ifc_fetch_req_f & ~ifc_iccm_access_f & ~ifc_region_acc_fault_final_f; assign fetch_req_iccm_f = ifc_fetch_req_f & ifc_iccm_access_f; assign ic_iccm_hit_f = fetch_req_iccm_f & (~miss_pending | (miss_state==HIT_U_MISS) | (miss_state==STREAM)); assign ic_byp_hit_f = (crit_byp_hit_f | stream_hit_f) & fetch_req_icache_f & miss_pending ; assign ic_act_hit_f = (|ic_rd_hit[pt.ICACHE_NUM_WAYS-1:0]) & fetch_req_icache_f & ~reset_all_tags & (~miss_pending | (miss_state==HIT_U_MISS)) & ~sel_mb_addr_ff; assign ic_act_miss_f = (((~(|ic_rd_hit[pt.ICACHE_NUM_WAYS-1:0]) | reset_all_tags) & fetch_req_icache_f & ~miss_pending) | scnd_miss_req) & ~ifc_region_acc_fault_final_f; assign ic_miss_under_miss_f = (~(|ic_rd_hit[pt.ICACHE_NUM_WAYS-1:0]) | reset_all_tags) & fetch_req_icache_f & (miss_state == HIT_U_MISS) & (imb_ff[31:pt.ICACHE_TAG_INDEX_LO] != ifu_fetch_addr_int_f[31:pt.ICACHE_TAG_INDEX_LO]) & ~uncacheable_miss_ff & ~sel_mb_addr_ff & ~ifc_region_acc_fault_final_f; assign ic_ignore_2nd_miss_f = (~(|ic_rd_hit[pt.ICACHE_NUM_WAYS-1:0]) | reset_all_tags) & fetch_req_icache_f & (miss_state == HIT_U_MISS) & ((imb_ff[31:pt.ICACHE_TAG_INDEX_LO] == ifu_fetch_addr_int_f[31:pt.ICACHE_TAG_INDEX_LO]) | uncacheable_miss_ff) ; assign ic_hit_f = ic_act_hit_f | ic_byp_hit_f | ic_iccm_hit_f | (ifc_region_acc_fault_final_f & ifc_fetch_req_f); assign uncacheable_miss_in = scnd_miss_req ? uncacheable_miss_scnd_ff : sel_hold_imb ? uncacheable_miss_ff : ifc_fetch_uncacheable_bf ; assign imb_in[31:1] = scnd_miss_req ? imb_scnd_ff[31:1] : sel_hold_imb ? imb_ff[31:1] : {ifc_fetch_addr_bf[31:1]} ; assign imb_scnd_in[31:1] = sel_hold_imb_scnd ? imb_scnd_ff[31:1] : {ifc_fetch_addr_bf[31:1]} ; assign scnd_miss_index_match = (imb_ff[pt.ICACHE_INDEX_HI:pt.ICACHE_TAG_INDEX_LO] == imb_scnd_ff[pt.ICACHE_INDEX_HI:pt.ICACHE_TAG_INDEX_LO]) & scnd_miss_req & ~ifu_wr_cumulative_err_data; assign way_status_mb_in[pt.ICACHE_STATUS_BITS-1:0] = (scnd_miss_req & ~scnd_miss_index_match) ? way_status_mb_scnd_ff[pt.ICACHE_STATUS_BITS-1:0] : (scnd_miss_req & scnd_miss_index_match) ? way_status_rep_new[pt.ICACHE_STATUS_BITS-1:0] : miss_pending ? way_status_mb_ff[pt.ICACHE_STATUS_BITS-1:0] : {way_status[pt.ICACHE_STATUS_BITS-1:0]} ; assign tagv_mb_in[pt.ICACHE_NUM_WAYS-1:0] = scnd_miss_req ? (tagv_mb_scnd_ff[pt.ICACHE_NUM_WAYS-1:0] | ({pt.ICACHE_NUM_WAYS {scnd_miss_index_match}} & replace_way_mb_any[pt.ICACHE_NUM_WAYS-1:0])) : miss_pending ? tagv_mb_ff[pt.ICACHE_NUM_WAYS-1:0] : ({ic_tag_valid[pt.ICACHE_NUM_WAYS-1:0]} & {pt.ICACHE_NUM_WAYS{~reset_all_tags}}) ; assign reset_ic_in = miss_pending & ~scnd_miss_req_q & (reset_all_tags | reset_ic_ff) ; rvdff #(1) reset_ic_f (.*, .clk(free_clk), .din (reset_ic_in), .dout(reset_ic_ff)); rvdff #(1) uncache_ff (.*, .clk(active_clk), .din (ifc_fetch_uncacheable_bf), .dout(fetch_uncacheable_ff)); rvdff #(31) ifu_fetch_addr_f_ff (.*, .clk (fetch_bf_f_c1_clk), .din ({ifc_fetch_addr_bf[31:1]}), .dout({ifu_fetch_addr_int_f[31:1]})); assign vaddr_f[pt.ICACHE_BEAT_ADDR_HI:1] = ifu_fetch_addr_int_f[pt.ICACHE_BEAT_ADDR_HI:1] ; rvdff #(1) unc_miss_ff (.*, .clk(fetch_bf_f_c1_clk), .din (uncacheable_miss_in), .dout(uncacheable_miss_ff)); rvdff #(31) imb_f_ff (.*, .clk(fetch_bf_f_c1_clk), .din ({imb_in[31:1]}), .dout({imb_ff[31:1]})); assign miss_addr_in[31:pt.ICACHE_BEAT_ADDR_HI+1] = (~miss_pending ) ? imb_ff[31:pt.ICACHE_BEAT_ADDR_HI+1] : ( scnd_miss_req_q ) ? imb_scnd_ff[31:pt.ICACHE_BEAT_ADDR_HI+1] : miss_addr[31:pt.ICACHE_BEAT_ADDR_HI+1] ; rvdff #(31-pt.ICACHE_BEAT_ADDR_HI) miss_f_ff (.*, .clk(busclk_reset), .din ({miss_addr_in[31:pt.ICACHE_BEAT_ADDR_HI+1]}), .dout({miss_addr[31:pt.ICACHE_BEAT_ADDR_HI+1]})); rvdff #(pt.ICACHE_STATUS_BITS) mb_rep_wayf2_ff (.*, .clk(fetch_bf_f_c1_clk), .din ({way_status_mb_in[pt.ICACHE_STATUS_BITS-1:0]}), .dout({way_status_mb_ff[pt.ICACHE_STATUS_BITS-1:0]})); rvdff #(pt.ICACHE_NUM_WAYS) mb_tagv_ff (.*, .clk(fetch_bf_f_c1_clk), .din ({tagv_mb_in[pt.ICACHE_NUM_WAYS-1:0]}), .dout({tagv_mb_ff[pt.ICACHE_NUM_WAYS-1:0]})); assign ifc_fetch_req_qual_bf = ifc_fetch_req_bf & ~((miss_state == CRIT_WRD_RDY) & flush_final_f) & ~stream_miss_f ;// & ~exu_flush_final ; rvdff #(1) fetch_req_f_ff (.*, .clk(active_clk), .din(ifc_fetch_req_qual_bf), .dout(ifc_fetch_req_f_raw)); assign ifc_fetch_req_f = ifc_fetch_req_f_raw & ~exu_flush_final ; rvdff #(1) ifu_iccm_acc_ff (.*, .clk(fetch_bf_f_c1_clk), .din(ifc_iccm_access_bf), .dout(ifc_iccm_access_f)); rvdff #(1) ifu_iccm_reg_acc_ff (.*, .clk(fetch_bf_f_c1_clk), .din(ifc_region_acc_fault_final_bf), .dout(ifc_region_acc_fault_final_f)); rvdff #(1) rgn_acc_ff (.*, .clk(fetch_bf_f_c1_clk), .din(ifc_region_acc_fault_bf), .dout(ifc_region_acc_fault_f)); assign ifu_ic_req_addr_f[31:3] = {miss_addr[31:pt.ICACHE_BEAT_ADDR_HI+1] , ic_req_addr_bits_hi_3[pt.ICACHE_BEAT_ADDR_HI:3] }; assign ifu_ic_mb_empty = (((miss_state == HIT_U_MISS) | (miss_state == STREAM)) & ~(bus_ifu_wr_en_ff & last_beat)) | ~miss_pending ; assign ifu_miss_state_idle = (miss_state == IDLE) ; assign sel_mb_addr = ((miss_pending & write_ic_16_bytes & ~uncacheable_miss_ff) | reset_tag_valid_for_miss) ; assign ifu_ic_rw_int_addr[31:1] = ({31{ sel_mb_addr}} & {imb_ff[31:pt.ICACHE_BEAT_ADDR_HI+1] , ic_wr_addr_bits_hi_3[pt.ICACHE_BEAT_ADDR_HI:3] , imb_ff[2:1]}) | ({31{~sel_mb_addr}} & ifc_fetch_addr_bf[31:1] ) ; assign sel_mb_status_addr = ((miss_pending & write_ic_16_bytes & ~uncacheable_miss_ff & last_beat & bus_ifu_wr_en_ff_q) | reset_tag_valid_for_miss) ; assign ifu_status_wr_addr[31:1] = ({31{ sel_mb_status_addr}} & {imb_ff[31:pt.ICACHE_BEAT_ADDR_HI+1] , ic_wr_addr_bits_hi_3[pt.ICACHE_BEAT_ADDR_HI:3] , imb_ff[2:1]}) | ({31{~sel_mb_status_addr}} & ifu_fetch_addr_int_f[31:1] ) ; assign ic_rw_addr[31:1] = ifu_ic_rw_int_addr[31:1] ; rvdff #(1) sel_mb_ff (.*, .clk(free_clk), .din (sel_mb_addr), .dout(sel_mb_addr_ff)); if (pt.ICACHE_ECC == 1) begin: icache_ecc_1 logic [6:0] ic_wr_ecc; logic [6:0] ic_miss_buff_ecc; logic [141:0] ic_wr_16bytes_data ; logic [70:0] ifu_ic_debug_rd_data_in ; rvecc_encode_64 ic_ecc_encode_64_bus ( .din (ifu_bus_rdata_ff[63:0]), .ecc_out(ic_wr_ecc[6:0])); rvecc_encode_64 ic_ecc_encode_64_buff ( .din (ic_miss_buff_half[63:0]), .ecc_out(ic_miss_buff_ecc[6:0])); for (genvar i=0; i < 32'(pt.ICACHE_BANKS_WAY) ; i++) begin : ic_wr_data_loop assign ic_wr_data[i][70:0] = ic_wr_16bytes_data[((71*i)+70): (71*i)]; end assign ic_debug_wr_data[70:0] = {dec_tlu_ic_diag_pkt.icache_wrdata[70:0]} ; assign ic_error_start = ((|ic_eccerr[pt.ICACHE_BANKS_WAY-1:0]) & ic_act_hit_f) | ic_rd_parity_final_err; assign ifu_ic_debug_rd_data_in[70:0] = ic_debug_ict_array_sel_ff ? {2'b0,ictag_debug_rd_data[25:21],32'b0,ictag_debug_rd_data[20:0],{7-pt.ICACHE_STATUS_BITS{1'b0}}, way_status[pt.ICACHE_STATUS_BITS-1:0],3'b0,ic_debug_tag_val_rd_out} : ic_debug_rd_data[70:0]; rvdff #(71) ifu_debug_data_ff (.*, .clk (debug_data_clk), .din ({ ifu_ic_debug_rd_data_in[70:0] }), .dout({ ifu_ic_debug_rd_data[70:0] })); assign ic_wr_16bytes_data[141:0] = ifu_bus_rid_ff[0] ? {ic_wr_ecc[6:0] , ifu_bus_rdata_ff[63:0] , ic_miss_buff_ecc[6:0] , ic_miss_buff_half[63:0] } : {ic_miss_buff_ecc[6:0] , ic_miss_buff_half[63:0] , ic_wr_ecc[6:0] , ifu_bus_rdata_ff[63:0] } ; end else begin : icache_parity_1 logic [3:0] ic_wr_parity; logic [3:0] ic_miss_buff_parity; logic [135:0] ic_wr_16bytes_data ; logic [70:0] ifu_ic_debug_rd_data_in ; for (genvar i=0 ; i < 4 ; i++) begin : DATA_PGEN rveven_paritygen #(16) par_bus (.data_in (ifu_bus_rdata_ff[((16*i)+15):(16*i)]), .parity_out(ic_wr_parity[i])); rveven_paritygen #(16) par_buff (.data_in (ic_miss_buff_half[((16*i)+15):(16*i)]), .parity_out(ic_miss_buff_parity[i])); end for (genvar i=0; i < pt.ICACHE_BANKS_WAY ; i++) begin : ic_wr_data_loop assign ic_wr_data[i][67:0] = ic_wr_16bytes_data[((68*i)+67): (68*i)]; end assign ic_debug_wr_data[70:0] = {dec_tlu_ic_diag_pkt.icache_wrdata[70:0]} ; assign ic_error_start = ((|ic_parerr[pt.ICACHE_BANKS_WAY-1:0]) & ic_act_hit_f) | ic_rd_parity_final_err; assign ifu_ic_debug_rd_data_in[70:0] = ic_debug_ict_array_sel_ff ? {6'b0,ictag_debug_rd_data[21],32'b0,ictag_debug_rd_data[20:0],{7-pt.ICACHE_STATUS_BITS{1'b0}},way_status[pt.ICACHE_STATUS_BITS-1:0],3'b0,ic_debug_tag_val_rd_out} : ic_debug_rd_data[70:0] ; rvdff #(71) ifu_debug_data_ff (.*, .clk (debug_data_clk), .din ({ ifu_ic_debug_rd_data_in[70:0] }), .dout({ ifu_ic_debug_rd_data[70:0] })); assign ic_wr_16bytes_data[135:0] = ifu_bus_rid_ff[0] ? {ic_wr_parity[3:0] , ifu_bus_rdata_ff[63:0] , ic_miss_buff_parity[3:0] , ic_miss_buff_half[63:0] } : {ic_miss_buff_parity[3:0] , ic_miss_buff_half[63:0] , ic_wr_parity[3:0] , ifu_bus_rdata_ff[63:0] } ; end assign ifu_wr_data_comb_err = bus_ifu_wr_data_error_ff ; assign ifu_wr_cumulative_err = (ifu_wr_data_comb_err | ifu_wr_data_comb_err_ff) & ~reset_beat_cnt; assign ifu_wr_cumulative_err_data = ifu_wr_data_comb_err | ifu_wr_data_comb_err_ff ; rvdff #(1) cumul_err_ff (.*, .clk(free_clk), .din (ifu_wr_cumulative_err), .dout(ifu_wr_data_comb_err_ff)); assign sel_byp_data = (ic_crit_wd_rdy | (miss_state == STREAM) | (miss_state == CRIT_BYP_OK)) & ~ifu_byp_data_err_new; assign sel_ic_data = ~(ic_crit_wd_rdy | (miss_state == STREAM) | (miss_state == CRIT_BYP_OK)) & ~fetch_req_iccm_f ; if (pt.ICCM_ICACHE==1) begin: iccm_icache assign sel_iccm_data = fetch_req_iccm_f ; assign ic_final_data[63:0] = ({64{sel_byp_data | sel_iccm_data | sel_ic_data}} & {ic_rd_data[63:0]} ) ; assign ic_premux_data[63:0] = ({64{sel_byp_data }} & {ic_byp_data_only_new[63:0]} ) | ({64{sel_iccm_data}} & {iccm_rd_data[63:0]}); assign ic_sel_premux_data = sel_iccm_data | sel_byp_data ; end if (pt.ICCM_ONLY == 1 ) begin: iccm_only assign sel_iccm_data = fetch_req_iccm_f ; assign ic_final_data[63:0] = ({64{sel_byp_data }} & {ic_byp_data_only_new[63:0]} ) | ({64{sel_iccm_data}} & {iccm_rd_data[63:0]}); assign ic_premux_data = '0 ; assign ic_sel_premux_data = '0 ; end if (pt.ICACHE_ONLY == 1 ) begin: icache_only assign ic_final_data[63:0] = ({64{sel_byp_data | sel_ic_data}} & {ic_rd_data[63:0]} ) ; assign ic_premux_data[63:0] = ({64{sel_byp_data }} & {ic_byp_data_only_new[63:0]} ) ; assign ic_sel_premux_data = sel_byp_data ; end if (pt.NO_ICCM_NO_ICACHE == 1 ) begin: no_iccm_no_icache assign ic_final_data[63:0] = ({64{sel_byp_data }} & {ic_byp_data_only_new[63:0]} ) ; assign ic_premux_data = 0 ; assign ic_sel_premux_data = '0 ; end assign ifc_bus_acc_fault_f = ic_byp_hit_f & ifu_byp_data_err_new ; assign ic_data_f[31:0] = ic_final_data[31:0]; rvdff #(1) flush_final_ff (.*, .clk(free_clk), .din({exu_flush_final}), .dout({flush_final_f})); assign fetch_req_f_qual = ic_hit_f & ~exu_flush_final; assign ic_access_fault_f = (ifc_region_acc_fault_final_f | ifc_bus_acc_fault_f) & ~exu_flush_final; assign ic_access_fault_type_f[1:0] = iccm_rd_ecc_double_err ? 2'b01 : ifc_region_acc_fault_f ? 2'b10 : ifc_region_acc_fault_memory_f ? 2'b11 : 2'b00 ; // right justified assign ic_fetch_val_f[1] = fetch_req_f_qual & ifu_bp_inst_mask_f & ~(vaddr_f[pt.ICACHE_BEAT_ADDR_HI:1] == {pt.ICACHE_BEAT_ADDR_HI{1'b1}}) & (err_stop_state != ERR_FETCH2); assign ic_fetch_val_f[0] = fetch_req_f_qual ; assign two_byte_instr = (ic_data_f[1:0] != 2'b11 ) ; ///////////////////////////////////////////////////////////////////////////////////// // Create full buffer... // ///////////////////////////////////////////////////////////////////////////////////// logic [63:0] ic_miss_buff_data_in; assign ic_miss_buff_data_in[63:0] = ifu_bus_rsp_rdata[63:0]; for (genvar i=0; i<32'(pt.ICACHE_NUM_BEATS); i++) begin : wr_flop assign write_fill_data[i] = bus_ifu_wr_en & ( (pt.IFU_BUS_TAG)'(i) == ifu_bus_rsp_tag[pt.IFU_BUS_TAG-1:0]); rvclkhdr data_c1_cgc ( .en(write_fill_data[i]), .l1clk(wr_data_c1_clk[i]), .* ); rvdff #(32) byp_data_0_ff (.*, .clk (wr_data_c1_clk[i]), .din (ic_miss_buff_data_in[31:0]), .dout(ic_miss_buff_data[i*2][31:0])); rvdff #(32) byp_data_1_ff (.*, .clk (wr_data_c1_clk[i]), .din (ic_miss_buff_data_in[63:32]), .dout(ic_miss_buff_data[i*2+1][31:0])); assign ic_miss_buff_data_valid_in[i] = write_fill_data[i] ? 1'b1 : (ic_miss_buff_data_valid[i] & ~ic_act_miss_f) ; rvdff #(1) byp_data_valid_ff (.*, .clk (free_clk), .din (ic_miss_buff_data_valid_in[i]), .dout(ic_miss_buff_data_valid[i])); assign ic_miss_buff_data_error_in[i] = write_fill_data[i] ? bus_ifu_wr_data_error : (ic_miss_buff_data_error[i] & ~ic_act_miss_f) ; rvdff #(1) byp_data_error_ff (.*, .clk (free_clk), .din (ic_miss_buff_data_error_in[i] ), .dout(ic_miss_buff_data_error[i])); end ///////////////////////////////////////////////////////////////////////////////////// // New bypass ready // ///////////////////////////////////////////////////////////////////////////////////// logic [pt.ICACHE_BEAT_ADDR_HI:1] bypass_index; logic [pt.ICACHE_BEAT_ADDR_HI:3] bypass_index_5_3_inc; logic bypass_data_ready_in; logic ic_crit_wd_rdy_new_in; assign bypass_index[pt.ICACHE_BEAT_ADDR_HI:1] = imb_ff[pt.ICACHE_BEAT_ADDR_HI:1] ; assign bypass_index_5_3_inc[pt.ICACHE_BEAT_ADDR_HI:3] = bypass_index[pt.ICACHE_BEAT_ADDR_HI:3] + 1 ; assign bypass_data_ready_in = ((ic_miss_buff_data_valid_in[bypass_index[pt.ICACHE_BEAT_ADDR_HI:3]] & ~bypass_index[2] & ~bypass_index[1])) | ((ic_miss_buff_data_valid_in[bypass_index[pt.ICACHE_BEAT_ADDR_HI:3]] & ~bypass_index[2] & bypass_index[1])) | ((ic_miss_buff_data_valid_in[bypass_index[pt.ICACHE_BEAT_ADDR_HI:3]] & bypass_index[2] & ~bypass_index[1])) | ((ic_miss_buff_data_valid_in[bypass_index[pt.ICACHE_BEAT_ADDR_HI:3]] & ic_miss_buff_data_valid_in[bypass_index_5_3_inc[pt.ICACHE_BEAT_ADDR_HI:3]] & bypass_index[2] & bypass_index[1])) | ((ic_miss_buff_data_valid_in[bypass_index[pt.ICACHE_BEAT_ADDR_HI:3]] & (bypass_index[pt.ICACHE_BEAT_ADDR_HI:3] == {pt.ICACHE_BEAT_ADDR_HI{1'b1}}))) ; assign ic_crit_wd_rdy_new_in = ( bypass_data_ready_in & crit_wd_byp_ok_ff & uncacheable_miss_ff & ~exu_flush_final & ~ifu_bp_hit_taken_q_f) | ( crit_wd_byp_ok_ff & ~uncacheable_miss_ff & ~exu_flush_final & ~ifu_bp_hit_taken_q_f) | (ic_crit_wd_rdy_new_ff & ~fetch_req_icache_f & crit_wd_byp_ok_ff & ~exu_flush_final) ; rvdff #(1) crit_wd_new_ff (.*, .clk(free_clk), .din(ic_crit_wd_rdy_new_in), .dout(ic_crit_wd_rdy_new_ff)); assign byp_fetch_index[pt.ICACHE_BEAT_ADDR_HI:1] = ifu_fetch_addr_int_f[pt.ICACHE_BEAT_ADDR_HI:1] ; assign byp_fetch_index_0[pt.ICACHE_BEAT_ADDR_HI:2] = {ifu_fetch_addr_int_f[pt.ICACHE_BEAT_ADDR_HI:3],1'b0} ; assign byp_fetch_index_1[pt.ICACHE_BEAT_ADDR_HI:2] = {ifu_fetch_addr_int_f[pt.ICACHE_BEAT_ADDR_HI:3],1'b1} ; assign byp_fetch_index_inc[pt.ICACHE_BEAT_ADDR_HI:3] = ifu_fetch_addr_int_f[pt.ICACHE_BEAT_ADDR_HI:3]+1'b1 ; assign byp_fetch_index_inc_0[pt.ICACHE_BEAT_ADDR_HI:2] = {byp_fetch_index_inc[pt.ICACHE_BEAT_ADDR_HI:3], 1'b0} ; assign byp_fetch_index_inc_1[pt.ICACHE_BEAT_ADDR_HI:2] = {byp_fetch_index_inc[pt.ICACHE_BEAT_ADDR_HI:3], 1'b1} ; assign ifu_byp_data_err_new = (~ifu_fetch_addr_int_f[2] & ~ifu_fetch_addr_int_f[1] & ic_miss_buff_data_error[byp_fetch_index[pt.ICACHE_BEAT_ADDR_HI:3]] ) | (~ifu_fetch_addr_int_f[2] & ifu_fetch_addr_int_f[1] & ic_miss_buff_data_error[byp_fetch_index[pt.ICACHE_BEAT_ADDR_HI:3]] ) | ( ifu_fetch_addr_int_f[2] & ~ifu_fetch_addr_int_f[1] & ic_miss_buff_data_error[byp_fetch_index[pt.ICACHE_BEAT_ADDR_HI:3]] ) | ( ifu_fetch_addr_int_f[2] & ifu_fetch_addr_int_f[1] & (ic_miss_buff_data_error[byp_fetch_index_inc[pt.ICACHE_BEAT_ADDR_HI:3]] | ic_miss_buff_data_error[byp_fetch_index[pt.ICACHE_BEAT_ADDR_HI:3]] )) ; assign ic_byp_data_only_pre_new[79:0] = ({80{~ifu_fetch_addr_int_f[2]}} & {ic_miss_buff_data[byp_fetch_index_inc_0][15:0],ic_miss_buff_data[byp_fetch_index_1][31:0] , ic_miss_buff_data[byp_fetch_index_0][31:0]}) | ({80{ ifu_fetch_addr_int_f[2]}} & {ic_miss_buff_data[byp_fetch_index_inc_1][15:0],ic_miss_buff_data[byp_fetch_index_inc_0][31:0] , ic_miss_buff_data[byp_fetch_index_1][31:0]}) ; assign ic_byp_data_only_new[79:0] = ~ifu_fetch_addr_int_f[1] ? {ic_byp_data_only_pre_new[79:0]} : {16'b0,ic_byp_data_only_pre_new[79:16]} ; assign miss_wrap_f = (imb_ff[pt.ICACHE_TAG_INDEX_LO] != ifu_fetch_addr_int_f[pt.ICACHE_TAG_INDEX_LO] ) ; assign miss_buff_hit_unq_f = ((ic_miss_buff_data_valid[byp_fetch_index[pt.ICACHE_BEAT_ADDR_HI:3]] & ~byp_fetch_index[2] & ~byp_fetch_index[1])) | ((ic_miss_buff_data_valid[byp_fetch_index[pt.ICACHE_BEAT_ADDR_HI:3]] & ~byp_fetch_index[2] & byp_fetch_index[1])) | ((ic_miss_buff_data_valid[byp_fetch_index[pt.ICACHE_BEAT_ADDR_HI:3]] & byp_fetch_index[2] & ~byp_fetch_index[1])) | ((ic_miss_buff_data_valid[byp_fetch_index[pt.ICACHE_BEAT_ADDR_HI:3]] & ic_miss_buff_data_valid[byp_fetch_index_inc[pt.ICACHE_BEAT_ADDR_HI:3]] & byp_fetch_index[2] & byp_fetch_index[1])) | ((ic_miss_buff_data_valid[byp_fetch_index[pt.ICACHE_BEAT_ADDR_HI:3]] & (byp_fetch_index[pt.ICACHE_BEAT_ADDR_HI:3] == {pt.ICACHE_BEAT_BITS{1'b1}}))) ; assign stream_hit_f = (miss_buff_hit_unq_f & ~miss_wrap_f ) & (miss_state==STREAM) ; assign stream_miss_f = ~(miss_buff_hit_unq_f & ~miss_wrap_f ) & (miss_state==STREAM) & ifc_fetch_req_f; assign stream_eol_f = (byp_fetch_index[pt.ICACHE_BEAT_ADDR_HI:2] == {pt.ICACHE_BEAT_BITS+1{1'b1}}) & ifc_fetch_req_f & stream_hit_f; assign crit_byp_hit_f = (miss_buff_hit_unq_f ) & ((miss_state == CRIT_WRD_RDY) | (miss_state==CRIT_BYP_OK)) ; ///////////////////////////////////////////////////////////////////////////////////// // Figure out if you have the data to write. // ///////////////////////////////////////////////////////////////////////////////////// assign other_tag[pt.IFU_BUS_TAG-1:0] = {ifu_bus_rid_ff[pt.IFU_BUS_TAG-1:1] , ~ifu_bus_rid_ff[0] } ; assign second_half_available = ic_miss_buff_data_valid[other_tag] ; assign write_ic_16_bytes = second_half_available & bus_ifu_wr_en_ff ; assign ic_miss_buff_half[63:0] = {ic_miss_buff_data[{other_tag,1'b1}],ic_miss_buff_data[{other_tag,1'b0}] } ; ///////////////////////////////////////////////////////////////////////////////////// // Parity checking logic for Icache logic. // ///////////////////////////////////////////////////////////////////////////////////// assign ic_rd_parity_final_err = ic_tag_perr & sel_ic_data & ~(ifc_region_acc_fault_final_f | ifc_bus_acc_fault_f) ; logic [pt.ICACHE_NUM_WAYS-1:0] perr_err_inv_way; logic [pt.ICACHE_INDEX_HI:pt.ICACHE_TAG_INDEX_LO] perr_ic_index_ff; logic perr_sel_invalidate; logic perr_sb_write_status ; rvdffs #(pt.ICACHE_INDEX_HI-pt.ICACHE_TAG_INDEX_LO+1) perr_dat_ff (.clk(active_clk), .din(ifu_ic_rw_int_addr_ff[pt.ICACHE_INDEX_HI:pt.ICACHE_TAG_INDEX_LO]), .dout(perr_ic_index_ff[pt.ICACHE_INDEX_HI : pt.ICACHE_TAG_INDEX_LO]), .en(perr_sb_write_status), .*); assign perr_err_inv_way[pt.ICACHE_NUM_WAYS-1:0] = {pt.ICACHE_NUM_WAYS{perr_sel_invalidate}} ; assign iccm_correct_ecc = (perr_state == ECC_CORR); assign dma_sb_err_state = (perr_state == DMA_SB_ERR); assign iccm_buf_correct_ecc = iccm_correct_ecc & ~dma_sb_err_state_ff; rvdff #((1)) dma_sb_err_ff (.clk(active_clk), .din(dma_sb_err_state), .dout(dma_sb_err_state_ff), .*); //////////////////////////////////// Create Parity Error State Machine /////////////////////// // Create Parity Error State Machine // // Create Parity Error State Machine // // Create Parity Error State Machine // //////////////////////////////////// Create Parity Error State Machine /////////////////////// // FIFO state machine always_comb begin : ERROR_SM perr_nxtstate = ERR_IDLE; perr_state_en = 1'b0; perr_sb_write_status = 1'b0; perr_sel_invalidate = 1'b0; case (perr_state) ERR_IDLE: begin : err_idle perr_nxtstate = iccm_dma_sb_error ? DMA_SB_ERR : (ic_error_start & ~exu_flush_final) ? IC_WFF : ECC_WFF; perr_state_en = (((iccm_error_start | ic_error_start) & ~exu_flush_final) | iccm_dma_sb_error) & ~dec_tlu_force_halt; perr_sb_write_status = perr_state_en; end IC_WFF: begin : icache_wff // All the I$ data and/or Tag errors ( parity/ECC ) will come to this state perr_nxtstate = ERR_IDLE ; perr_state_en = dec_tlu_flush_lower_wb | dec_tlu_force_halt ; perr_sel_invalidate = (dec_tlu_flush_err_wb & dec_tlu_flush_lower_wb); end ECC_WFF: begin : ecc_wff perr_nxtstate = ((~dec_tlu_flush_err_wb & dec_tlu_flush_lower_wb ) | dec_tlu_force_halt) ? ERR_IDLE : ECC_CORR ; perr_state_en = dec_tlu_flush_lower_wb | dec_tlu_force_halt ; end DMA_SB_ERR : begin : dma_sb_ecc perr_nxtstate = dec_tlu_force_halt ? ERR_IDLE : ECC_CORR; perr_state_en = 1'b1; end ECC_CORR: begin : ecc_corr perr_nxtstate = ERR_IDLE ; perr_state_en = 1'b1 ; end default: begin : def_case perr_nxtstate = ERR_IDLE; perr_state_en = 1'b0; perr_sb_write_status = 1'b0; perr_sel_invalidate = 1'b0; end endcase end rvdffs #(($bits(perr_state_t))) perr_state_ff (.clk(free_clk), .din(perr_nxtstate), .dout({perr_state}), .en(perr_state_en), .*); //////////////////////////////////// Create stop fetch State Machine ///////////////////////// //////////////////////////////////// Create stop fetch State Machine ///////////////////////// //////////////////////////////////// Create stop fetch State Machine ///////////////////////// //////////////////////////////////// Create stop fetch State Machine ///////////////////////// //////////////////////////////////// Create stop fetch State Machine ///////////////////////// always_comb begin : ERROR_STOP_FETCH err_stop_nxtstate = ERR_STOP_IDLE; err_stop_state_en = 1'b0; err_stop_fetch = 1'b0; iccm_correction_state = 1'b0; case (err_stop_state) ERR_STOP_IDLE: begin : err_stop_idle err_stop_nxtstate = ERR_FETCH1; err_stop_state_en = dec_tlu_flush_err_wb & (perr_state == ECC_WFF) & ~dec_tlu_force_halt; end ERR_FETCH1: begin : err_fetch1 // All the I$ data and/or Tag errors ( parity/ECC ) will come to this state err_stop_nxtstate = (dec_tlu_flush_lower_wb | dec_tlu_i0_commit_cmt | dec_tlu_force_halt) ? ERR_STOP_IDLE : ((ifu_fetch_val[1:0] == 2'b11) | (ifu_fetch_val[0] & two_byte_instr)) ? ERR_STOP_FETCH : ifu_fetch_val[0] ? ERR_FETCH2 : ERR_FETCH1; err_stop_state_en = dec_tlu_flush_lower_wb | dec_tlu_i0_commit_cmt | ifu_fetch_val[0] | ifu_bp_hit_taken_q_f | dec_tlu_force_halt; err_stop_fetch = ((ifu_fetch_val[1:0] == 2'b11) | (ifu_fetch_val[0] & two_byte_instr)) & ~(exu_flush_final | dec_tlu_i0_commit_cmt); iccm_correction_state = 1'b1; end ERR_FETCH2: begin : err_fetch2 // All the I$ data and/or Tag errors ( parity/ECC ) will come to this state err_stop_nxtstate = (dec_tlu_flush_lower_wb | dec_tlu_i0_commit_cmt | dec_tlu_force_halt) ? ERR_STOP_IDLE : ifu_fetch_val[0] ? ERR_STOP_FETCH : ERR_FETCH2; err_stop_state_en = dec_tlu_flush_lower_wb | dec_tlu_i0_commit_cmt | ifu_fetch_val[0] | dec_tlu_force_halt ; err_stop_fetch = ifu_fetch_val[0] & ~exu_flush_final & ~dec_tlu_i0_commit_cmt ; iccm_correction_state = 1'b1; end ERR_STOP_FETCH: begin : ecc_wff err_stop_nxtstate = ( (dec_tlu_flush_lower_wb & ~dec_tlu_flush_err_wb) | dec_tlu_i0_commit_cmt | dec_tlu_force_halt) ? ERR_STOP_IDLE : dec_tlu_flush_err_wb ? ERR_FETCH1 : ERR_STOP_FETCH ; err_stop_state_en = dec_tlu_flush_lower_wb | dec_tlu_i0_commit_cmt | dec_tlu_force_halt ; err_stop_fetch = 1'b1; iccm_correction_state = 1'b1; end default: begin : def_case err_stop_nxtstate = ERR_STOP_IDLE; err_stop_state_en = 1'b0; err_stop_fetch = 1'b0 ; iccm_correction_state = 1'b1; end endcase end rvdffs #(($bits(err_stop_state_t))) err_stop_state_ff (.clk(free_clk), .din(err_stop_nxtstate), .dout({err_stop_state}), .en(err_stop_state_en), .*); assign bus_ifu_bus_clk_en = ifu_bus_clk_en ; rvclkhdr bus_clk_f(.en(bus_ifu_bus_clk_en), .l1clk(busclk), .*); rvclkhdr bus_clk(.en(bus_ifu_bus_clk_en | dec_tlu_force_halt), .l1clk(busclk_force), .*); rvdff #(1) bus_clken_ff (.*, .clk(free_clk), .din(bus_ifu_bus_clk_en), .dout(bus_ifu_bus_clk_en_ff)); rvdff #(1) scnd_mss_req_ff (.*, .clk(free_clk), .din(scnd_miss_req_in), .dout(scnd_miss_req_q)); rvdff #(1) scnd_mss_req_ff2 (.*, .clk(free_clk), .din(scnd_miss_req), .dout(scnd_miss_req_ff2)); assign scnd_miss_req = scnd_miss_req_q & ~exu_flush_final; assign ifc_bus_ic_req_ff_in = (ic_act_miss_f | bus_cmd_req_hold | ifu_bus_cmd_valid) & ~dec_tlu_force_halt & ~((bus_cmd_beat_count== {pt.ICACHE_BEAT_BITS{1'b1}}) & ifu_bus_cmd_valid & ifu_bus_cmd_ready & miss_pending); rvdff #(1) bus_ic_req_ff2(.*, .clk(busclk_force), .din(ifc_bus_ic_req_ff_in), .dout(ifu_bus_cmd_valid)); assign bus_cmd_req_in = (ic_act_miss_f | bus_cmd_req_hold) & ~bus_cmd_sent & ~dec_tlu_force_halt ; // hold until first command sent // changes for making the bus blocking rvdff #(1) bus_cmd_req_ff (.*, .clk(free_clk), .din(bus_cmd_req_in), .dout(bus_cmd_req_hold)); // AXI command signals // Read Channel assign ifu_axi_arvalid = ifu_bus_cmd_valid ; assign ifu_axi_arid[pt.IFU_BUS_TAG-1:0] = ((pt.IFU_BUS_TAG)'(bus_rd_addr_count[pt.ICACHE_BEAT_BITS-1:0])) & {pt.IFU_BUS_TAG{ifu_bus_cmd_valid}}; assign ifu_axi_araddr[31:0] = {ifu_ic_req_addr_f[31:3],3'b0} & {32{ifu_bus_cmd_valid}}; assign ifu_axi_arsize[2:0] = 3'b011; assign ifu_axi_arprot[2:0] = '0; assign ifu_axi_arcache[3:0] = 4'b1111; assign ifu_axi_arregion[3:0] = ifu_ic_req_addr_f[31:28]; assign ifu_axi_arlen[7:0] = '0; assign ifu_axi_arburst[1:0] = 2'b01; assign ifu_axi_arqos[3:0] = '0; assign ifu_axi_arlock = '0; assign ifu_axi_rready = 1'b1; // Write Channel assign ifu_axi_awvalid = '0 ; assign ifu_axi_awid[pt.IFU_BUS_TAG-1:0] = '0 ; assign ifu_axi_awaddr[31:0] = '0 ; assign ifu_axi_awsize[2:0] = '0 ; assign ifu_axi_awprot[2:0] = '0; assign ifu_axi_awcache[3:0] = '0 ; assign ifu_axi_awregion[3:0] = '0 ; assign ifu_axi_awlen[7:0] = '0; assign ifu_axi_awburst[1:0] = '0 ; assign ifu_axi_awqos[3:0] = '0; assign ifu_axi_awlock = '0; assign ifu_axi_wvalid = '0; assign ifu_axi_wstrb[7:0] = '0; assign ifu_axi_wdata[63:0] = '0; assign ifu_axi_wlast = '0; assign ifu_axi_bready = '0; assign ifu_bus_arready_unq = ifu_axi_arready ; assign ifu_bus_rvalid_unq = ifu_axi_rvalid ; assign ifu_bus_arvalid = ifu_axi_arvalid ; rvdff #(1) bus_rdy_ff (.*, .clk(busclk), .din(ifu_bus_arready_unq), .dout(ifu_bus_arready_unq_ff)); rvdff #(1) bus_rsp_vld_ff (.*, .clk(busclk), .din(ifu_bus_rvalid_unq), .dout(ifu_bus_rvalid_unq_ff)); rvdff #(1) bus_cmd_ff (.*, .clk(busclk), .din(ifu_bus_arvalid), .dout(ifu_bus_arvalid_ff)); rvdff #(2) bus_rsp_cmd_ff (.*, .clk(busclk), .din(ifu_axi_rresp[1:0]), .dout(ifu_bus_rresp_ff[1:0])); rvdff #(64) bus_data_ff (.*, .clk(busclk), .din(ifu_axi_rdata[63:0]), .dout(ifu_bus_rdata_ff[63:0])); rvdff #(pt.IFU_BUS_TAG) bus_rsp_tag_ff (.*, .clk(busclk), .din(ifu_axi_rid[pt.IFU_BUS_TAG-1:0]),.dout(ifu_bus_rid_ff[pt.IFU_BUS_TAG-1:0])); assign ifu_bus_cmd_ready = ifu_axi_arready ; assign ifu_bus_rsp_valid = ifu_axi_rvalid ; assign ifu_bus_rsp_ready = ifu_axi_rready ; assign ifu_bus_rsp_tag[pt.IFU_BUS_TAG-1:0] = ifu_axi_rid[pt.IFU_BUS_TAG-1:0] ; assign ifu_bus_rsp_rdata[63:0] = ifu_axi_rdata[63:0] ; assign ifu_bus_rsp_opc[1:0] = {ifu_axi_rresp[1:0]} ; // Create write signals so we can write to the miss-buffer directly from // the bus. assign ifu_bus_rvalid = ifu_bus_rsp_valid & bus_ifu_bus_clk_en ; assign ifu_bus_arready = ifu_bus_arready_unq & bus_ifu_bus_clk_en ; assign ifu_bus_arready_ff = ifu_bus_arready_unq_ff & bus_ifu_bus_clk_en_ff ; assign ifu_bus_rvalid_ff = ifu_bus_rvalid_unq_ff & bus_ifu_bus_clk_en_ff ; assign bus_cmd_sent = ifu_bus_arvalid & ifu_bus_arready & miss_pending & ~dec_tlu_force_halt; assign bus_inc_data_beat_cnt = (bus_ifu_wr_en_ff & ~bus_last_data_beat & ~dec_tlu_force_halt) ; assign bus_reset_data_beat_cnt = ic_act_miss_f | (bus_ifu_wr_en_ff & bus_last_data_beat) | dec_tlu_force_halt; assign bus_hold_data_beat_cnt = ~bus_inc_data_beat_cnt & ~bus_reset_data_beat_cnt ; assign bus_new_data_beat_count[pt.ICACHE_BEAT_BITS-1:0] = ({pt.ICACHE_BEAT_BITS{bus_reset_data_beat_cnt}} & (pt.ICACHE_BEAT_BITS)'(0)) | ({pt.ICACHE_BEAT_BITS{bus_inc_data_beat_cnt}} & (bus_data_beat_count[pt.ICACHE_BEAT_BITS-1:0] + {{pt.ICACHE_BEAT_BITS-1{1'b0}},1'b1})) | ({pt.ICACHE_BEAT_BITS{bus_hold_data_beat_cnt}} & bus_data_beat_count[pt.ICACHE_BEAT_BITS-1:0]); rvdff #(pt.ICACHE_BEAT_BITS) bus_mb_beat_count_ff (.*, .clk(free_clk), .din ({bus_new_data_beat_count[pt.ICACHE_BEAT_BITS-1:0]}), .dout({bus_data_beat_count[pt.ICACHE_BEAT_BITS-1:0]})); assign last_data_recieved_in = (bus_ifu_wr_en_ff & bus_last_data_beat & ~scnd_miss_req) | (last_data_recieved_ff & ~ic_act_miss_f) ; rvdff #(1) last_beat_ff (.*, .clk(free_clk), .din (last_data_recieved_in), .dout(last_data_recieved_ff)); // Request Address Count assign bus_new_rd_addr_count[pt.ICACHE_BEAT_BITS-1:0] = (~miss_pending ) ? imb_ff[pt.ICACHE_BEAT_ADDR_HI:3] : ( scnd_miss_req_q ) ? imb_scnd_ff[pt.ICACHE_BEAT_ADDR_HI:3] : ( bus_cmd_sent ) ? (bus_rd_addr_count[pt.ICACHE_BEAT_BITS-1:0] + 3'b001) : bus_rd_addr_count[pt.ICACHE_BEAT_BITS-1:0]; rvdff #(pt.ICACHE_BEAT_BITS) bus_rd_addr_ff (.*, .clk(busclk_reset), .din ({bus_new_rd_addr_count[pt.ICACHE_BEAT_BITS-1:0]}), .dout({bus_rd_addr_count[pt.ICACHE_BEAT_BITS-1:0]})); // command beat Count assign bus_inc_cmd_beat_cnt = ifu_bus_cmd_valid & ifu_bus_cmd_ready & miss_pending & ~dec_tlu_force_halt; assign bus_reset_cmd_beat_cnt_0 = (ic_act_miss_f & ~uncacheable_miss_in) | dec_tlu_force_halt ; assign bus_reset_cmd_beat_cnt_secondlast = ic_act_miss_f & uncacheable_miss_in ; assign bus_hold_cmd_beat_cnt = ~bus_inc_cmd_beat_cnt & ~(ic_act_miss_f | scnd_miss_req | dec_tlu_force_halt) ; assign bus_cmd_beat_en = bus_inc_cmd_beat_cnt | ic_act_miss_f | dec_tlu_force_halt; assign bus_new_cmd_beat_count[pt.ICACHE_BEAT_BITS-1:0] = ({pt.ICACHE_BEAT_BITS{bus_reset_cmd_beat_cnt_0}} & (pt.ICACHE_BEAT_BITS)'(0) ) | ({pt.ICACHE_BEAT_BITS{bus_reset_cmd_beat_cnt_secondlast}} & (pt.ICACHE_BEAT_BITS)'(pt.ICACHE_SCND_LAST)) | ({pt.ICACHE_BEAT_BITS{bus_inc_cmd_beat_cnt}} & (bus_cmd_beat_count[pt.ICACHE_BEAT_BITS-1:0] + {{pt.ICACHE_BEAT_BITS-1{1'b0}}, 1'b1})) | ({pt.ICACHE_BEAT_BITS{bus_hold_cmd_beat_cnt}} & bus_cmd_beat_count[pt.ICACHE_BEAT_BITS-1:0]) ; rvclkhdr bus_clk_reset(.en(bus_ifu_bus_clk_en | ic_act_miss_f | dec_tlu_force_halt), .l1clk(busclk_reset), .*); rvdffs #(pt.ICACHE_BEAT_BITS) bus_cmd_beat_ff (.*, .clk(busclk_reset), .en (bus_cmd_beat_en), .din ({bus_new_cmd_beat_count[pt.ICACHE_BEAT_BITS-1:0]}), .dout({bus_cmd_beat_count[pt.ICACHE_BEAT_BITS-1:0]})); assign bus_last_data_beat = uncacheable_miss_ff ? (bus_data_beat_count[pt.ICACHE_BEAT_BITS-1:0] == {{pt.ICACHE_BEAT_BITS-1{1'b0}},1'b1}) : (&bus_data_beat_count[pt.ICACHE_BEAT_BITS-1:0]); assign bus_ifu_wr_en = ifu_bus_rvalid & miss_pending ; assign bus_ifu_wr_en_ff = ifu_bus_rvalid_ff & miss_pending ; assign bus_ifu_wr_en_ff_q = ifu_bus_rvalid_ff & miss_pending & ~uncacheable_miss_ff & ~(|ifu_bus_rresp_ff[1:0]) & write_ic_16_bytes; // qualify with no-error conditions ; assign bus_ifu_wr_en_ff_wo_err = ifu_bus_rvalid_ff & miss_pending & ~uncacheable_miss_ff; rvdff #(1) act_miss_ff (.*, .clk(free_clk), .din (ic_act_miss_f), .dout(ic_act_miss_f_delayed)); assign reset_tag_valid_for_miss = ic_act_miss_f_delayed & (miss_state == CRIT_BYP_OK) & ~uncacheable_miss_ff; assign bus_ifu_wr_data_error = |ifu_bus_rsp_opc[1:0] & ifu_bus_rvalid & miss_pending; assign bus_ifu_wr_data_error_ff = |ifu_bus_rresp_ff[1:0] & ifu_bus_rvalid_ff & miss_pending; rvdff #(1) dma_ok_prev_ff (.*, .clk(free_clk), .din(ifc_dma_access_ok_d), .dout(ifc_dma_access_ok_prev)); assign ic_crit_wd_rdy = ic_crit_wd_rdy_new_in | ic_crit_wd_rdy_new_ff ; assign last_beat = bus_last_data_beat & bus_ifu_wr_en_ff; assign reset_beat_cnt = bus_reset_data_beat_cnt ; // DMA // Making sure that the dma_access is allowed when we have 2 back to back dma_access_ok. Also gating with current state == idle assign ifc_dma_access_ok_d = ifc_dma_access_ok & ~iccm_correct_ecc & ~iccm_dma_sb_error; assign ifc_dma_access_q_ok = ifc_dma_access_ok & ~iccm_correct_ecc & ifc_dma_access_ok_prev & (perr_state == ERR_IDLE) & ~iccm_dma_sb_error; assign iccm_ready = ifc_dma_access_q_ok ; rvdff #(1) dma_req_ff (.*, .clk(free_clk), .din (dma_iccm_req), .dout(dma_iccm_req_f)); logic [1:0] iccm_ecc_word_enable; if (pt.ICCM_ENABLE == 1 ) begin: iccm_enabled logic [3:2] dma_mem_addr_ff ; logic iccm_dma_rden ; logic iccm_dma_ecc_error_in; logic [13:0] dma_mem_ecc; logic [63:0] iccm_dma_rdata_in; logic [31:0] iccm_dma_rdata_1_muxed; logic [1:0] [31:0] iccm_corrected_data; logic [1:0] [06:0] iccm_corrected_ecc; logic [1:0] iccm_double_ecc_error; logic [pt.ICCM_BITS-1:2] iccm_rw_addr_f; logic [31:0] iccm_corrected_data_f_mux; logic [06:0] iccm_corrected_ecc_f_mux; logic iccm_dma_rvalid_in; logic [77:0] iccm_rdmux_data; logic iccm_rd_ecc_single_err_hold_in ; logic [2:0] dma_mem_tag_ff; assign iccm_wren = (ifc_dma_access_q_ok & dma_iccm_req & dma_mem_write) | iccm_correct_ecc; assign iccm_rden = (ifc_dma_access_q_ok & dma_iccm_req & ~dma_mem_write) | (ifc_iccm_access_bf & ifc_fetch_req_bf); assign iccm_dma_rden = (ifc_dma_access_q_ok & dma_iccm_req & ~dma_mem_write) ; assign iccm_wr_size[2:0] = {3{dma_iccm_req}} & dma_mem_sz[2:0] ; rvecc_encode iccm_ecc_encode0 ( .din(dma_mem_wdata[31:0]), .ecc_out(dma_mem_ecc[6:0])); rvecc_encode iccm_ecc_encode1 ( .din(dma_mem_wdata[63:32]), .ecc_out(dma_mem_ecc[13:7])); assign iccm_wr_data[77:0] = (iccm_correct_ecc & ~(ifc_dma_access_q_ok & dma_iccm_req)) ? {iccm_ecc_corr_data_ff[38:0], iccm_ecc_corr_data_ff[38:0]} : {dma_mem_ecc[13:7],dma_mem_wdata[63:32], dma_mem_ecc[6:0],dma_mem_wdata[31:0]}; assign iccm_dma_rdata_1_muxed[31:0] = dma_mem_addr_ff[2] ? iccm_corrected_data[0][31:0] : iccm_corrected_data[1][31:0] ; assign iccm_dma_rdata_in[63:0] = iccm_dma_ecc_error_in ? {2{dma_mem_addr[31:0]}} : {iccm_dma_rdata_1_muxed[31:0], iccm_corrected_data[0]}; assign iccm_dma_ecc_error_in = |(iccm_double_ecc_error[1:0]); rvdff #(3) dma_tag_ff1 (.*, .clk(free_clk), .din(dma_mem_tag[2:0]), .dout(dma_mem_tag_ff[2:0])); rvdff #(3) dma_tag_ff2 (.*, .clk(free_clk), .din(dma_mem_tag_ff[2:0]), .dout(iccm_dma_rtag[2:0])); rvdff #(2) dma_addr_bt3_ff (.*, .clk(free_clk), .din(dma_mem_addr[3:2]), .dout(dma_mem_addr_ff[3:2])); rvdff #(1) ccm_rdy_in_ff (.*, .clk(free_clk), .din(iccm_dma_rden), .dout(iccm_dma_rvalid_in)); rvdff #(1) ccm_rdy_ff (.*, .clk(free_clk), .din(iccm_dma_rvalid_in), .dout(iccm_dma_rvalid)); rvdff #(1) ccm_err_ff (.*, .clk(free_clk), .din(iccm_dma_ecc_error_in), .dout(iccm_dma_ecc_error)); rvdff #(64)dma_data_ff (.*, .clk(free_clk), .din(iccm_dma_rdata_in[63:0]), .dout(iccm_dma_rdata[63:0])); assign iccm_rw_addr[pt.ICCM_BITS-1:1] = ( ifc_dma_access_q_ok & dma_iccm_req & ~iccm_correct_ecc) ? dma_mem_addr[pt.ICCM_BITS-1:1] : (~(ifc_dma_access_q_ok & dma_iccm_req) & iccm_correct_ecc) ? {iccm_ecc_corr_index_ff[pt.ICCM_BITS-1:2],1'b0} : ifc_fetch_addr_bf[pt.ICCM_BITS-1:1] ; ///////////////////////////////////////////////////////////////////////////////////// // ECC checking logic for ICCM data. // ///////////////////////////////////////////////////////////////////////////////////// logic [3:0] ic_fetch_val_int_f; logic [3:0] ic_fetch_val_shift_right; assign ic_fetch_val_int_f[3:0] = {2'b00 , ic_fetch_val_f[1:0] } ; assign ic_fetch_val_shift_right[3:0] = {ic_fetch_val_int_f << ifu_fetch_addr_int_f[1] } ; assign iccm_rdmux_data[77:0] = iccm_rd_data_ecc[77:0]; for (genvar i=0; i < 2 ; i++) begin : ICCM_ECC_CHECK assign iccm_ecc_word_enable[i] = ((|ic_fetch_val_shift_right[(2*i+1):(2*i)] & ~exu_flush_final & sel_iccm_data) | iccm_dma_rvalid_in) & ~dec_tlu_core_ecc_disable; rvecc_decode ecc_decode ( .en(iccm_ecc_word_enable[i]), .sed_ded ( 1'b0 ), // 1 : means only detection .din(iccm_rdmux_data[(39*i+31):(39*i)]), .ecc_in(iccm_rdmux_data[(39*i+38):(39*i+32)]), .dout(iccm_corrected_data[i][31:0]), .ecc_out(iccm_corrected_ecc[i][6:0]), .single_ecc_error(iccm_single_ecc_error[i]), .double_ecc_error(iccm_double_ecc_error[i])); end assign iccm_rd_ecc_single_err = (|iccm_single_ecc_error[1:0] ) & ifc_iccm_access_f & ifc_fetch_req_f; assign iccm_rd_ecc_double_err = (|iccm_double_ecc_error[1:0] ) & ifc_iccm_access_f; assign iccm_corrected_data_f_mux[31:0] = iccm_single_ecc_error[0] ? iccm_corrected_data[0] : iccm_corrected_data[1]; assign iccm_corrected_ecc_f_mux[6:0] = iccm_single_ecc_error[0] ? iccm_corrected_ecc[0] : iccm_corrected_ecc[1]; assign iccm_ecc_write_status = ((iccm_rd_ecc_single_err & ~iccm_rd_ecc_single_err_ff) & ~exu_flush_final) | iccm_dma_sb_error; assign iccm_rd_ecc_single_err_hold_in = (iccm_rd_ecc_single_err | iccm_rd_ecc_single_err_ff) & ~exu_flush_final ; // & ~(perr_state == ERR_IDLE); assign iccm_error_start = iccm_rd_ecc_single_err; assign iccm_ecc_corr_index_in[pt.ICCM_BITS-1:2] = iccm_single_ecc_error[0] ? iccm_rw_addr_f[pt.ICCM_BITS-1:2] : iccm_rw_addr_f[pt.ICCM_BITS-1:2] + 1'b1 ; rvdff #(pt.ICCM_BITS-2) iccm_index_f (.*, .clk(free_clk), .din(iccm_rw_addr[pt.ICCM_BITS-1:2]), .dout(iccm_rw_addr_f[pt.ICCM_BITS-1:2])); rvdff #((1)) ecc_rr_ff (.clk(free_clk), .din(iccm_rd_ecc_single_err_hold_in), .dout(iccm_rd_ecc_single_err_ff), .*); rvdffs #((32)) ecc_dat0_ff (.clk(free_clk), .din(iccm_corrected_data_f_mux[31:0]), .dout(iccm_ecc_corr_data_ff[31:0]), .en(iccm_ecc_write_status), .*); rvdffs #((7)) ecc_dat1_ff (.clk(free_clk), .din(iccm_corrected_ecc_f_mux[6:0]), .dout(iccm_ecc_corr_data_ff[38:32]), .en(iccm_ecc_write_status), .*); rvdffs #((pt.ICCM_BITS-2))ecc_ind0_ff (.clk(free_clk), .din(iccm_ecc_corr_index_in[pt.ICCM_BITS-1:2]), .dout(iccm_ecc_corr_index_ff[pt.ICCM_BITS-1:2]),.en(iccm_ecc_write_status), .*); end else begin : iccm_disabled assign iccm_dma_rvalid = 1'b0 ; assign iccm_dma_ecc_error = 1'b0 ; assign iccm_dma_rdata[63:0] = '0 ; assign iccm_single_ecc_error = '0 ; assign iccm_dma_rtag = '0 ; assign iccm_rd_ecc_single_err = 1'b0 ; assign iccm_rd_ecc_double_err = 1'b0 ; assign iccm_rd_ecc_single_err_ff = 1'b0 ; assign iccm_error_start = 1'b0; assign iccm_ecc_corr_index_ff[pt.ICCM_BITS-1:2] = '0; assign iccm_ecc_corr_data_ff[38:0] = '0; assign iccm_ecc_write_status = '0; end ////// ICCM signals // Use the equation below for more power savings. assign ic_rd_en = (ifc_fetch_req_bf & ~ifc_fetch_uncacheable_bf & ~ifc_iccm_access_bf & ~(((miss_state == STREAM) & ~miss_state_en) | ((miss_state == CRIT_BYP_OK) & ~miss_state_en) | ((miss_state == STALL_SCND_MISS) & ~miss_state_en) | ((miss_state == MISS_WAIT) & ~miss_state_en) | ((miss_state == CRIT_WRD_RDY) & ~miss_state_en) | ((miss_state == CRIT_BYP_OK) & miss_state_en & (miss_nxtstate == MISS_WAIT)) )) | ( ifc_fetch_req_bf & exu_flush_final & ~ifc_fetch_uncacheable_bf & ~ifc_iccm_access_bf ) ; logic ic_real_rd_wp_unused; assign ic_real_rd_wp_unused = (ifc_fetch_req_bf & ~ifc_iccm_access_bf & ~ifc_region_acc_fault_final_bf & ~dec_tlu_fence_i_wb & ~stream_miss_f & ~ic_act_miss_f & ~(((miss_state == STREAM) & ~miss_state_en) | ((miss_state == CRIT_BYP_OK) & ~miss_state_en & ~(miss_nxtstate == MISS_WAIT)) | ((miss_state == CRIT_BYP_OK) & miss_state_en & (miss_nxtstate == MISS_WAIT)) | ((miss_state == MISS_WAIT) & ~miss_state_en) | ((miss_state == STALL_SCND_MISS) & ~miss_state_en) | ((miss_state == CRIT_WRD_RDY) & ~miss_state_en) | ((miss_nxtstate == STREAM) & miss_state_en) | ((miss_state == SCND_MISS) & ~miss_state_en))) | (ifc_fetch_req_bf & ~ifc_iccm_access_bf & ~ifc_region_acc_fault_final_bf & ~dec_tlu_fence_i_wb & ~stream_miss_f & exu_flush_final) ; assign ic_wr_en[pt.ICACHE_NUM_WAYS-1:0] = bus_ic_wr_en[pt.ICACHE_NUM_WAYS-1:0] & {pt.ICACHE_NUM_WAYS{write_ic_16_bytes}}; assign ic_write_stall = write_ic_16_bytes & ~((((miss_state== CRIT_BYP_OK) | (miss_state==STREAM)) & ~(bus_ifu_wr_en_ff & last_beat & ~uncacheable_miss_ff))); rvdff #(1) reset_all_tag_ff (.*, .clk(active_clk), .din(dec_tlu_fence_i_wb), .dout(reset_all_tags)); /////////////////////////////////////////////////////////////// // Icache status and LRU /////////////////////////////////////////////////////////////// logic [pt.ICACHE_NUM_WAYS-1:0] ic_tag_valid_unq; if (pt.ICACHE_ENABLE == 1 ) begin: icache_enabled assign ic_valid = ~ifu_wr_cumulative_err_data & ~(reset_ic_in | reset_ic_ff) & ~reset_tag_valid_for_miss; assign ifu_status_wr_addr_w_debug[pt.ICACHE_INDEX_HI:pt.ICACHE_TAG_INDEX_LO] = ((ic_debug_rd_en | ic_debug_wr_en ) & ic_debug_tag_array) ? ic_debug_addr[pt.ICACHE_INDEX_HI:pt.ICACHE_TAG_INDEX_LO] : ifu_status_wr_addr[pt.ICACHE_INDEX_HI:pt.ICACHE_TAG_INDEX_LO]; // status rvdff #(pt.ICACHE_TAG_LO-pt.ICACHE_TAG_INDEX_LO) status_wr_addr_ff (.*, .clk(free_clk), .din(ifu_status_wr_addr_w_debug[pt.ICACHE_INDEX_HI:pt.ICACHE_TAG_INDEX_LO]), .dout(ifu_status_wr_addr_ff[pt.ICACHE_INDEX_HI:pt.ICACHE_TAG_INDEX_LO])); assign way_status_wr_en_w_debug = way_status_wr_en | (ic_debug_wr_en & ic_debug_tag_array); rvdff #(1) status_wren_ff (.*, .clk(free_clk), .din(way_status_wr_en_w_debug), .dout(way_status_wr_en_ff)); assign way_status_new_w_debug[pt.ICACHE_STATUS_BITS-1:0] = (ic_debug_wr_en & ic_debug_tag_array) ? (pt.ICACHE_STATUS_BITS == 1) ? ic_debug_wr_data[4] : ic_debug_wr_data[6:4] : way_status_new[pt.ICACHE_STATUS_BITS-1:0] ; rvdff #(pt.ICACHE_STATUS_BITS) status_data_ff (.*, .clk(free_clk), .din(way_status_new_w_debug[pt.ICACHE_STATUS_BITS-1:0]), .dout(way_status_new_ff[pt.ICACHE_STATUS_BITS-1:0])); logic [(pt.ICACHE_TAG_DEPTH/8)-1 : 0] way_status_clken; logic [(pt.ICACHE_TAG_DEPTH/8)-1 : 0] way_status_clk; for (genvar i=0 ; i<32'(pt.ICACHE_TAG_DEPTH)/8 ; i++) begin : CLK_GRP_WAY_STATUS assign way_status_clken[i] = (ifu_status_wr_addr_ff[pt.ICACHE_INDEX_HI:pt.ICACHE_TAG_INDEX_LO+3] == i ); rvclkhdr way_status_cgc ( .en(way_status_clken[i]), .l1clk(way_status_clk[i]), .* ); for (genvar j=0 ; j<8 ; j++) begin : WAY_STATUS rvdffs #(pt.ICACHE_STATUS_BITS) ic_way_status (.*, .clk(way_status_clk[i]), .en(((ifu_status_wr_addr_ff[pt.ICACHE_TAG_INDEX_LO+2:pt.ICACHE_TAG_INDEX_LO] == j) & way_status_wr_en_ff)), .din(way_status_new_ff[pt.ICACHE_STATUS_BITS-1:0]), .dout(way_status_out[8*i+j])); end // WAY_STATUS end // CLK_GRP_WAY_STATUS always_comb begin : way_status_out_mux way_status[pt.ICACHE_STATUS_BITS-1:0] = '0 ; for (int j=0; j< 32'(pt.ICACHE_TAG_DEPTH); j++) begin : status_mux_loop if (ifu_ic_rw_int_addr_ff[pt.ICACHE_INDEX_HI:pt.ICACHE_TAG_INDEX_LO] == (pt.ICACHE_TAG_LO-pt.ICACHE_TAG_INDEX_LO)'(j)) begin : mux_out way_status[pt.ICACHE_STATUS_BITS-1:0] = way_status_out[j]; end end end assign ifu_ic_rw_int_addr_w_debug[pt.ICACHE_INDEX_HI:pt.ICACHE_TAG_INDEX_LO] = ((ic_debug_rd_en | ic_debug_wr_en ) & ic_debug_tag_array) ? ic_debug_addr[pt.ICACHE_INDEX_HI:pt.ICACHE_TAG_INDEX_LO] : ifu_ic_rw_int_addr[pt.ICACHE_INDEX_HI:pt.ICACHE_TAG_INDEX_LO]; rvdff #(pt.ICACHE_TAG_LO-pt.ICACHE_TAG_INDEX_LO) tag_addr_ff (.*, .clk(free_clk), .din(ifu_ic_rw_int_addr_w_debug[pt.ICACHE_INDEX_HI:pt.ICACHE_TAG_INDEX_LO]), .dout(ifu_ic_rw_int_addr_ff[pt.ICACHE_INDEX_HI:pt.ICACHE_TAG_INDEX_LO])); assign ifu_tag_wren_w_debug[pt.ICACHE_NUM_WAYS-1:0] = ifu_tag_wren[pt.ICACHE_NUM_WAYS-1:0] | ic_debug_tag_wr_en[pt.ICACHE_NUM_WAYS-1:0] ; rvdff #(pt.ICACHE_NUM_WAYS) tag_v_we_ff (.*, .clk(free_clk), .din(ifu_tag_wren_w_debug[pt.ICACHE_NUM_WAYS-1:0]), .dout(ifu_tag_wren_ff[pt.ICACHE_NUM_WAYS-1:0])); assign ic_valid_w_debug = (ic_debug_wr_en & ic_debug_tag_array) ? ic_debug_wr_data[0] : ic_valid; rvdff #(1) tag_v_ff (.*, .clk(free_clk), .din(ic_valid_w_debug), .dout(ic_valid_ff)); logic [pt.ICACHE_NUM_WAYS-1:0] [pt.ICACHE_TAG_DEPTH-1:0] ic_tag_valid_out ; logic [(pt.ICACHE_TAG_DEPTH/32)-1:0] [pt.ICACHE_NUM_WAYS-1:0] tag_valid_clken ; logic [(pt.ICACHE_TAG_DEPTH/32)-1:0] [pt.ICACHE_NUM_WAYS-1:0] tag_valid_clk ; for (genvar i=0 ; i<32'(pt.ICACHE_TAG_DEPTH)/32 ; i++) begin : CLK_GRP_TAG_VALID for (genvar j=0; j<32'(pt.ICACHE_NUM_WAYS); j++) begin : way_clken if (pt.ICACHE_TAG_DEPTH == 32 ) begin assign tag_valid_clken[i][j] = ifu_tag_wren_ff[j] | perr_err_inv_way[j] | reset_all_tags; end else begin assign tag_valid_clken[i][j] = (((ifu_ic_rw_int_addr_ff[pt.ICACHE_INDEX_HI:pt.ICACHE_TAG_INDEX_LO+5] == i ) & ifu_tag_wren_ff[j] ) | ((perr_ic_index_ff [pt.ICACHE_INDEX_HI:pt.ICACHE_TAG_INDEX_LO+5] == i ) & perr_err_inv_way[j]) | reset_all_tags); end rvclkhdr way_status_cgc ( .en(tag_valid_clken[i][j]), .l1clk(tag_valid_clk[i][j]), .* ); for (genvar k=0 ; k<32 ; k++) begin : TAG_VALID rvdffs #(1) ic_way_tagvalid_dup (.*, .clk(tag_valid_clk[i][j]), .en(((ifu_ic_rw_int_addr_ff[pt.ICACHE_INDEX_HI:pt.ICACHE_TAG_INDEX_LO] == (k + 32*i)) & ifu_tag_wren_ff[j] ) | ((perr_ic_index_ff [pt.ICACHE_INDEX_HI:pt.ICACHE_TAG_INDEX_LO] == (k + 32*i)) & perr_err_inv_way[j]) | reset_all_tags), .din(ic_valid_ff & ~reset_all_tags & ~perr_sel_invalidate), .dout(ic_tag_valid_out[j][32*i+k])); end end end always_comb begin : tag_valid_out_mux ic_tag_valid_unq[pt.ICACHE_NUM_WAYS-1:0] = '0; for (int j=0; j< pt.ICACHE_TAG_DEPTH; j++) begin : tag_valid_loop if (ifu_ic_rw_int_addr_ff[pt.ICACHE_INDEX_HI:pt.ICACHE_TAG_INDEX_LO] == (pt.ICACHE_TAG_LO-pt.ICACHE_TAG_INDEX_LO)'(j)) begin : valid_out for ( int k=0; k