Project Full coverage report
Current view: Cores-VeeR-EL2—Cores-VeeR-EL2—design—ifu—el2_ifu_ic_mem.sv Coverage Hit Total
Test Date: 21-11-2024 Toggle 64.2% 88 137
Test: all Branch 100.0% 35 35

            Line data    Source code
       1              : //********************************************************************************
       2              : // SPDX-License-Identifier: Apache-2.0
       3              : // Copyright 2020 Western Digital Corporation or its affiliates.
       4              : //
       5              : // Licensed under the Apache License, Version 2.0 (the "License");
       6              : // you may not use this file except in compliance with the License.
       7              : // You may obtain a copy of the License at
       8              : //
       9              : // http://www.apache.org/licenses/LICENSE-2.0
      10              : //
      11              : // Unless required by applicable law or agreed to in writing, software
      12              : // distributed under the License is distributed on an "AS IS" BASIS,
      13              : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      14              : // See the License for the specific language governing permissions and
      15              : // limitations under the License.
      16              : //********************************************************************************
      17              : ////////////////////////////////////////////////////
      18              : //   ICACHE DATA & TAG MODULE WRAPPER              //
      19              : /////////////////////////////////////////////////////
      20              : module el2_ifu_ic_mem
      21              : import el2_pkg::*;
      22              :  #(
      23              : `include "el2_param.vh"
      24              :  )
      25              :   (
      26     69840565 :       input logic                                   clk,                // Clock only while core active.  Through one clock header.  For flops with    second clock header built in.  Connected to ACTIVE_L2CLK.
      27     69840565 :       input logic                                   active_clk,         // Clock only while core active.  Through two clock headers. For flops without second clock header built in.
      28          338 :       input logic                                   rst_l,              // reset, active low
      29            2 :       input logic                                   clk_override,       // Override non-functional clock gating
      30            8 :       input logic                                   dec_tlu_core_ecc_disable,  // Disable ECC checking
      31              : 
      32          489 :       input logic [31:1]                            ic_rw_addr,
      33        10432 :       input logic [pt.ICACHE_NUM_WAYS-1:0]          ic_wr_en  ,         // Which way to write
      34       680948 :       input logic                                   ic_rd_en  ,         // Read enable
      35            0 :       input logic [pt.ICACHE_INDEX_HI:3]            ic_debug_addr,      // Read/Write addresss to the Icache.
      36           20 :       input logic                                   ic_debug_rd_en,     // Icache debug rd
      37           20 :       input logic                                   ic_debug_wr_en,     // Icache debug wr
      38            8 :       input logic                                   ic_debug_tag_array, // Debug tag array
      39            0 :       input logic [pt.ICACHE_NUM_WAYS-1:0]          ic_debug_way,       // Debug way. Rd or Wr.
      40      1737398 :       input logic [63:0]                            ic_premux_data,     // Premux data to be muxed with each way of the Icache.
      41      5599841 :       input logic                                   ic_sel_premux_data, // Select the pre_muxed data
      42              : 
      43       560245 :       input  logic [pt.ICACHE_BANKS_WAY-1:0][70:0]  ic_wr_data,         // Data to fill to the Icache. With ECC
      44      2135818 :       output logic [63:0]                           ic_rd_data ,        // Data read from Icache. 2x64bits + parity bits. F2 stage. With ECC
      45       231591 :       output logic [70:0]                           ic_debug_rd_data ,  // Data read from Icache. 2x64bits + parity bits. F2 stage. With ECC
      46            0 :       output logic [25:0]                           ictag_debug_rd_data,// Debug icache tag.
      47            0 :       input logic  [70:0]                           ic_debug_wr_data,   // Debug wr cache.
      48              : 
      49            0 :       output logic [pt.ICACHE_BANKS_WAY-1:0]        ic_eccerr,          // ecc error per bank
      50            0 :       output logic [pt.ICACHE_BANKS_WAY-1:0]        ic_parerr,          // ecc error per bank
      51       255918 :       input logic [pt.ICACHE_NUM_WAYS-1:0]          ic_tag_valid,       // Valid from the I$ tag valid outside (in flops).
      52            0 :       input el2_ic_data_ext_in_pkt_t [pt.ICACHE_NUM_WAYS-1:0][pt.ICACHE_BANKS_WAY-1:0] ic_data_ext_in_pkt,   // this is being driven by the top level for soc testing/etc
      53            0 :       input el2_ic_tag_ext_in_pkt_t  [pt.ICACHE_NUM_WAYS-1:0]                          ic_tag_ext_in_pkt,    // this is being driven by the top level for soc testing/etc
      54              : 
      55       109586 :       output logic [pt.ICACHE_NUM_WAYS-1:0]         ic_rd_hit,          // ic_rd_hit[3:0]
      56            0 :       output logic                                  ic_tag_perr,        // Tag Parity error
      57              :       // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core.
      58              :       /*verilator coverage_off*/
      59              :       input  logic                                  scan_mode           // Flop scan mode control
      60              :       /*verilator coverage_on*/
      61              :       ) ;
      62              : 
      63              : 
      64              : 
      65              : 
      66              :    EL2_IC_TAG #(.pt(pt)) ic_tag_inst
      67              :           (
      68              :            .*,
      69              :            .ic_wr_en     (ic_wr_en[pt.ICACHE_NUM_WAYS-1:0]),
      70              :            .ic_debug_addr(ic_debug_addr[pt.ICACHE_INDEX_HI:3]),
      71              :            .ic_rw_addr   (ic_rw_addr[31:3])
      72              :            ) ;
      73              : 
      74              :    EL2_IC_DATA #(.pt(pt)) ic_data_inst
      75              :           (
      76              :            .*,
      77              :            .ic_wr_en     (ic_wr_en[pt.ICACHE_NUM_WAYS-1:0]),
      78              :            .ic_debug_addr(ic_debug_addr[pt.ICACHE_INDEX_HI:3]),
      79              :            .ic_rw_addr   (ic_rw_addr[31:1])
      80              :            ) ;
      81              : 
      82              :  endmodule
      83              : 
      84              : 
      85              : /////////////////////////////////////////////////
      86              : ////// ICACHE DATA MODULE    ////////////////////
      87              : /////////////////////////////////////////////////
      88              : module EL2_IC_DATA
      89              : import el2_pkg::*;
      90              : #(
      91              : `include "el2_param.vh"
      92              :  )
      93              :      (
      94     69840565 :       input logic clk,
      95     69840565 :       input logic active_clk,
      96          338 :       input logic rst_l,
      97            2 :       input logic clk_override,
      98              : 
      99          489 :       input logic [31:1]                  ic_rw_addr,
     100        10432 :       input logic [pt.ICACHE_NUM_WAYS-1:0]ic_wr_en,
     101       680948 :       input logic                          ic_rd_en,           // Read enable
     102              : 
     103       560245 :       input  logic [pt.ICACHE_BANKS_WAY-1:0][70:0]    ic_wr_data,         // Data to fill to the Icache. With ECC
     104      2135818 :       output logic [63:0]                             ic_rd_data ,                                 // Data read from Icache. 2x64bits + parity bits. F2 stage. With ECC
     105            0 :       input  logic [70:0]                             ic_debug_wr_data,   // Debug wr cache.
     106       231591 :       output logic [70:0]                             ic_debug_rd_data ,  // Data read from Icache. 2x64bits + parity bits. F2 stage. With ECC
     107            0 :       output logic [pt.ICACHE_BANKS_WAY-1:0] ic_parerr,
     108            0 :       output logic [pt.ICACHE_BANKS_WAY-1:0] ic_eccerr,    // ecc error per bank
     109            0 :       input logic [pt.ICACHE_INDEX_HI:3]     ic_debug_addr,     // Read/Write addresss to the Icache.
     110           20 :       input logic                            ic_debug_rd_en,      // Icache debug rd
     111           20 :       input logic                            ic_debug_wr_en,      // Icache debug wr
     112            8 :       input logic                            ic_debug_tag_array,  // Debug tag array
     113            0 :       input logic [pt.ICACHE_NUM_WAYS-1:0]   ic_debug_way,        // Debug way. Rd or Wr.
     114      1737398 :       input logic [63:0]                     ic_premux_data,      // Premux data to be muxed with each way of the Icache.
     115      5599841 :       input logic                            ic_sel_premux_data,  // Select the pre_muxed data
     116              : 
     117       109586 :       input logic [pt.ICACHE_NUM_WAYS-1:0]ic_rd_hit,
     118            0 :       input el2_ic_data_ext_in_pkt_t  [pt.ICACHE_NUM_WAYS-1:0][pt.ICACHE_BANKS_WAY-1:0] ic_data_ext_in_pkt,   // this is being driven by the top level for soc testing/etc
     119              :       // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core.
     120              :       /*verilator coverage_off*/
     121              :       input  logic                         scan_mode
     122              :       /*verilator coverage_on*/
     123              : 
     124              :       ) ;
     125              : 
     126       466517 :    logic [pt.ICACHE_TAG_INDEX_LO-1:1]                                             ic_rw_addr_ff;
     127        10432 :    logic [pt.ICACHE_BANKS_WAY-1:0][pt.ICACHE_NUM_WAYS-1:0]                        ic_b_sb_wren;    //bank x ways
     128      1011037 :    logic [pt.ICACHE_BANKS_WAY-1:0][pt.ICACHE_NUM_WAYS-1:0]                        ic_b_sb_rden;    //bank x ways
     129              : 
     130              : 
     131      1011037 :    logic [pt.ICACHE_BANKS_WAY-1:0]                                                ic_b_rden;       //bank
     132      1011018 :    logic [pt.ICACHE_BANKS_WAY-1:0]                                                ic_b_rden_ff;    //bank
     133            0 :    logic [pt.ICACHE_BANKS_WAY-1:0]                                                ic_debug_sel_sb;
     134              : 
     135              :    logic [pt.ICACHE_NUM_WAYS-1:0][pt.ICACHE_BANKS_WAY-1:0][70:0]                  wb_dout ;       //  ways x bank
     136       560245 :    logic [pt.ICACHE_BANKS_WAY-1:0][70:0]                                          ic_sb_wr_data, ic_bank_wr_data, wb_dout_ecc_bank;
     137              :    logic [pt.ICACHE_NUM_WAYS-1:0] [141:0]                                         wb_dout_way_pre;
     138      1923736 :    logic [pt.ICACHE_NUM_WAYS-1:0] [63:0]                                          wb_dout_way, wb_dout_way_with_premux;
     139       218087 :    logic [141:0]                                                                  wb_dout_ecc;
     140              : 
     141       462473 :    logic [pt.ICACHE_BANKS_WAY-1:0]                                                bank_check_en;
     142              : 
     143      1017489 :    logic [pt.ICACHE_BANKS_WAY-1:0][pt.ICACHE_NUM_WAYS-1:0]                        ic_bank_way_clken;
     144       669817 :    logic [pt.ICACHE_BANKS_WAY-1:0]                                                ic_bank_way_clken_final;
     145            0 :    logic [pt.ICACHE_NUM_WAYS-1:0][pt.ICACHE_BANKS_WAY-1:0]                        ic_bank_way_clken_final_up;
     146              : 
     147            0 :    logic [pt.ICACHE_NUM_WAYS-1:0]                                                 ic_debug_rd_way_en;    // debug wr_way
     148            0 :    logic [pt.ICACHE_NUM_WAYS-1:0]                                                 ic_debug_rd_way_en_ff; // debug wr_way
     149            0 :    logic [pt.ICACHE_NUM_WAYS-1:0]                                                 ic_debug_wr_way_en;    // debug wr_way
     150        84671 :    logic [pt.ICACHE_INDEX_HI:1]                                                   ic_rw_addr_q;
     151              : 
     152        85251 :    logic [pt.ICACHE_BANKS_WAY-1:0]       [pt.ICACHE_INDEX_HI : pt.ICACHE_DATA_INDEX_LO] ic_rw_addr_bank_q;
     153              : 
     154        86001 :    logic [pt.ICACHE_TAG_LO-1 : pt.ICACHE_DATA_INDEX_LO]                           ic_rw_addr_q_inc;
     155       109586 :    logic [pt.ICACHE_NUM_WAYS-1:0]                                                 ic_rd_hit_q;
     156              : 
     157              : 
     158              : 
     159      1025805 :       logic [pt.ICACHE_BANKS_WAY-1:0]                                                ic_b_sram_en;
     160      1011037 :       logic [pt.ICACHE_BANKS_WAY-1:0]                                                ic_b_read_en;
     161        25640 :       logic [pt.ICACHE_BANKS_WAY-1:0]                                                ic_b_write_en;
     162           37 :       logic [pt.ICACHE_BANKS_WAY-1:0][pt.ICACHE_NUM_BYPASS-1:0] [31 : pt.ICACHE_DATA_INDEX_LO]  wb_index_hold;
     163       340461 :       logic [pt.ICACHE_BANKS_WAY-1:0][pt.ICACHE_NUM_BYPASS-1:0]                                 write_bypass_en;     //bank
     164       340460 :       logic [pt.ICACHE_BANKS_WAY-1:0][pt.ICACHE_NUM_BYPASS-1:0]                                 write_bypass_en_ff;  //bank
     165         1321 :       logic [pt.ICACHE_BANKS_WAY-1:0][pt.ICACHE_NUM_BYPASS-1:0]                                 index_valid;  //bank
     166         1290 :       logic [pt.ICACHE_BANKS_WAY-1:0][pt.ICACHE_NUM_BYPASS-1:0]                                 ic_b_clear_en;
     167       359475 :       logic [pt.ICACHE_BANKS_WAY-1:0][pt.ICACHE_NUM_BYPASS-1:0]                                 ic_b_addr_match;
     168       359479 :       logic [pt.ICACHE_BANKS_WAY-1:0][pt.ICACHE_NUM_BYPASS-1:0]                                 ic_b_addr_match_index_only;
     169              : 
     170            0 :       logic [pt.ICACHE_NUM_WAYS-1:0][pt.ICACHE_BANKS_WAY-1:0]                                                ic_b_sram_en_up;
     171            0 :       logic [pt.ICACHE_NUM_WAYS-1:0][pt.ICACHE_BANKS_WAY-1:0]                                                ic_b_read_en_up;
     172            0 :       logic [pt.ICACHE_NUM_WAYS-1:0][pt.ICACHE_BANKS_WAY-1:0]                                                ic_b_write_en_up;
     173            0 :       logic [pt.ICACHE_NUM_WAYS-1:0][pt.ICACHE_BANKS_WAY-1:0][pt.ICACHE_NUM_BYPASS-1:0] [31 : pt.ICACHE_DATA_INDEX_LO]  wb_index_hold_up;
     174            0 :       logic [pt.ICACHE_NUM_WAYS-1:0][pt.ICACHE_BANKS_WAY-1:0][pt.ICACHE_NUM_BYPASS-1:0]                                 write_bypass_en_up;     //bank
     175            0 :       logic [pt.ICACHE_NUM_WAYS-1:0][pt.ICACHE_BANKS_WAY-1:0][pt.ICACHE_NUM_BYPASS-1:0]                                 write_bypass_en_ff_up;  //bank
     176            0 :       logic [pt.ICACHE_NUM_WAYS-1:0][pt.ICACHE_BANKS_WAY-1:0][pt.ICACHE_NUM_BYPASS-1:0]                                 index_valid_up;  //bank
     177            0 :       logic [pt.ICACHE_NUM_WAYS-1:0][pt.ICACHE_BANKS_WAY-1:0][pt.ICACHE_NUM_BYPASS-1:0]                                 ic_b_clear_en_up;
     178            0 :       logic [pt.ICACHE_NUM_WAYS-1:0][pt.ICACHE_BANKS_WAY-1:0][pt.ICACHE_NUM_BYPASS-1:0]                                 ic_b_addr_match_up;
     179            0 :       logic [pt.ICACHE_NUM_WAYS-1:0][pt.ICACHE_BANKS_WAY-1:0][pt.ICACHE_NUM_BYPASS-1:0]                                 ic_b_addr_match_index_only_up;
     180              : 
     181              : 
     182          489 :    logic [pt.ICACHE_BANKS_WAY-1:0]                 [31 : pt.ICACHE_DATA_INDEX_LO] ic_b_rw_addr;
     183       242070 :    logic [pt.ICACHE_BANKS_WAY-1:0]                 [31 : pt.ICACHE_DATA_INDEX_LO] ic_b_rw_addr_index_only;
     184              : 
     185            0 :    logic [pt.ICACHE_NUM_WAYS-1:0][pt.ICACHE_BANKS_WAY-1:0]                 [31 : pt.ICACHE_DATA_INDEX_LO] ic_b_rw_addr_up;
     186            0 :    logic [pt.ICACHE_NUM_WAYS-1:0][pt.ICACHE_BANKS_WAY-1:0]                 [31 : pt.ICACHE_DATA_INDEX_LO] ic_b_rw_addr_index_only_up;
     187              : 
     188              : 
     189              : 
     190       680968 :    logic                                                                          ic_rd_en_with_debug;
     191       213068 :    logic                                                                          ic_rw_addr_wrap, ic_cacheline_wrap_ff;
     192           20 :    logic                                                                          ic_debug_rd_en_ff;
     193              : 
     194              : 
     195              : //-----------------------------------------------------------
     196              : // ----------- Logic section starts here --------------------
     197              : //-----------------------------------------------------------
     198              :    assign  ic_debug_rd_way_en[pt.ICACHE_NUM_WAYS-1:0] =  {pt.ICACHE_NUM_WAYS{ic_debug_rd_en & ~ic_debug_tag_array}} & ic_debug_way[pt.ICACHE_NUM_WAYS-1:0] ;
     199              :    assign  ic_debug_wr_way_en[pt.ICACHE_NUM_WAYS-1:0] =  {pt.ICACHE_NUM_WAYS{ic_debug_wr_en & ~ic_debug_tag_array}} & ic_debug_way[pt.ICACHE_NUM_WAYS-1:0] ;
     200              : 
     201       883883 :    logic end_of_cache_line;
     202              :    assign end_of_cache_line = (pt.ICACHE_LN_SZ==7'h40) ? (&ic_rw_addr_q[5:4]) : ic_rw_addr_q[4];
     203          339 :    always_comb begin : clkens
     204          339 :       ic_bank_way_clken  = '0;
     205              : 
     206          339 :       for ( int i=0; i<pt.ICACHE_BANKS_WAY; i++) begin: wr_ens
     207          678 :        ic_b_sb_wren[i]        =  ic_wr_en[pt.ICACHE_NUM_WAYS-1:0]  |
     208          678 :                                        (ic_debug_wr_way_en[pt.ICACHE_NUM_WAYS-1:0] & {pt.ICACHE_NUM_WAYS{ic_debug_addr[pt.ICACHE_BANK_HI : pt.ICACHE_BANK_LO] == i}}) ;
     209          678 :        ic_debug_sel_sb[i]     = (ic_debug_addr[pt.ICACHE_BANK_HI : pt.ICACHE_BANK_LO] == i );
     210          678 :        ic_sb_wr_data[i]       = (ic_debug_sel_sb[i] & ic_debug_wr_en) ? ic_debug_wr_data : ic_bank_wr_data[i] ;
     211          678 :        ic_b_rden[i]           =  ic_rd_en_with_debug & ( ( ~ic_rw_addr_q[pt.ICACHE_BANK_HI] & (i==0)) |
     212          678 :                                                         (( ic_rw_addr_q[pt.ICACHE_BANK_HI] & ic_rw_addr_q[2:1] == 2'b11) & (i==0) & ~end_of_cache_line) |
     213          678 :                                                          (  ic_rw_addr_q[pt.ICACHE_BANK_HI] & (i==1)) |
     214          678 :                                                          ((~ic_rw_addr_q[pt.ICACHE_BANK_HI] & ic_rw_addr_q[2:1] == 2'b11) & (i==1)) ) ;
     215              : 
     216              : 
     217              : 
     218          678 :        ic_b_sb_rden[i]        =  {pt.ICACHE_NUM_WAYS{ic_b_rden[i]}}   ;
     219              : 
     220          678 :        for ( int j=0; j<pt.ICACHE_NUM_WAYS; j++) begin: way_clkens
     221         1356 :          ic_bank_way_clken[i][j] |= ic_b_sb_rden[i][j] | clk_override | ic_b_sb_wren[i][j];
     222              :        end
     223              :      end // block: wr_ens
     224              :    end // block: clkens
     225              : 
     226              : // bank read enables
     227              :   assign ic_rd_en_with_debug                          = (ic_rd_en   | ic_debug_rd_en ) & ~(|ic_wr_en);
     228              :   assign ic_rw_addr_q[pt.ICACHE_INDEX_HI:1] = (ic_debug_rd_en | ic_debug_wr_en) ?
     229              :                                               {ic_debug_addr[pt.ICACHE_INDEX_HI:3],2'b0} :
     230              :                                               ic_rw_addr[pt.ICACHE_INDEX_HI:1] ;
     231              : 
     232              :    assign ic_rw_addr_q_inc[pt.ICACHE_TAG_LO-1:pt.ICACHE_DATA_INDEX_LO] = ic_rw_addr_q[pt.ICACHE_TAG_LO-1 : pt.ICACHE_DATA_INDEX_LO] + 1 ;
     233              :    assign ic_rw_addr_wrap                                        = ic_rw_addr_q[pt.ICACHE_BANK_HI] & (ic_rw_addr_q[2:1] == 2'b11) & ic_rd_en_with_debug & ~(|ic_wr_en[pt.ICACHE_NUM_WAYS-1:0]);
     234              :    assign ic_cacheline_wrap_ff                                   = ic_rw_addr_ff[pt.ICACHE_TAG_INDEX_LO-1:pt.ICACHE_BANK_LO] == {(pt.ICACHE_TAG_INDEX_LO - pt.ICACHE_BANK_LO){1'b1}};
     235              : 
     236              : 
     237              :    assign ic_rw_addr_bank_q[0] = ~ic_rw_addr_wrap ? ic_rw_addr_q[pt.ICACHE_INDEX_HI:pt.ICACHE_DATA_INDEX_LO] : {ic_rw_addr_q[pt.ICACHE_INDEX_HI: pt.ICACHE_TAG_INDEX_LO] , ic_rw_addr_q_inc[pt.ICACHE_TAG_INDEX_LO-1: pt.ICACHE_DATA_INDEX_LO] } ;
     238              :    assign ic_rw_addr_bank_q[1] = ic_rw_addr_q[pt.ICACHE_INDEX_HI:pt.ICACHE_DATA_INDEX_LO];
     239              : 
     240              : 
     241              :    rvdffie #(.WIDTH(int'(pt.ICACHE_TAG_INDEX_LO+pt.ICACHE_BANKS_WAY+pt.ICACHE_NUM_WAYS)),.OVERRIDE(1)) miscff
     242              :             (.*,
     243              :              .din({ ic_b_rden[pt.ICACHE_BANKS_WAY-1:0],   ic_rw_addr_q[pt.ICACHE_TAG_INDEX_LO-1:1], ic_debug_rd_way_en[pt.ICACHE_NUM_WAYS-1:0],   ic_debug_rd_en}),
     244              :              .dout({ic_b_rden_ff[pt.ICACHE_BANKS_WAY-1:0],ic_rw_addr_ff[pt.ICACHE_TAG_INDEX_LO-1:1],ic_debug_rd_way_en_ff[pt.ICACHE_NUM_WAYS-1:0],ic_debug_rd_en_ff})
     245              :              );
     246              : 
     247              :  if (pt.ICACHE_WAYPACK == 0 ) begin : PACKED_0
     248              : 
     249              : 
     250              :     logic [pt.ICACHE_NUM_WAYS-1:0][pt.ICACHE_BANKS_WAY-1:0][pt.ICACHE_NUM_BYPASS_WIDTH-1:0] wrptr_up;
     251              :     logic [pt.ICACHE_NUM_WAYS-1:0][pt.ICACHE_BANKS_WAY-1:0][pt.ICACHE_NUM_BYPASS_WIDTH-1:0] wrptr_in_up;
     252              :     logic [pt.ICACHE_NUM_WAYS-1:0][pt.ICACHE_BANKS_WAY-1:0][pt.ICACHE_NUM_BYPASS-1:0]       sel_bypass_up;
     253              :     logic [pt.ICACHE_NUM_WAYS-1:0][pt.ICACHE_BANKS_WAY-1:0][pt.ICACHE_NUM_BYPASS-1:0]       sel_bypass_ff_up;
     254              :     logic [pt.ICACHE_NUM_WAYS-1:0][pt.ICACHE_BANKS_WAY-1:0][(71*pt.ICACHE_NUM_WAYS)-1:0]    sel_bypass_data_up;
     255              :     logic [pt.ICACHE_NUM_WAYS-1:0][pt.ICACHE_BANKS_WAY-1:0]                                 any_bypass_up;
     256              :     logic [pt.ICACHE_NUM_WAYS-1:0][pt.ICACHE_BANKS_WAY-1:0]                                 any_addr_match_up;
     257              : 
     258              : `define EL2_IC_DATA_SRAM(depth,width)                                                                               \
     259              :            ram_``depth``x``width ic_bank_sb_way_data (                                                               \
     260              :                                      .ME(ic_bank_way_clken_final_up[i][k]),                                          \
     261              :                                      .WE (ic_b_sb_wren[k][i]),                                                       \
     262              :                                      .D  (ic_sb_wr_data[k][``width-1:0]),                                            \
     263              :                                      .ADR(ic_rw_addr_bank_q[k][pt.ICACHE_INDEX_HI:pt.ICACHE_DATA_INDEX_LO]),         \
     264              :                                      .Q  (wb_dout_pre_up[i][k]),                                                     \
     265              :                                      .CLK (clk),                                                                     \
     266              :                                      .ROP ( ),                                                                       \
     267              :                                      .TEST1(ic_data_ext_in_pkt[i][k].TEST1),                                         \
     268              :                                      .RME(ic_data_ext_in_pkt[i][k].RME),                                             \
     269              :                                      .RM(ic_data_ext_in_pkt[i][k].RM),                                               \
     270              :                                                                                                                      \
     271              :                                      .LS(ic_data_ext_in_pkt[i][k].LS),                                               \
     272              :                                      .DS(ic_data_ext_in_pkt[i][k].DS),                                               \
     273              :                                      .SD(ic_data_ext_in_pkt[i][k].SD),                                               \
     274              :                                                                                                                      \
     275              :                                      .TEST_RNM(ic_data_ext_in_pkt[i][k].TEST_RNM),                                   \
     276              :                                      .BC1(ic_data_ext_in_pkt[i][k].BC1),                                             \
     277              :                                      .BC2(ic_data_ext_in_pkt[i][k].BC2)                                              \
     278              :                                     );  \
     279              : if (pt.ICACHE_BYPASS_ENABLE == 1) begin \
     280              :                  assign wrptr_in_up[i][k] = (wrptr_up[i][k] == (pt.ICACHE_NUM_BYPASS-1)) ? '0 : (wrptr_up[i][k] + 1'd1);                                    \
     281              :                  rvdffs  #(pt.ICACHE_NUM_BYPASS_WIDTH)  wrptr_ff(.*, .clk(active_clk),  .en(|write_bypass_en_up[i][k]), .din (wrptr_in_up[i][k]), .dout(wrptr_up[i][k])) ;     \
     282              :                  assign ic_b_sram_en_up[i][k]              = ic_bank_way_clken[k][i];                             \
     283              :                  assign ic_b_read_en_up[i][k]              =  ic_b_sram_en_up[i][k] &   ic_b_sb_rden[k][i];       \
     284              :                  assign ic_b_write_en_up[i][k]             =  ic_b_sram_en_up[i][k] &   ic_b_sb_wren[k][i];       \
     285              :                  assign ic_bank_way_clken_final_up[i][k]   =  ic_b_sram_en_up[i][k] &    ~(|sel_bypass_up[i][k]); \
     286              :                  assign ic_b_rw_addr_up[i][k] = {ic_rw_addr[31:pt.ICACHE_INDEX_HI+1],ic_rw_addr_bank_q[k]};       \
     287              :                  assign ic_b_rw_addr_index_only_up[i][k] = ic_rw_addr_bank_q[k];                                  \
     288              :                  always_comb begin                                                                                \
     289              :                     any_addr_match_up[i][k] = '0;                                                                 \
     290              :                     for (int l=0; l<pt.ICACHE_NUM_BYPASS; l++) begin                                              \
     291              :                        any_addr_match_up[i][k] |= ic_b_addr_match_up[i][k][l];                                    \
     292              :                     end                                                                                           \
     293              :                  end                                                                                              \
     294              :                 // it is an error to ever have 2 entries with the same index and both valid                       \
     295              :                 for (genvar l=0; l<pt.ICACHE_NUM_BYPASS; l++) begin: BYPASS                                       \
     296              :                    // full match up to bit 31                                                                     \
     297              :                    assign ic_b_addr_match_up[i][k][l] = (wb_index_hold_up[i][k][l] ==  ic_b_rw_addr_up[i][k]) & index_valid_up[i][k][l];            \
     298              :                    assign ic_b_addr_match_index_only_up[i][k][l] = (wb_index_hold_up[i][k][l][pt.ICACHE_INDEX_HI:pt.ICACHE_DATA_INDEX_LO] ==  ic_b_rw_addr_index_only_up[i][k]) & index_valid_up[i][k][l];            \
     299              :                                                                                                                                                     \
     300              :                    assign ic_b_clear_en_up[i][k][l]   = ic_b_write_en_up[i][k] &   ic_b_addr_match_index_only_up[i][k][l];                                     \
     301              :                                                                                                                                                     \
     302              :                    assign sel_bypass_up[i][k][l]      = ic_b_read_en_up[i][k]  &   ic_b_addr_match_up[i][k][l] ;                                    \
     303              :                                                                                                                                                     \
     304              :                    assign write_bypass_en_up[i][k][l] = ic_b_read_en_up[i][k]  &  ~any_addr_match_up[i][k] & (wrptr_up[i][k] == l);                 \
     305              :                                                                                                                                                     \
     306              :                    rvdff  #(1)  write_bypass_ff (.*, .clk(active_clk),                                                                 .din(write_bypass_en_up[i][k][l]), .dout(write_bypass_en_ff_up[i][k][l])) ; \
     307              :                    rvdffs #(1)  index_val_ff    (.*, .clk(active_clk), .en(write_bypass_en_up[i][k][l] | ic_b_clear_en_up[i][k][l]),   .din(~ic_b_clear_en_up[i][k][l]),  .dout(index_valid_up[i][k][l])) ;       \
     308              :                    rvdff  #(1)  sel_hold_ff     (.*, .clk(active_clk),                                                                 .din(sel_bypass_up[i][k][l]),      .dout(sel_bypass_ff_up[i][k][l])) ;     \
     309              :                    rvdffe #((31-pt.ICACHE_DATA_INDEX_LO+1)) ic_addr_index    (.*, .en(write_bypass_en_up[i][k][l]),    .din (ic_b_rw_addr_up[i][k]), .dout(wb_index_hold_up[i][k][l]));         \
     310              :                    rvdffe #(``width)                             rd_data_hold_ff  (.*, .en(write_bypass_en_ff_up[i][k][l]), .din (wb_dout_pre_up[i][k]),  .dout(wb_dout_hold_up[i][k][l]));     \
     311              :                 end                                                                                                                       \
     312              :                 always_comb begin                                                                                                         \
     313              :                  any_bypass_up[i][k] = '0;                                                                                                \
     314              :                  sel_bypass_data_up[i][k] = '0;                                                                                           \
     315              :                  for (int l=0; l<pt.ICACHE_NUM_BYPASS; l++) begin                                                                         \
     316              :                     any_bypass_up[i][k]      |=  sel_bypass_ff_up[i][k][l];                                                               \
     317              :                     sel_bypass_data_up[i][k] |= (sel_bypass_ff_up[i][k][l]) ? wb_dout_hold_up[i][k][l] : '0;                              \
     318              :                  end                                                                                                                      \
     319              :                  wb_dout[i][k]   =   any_bypass_up[i][k] ?  sel_bypass_data_up[i][k] :  wb_dout_pre_up[i][k] ;                            \
     320              :                  end                                                                                                                      \
     321              :              end                                                                                                                          \
     322              :              else begin                                                                                                                   \
     323              :                  assign wb_dout[i][k]                      =   wb_dout_pre_up[i][k] ;                                                     \
     324              :                  assign ic_bank_way_clken_final_up[i][k]   =  ic_bank_way_clken[k][i];                                                    \
     325              :              end
     326              : 
     327              : 
     328              :    for (genvar i=0; i<pt.ICACHE_NUM_WAYS; i++) begin: WAYS
     329              :       for (genvar k=0; k<pt.ICACHE_BANKS_WAY; k++) begin: BANKS_WAY   // 16B subbank
     330              :       if (pt.ICACHE_ECC) begin : ECC1
     331              :         logic [pt.ICACHE_NUM_WAYS-1:0][pt.ICACHE_BANKS_WAY-1:0] [71-1:0]        wb_dout_pre_up;           // data and its bit enables
     332              :         logic [pt.ICACHE_NUM_WAYS-1:0][pt.ICACHE_BANKS_WAY-1:0] [pt.ICACHE_NUM_BYPASS-1:0] [71-1:0]  wb_dout_hold_up;
     333              : 
     334              :         if ($clog2(pt.ICACHE_DATA_DEPTH) == 13 )   begin : size_8192
     335              :            `EL2_IC_DATA_SRAM(8192,71)
     336              :         end
     337              :         else if ($clog2(pt.ICACHE_DATA_DEPTH) == 12 )   begin : size_4096
     338              :            `EL2_IC_DATA_SRAM(4096,71)
     339              :         end
     340              :         else if ($clog2(pt.ICACHE_DATA_DEPTH) == 11 ) begin : size_2048
     341              :            `EL2_IC_DATA_SRAM(2048,71)
     342              :         end
     343              :         else if ( $clog2(pt.ICACHE_DATA_DEPTH) == 10 ) begin : size_1024
     344              :            `EL2_IC_DATA_SRAM(1024,71)
     345              :         end
     346              :         else if ( $clog2(pt.ICACHE_DATA_DEPTH) == 9 ) begin : size_512
     347              :            `EL2_IC_DATA_SRAM(512,71)
     348              :         end
     349              :          else if ( $clog2(pt.ICACHE_DATA_DEPTH) == 8 ) begin : size_256
     350              :            `EL2_IC_DATA_SRAM(256,71)
     351              :          end
     352              :          else if ( $clog2(pt.ICACHE_DATA_DEPTH) == 7 ) begin : size_128
     353              :            `EL2_IC_DATA_SRAM(128,71)
     354              :          end
     355              :          else  begin : size_64
     356              :            `EL2_IC_DATA_SRAM(64,71)
     357              :          end
     358              :       end // if (pt.ICACHE_ECC)
     359              : 
     360              :      else  begin  : ECC0
     361              :         logic [pt.ICACHE_NUM_WAYS-1:0][pt.ICACHE_BANKS_WAY-1:0] [68-1:0]        wb_dout_pre_up;           // data and its bit enables
     362              :         logic [pt.ICACHE_NUM_WAYS-1:0][pt.ICACHE_BANKS_WAY-1:0] [pt.ICACHE_NUM_BYPASS-1:0] [68-1:0]  wb_dout_hold_up;
     363              :         if ($clog2(pt.ICACHE_DATA_DEPTH) == 13 )   begin : size_8192
     364              :            `EL2_IC_DATA_SRAM(8192,68)
     365              :         end
     366              :         else if ($clog2(pt.ICACHE_DATA_DEPTH) == 12 )   begin : size_4096
     367              :            `EL2_IC_DATA_SRAM(4096,68)
     368              :         end
     369              :         else if ($clog2(pt.ICACHE_DATA_DEPTH) == 11 ) begin : size_2048
     370              :            `EL2_IC_DATA_SRAM(2048,68)
     371              :         end
     372              :         else if ( $clog2(pt.ICACHE_DATA_DEPTH) == 10 ) begin : size_1024
     373              :            `EL2_IC_DATA_SRAM(1024,68)
     374              :         end
     375              :         else if ( $clog2(pt.ICACHE_DATA_DEPTH) == 9 ) begin : size_512
     376              :            `EL2_IC_DATA_SRAM(512,68)
     377              :         end
     378              :          else if ( $clog2(pt.ICACHE_DATA_DEPTH) == 8 ) begin : size_256
     379              :            `EL2_IC_DATA_SRAM(256,68)
     380              :          end
     381              :          else if ( $clog2(pt.ICACHE_DATA_DEPTH) == 7 ) begin : size_128
     382              :            `EL2_IC_DATA_SRAM(128,68)
     383              :          end
     384              :          else  begin : size_64
     385              :            `EL2_IC_DATA_SRAM(64,68)
     386              :          end
     387              :       end // else: !if(pt.ICACHE_ECC)
     388              :       end // block: BANKS_WAY
     389              :    end // block: WAYS
     390              : 
     391              :  end // block: PACKED_0
     392              : 
     393              :  // WAY PACKED
     394              :  else begin : PACKED_1
     395              : 
     396              :     logic [pt.ICACHE_BANKS_WAY-1:0][pt.ICACHE_NUM_BYPASS_WIDTH-1:0] wrptr;
     397              :     logic [pt.ICACHE_BANKS_WAY-1:0][pt.ICACHE_NUM_BYPASS_WIDTH-1:0] wrptr_in;
     398              :     logic [pt.ICACHE_BANKS_WAY-1:0][pt.ICACHE_NUM_BYPASS-1:0]                       sel_bypass;
     399              :     logic [pt.ICACHE_BANKS_WAY-1:0][pt.ICACHE_NUM_BYPASS-1:0]                       sel_bypass_ff;
     400              : 
     401              : 
     402              :     logic [pt.ICACHE_BANKS_WAY-1:0][(71*pt.ICACHE_NUM_WAYS)-1:0]  sel_bypass_data;
     403              :     logic [pt.ICACHE_BANKS_WAY-1:0]                               any_bypass;
     404              :     logic [pt.ICACHE_BANKS_WAY-1:0]                               any_addr_match;
     405              : 
     406              : 
     407              : // SRAM macros
     408              : 
     409              : `define EL2_PACKED_IC_DATA_SRAM(depth,width,waywidth)                                                                                                 \
     410              :             ram_be_``depth``x``width  ic_bank_sb_way_data (                                                                                           \
     411              :                             .CLK   (clk),                                                                                                             \
     412              :                             .WE    (|ic_b_sb_wren[k]),                                                    // OR of all the ways in the bank           \
     413              :                             .WEM   (ic_b_sb_bit_en_vec[k]),                                               // 284 bits of bit enables                  \
     414              :                             .D     ({pt.ICACHE_NUM_WAYS{ic_sb_wr_data[k][``waywidth-1:0]}}),                                                          \
     415              :                             .ADR   (ic_rw_addr_bank_q[k][pt.ICACHE_INDEX_HI:pt.ICACHE_DATA_INDEX_LO]),                                                \
     416              :                             .Q     (wb_packeddout_pre[k]),                                                                                            \
     417              :                             .ME    (|ic_bank_way_clken_final[k]),                                                                                     \
     418              :                             .ROP   ( ),                                                                                                               \
     419              :                             .TEST1  (ic_data_ext_in_pkt[0][k].TEST1),                                                                                 \
     420              :                             .RME   (ic_data_ext_in_pkt[0][k].RME),                                                                                    \
     421              :                             .RM    (ic_data_ext_in_pkt[0][k].RM),                                                                                     \
     422              :                                                                                                                                                       \
     423              :                             .LS    (ic_data_ext_in_pkt[0][k].LS),                                                                                     \
     424              :                             .DS    (ic_data_ext_in_pkt[0][k].DS),                                                                                     \
     425              :                             .SD    (ic_data_ext_in_pkt[0][k].SD),                                                                                     \
     426              :                                                                                                                                                       \
     427              :                             .TEST_RNM (ic_data_ext_in_pkt[0][k].TEST_RNM),                                                                            \
     428              :                             .BC1      (ic_data_ext_in_pkt[0][k].BC1),                                                                                 \
     429              :                             .BC2      (ic_data_ext_in_pkt[0][k].BC2)                                                                                  \
     430              :                            );                                                                                                                         \
     431              :                                                                                                                                                       \
     432              :               if (pt.ICACHE_BYPASS_ENABLE == 1) begin                                                                                                                                                 \
     433              :                                                                                                                                                                                                       \
     434              :                  assign wrptr_in[k] = (wrptr[k] == (pt.ICACHE_NUM_BYPASS-1)) ? '0 : (wrptr[k] + 1'd1);                                                                                                \
     435              :                                                                                                                                                                                                       \
     436              :                  rvdffs  #(pt.ICACHE_NUM_BYPASS_WIDTH)  wrptr_ff(.*, .clk(active_clk), .en(|write_bypass_en[k]), .din (wrptr_in[k]), .dout(wrptr[k])) ;                                                                       \
     437              :                                                                                                                                                                                                       \
     438              :                  assign ic_b_sram_en[k]              = |ic_bank_way_clken[k];                                                                                                                         \
     439              :                                                                                                                                                                                                       \
     440              :                                                                                                                                                                                                       \
     441              :                  assign ic_b_read_en[k]              =  ic_b_sram_en[k]  &  (|ic_b_sb_rden[k]) ;                                                                                                              \
     442              :                  assign ic_b_write_en[k]             =  ic_b_sram_en[k] &   (|ic_b_sb_wren[k]);                                                                                                       \
     443              :                  assign ic_bank_way_clken_final[k]   =  ic_b_sram_en[k] &    ~(|sel_bypass[k]);                                                                                                       \
     444              :                                                                                                                                                                                                       \
     445              :                  assign ic_b_rw_addr[k] = {ic_rw_addr[31:pt.ICACHE_INDEX_HI+1],ic_rw_addr_bank_q[k]};                                                                                                 \
     446              :                  assign ic_b_rw_addr_index_only[k] = ic_rw_addr_bank_q[k];                                                                                                    \
     447              :                                                                                                                                                                                                       \
     448              :                  always_comb begin                                                                                                                                                                    \
     449              :                     any_addr_match[k] = '0;                                                                                                                                                           \
     450              :                                                                                                                                                                                                       \
     451              :                     for (int l=0; l<pt.ICACHE_NUM_BYPASS; l++) begin                                                                                                                                  \
     452              :                        any_addr_match[k] |= ic_b_addr_match[k][l];                                                                                                                                    \
     453              :                     end                                                                                                                                                                               \
     454              :                  end                                                                                                                                                                                  \
     455              :                                                                                                                                                                                                       \
     456              :                 // it is an error to ever have 2 entries with the same index and both valid                                                                                                           \
     457              :                 for (genvar l=0; l<pt.ICACHE_NUM_BYPASS; l++) begin: BYPASS                                                                                                                           \
     458              :                                                                                                                                                                                                       \
     459              :                    // full match up to bit 31                                                                                                                                                         \
     460              :                    assign ic_b_addr_match[k][l] = (wb_index_hold[k][l] ==  ic_b_rw_addr[k]) & index_valid[k][l];                                                                                      \
     461              :                    assign ic_b_addr_match_index_only[k][l] = (wb_index_hold[k][l][pt.ICACHE_INDEX_HI:pt.ICACHE_DATA_INDEX_LO] ==  ic_b_rw_addr_index_only[k]) & index_valid[k][l];                    \
     462              :                                                                                                                                                                                                       \
     463              :                    assign ic_b_clear_en[k][l]   = ic_b_write_en[k] &   ic_b_addr_match_index_only[k][l];                                                                                                              \
     464              :                                                                                                                                                                                                       \
     465              :                    assign sel_bypass[k][l]      = ic_b_read_en[k]  &   ic_b_addr_match[k][l] ;                                                                                                        \
     466              :                                                                                                                                                                                                       \
     467              :                    assign write_bypass_en[k][l] = ic_b_read_en[k]  &  ~any_addr_match[k] & (wrptr[k] == l);                                                                                           \
     468              :                                                                                                                                                                                                       \
     469              :                    rvdff  #(1)  write_bypass_ff (.*, .clk(active_clk),                                                     .din(write_bypass_en[k][l]), .dout(write_bypass_en_ff[k][l])) ;                            \
     470              :                    rvdffs #(1)  index_val_ff    (.*, .clk(active_clk), .en(write_bypass_en[k][l] | ic_b_clear_en[k][l]),   .din(~ic_b_clear_en[k][l]),  .dout(index_valid[k][l])) ;                                   \
     471              :                    rvdff  #(1)  sel_hold_ff     (.*, .clk(active_clk),                                                     .din(sel_bypass[k][l]),      .dout(sel_bypass_ff[k][l])) ;                                 \
     472              :                                                                                                                                                                                                       \
     473              :                    rvdffe #((31-pt.ICACHE_DATA_INDEX_LO+1)) ic_addr_index    (.*, .en(write_bypass_en[k][l]),    .din (ic_b_rw_addr[k]),      .dout(wb_index_hold[k][l]));                            \
     474              :                    rvdffe #((``waywidth*pt.ICACHE_NUM_WAYS))        rd_data_hold_ff  (.*, .en(write_bypass_en_ff[k][l]), .din (wb_packeddout_pre[k]), .dout(wb_packeddout_hold[k][l]));                       \
     475              :                                                                                                                                                                                                       \
     476              :                 end // block: BYPASS                                                                                                                                                                  \
     477              :                                                                                                                                                                                                       \
     478              :                 always_comb begin                                                                                                                                                                     \
     479              :                  any_bypass[k] = '0;                                                                                                                                                                  \
     480              :                  sel_bypass_data[k] = '0;                                                                                                                                                             \
     481              :                                                                                                                                                                                                       \
     482              :                  for (int l=0; l<pt.ICACHE_NUM_BYPASS; l++) begin                                                                                                                                     \
     483              :                     any_bypass[k]      |=  sel_bypass_ff[k][l];                                                                                                                                       \
     484              :                       sel_bypass_data[k] |= (sel_bypass_ff[k][l]) ? wb_packeddout_hold[k][l] : '0;                                                                                                    \
     485              :                  end                                                                                                                                                                                  \
     486              :                                                                                                                                                                                                       \
     487              :                    wb_packeddout[k]   =   any_bypass[k] ?  sel_bypass_data[k] :  wb_packeddout_pre[k] ;                                                                                               \
     488              :                 end // always_comb begin                                                                                                                                                              \
     489              :                                                                                                                                                                                                       \
     490              :              end // if (pt.ICACHE_BYPASS_ENABLE == 1)                                                                                                                                                 \
     491              :              else begin                                                                                                                                                                               \
     492              :                  assign wb_packeddout[k]   =   wb_packeddout_pre[k] ;                                                                                                                                 \
     493              :                  assign ic_bank_way_clken_final[k]   =  |ic_bank_way_clken[k] ;                                                                                                                       \
     494              :              end
     495              : 
     496              :  // generate IC DATA PACKED SRAMS for 2/4 ways
     497          678 :   for (genvar k=0; k<pt.ICACHE_BANKS_WAY; k++) begin: BANKS_WAY   // 16B subbank
     498              :      if (pt.ICACHE_ECC) begin : ECC1
     499              :         logic [pt.ICACHE_BANKS_WAY-1:0] [(71*pt.ICACHE_NUM_WAYS)-1:0]        wb_packeddout, ic_b_sb_bit_en_vec, wb_packeddout_pre;           // data and its bit enables
     500              : 
     501              :         logic [pt.ICACHE_BANKS_WAY-1:0] [pt.ICACHE_NUM_BYPASS-1:0] [(71*pt.ICACHE_NUM_WAYS)-1:0]  wb_packeddout_hold;
     502              : 
     503              :         for (genvar i=0; i<pt.ICACHE_NUM_WAYS; i++) begin: BITEN
     504              :            assign ic_b_sb_bit_en_vec[k][(71*i)+70:71*i] = {71{ic_b_sb_wren[k][i]}};
     505              :         end
     506              : 
     507              :         // SRAMS with ECC (single/double detect; no correct)
     508              :         if ($clog2(pt.ICACHE_DATA_DEPTH) == 13 )   begin : size_8192
     509              :            if (pt.ICACHE_NUM_WAYS == 4) begin : WAYS
     510              :               `EL2_PACKED_IC_DATA_SRAM(8192,284,71)    // 64b data + 7b ecc
     511              :            end // block: WAYS
     512              :            else   begin : WAYS
     513              :               `EL2_PACKED_IC_DATA_SRAM(8192,142,71)
     514              :            end // block: WAYS
     515              :         end // block: size_8192
     516              : 
     517              :         else if ($clog2(pt.ICACHE_DATA_DEPTH) == 12 )   begin : size_4096
     518              :            if (pt.ICACHE_NUM_WAYS == 4) begin : WAYS
     519              :               `EL2_PACKED_IC_DATA_SRAM(4096,284,71)
     520              :            end // block: WAYS
     521              :            else   begin : WAYS
     522              :               `EL2_PACKED_IC_DATA_SRAM(4096,142,71)
     523              :            end // block: WAYS
     524              :         end // block: size_4096
     525              : 
     526              :         else if ($clog2(pt.ICACHE_DATA_DEPTH) == 11 ) begin : size_2048
     527              :            if (pt.ICACHE_NUM_WAYS == 4) begin : WAYS
     528              :               `EL2_PACKED_IC_DATA_SRAM(2048,284,71)
     529              :            end // block: WAYS
     530              :            else   begin : WAYS
     531              :               `EL2_PACKED_IC_DATA_SRAM(2048,142,71)
     532              :            end // block: WAYS
     533              :         end // block: size_2048
     534              : 
     535              :         else if ( $clog2(pt.ICACHE_DATA_DEPTH) == 10 ) begin : size_1024
     536              :            if (pt.ICACHE_NUM_WAYS == 4) begin : WAYS
     537              :               `EL2_PACKED_IC_DATA_SRAM(1024,284,71)
     538              :            end // block: WAYS
     539              :            else   begin : WAYS
     540              :               `EL2_PACKED_IC_DATA_SRAM(1024,142,71)
     541              :            end // block: WAYS
     542              :         end // block: size_1024
     543              : 
     544              :         else if ( $clog2(pt.ICACHE_DATA_DEPTH) == 9 ) begin : size_512
     545              :            if (pt.ICACHE_NUM_WAYS == 4) begin : WAYS
     546              :               `EL2_PACKED_IC_DATA_SRAM(512,284,71)
     547              :            end // block: WAYS
     548              :            else   begin : WAYS
     549          678 :               `EL2_PACKED_IC_DATA_SRAM(512,142,71)
     550              :            end // block: WAYS
     551              :         end // block: size_512
     552              : 
     553              :         else if ( $clog2(pt.ICACHE_DATA_DEPTH) == 8 ) begin : size_256
     554              :            if (pt.ICACHE_NUM_WAYS == 4) begin : WAYS
     555              :               `EL2_PACKED_IC_DATA_SRAM(256,284,71)
     556              :            end // block: WAYS
     557              :            else   begin : WAYS
     558              :               `EL2_PACKED_IC_DATA_SRAM(256,142,71)
     559              :            end // block: WAYS
     560              :         end // block: size_256
     561              : 
     562              :         else if ( $clog2(pt.ICACHE_DATA_DEPTH) == 7 ) begin : size_128
     563              :            if (pt.ICACHE_NUM_WAYS == 4) begin : WAYS
     564              :               `EL2_PACKED_IC_DATA_SRAM(128,284,71)
     565              :            end // block: WAYS
     566              :            else   begin : WAYS
     567              :               `EL2_PACKED_IC_DATA_SRAM(128,142,71)
     568              :            end // block: WAYS
     569              :         end // block: size_128
     570              : 
     571              :         else  begin : size_64
     572              :            if (pt.ICACHE_NUM_WAYS == 4) begin : WAYS
     573              :               `EL2_PACKED_IC_DATA_SRAM(64,284,71)
     574              :            end // block: WAYS
     575              :            else   begin : WAYS
     576              :               `EL2_PACKED_IC_DATA_SRAM(64,142,71)
     577              :            end // block: WAYS
     578              :         end // block: size_64
     579              : 
     580              : 
     581              :        for (genvar i=0; i<pt.ICACHE_NUM_WAYS; i++) begin: WAYS
     582              :           assign wb_dout[i][k][70:0]  = wb_packeddout[k][(71*i)+70:71*i];
     583              :        end : WAYS
     584              : 
     585              :        end // if (pt.ICACHE_ECC)
     586              : 
     587              : 
     588              :      else  begin  : ECC0
     589              :         logic [pt.ICACHE_BANKS_WAY-1:0] [(68*pt.ICACHE_NUM_WAYS)-1:0]        wb_packeddout, ic_b_sb_bit_en_vec, wb_packeddout_pre;           // data and its bit enables
     590              : 
     591              :         logic [pt.ICACHE_BANKS_WAY-1:0] [pt.ICACHE_NUM_BYPASS-1:0] [(68*pt.ICACHE_NUM_WAYS)-1:0]  wb_packeddout_hold;
     592              : 
     593              :         for (genvar i=0; i<pt.ICACHE_NUM_WAYS; i++) begin: BITEN
     594              :            assign ic_b_sb_bit_en_vec[k][(68*i)+67:68*i] = {68{ic_b_sb_wren[k][i]}};
     595              :         end
     596              : 
     597              :         // SRAMs with parity
     598              :         if ($clog2(pt.ICACHE_DATA_DEPTH) == 13 )   begin : size_8192
     599              :            if (pt.ICACHE_NUM_WAYS == 4) begin : WAYS
     600              :               `EL2_PACKED_IC_DATA_SRAM(8192,272,68)    // 64b data + 4b parity
     601              :            end // block: WAYS
     602              :            else   begin : WAYS
     603              :               `EL2_PACKED_IC_DATA_SRAM(8192,136,68)
     604              :            end // block: WAYS
     605              :         end // block: size_8192
     606              : 
     607              :         else if ($clog2(pt.ICACHE_DATA_DEPTH) == 12 )   begin : size_4096
     608              :            if (pt.ICACHE_NUM_WAYS == 4) begin : WAYS
     609              :               `EL2_PACKED_IC_DATA_SRAM(4096,272,68)
     610              :            end // block: WAYS
     611              :            else   begin : WAYS
     612              :               `EL2_PACKED_IC_DATA_SRAM(4096,136,68)
     613              :            end // block: WAYS
     614              :         end // block: size_4096
     615              : 
     616              :         else if ($clog2(pt.ICACHE_DATA_DEPTH) == 11 ) begin : size_2048
     617              :            if (pt.ICACHE_NUM_WAYS == 4) begin : WAYS
     618              :               `EL2_PACKED_IC_DATA_SRAM(2048,272,68)
     619              :            end // block: WAYS
     620              :            else   begin : WAYS
     621              :               `EL2_PACKED_IC_DATA_SRAM(2048,136,68)
     622              :            end // block: WAYS
     623              :         end // block: size_2048
     624              : 
     625              :         else if ( $clog2(pt.ICACHE_DATA_DEPTH) == 10 ) begin : size_1024
     626              :            if (pt.ICACHE_NUM_WAYS == 4) begin : WAYS
     627              :               `EL2_PACKED_IC_DATA_SRAM(1024,272,68)
     628              :            end // block: WAYS
     629              :            else   begin : WAYS
     630              :               `EL2_PACKED_IC_DATA_SRAM(1024,136,68)
     631              :            end // block: WAYS
     632              :         end // block: size_1024
     633              : 
     634              :         else if ( $clog2(pt.ICACHE_DATA_DEPTH) == 9 ) begin : size_512
     635              :            if (pt.ICACHE_NUM_WAYS == 4) begin : WAYS
     636              :               `EL2_PACKED_IC_DATA_SRAM(512,272,68)
     637              :            end // block: WAYS
     638              :            else   begin : WAYS
     639              :               `EL2_PACKED_IC_DATA_SRAM(512,136,68)
     640              :            end // block: WAYS
     641              :         end // block: size_512
     642              : 
     643              :         else if ( $clog2(pt.ICACHE_DATA_DEPTH) == 8 ) begin : size_256
     644              :            if (pt.ICACHE_NUM_WAYS == 4) begin : WAYS
     645              :               `EL2_PACKED_IC_DATA_SRAM(256,272,68)
     646              :            end // block: WAYS
     647              :            else   begin : WAYS
     648              :               `EL2_PACKED_IC_DATA_SRAM(256,136,68)
     649              :            end // block: WAYS
     650              :         end // block: size_256
     651              : 
     652              :         else if ( $clog2(pt.ICACHE_DATA_DEPTH) == 7 ) begin : size_128
     653              :            if (pt.ICACHE_NUM_WAYS == 4) begin : WAYS
     654              :               `EL2_PACKED_IC_DATA_SRAM(128,272,68)
     655              :            end // block: WAYS
     656              :            else   begin : WAYS
     657              :               `EL2_PACKED_IC_DATA_SRAM(128,136,68)
     658              :            end // block: WAYS
     659              :         end // block: size_128
     660              : 
     661              :         else  begin : size_64
     662              :            if (pt.ICACHE_NUM_WAYS == 4) begin : WAYS
     663              :               `EL2_PACKED_IC_DATA_SRAM(64,272,68)
     664              :            end // block: WAYS
     665              :            else   begin : WAYS
     666              :               `EL2_PACKED_IC_DATA_SRAM(64,136,68)
     667              :            end // block: WAYS
     668              :         end // block: size_64
     669              : 
     670              :        for (genvar i=0; i<pt.ICACHE_NUM_WAYS; i++) begin: WAYS
     671              :           assign wb_dout[i][k][67:0]  = wb_packeddout[k][(68*i)+67:68*i];
     672              :        end
     673              :      end // block: ECC0
     674              :      end // block: BANKS_WAY
     675              :  end // block: PACKED_1
     676              : 
     677              : 
     678              :    assign ic_rd_hit_q[pt.ICACHE_NUM_WAYS-1:0] = ic_debug_rd_en_ff ? ic_debug_rd_way_en_ff[pt.ICACHE_NUM_WAYS-1:0] : ic_rd_hit[pt.ICACHE_NUM_WAYS-1:0] ;
     679              : 
     680              : 
     681              :  if ( pt.ICACHE_ECC ) begin : ECC1_MUX
     682              : 
     683              :    assign ic_bank_wr_data[1] = ic_wr_data[1][70:0];
     684              :    assign ic_bank_wr_data[0] = ic_wr_data[0][70:0];
     685              : 
     686          339 :     always_comb begin : rd_mux
     687          339 :       wb_dout_way_pre[pt.ICACHE_NUM_WAYS-1:0] = '0;
     688              : 
     689          339 :       for ( int i=0; i<pt.ICACHE_NUM_WAYS; i++) begin : num_ways
     690          678 :         for ( int j=0; j<pt.ICACHE_BANKS_WAY; j++) begin : banks
     691         1356 :          wb_dout_way_pre[i][70:0]      |=  ({71{(ic_rw_addr_ff[pt.ICACHE_BANK_HI : pt.ICACHE_BANK_LO] == (pt.ICACHE_BANK_BITS)'(j))}}   &  wb_dout[i][j]);
     692         1356 :          wb_dout_way_pre[i][141 : 71]  |=  ({71{(ic_rw_addr_ff[pt.ICACHE_BANK_HI : pt.ICACHE_BANK_LO] == (pt.ICACHE_BANK_BITS)'(j-1))}} &  wb_dout[i][j]);
     693              :         end
     694              :       end
     695              :     end
     696              : 
     697              :     for ( genvar i=0; i<pt.ICACHE_NUM_WAYS; i++) begin : num_ways_mux1
     698              :       assign wb_dout_way[i][63:0] = (ic_rw_addr_ff[2:1] == 2'b00) ? wb_dout_way_pre[i][63:0]   :
     699              :                                     (ic_rw_addr_ff[2:1] == 2'b01) ?{wb_dout_way_pre[i][86:71], wb_dout_way_pre[i][63:16]} :
     700              :                                     (ic_rw_addr_ff[2:1] == 2'b10) ?{wb_dout_way_pre[i][102:71],wb_dout_way_pre[i][63:32]} :
     701              :                                                                    {wb_dout_way_pre[i][119:71],wb_dout_way_pre[i][63:48]};
     702              : 
     703              :       assign wb_dout_way_with_premux[i][63:0]  =  ic_sel_premux_data ? ic_premux_data[63:0] : wb_dout_way[i][63:0] ;
     704              :    end
     705              : 
     706          339 :    always_comb begin : rd_out
     707          339 :       ic_debug_rd_data[70:0]     = '0;
     708          339 :       ic_rd_data[63:0]           = '0;
     709          339 :       wb_dout_ecc[141:0]         = '0;
     710          339 :       for ( int i=0; i<pt.ICACHE_NUM_WAYS; i++) begin : num_ways_mux2
     711          678 :          ic_rd_data[63:0]       |= ({64{ic_rd_hit_q[i] | ic_sel_premux_data}}) &  wb_dout_way_with_premux[i][63:0];
     712          678 :          ic_debug_rd_data[70:0] |= ({71{ic_rd_hit_q[i]}}) & wb_dout_way_pre[i][70:0];
     713          678 :          wb_dout_ecc[141:0]     |= {142{ic_rd_hit_q[i]}}  & wb_dout_way_pre[i];
     714              :       end
     715              :    end
     716              : 
     717              : 
     718              :  for (genvar i=0; i < pt.ICACHE_BANKS_WAY ; i++) begin : ic_ecc_error
     719              :     assign bank_check_en[i]    = |ic_rd_hit[pt.ICACHE_NUM_WAYS-1:0] & ((i==0) | (~ic_cacheline_wrap_ff & (ic_b_rden_ff[pt.ICACHE_BANKS_WAY-1:0] == {pt.ICACHE_BANKS_WAY{1'b1}})));  // always check the lower address bank, and drop the upper address bank on a CL wrap
     720              :     assign wb_dout_ecc_bank[i] = wb_dout_ecc[(71*i)+70:(71*i)];
     721              : 
     722              :    rvecc_decode_64  ecc_decode_64 (
     723              :                            .en               (bank_check_en[i]),
     724              :                            .din              (wb_dout_ecc_bank[i][63 : 0]),                // [134:71],  [63:0]
     725              :                            .ecc_in           (wb_dout_ecc_bank[i][70 : 64]),               // [141:135] [70:64]
     726              :                            .ecc_error        (ic_eccerr[i]));
     727              : 
     728              :    // or the sb and db error detects into 1 signal called aligndataperr[i] where i corresponds to 2B position
     729              :   assign  ic_parerr[i]  = '0 ;
     730              :   end // block: ic_ecc_error
     731              : 
     732              : end // if ( pt.ICACHE_ECC )
     733              : 
     734              : else  begin : ECC0_MUX
     735              :    assign ic_bank_wr_data[1] = ic_wr_data[1][70:0];
     736              :    assign ic_bank_wr_data[0] = ic_wr_data[0][70:0];
     737              : 
     738              :    always_comb begin : rd_mux
     739              :       wb_dout_way_pre[pt.ICACHE_NUM_WAYS-1:0] = '0;
     740              : 
     741              :    for ( int i=0; i<pt.ICACHE_NUM_WAYS; i++) begin : num_ways
     742              :      for ( int j=0; j<pt.ICACHE_BANKS_WAY; j++) begin : banks
     743              :          wb_dout_way_pre[i][67:0]         |=  ({68{(ic_rw_addr_ff[pt.ICACHE_BANK_HI : pt.ICACHE_BANK_LO] == (pt.ICACHE_BANK_BITS)'(j))}}   &  wb_dout[i][j][67:0]);
     744              :          wb_dout_way_pre[i][135 : 68]     |=  ({68{(ic_rw_addr_ff[pt.ICACHE_BANK_HI : pt.ICACHE_BANK_LO] == (pt.ICACHE_BANK_BITS)'(j-1))}} &  wb_dout[i][j][67:0]);
     745              :       end
     746              :      end
     747              :    end
     748              :    // When we straddle the banks like this - the ECC we capture is not correct ??
     749              :    for ( genvar i=0; i<pt.ICACHE_NUM_WAYS; i++) begin : num_ways_mux1
     750              :       assign wb_dout_way[i][63:0] = (ic_rw_addr_ff[2:1] == 2'b00) ? wb_dout_way_pre[i][63:0]   :
     751              :                                     (ic_rw_addr_ff[2:1] == 2'b01) ?{wb_dout_way_pre[i][83:68],  wb_dout_way_pre[i][63:16]} :
     752              :                                     (ic_rw_addr_ff[2:1] == 2'b10) ?{wb_dout_way_pre[i][99:68],  wb_dout_way_pre[i][63:32]} :
     753              :                                                                    {wb_dout_way_pre[i][115:68], wb_dout_way_pre[i][63:48]};
     754              : 
     755              :       assign wb_dout_way_with_premux[i][63:0]      =  ic_sel_premux_data ? ic_premux_data[63:0]  : wb_dout_way[i][63:0] ;
     756              :    end
     757              : 
     758              :    always_comb begin : rd_out
     759              :       ic_rd_data[63:0]   = '0;
     760              :       ic_debug_rd_data[70:0]   = '0;
     761              :       wb_dout_ecc[135:0] = '0;
     762              : 
     763              :       for ( int i=0; i<pt.ICACHE_NUM_WAYS; i++) begin : num_ways_mux2
     764              :          ic_rd_data[63:0]   |= ({64{ic_rd_hit_q[i] | ic_sel_premux_data}} &  wb_dout_way_with_premux[i][63:0]);
     765              :          ic_debug_rd_data[70:0] |= ({71{ic_rd_hit_q[i]}}) & {3'b0,wb_dout_way_pre[i][67:0]};
     766              :          wb_dout_ecc[135:0] |= {136{ic_rd_hit_q[i]}}  & wb_dout_way_pre[i][135:0];
     767              :       end
     768              :    end
     769              : 
     770              :    assign wb_dout_ecc_bank[0] =  wb_dout_ecc[67:0];
     771              :    assign wb_dout_ecc_bank[1] =  wb_dout_ecc[135:68];
     772              : 
     773              :    logic [pt.ICACHE_BANKS_WAY-1:0][3:0] ic_parerr_bank;
     774              : 
     775              :   for (genvar i=0; i < pt.ICACHE_BANKS_WAY ; i++) begin : ic_par_error
     776              :     assign bank_check_en[i]    = |ic_rd_hit[pt.ICACHE_NUM_WAYS-1:0] & ((i==0) | (~ic_cacheline_wrap_ff & (ic_b_rden_ff[pt.ICACHE_BANKS_WAY-1:0] == {pt.ICACHE_BANKS_WAY{1'b1}})));  // always check the lower address bank, and drop the upper address bank on a CL wrap
     777              :      for (genvar j=0; j<4; j++)  begin : parity
     778              :       rveven_paritycheck pchk (
     779              :                            .data_in   (wb_dout_ecc_bank[i][16*(j+1)-1: 16*j]),
     780              :                            .parity_in (wb_dout_ecc_bank[i][64+j]),
     781              :                            .parity_err(ic_parerr_bank[i][j] )
     782              :                            );
     783              :         end
     784              :      assign ic_eccerr [i] = '0 ;
     785              :   end
     786              : 
     787              :      assign ic_parerr[1] = (|ic_parerr_bank[1][3:0]) & bank_check_en[1];
     788              :      assign ic_parerr[0] = (|ic_parerr_bank[0][3:0]) & bank_check_en[0];
     789              : 
     790              : end // else: !if( pt.ICACHE_ECC )
     791              : 
     792              : 
     793              : endmodule // EL2_IC_DATA
     794              : 
     795              : //=============================================================================================================================================================
     796              : ///\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ END OF IC DATA MODULE \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
     797              : //\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
     798              : //=============================================================================================================================================================
     799              : 
     800              : /////////////////////////////////////////////////
     801              : ////// ICACHE TAG MODULE     ////////////////////
     802              : /////////////////////////////////////////////////
     803              : module EL2_IC_TAG
     804              : import el2_pkg::*;
     805              :  #(
     806              : `include "el2_param.vh"
     807              :  )
     808              :      (
     809     69840565 :       input logic                                                   clk,
     810     69840565 :       input logic                                                   active_clk,
     811          338 :       input logic                                                   rst_l,
     812            2 :       input logic                                                   clk_override,
     813            8 :       input logic                                                   dec_tlu_core_ecc_disable,
     814              : 
     815          489 :       input logic [31:3]                                            ic_rw_addr,
     816              : 
     817        10432 :       input logic [pt.ICACHE_NUM_WAYS-1:0]                         ic_wr_en,             // way
     818       255918 :       input logic [pt.ICACHE_NUM_WAYS-1:0]                         ic_tag_valid,
     819       680948 :       input logic                                                  ic_rd_en,
     820              : 
     821            0 :       input logic [pt.ICACHE_INDEX_HI:3]                           ic_debug_addr,        // Read/Write addresss to the Icache.
     822           20 :       input logic                                                  ic_debug_rd_en,       // Icache debug rd
     823           20 :       input logic                                                  ic_debug_wr_en,       // Icache debug wr
     824            8 :       input logic                                                  ic_debug_tag_array,   // Debug tag array
     825            0 :       input logic [pt.ICACHE_NUM_WAYS-1:0]                         ic_debug_way,         // Debug way. Rd or Wr.
     826            0 :       input el2_ic_tag_ext_in_pkt_t   [pt.ICACHE_NUM_WAYS-1:0]    ic_tag_ext_in_pkt,
     827              : 
     828            0 :       output logic [25:0]                                          ictag_debug_rd_data,
     829            0 :       input  logic [70:0]                                          ic_debug_wr_data,     // Debug wr cache.
     830              : 
     831       109586 :       output logic [pt.ICACHE_NUM_WAYS-1:0]                        ic_rd_hit,
     832            0 :       output logic                                                 ic_tag_perr,
     833              :       // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core.
     834              :       /*verilator coverage_off*/
     835              :       input  logic                                                 scan_mode
     836              :       /*verilator coverage_on*/
     837              :    ) ;
     838              : 
     839            0 :    logic [pt.ICACHE_NUM_WAYS-1:0] [25:0]                           ic_tag_data_raw;
     840            0 :    logic [pt.ICACHE_NUM_WAYS-1:0] [25:0]                           ic_tag_data_raw_pre;
     841        13378 :    logic [pt.ICACHE_NUM_WAYS-1:0] [36:pt.ICACHE_TAG_LO]            w_tout;
     842           16 :    logic [25:0]                                                    ic_tag_wr_data ;
     843            0 :    logic [pt.ICACHE_NUM_WAYS-1:0] [31:0]                           ic_tag_corrected_data_unc;
     844            0 :    logic [pt.ICACHE_NUM_WAYS-1:0] [06:0]                           ic_tag_corrected_ecc_unc;
     845            0 :    logic [pt.ICACHE_NUM_WAYS-1:0]                                  ic_tag_single_ecc_error;
     846            0 :    logic [pt.ICACHE_NUM_WAYS-1:0]                                  ic_tag_double_ecc_error;
     847        17778 :    logic [6:0]                                                     ic_tag_ecc;
     848              : 
     849            0 :    logic [pt.ICACHE_NUM_WAYS-1:0]                                  ic_tag_way_perr ;
     850            0 :    logic [pt.ICACHE_NUM_WAYS-1:0]                                  ic_debug_rd_way_en ;
     851            0 :    logic [pt.ICACHE_NUM_WAYS-1:0]                                  ic_debug_rd_way_en_ff ;
     852              : 
     853        85251 :    logic [pt.ICACHE_INDEX_HI: pt.ICACHE_TAG_INDEX_LO]              ic_rw_addr_q;
     854          559 :    logic [31:pt.ICACHE_TAG_LO]                                     ic_rw_addr_ff;
     855       680948 :    logic [pt.ICACHE_NUM_WAYS-1:0]                                  ic_tag_rden_q;          // way
     856         2608 :    logic [pt.ICACHE_NUM_WAYS-1:0]                                  ic_tag_wren;          // way
     857         2608 :    logic [pt.ICACHE_NUM_WAYS-1:0]                                  ic_tag_wren_q;        // way
     858       683658 :    logic [pt.ICACHE_NUM_WAYS-1:0]                                  ic_tag_clken;
     859            0 :    logic [pt.ICACHE_NUM_WAYS-1:0]                                  ic_debug_wr_way_en;   // debug wr_way
     860       680944 :    logic                                                           ic_rd_en_ff;
     861            0 :    logic                                                           ic_tag_parity;
     862              : 
     863              : 
     864              :    assign  ic_tag_wren [pt.ICACHE_NUM_WAYS-1:0]  = ic_wr_en[pt.ICACHE_NUM_WAYS-1:0] & {pt.ICACHE_NUM_WAYS{(ic_rw_addr[pt.ICACHE_BEAT_ADDR_HI:4] == {pt.ICACHE_BEAT_BITS-1{1'b1}})}} ;
     865              :    assign  ic_tag_clken[pt.ICACHE_NUM_WAYS-1:0]  = {pt.ICACHE_NUM_WAYS{ic_rd_en | clk_override}} | ic_wr_en[pt.ICACHE_NUM_WAYS-1:0] | ic_debug_wr_way_en[pt.ICACHE_NUM_WAYS-1:0] | ic_debug_rd_way_en[pt.ICACHE_NUM_WAYS-1:0];
     866              : 
     867              :    rvdff #(1) rd_en_ff (.*, .clk(active_clk),
     868              :                     .din (ic_rd_en),
     869              :                     .dout(ic_rd_en_ff)) ;
     870              : 
     871              : 
     872              :    rvdffie #(32-pt.ICACHE_TAG_LO) adr_ff (.*,
     873              :                                           .din ({ic_rw_addr[31:pt.ICACHE_TAG_LO]}),
     874              :                                           .dout({ic_rw_addr_ff[31:pt.ICACHE_TAG_LO]})
     875              :                                           );
     876              : 
     877              :    localparam PAD_BITS = 21 - (32 - pt.ICACHE_TAG_LO);  // sizing for a max tag width.
     878              : 
     879              :    // tags
     880              :    assign  ic_debug_rd_way_en[pt.ICACHE_NUM_WAYS-1:0] =  {pt.ICACHE_NUM_WAYS{ic_debug_rd_en & ic_debug_tag_array}} & ic_debug_way[pt.ICACHE_NUM_WAYS-1:0] ;
     881              :    assign  ic_debug_wr_way_en[pt.ICACHE_NUM_WAYS-1:0] =  {pt.ICACHE_NUM_WAYS{ic_debug_wr_en & ic_debug_tag_array}} & ic_debug_way[pt.ICACHE_NUM_WAYS-1:0] ;
     882              : 
     883              :    assign  ic_tag_wren_q[pt.ICACHE_NUM_WAYS-1:0]  =  ic_tag_wren[pt.ICACHE_NUM_WAYS-1:0]          |
     884              :                                   ic_debug_wr_way_en[pt.ICACHE_NUM_WAYS-1:0]   ;
     885              : 
     886              :    assign  ic_tag_rden_q[pt.ICACHE_NUM_WAYS-1:0]  =  ({pt.ICACHE_NUM_WAYS{ic_rd_en }}  | ic_debug_rd_way_en[pt.ICACHE_NUM_WAYS-1:0] ) &  {pt.ICACHE_NUM_WAYS{~(|ic_wr_en)  & ~ic_debug_wr_en}};
     887              : 
     888              : if (pt.ICACHE_TAG_LO == 11) begin: SMALLEST
     889              :  if (pt.ICACHE_ECC) begin : ECC1_W
     890              :            rvecc_encode  tag_ecc_encode (
     891              :                                   .din    ({{pt.ICACHE_TAG_LO{1'b0}}, ic_rw_addr[31:pt.ICACHE_TAG_LO]}),
     892              :                                   .ecc_out({ ic_tag_ecc[6:0]}));
     893              : 
     894              :    assign  ic_tag_wr_data[25:0] = (ic_debug_wr_en & ic_debug_tag_array) ?
     895              :                                   {ic_debug_wr_data[68:64], ic_debug_wr_data[31:11]} :
     896              :                                   {ic_tag_ecc[4:0], ic_rw_addr[31:pt.ICACHE_TAG_LO]} ;
     897              :  end
     898              : 
     899              :  else begin : ECC0_W
     900              :            rveven_paritygen #(32-pt.ICACHE_TAG_LO) pargen  (.data_in   (ic_rw_addr[31:pt.ICACHE_TAG_LO]),
     901              :                                                  .parity_out(ic_tag_parity));
     902              : 
     903              :    assign  ic_tag_wr_data[21:0] = (ic_debug_wr_en & ic_debug_tag_array) ?
     904              :                                   {ic_debug_wr_data[64], ic_debug_wr_data[31:11]} :
     905              :                                   {ic_tag_parity, ic_rw_addr[31:pt.ICACHE_TAG_LO]} ;
     906              :  end // else: !if(pt.ICACHE_ECC)
     907              : 
     908              : end // block: SMALLEST
     909              : 
     910              : 
     911              : else begin: OTHERS
     912              :   if(pt.ICACHE_ECC) begin :ECC1_W
     913              :            rvecc_encode  tag_ecc_encode (
     914              :                                   .din    ({{pt.ICACHE_TAG_LO{1'b0}}, ic_rw_addr[31:pt.ICACHE_TAG_LO]}),
     915              :                                   .ecc_out({ ic_tag_ecc[6:0]}));
     916              : 
     917              :    assign  ic_tag_wr_data[25:0] = (ic_debug_wr_en & ic_debug_tag_array) ?
     918              :                                   {ic_debug_wr_data[68:64],ic_debug_wr_data[31:11]} :
     919              :                                   {ic_tag_ecc[4:0], {PAD_BITS{1'b0}},ic_rw_addr[31:pt.ICACHE_TAG_LO]} ;
     920              : 
     921              :   end
     922              :   else  begin :ECC0_W
     923              :    logic   ic_tag_parity ;
     924              :            rveven_paritygen #(32-pt.ICACHE_TAG_LO) pargen  (.data_in   (ic_rw_addr[31:pt.ICACHE_TAG_LO]),
     925              :                                                  .parity_out(ic_tag_parity));
     926              :    assign  ic_tag_wr_data[21:0] = (ic_debug_wr_en & ic_debug_tag_array) ?
     927              :                                   {ic_debug_wr_data[64], ic_debug_wr_data[31:11]} :
     928              :                                   {ic_tag_parity, {PAD_BITS{1'b0}},ic_rw_addr[31:pt.ICACHE_TAG_LO]} ;
     929              :   end // else: !if(pt.ICACHE_ECC)
     930              : 
     931              : end // block: OTHERS
     932              : 
     933              : 
     934              :     assign ic_rw_addr_q[pt.ICACHE_INDEX_HI: pt.ICACHE_TAG_INDEX_LO] = (ic_debug_rd_en | ic_debug_wr_en) ?
     935              :                                                 ic_debug_addr[pt.ICACHE_INDEX_HI: pt.ICACHE_TAG_INDEX_LO] :
     936              :                                                 ic_rw_addr[pt.ICACHE_INDEX_HI: pt.ICACHE_TAG_INDEX_LO] ;
     937              : 
     938              :    rvdff #(pt.ICACHE_NUM_WAYS) tag_rd_wy_ff (.*, .clk(active_clk),
     939              :                     .din ({ic_debug_rd_way_en[pt.ICACHE_NUM_WAYS-1:0]}),
     940              :                     .dout({ic_debug_rd_way_en_ff[pt.ICACHE_NUM_WAYS-1:0]}));
     941              : 
     942              :  if (pt.ICACHE_WAYPACK == 0 ) begin : PACKED_0
     943              : 
     944              :    logic [pt.ICACHE_NUM_WAYS-1:0] ic_b_sram_en;
     945              :    logic [pt.ICACHE_NUM_WAYS-1:0]                                                                               ic_b_read_en;
     946              :    logic [pt.ICACHE_NUM_WAYS-1:0]                                                                               ic_b_write_en;
     947              :    logic [pt.ICACHE_NUM_WAYS-1:0][pt.ICACHE_TAG_NUM_BYPASS-1:0] [pt.ICACHE_INDEX_HI : pt.ICACHE_TAG_INDEX_LO]   wb_index_hold;
     948              :    logic [pt.ICACHE_NUM_WAYS-1:0]                               [pt.ICACHE_INDEX_HI : pt.ICACHE_TAG_INDEX_LO]   ic_b_rw_addr;
     949              :    logic [pt.ICACHE_NUM_WAYS-1:0][pt.ICACHE_TAG_NUM_BYPASS-1:0]                                                 write_bypass_en;     //bank
     950              :    logic [pt.ICACHE_NUM_WAYS-1:0][pt.ICACHE_TAG_NUM_BYPASS-1:0]                                                 write_bypass_en_ff;  //bank
     951              :    logic [pt.ICACHE_NUM_WAYS-1:0][pt.ICACHE_TAG_NUM_BYPASS-1:0]                                                 index_valid;  //bank
     952              :    logic [pt.ICACHE_NUM_WAYS-1:0][pt.ICACHE_TAG_NUM_BYPASS-1:0]                                                 ic_b_clear_en;
     953              :    logic [pt.ICACHE_NUM_WAYS-1:0][pt.ICACHE_TAG_NUM_BYPASS-1:0]                                                 ic_b_addr_match;
     954              : 
     955              : 
     956              : 
     957              : 
     958              :     logic [pt.ICACHE_NUM_WAYS-1:0] [pt.ICACHE_TAG_NUM_BYPASS_WIDTH-1:0] wrptr;
     959              :     logic [pt.ICACHE_NUM_WAYS-1:0] [pt.ICACHE_TAG_NUM_BYPASS_WIDTH-1:0] wrptr_in;
     960              :     logic [pt.ICACHE_NUM_WAYS-1:0] [pt.ICACHE_TAG_NUM_BYPASS-1:0]       sel_bypass;
     961              :     logic [pt.ICACHE_NUM_WAYS-1:0] [pt.ICACHE_TAG_NUM_BYPASS-1:0]       sel_bypass_ff;
     962              : 
     963              : 
     964              : 
     965              :     logic [pt.ICACHE_NUM_WAYS-1:0][25:0]  sel_bypass_data;
     966              :     logic [pt.ICACHE_NUM_WAYS-1:0]        any_bypass;
     967              :     logic [pt.ICACHE_NUM_WAYS-1:0]        any_addr_match;
     968              :     logic [pt.ICACHE_NUM_WAYS-1:0]        ic_tag_clken_final;
     969              : 
     970              :       `define EL2_IC_TAG_SRAM(depth,width)                                                                                                      \
     971              :                                   ram_``depth``x``width  ic_way_tag (                                                                           \
     972              :                                 .ME(ic_tag_clken_final[i]),                                                                                     \
     973              :                                 .WE (ic_tag_wren_q[i]),                                                                                         \
     974              :                                 .D  (ic_tag_wr_data[``width-1:0]),                                                                              \
     975              :                                 .ADR(ic_rw_addr_q[pt.ICACHE_INDEX_HI:pt.ICACHE_TAG_INDEX_LO]),                                                  \
     976              :                                 .Q  (ic_tag_data_raw_pre[i][``width-1:0]),                                                                      \
     977              :                                 .CLK (clk),                                                                                                     \
     978              :                                 .ROP ( ),                                                                                                       \
     979              :                                                                                                                                                 \
     980              :                                 .TEST1(ic_tag_ext_in_pkt[i].TEST1),                                                                             \
     981              :                                 .RME(ic_tag_ext_in_pkt[i].RME),                                                                                 \
     982              :                                 .RM(ic_tag_ext_in_pkt[i].RM),                                                                                   \
     983              :                                                                                                                                                 \
     984              :                                 .LS(ic_tag_ext_in_pkt[i].LS),                                                                                   \
     985              :                                 .DS(ic_tag_ext_in_pkt[i].DS),                                                                                   \
     986              :                                 .SD(ic_tag_ext_in_pkt[i].SD),                                                                                   \
     987              :                                                                                                                                                 \
     988              :                                 .TEST_RNM(ic_tag_ext_in_pkt[i].TEST_RNM),                                                                       \
     989              :                                 .BC1(ic_tag_ext_in_pkt[i].BC1),                                                                                 \
     990              :                                 .BC2(ic_tag_ext_in_pkt[i].BC2)                                                                                  \
     991              :                                                                                                                                                 \
     992              :                                );                                                                                                               \
     993              :                                                                                                                                                 \
     994              :                                                                                                                                                 \
     995              :                                                                                                                                                 \
     996              :                                                                                                                                                 \
     997              :               if (pt.ICACHE_TAG_BYPASS_ENABLE == 1) begin                                                                                                                                             \
     998              :                                                                                                                                                                                                       \
     999              :                  assign wrptr_in[i] = (wrptr[i] == (pt.ICACHE_TAG_NUM_BYPASS-1)) ? '0 : (wrptr[i] + 1'd1);                                                                                            \
    1000              :                                                                                                                                                                                                       \
    1001              :                  rvdffs  #(pt.ICACHE_TAG_NUM_BYPASS_WIDTH)  wrptr_ff(.*, .clk(active_clk), .en(|write_bypass_en[i]), .din (wrptr_in[i]), .dout(wrptr[i])) ;                                           \
    1002              :                                                                                                                                                                                                       \
    1003              :                  assign ic_b_sram_en[i]              = ic_tag_clken[i];                                                                                                                               \
    1004              :                                                                                                                                                                                                       \
    1005              :                  assign ic_b_read_en[i]              =  ic_b_sram_en[i] &   (ic_tag_rden_q[i]);                                                                                                       \
    1006              :                  assign ic_b_write_en[i]             =  ic_b_sram_en[i] &   (ic_tag_wren_q[i]);                                                                                                       \
    1007              :                  assign ic_tag_clken_final[i]        =  ic_b_sram_en[i] &    ~(|sel_bypass[i]);                                                                                                       \
    1008              :                                                                                                                                                                                                       \
    1009              :                  // LSB is pt.ICACHE_TAG_INDEX_LO]                                                                                                                                                    \
    1010              :                  assign ic_b_rw_addr[i] = {ic_rw_addr_q};                                                                                                                                             \
    1011              :                                                                                                                                                                                                       \
    1012              :                  always_comb begin                                                                                                                                                                    \
    1013              :                     any_addr_match[i] = '0;                                                                                                                                                           \
    1014              :                                                                                                                                                                                                       \
    1015              :                     for (int l=0; l<pt.ICACHE_TAG_NUM_BYPASS; l++) begin                                                                                                                              \
    1016              :                        any_addr_match[i] |= (ic_b_addr_match[i][l] & index_valid[i][l]);                                                                                                              \
    1017              :                     end                                                                                                                                                                               \
    1018              :                  end                                                                                                                                                                                  \
    1019              :                                                                                                                                                                                                       \
    1020              :                 // it is an error to ever have 2 entries with the same index and both valid                                                                                                           \
    1021              :                 for (genvar l=0; l<pt.ICACHE_TAG_NUM_BYPASS; l++) begin: BYPASS                                                                                                                       \
    1022              :                                                                                                                                                                                                       \
    1023              :                    assign ic_b_addr_match[i][l] = (wb_index_hold[i][l] ==  ic_b_rw_addr[i]) & index_valid[i][l];                                                                                      \
    1024              :                                                                                                                                                                                                       \
    1025              :                    assign ic_b_clear_en[i][l]   = ic_b_write_en[i] &   ic_b_addr_match[i][l];                                                                                                         \
    1026              :                                                                                                                                                                                                       \
    1027              :                    assign sel_bypass[i][l]      = ic_b_read_en[i]  &   ic_b_addr_match[i][l] ;                                                                                                        \
    1028              :                                                                                                                                                                                                       \
    1029              :                    assign write_bypass_en[i][l] = ic_b_read_en[i]  &  ~any_addr_match[i] & (wrptr[i] == l);                                                                                           \
    1030              :                                                                                                                                                                                                       \
    1031              :                    rvdff  #(1)  write_bypass_ff (.*, .clk(active_clk),                                                     .din(write_bypass_en[i][l]), .dout(write_bypass_en_ff[i][l])) ;                            \
    1032              :                    rvdffs #(1)  index_val_ff    (.*, .clk(active_clk), .en(write_bypass_en[i][l] | ic_b_clear_en[i][l]),         .din(~ic_b_clear_en[i][l]),  .dout(index_valid[i][l])) ;                             \
    1033              :                    rvdff  #(1)  sel_hold_ff     (.*, .clk(active_clk),                                                     .din(sel_bypass[i][l]),      .dout(sel_bypass_ff[i][l])) ;                                 \
    1034              :                                                                                                                                                                                                       \
    1035              :                    rvdffe #(.WIDTH(pt.ICACHE_INDEX_HI-pt.ICACHE_TAG_INDEX_LO+1),.OVERRIDE(1))  ic_addr_index   (.*, .en(write_bypass_en[i][l]),    .din (ic_b_rw_addr[i]),        .dout(wb_index_hold[i][l]));   \
    1036              :                    rvdffe #(``width)                                                           rd_data_hold_ff (.*, .en(write_bypass_en_ff[i][l]), .din (ic_tag_data_raw_pre[i][``width-1:0]), .dout(wb_dout_hold[i][l]));            \
    1037              :                                                                                                                                                                                                       \
    1038              :                 end // block: BYPASS                                                                                                                                                                  \
    1039              :                                                                                                                                                                                                       \
    1040              :                 always_comb begin                                                                                                                                                                     \
    1041              :                  any_bypass[i] = '0;                                                                                                                                                                  \
    1042              :                  sel_bypass_data[i] = '0;                                                                                                                                                             \
    1043              :                                                                                                                                                                                                       \
    1044              :                  for (int l=0; l<pt.ICACHE_TAG_NUM_BYPASS; l++) begin                                                                                                                                 \
    1045              :                     any_bypass[i]      |=  sel_bypass_ff[i][l];                                                                                                                                       \
    1046              :                     sel_bypass_data[i] |= (sel_bypass_ff[i][l]) ? wb_dout_hold[i][l] : '0;                                                                                                            \
    1047              :                  end                                                                                                                                                                                  \
    1048              :                                                                                                                                                                                                       \
    1049              :                    ic_tag_data_raw[i]   =   any_bypass[i] ?  sel_bypass_data[i] :  ic_tag_data_raw_pre[i] ;                                                                                           \
    1050              :                 end // always_comb begin                                                                                                                                                              \
    1051              :                                                                                                                                                                                                       \
    1052              :              end // if (pt.ICACHE_BYPASS_ENABLE == 1)                                                                                                                                                 \
    1053              :              else begin                                                                                                                                                                               \
    1054              :                  assign ic_tag_data_raw[i]   =   ic_tag_data_raw_pre[i] ;                                                                                                                             \
    1055              :                  assign ic_tag_clken_final[i]       =   ic_tag_clken[i];                                                                                                                              \
    1056              :              end
    1057              :    for (genvar i=0; i<pt.ICACHE_NUM_WAYS; i++) begin: WAYS
    1058              : 
    1059              :    if (pt.ICACHE_ECC) begin  : ECC1
    1060              :       logic [pt.ICACHE_NUM_WAYS-1:0] [pt.ICACHE_TAG_NUM_BYPASS-1:0][25 :0] wb_dout_hold;
    1061              : 
    1062              :       if (pt.ICACHE_TAG_DEPTH == 32)   begin : size_32
    1063              :                  `EL2_IC_TAG_SRAM(32,26)
    1064              :       end // if (pt.ICACHE_TAG_DEPTH == 32)
    1065              :       if (pt.ICACHE_TAG_DEPTH == 64)   begin : size_64
    1066              :                  `EL2_IC_TAG_SRAM(64,26)
    1067              :       end // if (pt.ICACHE_TAG_DEPTH == 64)
    1068              :       if (pt.ICACHE_TAG_DEPTH == 128)   begin : size_128
    1069              :                  `EL2_IC_TAG_SRAM(128,26)
    1070              :       end // if (pt.ICACHE_TAG_DEPTH == 128)
    1071              :        if (pt.ICACHE_TAG_DEPTH == 256)   begin : size_256
    1072              :                  `EL2_IC_TAG_SRAM(256,26)
    1073              :        end // if (pt.ICACHE_TAG_DEPTH == 256)
    1074              :        if (pt.ICACHE_TAG_DEPTH == 512)   begin : size_512
    1075              :                  `EL2_IC_TAG_SRAM(512,26)
    1076              :        end // if (pt.ICACHE_TAG_DEPTH == 512)
    1077              :        if (pt.ICACHE_TAG_DEPTH == 1024)   begin : size_1024
    1078              :                  `EL2_IC_TAG_SRAM(1024,26)
    1079              :        end // if (pt.ICACHE_TAG_DEPTH == 1024)
    1080              :        if (pt.ICACHE_TAG_DEPTH == 2048)   begin : size_2048
    1081              :                  `EL2_IC_TAG_SRAM(2048,26)
    1082              :        end // if (pt.ICACHE_TAG_DEPTH == 2048)
    1083              :        if (pt.ICACHE_TAG_DEPTH == 4096)   begin  : size_4096
    1084              :                  `EL2_IC_TAG_SRAM(4096,26)
    1085              :        end // if (pt.ICACHE_TAG_DEPTH == 4096)
    1086              : 
    1087              :          assign w_tout[i][31:pt.ICACHE_TAG_LO] = ic_tag_data_raw[i][31-pt.ICACHE_TAG_LO:0] ;
    1088              :          assign w_tout[i][36:32]              = ic_tag_data_raw[i][25:21] ;
    1089              : 
    1090              :          rvecc_decode  ecc_decode (
    1091              :                            .en(~dec_tlu_core_ecc_disable & ic_rd_en_ff),
    1092              :                            .sed_ded ( 1'b1 ),    // 1 : means only detection
    1093              :                            .din({11'b0,ic_tag_data_raw[i][20:0]}),
    1094              :                            .ecc_in({2'b0, ic_tag_data_raw[i][25:21]}),
    1095              :                            .dout(ic_tag_corrected_data_unc[i][31:0]),
    1096              :                            .ecc_out(ic_tag_corrected_ecc_unc[i][6:0]),
    1097              :                            .single_ecc_error(ic_tag_single_ecc_error[i]),
    1098              :                            .double_ecc_error(ic_tag_double_ecc_error[i]));
    1099              : 
    1100              :           assign ic_tag_way_perr[i]= ic_tag_single_ecc_error[i] | ic_tag_double_ecc_error[i]  ;
    1101              :       end
    1102              :       else  begin : ECC0
    1103              :       logic [pt.ICACHE_NUM_WAYS-1:0] [pt.ICACHE_TAG_NUM_BYPASS-1:0][21 :0] wb_dout_hold;
    1104              :       assign ic_tag_data_raw_pre[i][25:22] = '0 ;
    1105              : 
    1106              :       if (pt.ICACHE_TAG_DEPTH == 32)   begin : size_32
    1107              :                  `EL2_IC_TAG_SRAM(32,22)
    1108              :       end // if (pt.ICACHE_TAG_DEPTH == 32)
    1109              :       if (pt.ICACHE_TAG_DEPTH == 64)   begin : size_64
    1110              :                  `EL2_IC_TAG_SRAM(64,22)
    1111              :       end // if (pt.ICACHE_TAG_DEPTH == 64)
    1112              :       if (pt.ICACHE_TAG_DEPTH == 128)   begin : size_128
    1113              :                  `EL2_IC_TAG_SRAM(128,22)
    1114              :       end // if (pt.ICACHE_TAG_DEPTH == 128)
    1115              :        if (pt.ICACHE_TAG_DEPTH == 256)   begin : size_256
    1116              :                  `EL2_IC_TAG_SRAM(256,22)
    1117              :        end // if (pt.ICACHE_TAG_DEPTH == 256)
    1118              :        if (pt.ICACHE_TAG_DEPTH == 512)   begin : size_512
    1119              :                  `EL2_IC_TAG_SRAM(512,22)
    1120              :        end // if (pt.ICACHE_TAG_DEPTH == 512)
    1121              :        if (pt.ICACHE_TAG_DEPTH == 1024)   begin : size_1024
    1122              :                  `EL2_IC_TAG_SRAM(1024,22)
    1123              :        end // if (pt.ICACHE_TAG_DEPTH == 1024)
    1124              :        if (pt.ICACHE_TAG_DEPTH == 2048)   begin : size_2048
    1125              :                  `EL2_IC_TAG_SRAM(2048,22)
    1126              :        end // if (pt.ICACHE_TAG_DEPTH == 2048)
    1127              :        if (pt.ICACHE_TAG_DEPTH == 4096)   begin  : size_4096
    1128              :                  `EL2_IC_TAG_SRAM(4096,22)
    1129              :        end // if (pt.ICACHE_TAG_DEPTH == 4096)
    1130              : 
    1131              :          assign w_tout[i][31:pt.ICACHE_TAG_LO] = ic_tag_data_raw[i][31-pt.ICACHE_TAG_LO:0] ;
    1132              :          assign w_tout[i][32]                 = ic_tag_data_raw[i][21] ;
    1133              : 
    1134              :          rveven_paritycheck #(32-pt.ICACHE_TAG_LO) parcheck(.data_in   (w_tout[i][31:pt.ICACHE_TAG_LO]),
    1135              :                                                    .parity_in (w_tout[i][32]),
    1136              :                                                    .parity_err(ic_tag_way_perr[i]));
    1137              :       end // else: !if(pt.ICACHE_ECC)
    1138              : 
    1139              :    end // block: WAYS
    1140              :  end // block: PACKED_0
    1141              : 
    1142              : 
    1143              :  else begin : PACKED_1
    1144              : 
    1145              : 
    1146              :    logic                                                                                ic_b_sram_en;
    1147              :    logic                                                                                ic_b_read_en;
    1148              :    logic                                                                                ic_b_write_en;
    1149              :    logic [pt.ICACHE_TAG_NUM_BYPASS-1:0] [pt.ICACHE_INDEX_HI : pt.ICACHE_TAG_INDEX_LO]   wb_index_hold;
    1150              :    logic                                [pt.ICACHE_INDEX_HI : pt.ICACHE_TAG_INDEX_LO]   ic_b_rw_addr;
    1151              :    logic [pt.ICACHE_TAG_NUM_BYPASS-1:0]                                                 write_bypass_en;     //bank
    1152              :    logic [pt.ICACHE_TAG_NUM_BYPASS-1:0]                                                 write_bypass_en_ff;  //bank
    1153              :    logic [pt.ICACHE_TAG_NUM_BYPASS-1:0]                                                 index_valid;  //bank
    1154              :    logic [pt.ICACHE_TAG_NUM_BYPASS-1:0]                                                 ic_b_clear_en;
    1155              :    logic [pt.ICACHE_TAG_NUM_BYPASS-1:0]                                                 ic_b_addr_match;
    1156              : 
    1157              : 
    1158              : 
    1159              : 
    1160              :     logic [pt.ICACHE_TAG_NUM_BYPASS_WIDTH-1:0]  wrptr;
    1161              :     logic [pt.ICACHE_TAG_NUM_BYPASS_WIDTH-1:0]  wrptr_in;
    1162              :     logic [pt.ICACHE_TAG_NUM_BYPASS-1:0]        sel_bypass;
    1163              :     logic [pt.ICACHE_TAG_NUM_BYPASS-1:0]        sel_bypass_ff;
    1164              : 
    1165              : 
    1166              : 
    1167              :     logic [(26*pt.ICACHE_NUM_WAYS)-1:0]  sel_bypass_data;
    1168              :     logic                                any_bypass;
    1169              :     logic                                any_addr_match;
    1170              :     logic                                ic_tag_clken_final;
    1171              : 
    1172              : `define EL2_IC_TAG_PACKED_SRAM(depth,width)                                                               \
    1173              :                   ram_be_``depth``x``width  ic_way_tag (                                                   \
    1174              :                                 .ME  ( ic_tag_clken_final),                                                \
    1175              :                                 .WE  (|ic_tag_wren_q[pt.ICACHE_NUM_WAYS-1:0]),                             \
    1176              :                                 .WEM (ic_tag_wren_biten_vec[``width-1:0]),                                 \
    1177              :                                                                                                            \
    1178              :                                 .D   ({pt.ICACHE_NUM_WAYS{ic_tag_wr_data[``width/pt.ICACHE_NUM_WAYS-1:0]}}), \
    1179              :                                 .ADR (ic_rw_addr_q[pt.ICACHE_INDEX_HI:pt.ICACHE_TAG_INDEX_LO]),            \
    1180              :                                 .Q   (ic_tag_data_raw_packed_pre[``width-1:0]),                            \
    1181              :                                 .CLK (clk),                                                                \
    1182              :                                 .ROP ( ),                                                                  \
    1183              :                                                                                                            \
    1184              :                                 .TEST1     (ic_tag_ext_in_pkt[0].TEST1),                                   \
    1185              :                                 .RME      (ic_tag_ext_in_pkt[0].RME),                                      \
    1186              :                                 .RM       (ic_tag_ext_in_pkt[0].RM),                                       \
    1187              :                                                                                                            \
    1188              :                                 .LS       (ic_tag_ext_in_pkt[0].LS),                                       \
    1189              :                                 .DS       (ic_tag_ext_in_pkt[0].DS),                                       \
    1190              :                                 .SD       (ic_tag_ext_in_pkt[0].SD),                                       \
    1191              :                                                                                                            \
    1192              :                                 .TEST_RNM (ic_tag_ext_in_pkt[0].TEST_RNM),                                 \
    1193              :                                 .BC1      (ic_tag_ext_in_pkt[0].BC1),                                      \
    1194              :                                 .BC2      (ic_tag_ext_in_pkt[0].BC2)                                       \
    1195              :                                                                                                            \
    1196              :                                );                                                                          \
    1197              :                                                                                                            \
    1198              :               if (pt.ICACHE_TAG_BYPASS_ENABLE == 1) begin                                                                                                                                             \
    1199              :                                                                                                                                                                                                       \
    1200              :                  assign wrptr_in = (wrptr == (pt.ICACHE_TAG_NUM_BYPASS-1)) ? '0 : (wrptr + 1'd1);                                                                                                     \
    1201              :                                                                                                                                                                                                       \
    1202              :                  rvdffs  #(pt.ICACHE_TAG_NUM_BYPASS_WIDTH)  wrptr_ff(.*, .clk(active_clk), .en(|write_bypass_en), .din (wrptr_in), .dout(wrptr)) ;                                                    \
    1203              :                                                                                                                                                                                                       \
    1204              :                  assign ic_b_sram_en              = |ic_tag_clken;                                                                                                                                    \
    1205              :                                                                                                                                                                                                       \
    1206              :                  assign ic_b_read_en              =  ic_b_sram_en &   (|ic_tag_rden_q);                                                                                                               \
    1207              :                  assign ic_b_write_en             =  ic_b_sram_en &   (|ic_tag_wren_q);                                                                                                               \
    1208              :                  assign ic_tag_clken_final        =  ic_b_sram_en &    ~(|sel_bypass);                                                                                                                \
    1209              :                                                                                                                                                                                                       \
    1210              :                  // LSB is pt.ICACHE_TAG_INDEX_LO]                                                                                                                                                    \
    1211              :                  assign ic_b_rw_addr = {ic_rw_addr_q};                                                                                                                                                \
    1212              :                                                                                                                                                                                                       \
    1213              :                  always_comb begin                                                                                                                                                                    \
    1214              :                     any_addr_match = '0;                                                                                                                                                              \
    1215              :                                                                                                                                                                                                       \
    1216              :                     for (int l=0; l<pt.ICACHE_TAG_NUM_BYPASS; l++) begin                                                                                                                              \
    1217              :                        any_addr_match |= ic_b_addr_match[l];                                                                                                                                          \
    1218              :                     end                                                                                                                                                                               \
    1219              :                  end                                                                                                                                                                                  \
    1220              :                                                                                                                                                                                                       \
    1221              :                 // it is an error to ever have 2 entries with the same index and both valid                                                                                                           \
    1222              :                 for (genvar l=0; l<pt.ICACHE_TAG_NUM_BYPASS; l++) begin: BYPASS                                                                                                                       \
    1223              :                                                                                                                                                                                                       \
    1224              :                    assign ic_b_addr_match[l] = (wb_index_hold[l] ==  ic_b_rw_addr) & index_valid[l];                                                                                                  \
    1225              :                                                                                                                                                                                                       \
    1226              :                    assign ic_b_clear_en[l]   = ic_b_write_en &   ic_b_addr_match[l];                                                                                                                  \
    1227              :                                                                                                                                                                                                       \
    1228              :                    assign sel_bypass[l]      = ic_b_read_en  &   ic_b_addr_match[l] ;                                                                                                                 \
    1229              :                                                                                                                                                                                                       \
    1230              :                    assign write_bypass_en[l] = ic_b_read_en  &  ~any_addr_match & (wrptr == l);                                                                                                       \
    1231              :                                                                                                                                                                                                       \
    1232              :                    rvdff  #(1)  write_bypass_ff (.*, .clk(active_clk),                                                     .din(write_bypass_en[l]), .dout(write_bypass_en_ff[l])) ;                                  \
    1233              :                    rvdffs #(1)  index_val_ff    (.*, .clk(active_clk), .en(write_bypass_en[l] | ic_b_clear_en[l]),         .din(~ic_b_clear_en[l]),  .dout(index_valid[l])) ;                                         \
    1234              :                    rvdff  #(1)  sel_hold_ff     (.*, .clk(active_clk),                                                     .din(sel_bypass[l]),      .dout(sel_bypass_ff[l])) ;                                               \
    1235              :                                                                                                                                                                                                       \
    1236              :                    rvdffe #(.WIDTH(pt.ICACHE_INDEX_HI-pt.ICACHE_TAG_INDEX_LO+1),.OVERRIDE(1)) ic_addr_index    (.*, .en(write_bypass_en[l]),    .din (ic_b_rw_addr),               .dout(wb_index_hold[l]));          \
    1237              :                    rvdffe #(``width)                                                          rd_data_hold_ff  (.*, .en(write_bypass_en_ff[l]), .din (ic_tag_data_raw_packed_pre[``width-1:0]), .dout(wb_packeddout_hold[l]));        \
    1238              :                                                                                                                                                                                                       \
    1239              :                 end // block: BYPASS                                                                                                                                                                  \
    1240              :                                                                                                                                                                                                       \
    1241              :                 always_comb begin                                                                                                                                                                     \
    1242              :                  any_bypass = '0;                                                                                                                                                                     \
    1243              :                  sel_bypass_data = '0;                                                                                                                                                                \
    1244              :                                                                                                                                                                                                       \
    1245              :                  for (int l=0; l<pt.ICACHE_TAG_NUM_BYPASS; l++) begin                                                                                                                                 \
    1246              :                     any_bypass      |=  sel_bypass_ff[l];                                                                                                                                             \
    1247              :                     sel_bypass_data |= (sel_bypass_ff[l]) ? wb_packeddout_hold[l] : '0;                                                                                                               \
    1248              :                  end                                                                                                                                                                                  \
    1249              :                                                                                                                                                                                                       \
    1250              :                    ic_tag_data_raw_packed   =   any_bypass ?  sel_bypass_data :  ic_tag_data_raw_packed_pre ;                                                                                         \
    1251              :                 end // always_comb begin                                                                                                                                                              \
    1252              :                                                                                                                                                                                                       \
    1253              :              end // if (pt.ICACHE_BYPASS_ENABLE == 1)                                                                                                                                                 \
    1254              :              else begin                                                                                                                                                                               \
    1255              :                  assign ic_tag_data_raw_packed   =   ic_tag_data_raw_packed_pre ;                                                                                                                     \
    1256              :                  assign ic_tag_clken_final       =   |ic_tag_clken;                                                                                                                                   \
    1257              :              end
    1258              : 
    1259              :    if (pt.ICACHE_ECC) begin  : ECC1
    1260              :     logic [(26*pt.ICACHE_NUM_WAYS)-1 :0]  ic_tag_data_raw_packed, ic_tag_wren_biten_vec, ic_tag_data_raw_packed_pre;           // data and its bit enables
    1261              :     logic [pt.ICACHE_TAG_NUM_BYPASS-1:0][(26*pt.ICACHE_NUM_WAYS)-1 :0] wb_packeddout_hold;
    1262              :     for (genvar i=0; i<pt.ICACHE_NUM_WAYS; i++) begin: BITEN
    1263              :         assign ic_tag_wren_biten_vec[(26*i)+25:26*i] = {26{ic_tag_wren_q[i]}};
    1264              :      end
    1265              :       if (pt.ICACHE_TAG_DEPTH == 32)   begin : size_32
    1266              :         if (pt.ICACHE_NUM_WAYS == 4) begin : WAYS
    1267              :                  `EL2_IC_TAG_PACKED_SRAM(32,104)
    1268              :         end // block: WAYS
    1269              :       else begin : WAYS
    1270              :                  `EL2_IC_TAG_PACKED_SRAM(32,52)
    1271              :         end // block: WAYS
    1272              :       end // if (pt.ICACHE_TAG_DEPTH == 32
    1273              : 
    1274              :       if (pt.ICACHE_TAG_DEPTH == 64)   begin : size_64
    1275              :         if (pt.ICACHE_NUM_WAYS == 4) begin : WAYS
    1276              :                  `EL2_IC_TAG_PACKED_SRAM(64,104)
    1277              :         end // block: WAYS
    1278              :       else begin : WAYS
    1279              :                  `EL2_IC_TAG_PACKED_SRAM(64,52)
    1280              :         end // block: WAYS
    1281              :       end // block: size_64
    1282              : 
    1283              :       if (pt.ICACHE_TAG_DEPTH == 128)   begin : size_128
    1284              :        if (pt.ICACHE_NUM_WAYS == 4) begin : WAYS
    1285              :                  `EL2_IC_TAG_PACKED_SRAM(128,104)
    1286              :       end // block: WAYS
    1287              :       else begin : WAYS
    1288          339 :                  `EL2_IC_TAG_PACKED_SRAM(128,52)
    1289              :       end // block: WAYS
    1290              : 
    1291              :       end // block: size_128
    1292              : 
    1293              :       if (pt.ICACHE_TAG_DEPTH == 256)   begin : size_256
    1294              :        if (pt.ICACHE_NUM_WAYS == 4) begin : WAYS
    1295              :                  `EL2_IC_TAG_PACKED_SRAM(256,104)
    1296              :         end // block: WAYS
    1297              :        else begin : WAYS
    1298              :                  `EL2_IC_TAG_PACKED_SRAM(256,52)
    1299              :         end // block: WAYS
    1300              :       end // block: size_256
    1301              : 
    1302              :       if (pt.ICACHE_TAG_DEPTH == 512)   begin : size_512
    1303              :        if (pt.ICACHE_NUM_WAYS == 4) begin : WAYS
    1304              :                  `EL2_IC_TAG_PACKED_SRAM(512,104)
    1305              :         end // block: WAYS
    1306              :        else begin : WAYS
    1307              :                  `EL2_IC_TAG_PACKED_SRAM(512,52)
    1308              :         end // block: WAYS
    1309              :       end // block: size_512
    1310              : 
    1311              :       if (pt.ICACHE_TAG_DEPTH == 1024)   begin : size_1024
    1312              :          if (pt.ICACHE_NUM_WAYS == 4) begin : WAYS
    1313              :                  `EL2_IC_TAG_PACKED_SRAM(1024,104)
    1314              :         end // block: WAYS
    1315              :        else begin : WAYS
    1316              :                  `EL2_IC_TAG_PACKED_SRAM(1024,52)
    1317              :         end // block: WAYS
    1318              :       end // block: size_1024
    1319              : 
    1320              :       if (pt.ICACHE_TAG_DEPTH == 2048)   begin : size_2048
    1321              :        if (pt.ICACHE_NUM_WAYS == 4) begin : WAYS
    1322              :                  `EL2_IC_TAG_PACKED_SRAM(2048,104)
    1323              :         end // block: WAYS
    1324              :        else begin : WAYS
    1325              :                  `EL2_IC_TAG_PACKED_SRAM(2048,52)
    1326              :         end // block: WAYS
    1327              :       end // block: size_2048
    1328              : 
    1329              :       if (pt.ICACHE_TAG_DEPTH == 4096)   begin  : size_4096
    1330              :        if (pt.ICACHE_NUM_WAYS == 4) begin : WAYS
    1331              :                  `EL2_IC_TAG_PACKED_SRAM(4096,104)
    1332              :         end // block: WAYS
    1333              :        else begin : WAYS
    1334              :                  `EL2_IC_TAG_PACKED_SRAM(4096,52)
    1335              :         end // block: WAYS
    1336              :       end // block: size_4096
    1337              : 
    1338              :         for (genvar i=0; i<pt.ICACHE_NUM_WAYS; i++) begin
    1339              :           assign ic_tag_data_raw[i]  = ic_tag_data_raw_packed[(26*i)+25:26*i];
    1340              :           assign w_tout[i][31:pt.ICACHE_TAG_LO] = ic_tag_data_raw[i][31-pt.ICACHE_TAG_LO:0] ;
    1341              :           assign w_tout[i][36:32]              = ic_tag_data_raw[i][25:21] ;
    1342              :           rvecc_decode  ecc_decode (
    1343              :                            .en(~dec_tlu_core_ecc_disable & ic_rd_en_ff),
    1344              :                            .sed_ded ( 1'b1 ),    // 1 : means only detection
    1345              :                            .din({11'b0,ic_tag_data_raw[i][20:0]}),
    1346              :                            .ecc_in({2'b0, ic_tag_data_raw[i][25:21]}),
    1347              :                            .dout(ic_tag_corrected_data_unc[i][31:0]),
    1348              :                            .ecc_out(ic_tag_corrected_ecc_unc[i][6:0]),
    1349              :                            .single_ecc_error(ic_tag_single_ecc_error[i]),
    1350              :                            .double_ecc_error(ic_tag_double_ecc_error[i]));
    1351              : 
    1352              :           assign ic_tag_way_perr[i]= ic_tag_single_ecc_error[i] | ic_tag_double_ecc_error[i]  ;
    1353              :      end // for (genvar i=0; i<pt.ICACHE_NUM_WAYS; i++)
    1354              : 
    1355              :    end // block: ECC1
    1356              : 
    1357              : 
    1358              :    else  begin : ECC0
    1359              :     logic [(22*pt.ICACHE_NUM_WAYS)-1 :0]  ic_tag_data_raw_packed, ic_tag_wren_biten_vec, ic_tag_data_raw_packed_pre;           // data and its bit enables
    1360              :     logic [pt.ICACHE_TAG_NUM_BYPASS-1:0][(22*pt.ICACHE_NUM_WAYS)-1 :0] wb_packeddout_hold;
    1361              :     for (genvar i=0; i<pt.ICACHE_NUM_WAYS; i++) begin: BITEN
    1362              :         assign ic_tag_wren_biten_vec[(22*i)+21:22*i] = {22{ic_tag_wren_q[i]}};
    1363              :      end
    1364              :       if (pt.ICACHE_TAG_DEPTH == 32)   begin : size_32
    1365              :         if (pt.ICACHE_NUM_WAYS == 4) begin : WAYS
    1366              :                  `EL2_IC_TAG_PACKED_SRAM(32,88)
    1367              :         end // block: WAYS
    1368              :       else begin : WAYS
    1369              :                  `EL2_IC_TAG_PACKED_SRAM(32,44)
    1370              :         end // block: WAYS
    1371              :       end // if (pt.ICACHE_TAG_DEPTH == 32
    1372              : 
    1373              :       if (pt.ICACHE_TAG_DEPTH == 64)   begin : size_64
    1374              :         if (pt.ICACHE_NUM_WAYS == 4) begin : WAYS
    1375              :                  `EL2_IC_TAG_PACKED_SRAM(64,88)
    1376              :         end // block: WAYS
    1377              :       else begin : WAYS
    1378              :                  `EL2_IC_TAG_PACKED_SRAM(64,44)
    1379              :         end // block: WAYS
    1380              :       end // block: size_64
    1381              : 
    1382              :       if (pt.ICACHE_TAG_DEPTH == 128)   begin : size_128
    1383              :        if (pt.ICACHE_NUM_WAYS == 4) begin : WAYS
    1384              :                  `EL2_IC_TAG_PACKED_SRAM(128,88)
    1385              :       end // block: WAYS
    1386              :       else begin : WAYS
    1387              :                  `EL2_IC_TAG_PACKED_SRAM(128,44)
    1388              :       end // block: WAYS
    1389              : 
    1390              :       end // block: size_128
    1391              : 
    1392              :       if (pt.ICACHE_TAG_DEPTH == 256)   begin : size_256
    1393              :        if (pt.ICACHE_NUM_WAYS == 4) begin : WAYS
    1394              :                  `EL2_IC_TAG_PACKED_SRAM(256,88)
    1395              :         end // block: WAYS
    1396              :        else begin : WAYS
    1397              :                  `EL2_IC_TAG_PACKED_SRAM(256,44)
    1398              :         end // block: WAYS
    1399              :       end // block: size_256
    1400              : 
    1401              :       if (pt.ICACHE_TAG_DEPTH == 512)   begin : size_512
    1402              :        if (pt.ICACHE_NUM_WAYS == 4) begin : WAYS
    1403              :                  `EL2_IC_TAG_PACKED_SRAM(512,88)
    1404              :         end // block: WAYS
    1405              :        else begin : WAYS
    1406              :                  `EL2_IC_TAG_PACKED_SRAM(512,44)
    1407              :         end // block: WAYS
    1408              :       end // block: size_512
    1409              : 
    1410              :       if (pt.ICACHE_TAG_DEPTH == 1024)   begin : size_1024
    1411              :          if (pt.ICACHE_NUM_WAYS == 4) begin : WAYS
    1412              :                  `EL2_IC_TAG_PACKED_SRAM(1024,88)
    1413              :         end // block: WAYS
    1414              :        else begin : WAYS
    1415              :                  `EL2_IC_TAG_PACKED_SRAM(1024,44)
    1416              :         end // block: WAYS
    1417              :       end // block: size_1024
    1418              : 
    1419              :       if (pt.ICACHE_TAG_DEPTH == 2048)   begin : size_2048
    1420              :        if (pt.ICACHE_NUM_WAYS == 4) begin : WAYS
    1421              :                  `EL2_IC_TAG_PACKED_SRAM(2048,88)
    1422              :         end // block: WAYS
    1423              :        else begin : WAYS
    1424              :                  `EL2_IC_TAG_PACKED_SRAM(2048,44)
    1425              :         end // block: WAYS
    1426              :       end // block: size_2048
    1427              : 
    1428              :       if (pt.ICACHE_TAG_DEPTH == 4096)   begin  : size_4096
    1429              :        if (pt.ICACHE_NUM_WAYS == 4) begin : WAYS
    1430              :                  `EL2_IC_TAG_PACKED_SRAM(4096,88)
    1431              :         end // block: WAYS
    1432              :        else begin : WAYS
    1433              :                  `EL2_IC_TAG_PACKED_SRAM(4096,44)
    1434              :         end // block: WAYS
    1435              :       end // block: size_4096
    1436              : 
    1437              :       for (genvar i=0; i<pt.ICACHE_NUM_WAYS; i++) begin
    1438              :           assign ic_tag_data_raw[i]  = ic_tag_data_raw_packed[(22*i)+21:22*i];
    1439              :           assign w_tout[i][31:pt.ICACHE_TAG_LO] = ic_tag_data_raw[i][31-pt.ICACHE_TAG_LO:0] ;
    1440              :           assign w_tout[i][32]                 = ic_tag_data_raw[i][21] ;
    1441              :           assign w_tout[i][36:33]              = '0 ;
    1442              : 
    1443              : 
    1444              :           rveven_paritycheck #(32-pt.ICACHE_TAG_LO) parcheck(.data_in   (w_tout[i][31:pt.ICACHE_TAG_LO]),
    1445              :                                                    .parity_in (w_tout[i][32]),
    1446              :                                                    .parity_err(ic_tag_way_perr[i]));
    1447              :       end
    1448              : 
    1449              : 
    1450              :    end // block: ECC0
    1451              :  end // block: PACKED_1
    1452              : 
    1453              : 
    1454          339 :    always_comb begin : tag_rd_out
    1455          339 :       ictag_debug_rd_data[25:0] = '0;
    1456          339 :       for ( int j=0; j<pt.ICACHE_NUM_WAYS; j++) begin: debug_rd_out
    1457          678 :          ictag_debug_rd_data[25:0] |=  pt.ICACHE_ECC ? ({26{ic_debug_rd_way_en_ff[j]}} & ic_tag_data_raw[j] ) : {4'b0, ({22{ic_debug_rd_way_en_ff[j]}} & ic_tag_data_raw[j][21:0])};
    1458              :       end
    1459              :    end
    1460              : 
    1461              : 
    1462              :    for ( genvar i=0; i<pt.ICACHE_NUM_WAYS; i++) begin : ic_rd_hit_loop
    1463              :       assign ic_rd_hit[i] = (w_tout[i][31:pt.ICACHE_TAG_LO] == ic_rw_addr_ff[31:pt.ICACHE_TAG_LO]) & ic_tag_valid[i];
    1464              :    end
    1465              : 
    1466              :    assign  ic_tag_perr  = | (ic_tag_way_perr[pt.ICACHE_NUM_WAYS-1:0] & ic_tag_valid[pt.ICACHE_NUM_WAYS-1:0] ) ;
    1467              : endmodule // EL2_IC_TAG