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