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