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 :
19 : //********************************************************************************
20 : // Function: Icache , iccm control
21 : // BFF -> F1 -> F2 -> A
22 : //********************************************************************************
23 :
24 : module el2_ifu_mem_ctl
25 : import el2_pkg::*;
26 : #(
27 : `include "el2_param.vh"
28 : )
29 : (
30 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.
31 69890155 : input logic active_clk, // Clock only while core active. Through two clock headers. For flops without second clock header built in.
32 69890155 : input logic free_l2clk, // Clock always. Through one clock header. For flops with second header built in.
33 338 : input logic rst_l, // reset, active low
34 :
35 674202 : input logic exu_flush_final, // Flush from the pipeline., includes flush lower
36 59238 : input logic dec_tlu_flush_lower_wb, // Flush lower from the pipeline.
37 8 : input logic dec_tlu_flush_err_wb, // Flush from the pipeline due to perr.
38 6173148 : input logic dec_tlu_i0_commit_cmt, // committed i0 instruction
39 0 : input logic dec_tlu_force_halt, // force halt.
40 :
41 444 : input logic [31:1] ifc_fetch_addr_bf, // Fetch Address byte aligned always. F1 stage.
42 375 : input logic ifc_fetch_uncacheable_bf, // The fetch request is uncacheable space. F1 stage
43 3717960 : input logic ifc_fetch_req_bf, // Fetch request. Comes with the address. F1 stage
44 566 : input logic ifc_fetch_req_bf_raw, // Fetch request without some qualifications. Used for clock-gating. F1 stage
45 84 : input logic ifc_iccm_access_bf, // This request is to the ICCM. Do not generate misses to the bus.
46 2 : input logic ifc_region_acc_fault_bf, // Access fault. in ICCM region but offset is outside defined ICCM.
47 640775 : input logic ifc_dma_access_ok, // It is OK to give dma access to the ICCM. (ICCM is not busy this cycle).
48 18868 : input logic dec_tlu_fence_i_wb, // Fence.i instruction is committing. Clear all Icache valids.
49 3171757 : input logic ifu_bp_hit_taken_f, // Branch is predicted taken. Kill the fetch next cycle.
50 :
51 2405225 : input logic ifu_bp_inst_mask_f, // tell ic which valids to kill because of a taken branch, right justified
52 :
53 5894674 : output logic ifu_miss_state_idle, // No icache misses are outstanding.
54 5916062 : output logic ifu_ic_mb_empty, // Continue with normal fetching. This does not mean that miss is finished.
55 16 : output logic ic_dma_active , // In the middle of servicing dma request to ICCM. Do not make any new requests.
56 2635450 : output logic ic_write_stall, // Stall fetch the cycle we are writing the cache.
57 :
58 : /// PMU signals
59 5895668 : output logic ifu_pmu_ic_miss, // IC miss event
60 745274 : output logic ifu_pmu_ic_hit, // IC hit event
61 10 : output logic ifu_pmu_bus_error, // Bus error event
62 4468867 : output logic ifu_pmu_bus_busy, // Bus busy event
63 10364514 : output logic ifu_pmu_bus_trxn, // Bus transaction
64 :
65 : //-------------------------- IFU AXI signals--------------------------
66 : // AXI Write Channels
67 : /* exclude signals that are tied to constant value in this file */
68 : /*verilator coverage_off*/
69 : output logic ifu_axi_awvalid,
70 : output logic [pt.IFU_BUS_TAG-1:0] ifu_axi_awid,
71 : output logic [31:0] ifu_axi_awaddr,
72 : output logic [3:0] ifu_axi_awregion,
73 : output logic [7:0] ifu_axi_awlen,
74 : output logic [2:0] ifu_axi_awsize,
75 : output logic [1:0] ifu_axi_awburst,
76 : output logic ifu_axi_awlock,
77 : output logic [3:0] ifu_axi_awcache,
78 : output logic [2:0] ifu_axi_awprot,
79 : output logic [3:0] ifu_axi_awqos,
80 :
81 : output logic ifu_axi_wvalid,
82 : output logic [63:0] ifu_axi_wdata,
83 : output logic [7:0] ifu_axi_wstrb,
84 : output logic ifu_axi_wlast,
85 :
86 : output logic ifu_axi_bready,
87 : /*verilator coverage_on*/
88 :
89 : // AXI Read Channels
90 5895462 : output logic ifu_axi_arvalid,
91 10364845 : input logic ifu_axi_arready,
92 3590406 : output logic [pt.IFU_BUS_TAG-1:0] ifu_axi_arid,
93 2455058 : output logic [31:0] ifu_axi_araddr,
94 545 : output logic [3:0] ifu_axi_arregion,
95 : /* exclude signals that are tied to constant value in this file */
96 : /*verilator coverage_off*/
97 : output logic [7:0] ifu_axi_arlen,
98 : output logic [2:0] ifu_axi_arsize,
99 : output logic [1:0] ifu_axi_arburst,
100 : output logic ifu_axi_arlock,
101 : output logic [3:0] ifu_axi_arcache,
102 : output logic [2:0] ifu_axi_arprot,
103 : output logic [3:0] ifu_axi_arqos,
104 : /*verilator coverage_on*/
105 :
106 11810469 : input logic ifu_axi_rvalid,
107 : /* exclude signals that are tied to constant value in this file */
108 : /*verilator coverage_off*/
109 : output logic ifu_axi_rready,
110 : /*verilator coverage_on*/
111 1182850 : input logic [pt.IFU_BUS_TAG-1:0] ifu_axi_rid,
112 985567 : input logic [63:0] ifu_axi_rdata,
113 20 : input logic [1:0] ifu_axi_rresp,
114 :
115 338 : input logic ifu_bus_clk_en,
116 :
117 :
118 66 : input logic dma_iccm_req, // dma iccm command (read or write)
119 0 : input logic [31:0] dma_mem_addr, // dma address
120 0 : input logic [2:0] dma_mem_sz, // size
121 22 : input logic dma_mem_write, // write
122 12 : input logic [63:0] dma_mem_wdata, // write data
123 12 : input logic [2:0] dma_mem_tag, // DMA Buffer entry number
124 :
125 4 : output logic iccm_dma_ecc_error,// Data read from iccm has an ecc error
126 0 : output logic iccm_dma_rvalid, // Data read from iccm is valid
127 0 : output logic [63:0] iccm_dma_rdata, // dma data read from iccm
128 12 : output logic [2:0] iccm_dma_rtag, // Tag of the DMA req
129 638334 : output logic iccm_ready, // iccm ready to accept new command.
130 :
131 :
132 : // I$ & ITAG Ports
133 490 : output logic [31:1] ic_rw_addr, // Read/Write addresss to the Icache.
134 10432 : output logic [pt.ICACHE_NUM_WAYS-1:0] ic_wr_en, // Icache write enable, when filling the Icache.
135 680962 : output logic ic_rd_en, // Icache read enable.
136 :
137 560643 : output logic [pt.ICACHE_BANKS_WAY-1:0] [70:0] ic_wr_data, // Data to fill to the Icache. With ECC
138 2137120 : input logic [63:0] ic_rd_data , // Data read from Icache. 2x64bits + parity bits. F2 stage. With ECC
139 231589 : input logic [70:0] ic_debug_rd_data , // Data read from Icache. 2x64bits + parity bits. F2 stage. With ECC
140 0 : input logic [25:0] ictag_debug_rd_data, // Debug icache tag.
141 0 : output logic [70:0] ic_debug_wr_data, // Debug wr cache.
142 0 : output logic [70:0] ifu_ic_debug_rd_data, // debug data read
143 :
144 :
145 0 : input logic [pt.ICACHE_BANKS_WAY-1:0] ic_eccerr, //
146 0 : input logic [pt.ICACHE_BANKS_WAY-1:0] ic_parerr,
147 :
148 0 : output logic [pt.ICACHE_INDEX_HI:3] ic_debug_addr, // Read/Write addresss to the Icache.
149 0 : output logic ic_debug_rd_en, // Icache debug rd
150 0 : output logic ic_debug_wr_en, // Icache debug wr
151 0 : output logic ic_debug_tag_array, // Debug tag array
152 0 : output logic [pt.ICACHE_NUM_WAYS-1:0] ic_debug_way, // Debug way. Rd or Wr.
153 :
154 :
155 255918 : output logic [pt.ICACHE_NUM_WAYS-1:0] ic_tag_valid, // Valid bits when accessing the Icache. One valid bit per way. F2 stage
156 :
157 109586 : input logic [pt.ICACHE_NUM_WAYS-1:0] ic_rd_hit, // Compare hits from Icache tags. Per way. F2 stage
158 0 : input logic ic_tag_perr, // Icache Tag parity error
159 :
160 : // ICCM ports
161 160275 : output logic [pt.ICCM_BITS-1:1] iccm_rw_addr, // ICCM read/write address.
162 74 : output logic iccm_wren, // ICCM write enable (through the DMA)
163 133206 : output logic iccm_rden, // ICCM read enable.
164 14 : output logic [77:0] iccm_wr_data, // ICCM write data.
165 0 : output logic [2:0] iccm_wr_size, // ICCM write location within DW.
166 :
167 136532 : input logic [63:0] iccm_rd_data, // Data read from ICCM.
168 161264 : input logic [77:0] iccm_rd_data_ecc, // Data + ECC read from ICCM.
169 6340267 : input logic [1:0] ifu_fetch_val,
170 : // IFU control signals
171 6789925 : output logic ic_hit_f, // Hit in Icache(if Icache access) or ICCM access( ICCM always has ic_hit_f)
172 182 : output logic [1:0] ic_access_fault_f, // Access fault (bus error or ICCM access in region but out of offset range).
173 172 : output logic [1:0] ic_access_fault_type_f, // Access fault types
174 8 : output logic iccm_rd_ecc_single_err, // This fetch has a single ICCM ECC error.
175 4 : output logic [1:0] iccm_rd_ecc_double_err, // This fetch has a double ICCM ECC error.
176 0 : output logic iccm_dma_rd_ecc_single_err, // This fetch has a single ICCM DMA ECC error.
177 0 : output logic iccm_dma_rd_ecc_double_err, // This fetch has a double ICCM DMA ECC error.
178 0 : output logic ic_error_start, // This has any I$ errors ( data/tag/ecc/parity )
179 :
180 8 : output logic ifu_async_error_start, // Or of the sb iccm, and all the icache errors sent to aligner to stop
181 0 : output logic iccm_dma_sb_error, // Single Bit ECC error from a DMA access
182 6340267 : output logic [1:0] ic_fetch_val_f, // valid bytes for fetch. To the Aligner.
183 2168046 : output logic [31:0] ic_data_f, // Data read from Icache or ICCM. To the Aligner.
184 1738700 : output logic [63:0] ic_premux_data, // Premuxed data to be muxed with Icache data
185 5605966 : output logic ic_sel_premux_data, // Select premux data.
186 :
187 : ///// Debug
188 0 : input el2_cache_debug_pkt_t dec_tlu_ic_diag_pkt , // Icache/tag debug read/write packet
189 8 : input logic dec_tlu_core_ecc_disable, // disable the ecc checking and flagging
190 0 : output logic ifu_ic_debug_rd_data_valid, // debug data valid.
191 8 : output logic iccm_buf_correct_ecc,
192 8 : output logic iccm_correction_state,
193 :
194 110 : input logic ifu_pmp_error,
195 :
196 :
197 0 : input logic scan_mode
198 : );
199 :
200 : // Create different defines for ICACHE and ICCM enable combinations
201 :
202 : localparam NUM_OF_BEATS = 8 ;
203 :
204 :
205 :
206 444 : logic [31:3] ifu_ic_req_addr_f;
207 375 : logic uncacheable_miss_in ;
208 374 : logic uncacheable_miss_ff;
209 :
210 :
211 :
212 11810469 : logic bus_ifu_wr_en ;
213 11810197 : logic bus_ifu_wr_en_ff ;
214 25648 : logic bus_ifu_wr_en_ff_q ;
215 32444 : logic bus_ifu_wr_en_ff_wo_err ;
216 10432 : logic [pt.ICACHE_NUM_WAYS-1:0] bus_ic_wr_en ;
217 :
218 6412 : logic reset_tag_valid_for_miss ;
219 :
220 :
221 39384 : logic [pt.ICACHE_STATUS_BITS-1:0] way_status;
222 36444 : logic [pt.ICACHE_STATUS_BITS-1:0] way_status_mb_in;
223 658757 : logic [pt.ICACHE_STATUS_BITS-1:0] way_status_rep_new;
224 36444 : logic [pt.ICACHE_STATUS_BITS-1:0] way_status_mb_ff;
225 616386 : logic [pt.ICACHE_STATUS_BITS-1:0] way_status_new;
226 613108 : logic [pt.ICACHE_STATUS_BITS-1:0] way_status_hit_new;
227 616386 : logic [pt.ICACHE_STATUS_BITS-1:0] way_status_new_w_debug;
228 293066 : logic [pt.ICACHE_NUM_WAYS-1:0] tagv_mb_in;
229 293066 : logic [pt.ICACHE_NUM_WAYS-1:0] tagv_mb_ff;
230 :
231 :
232 18 : logic ifu_wr_data_comb_err ;
233 10 : logic ifu_byp_data_err_new;
234 10 : logic [1:0] ifu_byp_data_err_f;
235 18 : logic ifu_wr_cumulative_err_data;
236 18 : logic ifu_wr_cumulative_err;
237 18 : logic ifu_wr_data_comb_err_ff;
238 0 : logic scnd_miss_index_match ;
239 :
240 :
241 638334 : logic ifc_dma_access_q_ok;
242 84 : logic ifc_iccm_access_f ;
243 2 : logic ifc_region_acc_fault_f;
244 172 : logic ifc_region_acc_fault_final_f;
245 10 : logic [1:0] ifc_bus_acc_fault_f;
246 5895697 : logic ic_act_miss_f;
247 1276 : logic ic_miss_under_miss_f;
248 353012 : logic ic_ignore_2nd_miss_f;
249 745274 : logic ic_act_hit_f;
250 5894335 : logic miss_pending;
251 444 : logic [31:1] imb_in , imb_ff ;
252 444 : logic [31:pt.ICACHE_BEAT_ADDR_HI+1] miss_addr_in , miss_addr ;
253 575712 : logic miss_wrap_f ;
254 674202 : logic flush_final_f;
255 4269076 : logic ifc_fetch_req_f;
256 3719264 : logic ifc_fetch_req_f_raw;
257 6789925 : logic fetch_req_f_qual ;
258 3719302 : logic ifc_fetch_req_qual_bf ;
259 658418 : logic [pt.ICACHE_NUM_WAYS-1:0] replace_way_mb_any;
260 5895138 : logic last_beat;
261 8620613 : logic reset_beat_cnt ;
262 2940234 : logic [pt.ICACHE_BEAT_ADDR_HI:3] ic_req_addr_bits_hi_3 ;
263 5580223 : logic [pt.ICACHE_BEAT_ADDR_HI:3] ic_wr_addr_bits_hi_3 ;
264 444 : logic [31:1] ifu_fetch_addr_int_f ;
265 490 : logic [31:1] ifu_ic_rw_int_addr ;
266 5895441 : logic crit_wd_byp_ok_ff ;
267 5881106 : logic ic_crit_wd_rdy_new_ff;
268 1200480 : logic [79:0] ic_byp_data_only_pre_new;
269 961690 : logic [79:0] ic_byp_data_only_new;
270 5882773 : logic ic_byp_hit_f ;
271 10505 : logic ic_valid ;
272 10504 : logic ic_valid_ff;
273 18868 : logic reset_all_tags;
274 10505 : logic ic_valid_w_debug;
275 :
276 4954 : logic [pt.ICACHE_NUM_WAYS-1:0] ifu_tag_wren,ifu_tag_wren_ff;
277 0 : logic [pt.ICACHE_NUM_WAYS-1:0] ic_debug_tag_wr_en;
278 4954 : logic [pt.ICACHE_NUM_WAYS-1:0] ifu_tag_wren_w_debug;
279 0 : logic [pt.ICACHE_NUM_WAYS-1:0] ic_debug_way_ff;
280 0 : logic ic_debug_rd_en_ff ;
281 566 : logic fetch_bf_f_c1_clken ;
282 0 : logic fetch_bf_f_c1_clk;
283 0 : logic debug_c1_clken;
284 0 : logic debug_c1_clk;
285 :
286 3738 : logic reset_ic_in ;
287 3738 : logic reset_ic_ff ;
288 463254 : logic [pt.ICACHE_BEAT_ADDR_HI:1] vaddr_f ;
289 448 : logic [31:1] ifu_status_wr_addr;
290 31000 : logic sel_mb_addr ;
291 31000 : logic sel_mb_addr_ff ;
292 11764 : logic sel_mb_status_addr ;
293 2137120 : logic [63:0] ic_final_data;
294 :
295 616386 : logic [pt.ICACHE_STATUS_BITS-1:0] way_status_new_ff ;
296 750828 : logic way_status_wr_en_ff ;
297 30 : logic [pt.ICACHE_TAG_DEPTH-1:0][pt.ICACHE_STATUS_BITS-1:0] way_status_out ;
298 0 : logic [1:0] ic_debug_way_enc;
299 :
300 1182830 : logic [pt.IFU_BUS_TAG-1:0] ifu_bus_rid_ff;
301 :
302 4107126 : logic fetch_req_icache_f;
303 161786 : logic fetch_req_iccm_f;
304 161786 : logic ic_iccm_hit_f;
305 374 : logic fetch_uncacheable_ff;
306 750828 : logic way_status_wr_en;
307 5444186 : logic sel_byp_data;
308 5606386 : logic sel_ic_data;
309 161786 : logic sel_iccm_data;
310 0 : logic ic_rd_parity_final_err;
311 5895668 : logic ic_act_miss_f_delayed;
312 20 : logic bus_ifu_wr_data_error;
313 18 : logic bus_ifu_wr_data_error_ff;
314 750828 : logic way_status_wr_en_w_debug;
315 0 : logic ic_debug_tag_val_rd_out;
316 5895697 : logic ifu_pmu_ic_miss_in;
317 745274 : logic ifu_pmu_ic_hit_in;
318 10 : logic ifu_pmu_bus_error_in;
319 10364764 : logic ifu_pmu_bus_trxn_in;
320 4469097 : logic ifu_pmu_bus_busy_in;
321 0 : logic ic_debug_ict_array_sel_in;
322 0 : logic ic_debug_ict_array_sel_ff;
323 0 : logic debug_data_clken;
324 5894042 : logic last_data_recieved_in ;
325 5893997 : logic last_data_recieved_ff ;
326 :
327 11810469 : logic ifu_bus_rvalid ;
328 11810197 : logic ifu_bus_rvalid_ff ;
329 11810197 : logic ifu_bus_rvalid_unq_ff ;
330 10364845 : logic ifu_bus_arready_unq ;
331 10364577 : logic ifu_bus_arready_unq_ff ;
332 5895462 : logic ifu_bus_arvalid ;
333 5895417 : logic ifu_bus_arvalid_ff ;
334 10364845 : logic ifu_bus_arready ;
335 10364577 : logic ifu_bus_arready_ff ;
336 985546 : logic [63:0] ifu_bus_rdata_ff ;
337 18 : logic [1:0] ifu_bus_rresp_ff ;
338 11810469 : logic ifu_bus_rsp_valid ;
339 339 : logic ifu_bus_rsp_ready ;
340 1182850 : logic [pt.IFU_BUS_TAG-1:0] ifu_bus_rsp_tag;
341 985567 : logic [63:0] ifu_bus_rsp_rdata;
342 20 : logic [1:0] ifu_bus_rsp_opc;
343 :
344 1229554 : logic [pt.ICACHE_NUM_BEATS-1:0] write_fill_data;
345 0 : logic [pt.ICACHE_NUM_BEATS-1:0] wr_data_c1_clk;
346 1229489 : logic [pt.ICACHE_NUM_BEATS-1:0] ic_miss_buff_data_valid_in;
347 1229479 : logic [pt.ICACHE_NUM_BEATS-1:0] ic_miss_buff_data_valid;
348 0 : logic [pt.ICACHE_NUM_BEATS-1:0] ic_miss_buff_data_error_in;
349 0 : logic [pt.ICACHE_NUM_BEATS-1:0] ic_miss_buff_data_error;
350 463254 : logic [pt.ICACHE_BEAT_ADDR_HI:1] byp_fetch_index;
351 1007096 : logic [pt.ICACHE_BEAT_ADDR_HI:2] byp_fetch_index_0;
352 338 : logic [pt.ICACHE_BEAT_ADDR_HI:2] byp_fetch_index_1;
353 1040400 : logic [pt.ICACHE_BEAT_ADDR_HI:3] byp_fetch_index_inc;
354 1040400 : logic [pt.ICACHE_BEAT_ADDR_HI:2] byp_fetch_index_inc_0;
355 338 : logic [pt.ICACHE_BEAT_ADDR_HI:2] byp_fetch_index_inc_1;
356 8438643 : logic miss_buff_hit_unq_f ;
357 6018 : logic stream_hit_f ;
358 1462 : logic stream_miss_f ;
359 614 : logic stream_eol_f ;
360 5880677 : logic crit_byp_hit_f ;
361 1182830 : logic [pt.IFU_BUS_TAG-1:0] other_tag ;
362 : logic [(2*pt.ICACHE_NUM_BEATS)-1:0] [31:0] ic_miss_buff_data;
363 1013380 : logic [63:0] ic_miss_buff_half;
364 1060 : logic scnd_miss_req, scnd_miss_req_q;
365 1376 : logic scnd_miss_req_in;
366 :
367 :
368 0 : logic [pt.ICCM_BITS-1:2] iccm_ecc_corr_index_ff;
369 158179 : logic [pt.ICCM_BITS-1:2] iccm_ecc_corr_index_in;
370 2 : logic [38:0] iccm_ecc_corr_data_ff;
371 8 : logic iccm_ecc_write_status ;
372 8 : logic iccm_rd_ecc_single_err_ff ;
373 8 : logic iccm_error_start; // start the error fsm
374 8 : logic perr_state_en;
375 13547173 : logic miss_state_en;
376 :
377 0 : logic busclk;
378 0 : logic busclk_force;
379 0 : logic busclk_reset;
380 338 : logic bus_ifu_bus_clk_en_ff;
381 338 : logic bus_ifu_bus_clk_en ;
382 :
383 5895677 : logic ifc_bus_ic_req_ff_in;
384 5895462 : logic ifu_bus_cmd_valid ;
385 10364845 : logic ifu_bus_cmd_ready ;
386 :
387 5915059 : logic bus_inc_data_beat_cnt ;
388 8620613 : logic bus_reset_data_beat_cnt ;
389 14536011 : logic bus_hold_data_beat_cnt ;
390 :
391 10364764 : logic bus_inc_cmd_beat_cnt ;
392 6412 : logic bus_reset_cmd_beat_cnt_0 ;
393 5889285 : logic bus_reset_cmd_beat_cnt_secondlast ;
394 10365132 : logic bus_hold_cmd_beat_cnt ;
395 :
396 6412 : logic [pt.ICACHE_BEAT_BITS-1:0] bus_new_data_beat_count ;
397 6412 : logic [pt.ICACHE_BEAT_BITS-1:0] bus_data_beat_count ;
398 :
399 5895648 : logic [pt.ICACHE_BEAT_BITS-1:0] bus_new_cmd_beat_count ;
400 5895462 : logic [pt.ICACHE_BEAT_BITS-1:0] bus_cmd_beat_count ;
401 :
402 :
403 2940308 : logic [pt.ICACHE_BEAT_BITS-1:0] bus_new_rd_addr_count;
404 2940234 : logic [pt.ICACHE_BEAT_BITS-1:0] bus_rd_addr_count;
405 :
406 :
407 10364764 : logic bus_cmd_sent ;
408 5895187 : logic bus_last_data_beat ;
409 :
410 :
411 10432 : logic [pt.ICACHE_NUM_WAYS-1:0] bus_wren ;
412 :
413 2608 : logic [pt.ICACHE_NUM_WAYS-1:0] bus_wren_last ;
414 2608 : logic [pt.ICACHE_NUM_WAYS-1:0] wren_reset_miss ;
415 640775 : logic ifc_dma_access_ok_d;
416 640774 : logic ifc_dma_access_ok_prev;
417 :
418 5895697 : logic bus_cmd_req_in ;
419 5895668 : logic bus_cmd_req_hold ;
420 :
421 3004649 : logic second_half_available ;
422 3005962 : logic write_ic_16_bytes ;
423 :
424 172 : logic ifc_region_acc_fault_final_bf;
425 170 : logic ifc_region_acc_fault_memory_bf;
426 170 : logic ifc_region_acc_fault_memory_f;
427 449 : logic ifc_region_acc_okay;
428 :
429 8 : logic iccm_correct_ecc;
430 0 : logic dma_sb_err_state, dma_sb_err_state_ff;
431 4906797 : logic two_byte_instr;
432 :
433 : typedef enum logic [2:0] {IDLE=3'b000, CRIT_BYP_OK=3'b001, HIT_U_MISS=3'b010, MISS_WAIT=3'b011,CRIT_WRD_RDY=3'b100,SCND_MISS=3'b101,STREAM=3'b110 , STALL_SCND_MISS=3'b111} miss_state_t;
434 21456 : miss_state_t miss_state, miss_nxtstate;
435 :
436 : typedef enum logic [1:0] {ERR_STOP_IDLE=2'b00, ERR_FETCH1=2'b01 , ERR_FETCH2=2'b10 , ERR_STOP_FETCH=2'b11} err_stop_state_t;
437 8 : err_stop_state_t err_stop_state, err_stop_nxtstate;
438 24 : logic err_stop_state_en ;
439 8 : logic err_stop_fetch ;
440 :
441 5881136 : logic ic_crit_wd_rdy; // Critical fetch is ready to be bypassed.
442 :
443 2865729 : logic ifu_bp_hit_taken_q_f;
444 11810469 : logic ifu_bus_rvalid_unq;
445 10364793 : logic bus_cmd_beat_en;
446 :
447 :
448 : // ---- Clock gating section -----
449 : // c1 clock enables
450 :
451 :
452 : assign fetch_bf_f_c1_clken = ifc_fetch_req_bf_raw | ifc_fetch_req_f | miss_pending | exu_flush_final | scnd_miss_req;
453 : assign debug_c1_clken = ic_debug_rd_en | ic_debug_wr_en ;
454 : // C1 - 1 clock pulse for data
455 : `ifdef RV_FPGA_OPTIMIZE
456 : assign fetch_bf_f_c1_clk = 1'b0;
457 : assign debug_c1_clk = 1'b0;
458 : `else
459 : rvclkhdr fetch_bf_f_c1_cgc ( .en(fetch_bf_f_c1_clken), .l1clk(fetch_bf_f_c1_clk), .* );
460 : rvclkhdr debug_c1_cgc ( .en(debug_c1_clken), .l1clk(debug_c1_clk), .* );
461 : `endif
462 :
463 :
464 : // ------ end clock gating section ------------------------
465 :
466 0 : logic [1:0] iccm_single_ecc_error;
467 66 : logic dma_iccm_req_f ;
468 : assign iccm_dma_sb_error = (|iccm_single_ecc_error[1:0] ) & dma_iccm_req_f ;
469 : assign ifu_async_error_start = iccm_rd_ecc_single_err | ic_error_start;
470 :
471 :
472 : typedef enum logic [2:0] {ERR_IDLE=3'b000, IC_WFF=3'b001 , ECC_WFF=3'b010 , ECC_CORR=3'b011, DMA_SB_ERR=3'b100} perr_state_t;
473 0 : perr_state_t perr_state, perr_nxtstate;
474 :
475 :
476 : assign ic_dma_active = iccm_correct_ecc | (perr_state == DMA_SB_ERR) | (err_stop_state == ERR_STOP_FETCH) | err_stop_fetch |
477 : dec_tlu_flush_err_wb; // The last term is to give a error-correction a chance to finish before refetch starts
478 :
479 : assign scnd_miss_req_in = ifu_bus_rsp_valid & bus_ifu_bus_clk_en & ifu_bus_rsp_ready &
480 : (&bus_new_data_beat_count[pt.ICACHE_BEAT_BITS-1:0]) &
481 : ~uncacheable_miss_ff & ((miss_state == SCND_MISS) | (miss_nxtstate == SCND_MISS)) & ~exu_flush_final;
482 :
483 : assign ifu_bp_hit_taken_q_f = ifu_bp_hit_taken_f & ic_hit_f ;
484 :
485 : //////////////////////////////////// Create Miss State Machine ///////////////////////
486 : // Create Miss State Machine //
487 : // Create Miss State Machine //
488 : // Create Miss State Machine //
489 : //////////////////////////////////// Create Miss State Machine ///////////////////////
490 : // FIFO state machine
491 339 : always_comb begin : MISS_SM
492 339 : miss_nxtstate = IDLE;
493 339 : miss_state_en = 1'b0;
494 339 : case (miss_state)
495 12816269 : IDLE: begin : idle
496 12816269 : miss_nxtstate = (ic_act_miss_f & ~exu_flush_final) ? CRIT_BYP_OK : HIT_U_MISS ;
497 12816269 : miss_state_en = ic_act_miss_f & ~dec_tlu_force_halt ;
498 : end
499 10079786 : CRIT_BYP_OK: begin : crit_byp_ok
500 10079786 : miss_nxtstate = (dec_tlu_force_halt ) ? IDLE :
501 10079786 : ( ic_byp_hit_f & (last_data_recieved_ff | (bus_ifu_wr_en_ff & last_beat)) & uncacheable_miss_ff) ? IDLE :
502 10079786 : ( ic_byp_hit_f & ~last_data_recieved_ff & uncacheable_miss_ff) ? MISS_WAIT :
503 10079786 : (~ic_byp_hit_f & ~exu_flush_final & (bus_ifu_wr_en_ff & last_beat) & uncacheable_miss_ff) ? CRIT_WRD_RDY :
504 10079786 : ( (bus_ifu_wr_en_ff & last_beat) & ~uncacheable_miss_ff) ? IDLE :
505 10079786 : ( ic_byp_hit_f & ~exu_flush_final & ~(bus_ifu_wr_en_ff & last_beat) & ~ifu_bp_hit_taken_q_f & ~uncacheable_miss_ff) ? STREAM :
506 10079786 : ( bus_ifu_wr_en_ff & ~exu_flush_final & ~(bus_ifu_wr_en_ff & last_beat) & ~ifu_bp_hit_taken_q_f & ~uncacheable_miss_ff) ? STREAM :
507 10079786 : (~ic_byp_hit_f & ~exu_flush_final & (bus_ifu_wr_en_ff & last_beat) & ~uncacheable_miss_ff) ? IDLE :
508 10079786 : ( (exu_flush_final | ifu_bp_hit_taken_q_f) & ~(bus_ifu_wr_en_ff & last_beat) ) ? HIT_U_MISS : IDLE;
509 10079786 : miss_state_en = dec_tlu_force_halt | exu_flush_final | ic_byp_hit_f | ifu_bp_hit_taken_q_f | (bus_ifu_wr_en_ff & last_beat) | (bus_ifu_wr_en_ff & ~uncacheable_miss_ff) ;
510 : end
511 0 : CRIT_WRD_RDY: begin : crit_wrd_rdy
512 0 : miss_nxtstate = IDLE ;
513 0 : miss_state_en = exu_flush_final | flush_final_f | ic_byp_hit_f | dec_tlu_force_halt ;
514 : end
515 22074 : STREAM: begin : stream
516 22074 : miss_nxtstate = ((exu_flush_final | ifu_bp_hit_taken_q_f | stream_eol_f ) & ~(bus_ifu_wr_en_ff & last_beat) & ~dec_tlu_force_halt) ? HIT_U_MISS : IDLE ;
517 22074 : miss_state_en = exu_flush_final | ifu_bp_hit_taken_q_f | stream_eol_f | (bus_ifu_wr_en_ff & last_beat) | dec_tlu_force_halt ;
518 : end
519 5025451 : MISS_WAIT: begin : miss_wait
520 5025451 : miss_nxtstate = (exu_flush_final & ~(bus_ifu_wr_en_ff & last_beat) & ~dec_tlu_force_halt) ? HIT_U_MISS : IDLE ;
521 5025451 : miss_state_en = exu_flush_final | (bus_ifu_wr_en_ff & last_beat) | dec_tlu_force_halt ;
522 : end
523 181449 : HIT_U_MISS: begin : hit_u_miss
524 181449 : miss_nxtstate = ic_miss_under_miss_f & ~(bus_ifu_wr_en_ff & last_beat) & ~dec_tlu_force_halt ? SCND_MISS :
525 181449 : ic_ignore_2nd_miss_f & ~(bus_ifu_wr_en_ff & last_beat) & ~dec_tlu_force_halt ? STALL_SCND_MISS : IDLE ;
526 181449 : miss_state_en = (bus_ifu_wr_en_ff & last_beat) | ic_miss_under_miss_f | ic_ignore_2nd_miss_f | dec_tlu_force_halt;
527 : end
528 2979 : SCND_MISS: begin : scnd_miss
529 2979 : miss_nxtstate = dec_tlu_force_halt ? IDLE :
530 2979 : exu_flush_final ? ((bus_ifu_wr_en_ff & last_beat) ? IDLE : HIT_U_MISS) : CRIT_BYP_OK;
531 2979 : miss_state_en = (bus_ifu_wr_en_ff & last_beat) | exu_flush_final | dec_tlu_force_halt;
532 : end
533 23593 : STALL_SCND_MISS: begin : stall_scnd_miss
534 23593 : miss_nxtstate = dec_tlu_force_halt ? IDLE :
535 23593 : exu_flush_final ? ((bus_ifu_wr_en_ff & last_beat) ? IDLE : HIT_U_MISS) : IDLE;
536 23593 : miss_state_en = (bus_ifu_wr_en_ff & last_beat) | exu_flush_final | dec_tlu_force_halt;
537 : end
538 : /*verilator coverage_off*/
539 : default: begin : def_case
540 : miss_nxtstate = IDLE;
541 : miss_state_en = 1'b0;
542 : end
543 : /*verilator coverage_on*/
544 : endcase
545 : end
546 : rvdffs #(($bits(miss_state_t))) miss_state_ff (.clk(active_clk), .din(miss_nxtstate), .dout({miss_state}), .en(miss_state_en), .*);
547 :
548 5894380 : logic sel_hold_imb ;
549 :
550 : assign miss_pending = (miss_state != IDLE) ;
551 : assign crit_wd_byp_ok_ff = (miss_state == CRIT_BYP_OK) | ((miss_state == CRIT_WRD_RDY) & ~flush_final_f);
552 : assign sel_hold_imb = (miss_pending & ~(bus_ifu_wr_en_ff & last_beat) & ~((miss_state == CRIT_WRD_RDY) & exu_flush_final) &
553 : ~((miss_state == CRIT_WRD_RDY) & crit_byp_hit_f) ) | ic_act_miss_f |
554 : (miss_pending & (miss_nxtstate == CRIT_WRD_RDY)) ;
555 :
556 :
557 1192 : logic sel_hold_imb_scnd;
558 444 : logic [31:1] imb_scnd_in;
559 444 : logic [31:1] imb_scnd_ff;
560 375 : logic uncacheable_miss_scnd_in ;
561 374 : logic uncacheable_miss_scnd_ff ;
562 :
563 298350 : logic [pt.ICACHE_NUM_WAYS-1:0] tagv_mb_scnd_in;
564 298350 : logic [pt.ICACHE_NUM_WAYS-1:0] tagv_mb_scnd_ff;
565 :
566 38886 : logic [pt.ICACHE_STATUS_BITS-1:0] way_status_mb_scnd_in;
567 38886 : logic [pt.ICACHE_STATUS_BITS-1:0] way_status_mb_scnd_ff;
568 :
569 : assign sel_hold_imb_scnd =((miss_state == SCND_MISS) | ic_miss_under_miss_f) & ~flush_final_f ;
570 : assign way_status_mb_scnd_in[pt.ICACHE_STATUS_BITS-1:0] = (miss_state == SCND_MISS) ? way_status_mb_scnd_ff[pt.ICACHE_STATUS_BITS-1:0] : {way_status[pt.ICACHE_STATUS_BITS-1:0]} ;
571 : assign tagv_mb_scnd_in[pt.ICACHE_NUM_WAYS-1:0] = (miss_state == SCND_MISS) ? tagv_mb_scnd_ff[pt.ICACHE_NUM_WAYS-1:0] : ({ic_tag_valid[pt.ICACHE_NUM_WAYS-1:0]} & {pt.ICACHE_NUM_WAYS{~reset_all_tags & ~exu_flush_final}});
572 : assign uncacheable_miss_scnd_in = sel_hold_imb_scnd ? uncacheable_miss_scnd_ff : ifc_fetch_uncacheable_bf ;
573 :
574 :
575 : rvdff_fpga #(1) unc_miss_scnd_ff (.*, .clk(fetch_bf_f_c1_clk), .clken(fetch_bf_f_c1_clken), .rawclk(clk), .din (uncacheable_miss_scnd_in), .dout(uncacheable_miss_scnd_ff));
576 : rvdffpcie #(31) imb_f_scnd_ff (.*, .en(fetch_bf_f_c1_clken), .din ({imb_scnd_in[31:1]}), .dout({imb_scnd_ff[31:1]}));
577 : rvdff_fpga #(pt.ICACHE_STATUS_BITS) mb_rep_wayf2_scnd_ff (.*, .clk(fetch_bf_f_c1_clk), .clken(fetch_bf_f_c1_clken), .rawclk(clk), .din ({way_status_mb_scnd_in[pt.ICACHE_STATUS_BITS-1:0]}), .dout({way_status_mb_scnd_ff[pt.ICACHE_STATUS_BITS-1:0]}));
578 : rvdff_fpga #(pt.ICACHE_NUM_WAYS) mb_tagv_scnd_ff (.*, .clk(fetch_bf_f_c1_clk), .clken(fetch_bf_f_c1_clken), .rawclk(clk), .din ({tagv_mb_scnd_in[pt.ICACHE_NUM_WAYS-1:0]}), .dout({tagv_mb_scnd_ff[pt.ICACHE_NUM_WAYS-1:0]}));
579 :
580 :
581 :
582 :
583 : assign ic_req_addr_bits_hi_3[pt.ICACHE_BEAT_ADDR_HI:3] = bus_rd_addr_count[pt.ICACHE_BEAT_BITS-1:0] ;
584 : assign ic_wr_addr_bits_hi_3[pt.ICACHE_BEAT_ADDR_HI:3] = ifu_bus_rid_ff[pt.ICACHE_BEAT_BITS-1:0] & {pt.ICACHE_BEAT_BITS{bus_ifu_wr_en_ff}};
585 : // NOTE: Cacheline size is 16 bytes in this example.
586 : // Tag Index Bank Offset
587 : // [31:16] [15:5] [4] [3:0]
588 :
589 :
590 : assign fetch_req_icache_f = ifc_fetch_req_f & ~ifc_iccm_access_f & ~ifc_region_acc_fault_final_f;
591 : assign fetch_req_iccm_f = ifc_fetch_req_f & ifc_iccm_access_f;
592 :
593 : assign ic_iccm_hit_f = fetch_req_iccm_f & (~miss_pending | (miss_state==HIT_U_MISS) | (miss_state==STREAM));
594 : assign ic_byp_hit_f = (crit_byp_hit_f | stream_hit_f) & fetch_req_icache_f & miss_pending ;
595 : assign ic_act_hit_f = (|ic_rd_hit[pt.ICACHE_NUM_WAYS-1:0]) & fetch_req_icache_f & ~reset_all_tags & (~miss_pending | (miss_state==HIT_U_MISS)) & ~sel_mb_addr_ff;
596 : assign ic_act_miss_f = (((~(|ic_rd_hit[pt.ICACHE_NUM_WAYS-1:0]) | reset_all_tags) & fetch_req_icache_f & ~miss_pending) | scnd_miss_req) & ~ifc_region_acc_fault_final_f;
597 : assign ic_miss_under_miss_f = (~(|ic_rd_hit[pt.ICACHE_NUM_WAYS-1:0]) | reset_all_tags) & fetch_req_icache_f & (miss_state == HIT_U_MISS) &
598 : (imb_ff[31:pt.ICACHE_TAG_INDEX_LO] != ifu_fetch_addr_int_f[31:pt.ICACHE_TAG_INDEX_LO]) & ~uncacheable_miss_ff & ~sel_mb_addr_ff & ~ifc_region_acc_fault_final_f;
599 : assign ic_ignore_2nd_miss_f = (~(|ic_rd_hit[pt.ICACHE_NUM_WAYS-1:0]) | reset_all_tags) & fetch_req_icache_f & (miss_state == HIT_U_MISS) &
600 : ((imb_ff[31:pt.ICACHE_TAG_INDEX_LO] == ifu_fetch_addr_int_f[31:pt.ICACHE_TAG_INDEX_LO]) | uncacheable_miss_ff) ;
601 : assign ic_hit_f = ic_act_hit_f | ic_byp_hit_f | ic_iccm_hit_f | (ifc_region_acc_fault_final_f & ifc_fetch_req_f);
602 :
603 : assign uncacheable_miss_in = scnd_miss_req ? uncacheable_miss_scnd_ff : sel_hold_imb ? uncacheable_miss_ff : ifc_fetch_uncacheable_bf ;
604 : assign imb_in[31:1] = scnd_miss_req ? imb_scnd_ff[31:1] : sel_hold_imb ? imb_ff[31:1] : {ifc_fetch_addr_bf[31:1]} ;
605 :
606 : assign imb_scnd_in[31:1] = sel_hold_imb_scnd ? imb_scnd_ff[31:1] : {ifc_fetch_addr_bf[31:1]} ;
607 :
608 : assign scnd_miss_index_match = (imb_ff[pt.ICACHE_INDEX_HI:pt.ICACHE_TAG_INDEX_LO] == imb_scnd_ff[pt.ICACHE_INDEX_HI:pt.ICACHE_TAG_INDEX_LO]) & scnd_miss_req & ~ifu_wr_cumulative_err_data;
609 : assign way_status_mb_in[pt.ICACHE_STATUS_BITS-1:0] = (scnd_miss_req & ~scnd_miss_index_match) ? way_status_mb_scnd_ff[pt.ICACHE_STATUS_BITS-1:0] :
610 : (scnd_miss_req & scnd_miss_index_match) ? way_status_rep_new[pt.ICACHE_STATUS_BITS-1:0] :
611 : miss_pending ? way_status_mb_ff[pt.ICACHE_STATUS_BITS-1:0] :
612 : {way_status[pt.ICACHE_STATUS_BITS-1:0]} ;
613 : assign tagv_mb_in[pt.ICACHE_NUM_WAYS-1:0] = scnd_miss_req ? (tagv_mb_scnd_ff[pt.ICACHE_NUM_WAYS-1:0] | ({pt.ICACHE_NUM_WAYS {scnd_miss_index_match}} & replace_way_mb_any[pt.ICACHE_NUM_WAYS-1:0])) :
614 : miss_pending ? tagv_mb_ff[pt.ICACHE_NUM_WAYS-1:0] : ({ic_tag_valid[pt.ICACHE_NUM_WAYS-1:0]} & {pt.ICACHE_NUM_WAYS{~reset_all_tags & ~exu_flush_final}}) ;
615 :
616 : assign reset_ic_in = miss_pending & ~scnd_miss_req_q & (reset_all_tags | reset_ic_ff) ;
617 :
618 :
619 :
620 : rvdffpcie #(31) ifu_fetch_addr_f_ff (.*, .en(fetch_bf_f_c1_clken), .din ({ifc_fetch_addr_bf[31:1]}), .dout({ifu_fetch_addr_int_f[31:1]}));
621 :
622 : assign vaddr_f[pt.ICACHE_BEAT_ADDR_HI:1] = ifu_fetch_addr_int_f[pt.ICACHE_BEAT_ADDR_HI:1] ;
623 :
624 : rvdffpcie #(31) imb_f_ff (.*, .en(fetch_bf_f_c1_clken), .din (imb_in[31:1]), .dout(imb_ff[31:1]));
625 : rvdff_fpga #(1) unc_miss_ff (.*, .clk(fetch_bf_f_c1_clk), .clken(fetch_bf_f_c1_clken), .rawclk(clk), .din ( uncacheable_miss_in), .dout( uncacheable_miss_ff));
626 :
627 :
628 : assign miss_addr_in[31:pt.ICACHE_BEAT_ADDR_HI+1] = (~miss_pending ) ? imb_ff[31:pt.ICACHE_BEAT_ADDR_HI+1] :
629 : ( scnd_miss_req_q ) ? imb_scnd_ff[31:pt.ICACHE_BEAT_ADDR_HI+1] : miss_addr[31:pt.ICACHE_BEAT_ADDR_HI+1] ;
630 :
631 :
632 : rvdfflie #(.WIDTH(31-pt.ICACHE_BEAT_ADDR_HI),.LEFT(31-pt.ICACHE_BEAT_ADDR_HI-8)) miss_f_ff (.*, .en(bus_ifu_bus_clk_en | ic_act_miss_f | dec_tlu_force_halt), .din ({miss_addr_in[31:pt.ICACHE_BEAT_ADDR_HI+1]}), .dout({miss_addr[31:pt.ICACHE_BEAT_ADDR_HI+1]}));
633 :
634 :
635 :
636 :
637 :
638 : rvdff_fpga #(pt.ICACHE_STATUS_BITS) mb_rep_wayf2_ff (.*, .clk(fetch_bf_f_c1_clk), .clken(fetch_bf_f_c1_clken), .rawclk(clk), .din ({way_status_mb_in[pt.ICACHE_STATUS_BITS-1:0]}), .dout({way_status_mb_ff[pt.ICACHE_STATUS_BITS-1:0]}));
639 : rvdff_fpga #(pt.ICACHE_NUM_WAYS) mb_tagv_ff (.*, .clk(fetch_bf_f_c1_clk), .clken(fetch_bf_f_c1_clken), .rawclk(clk), .din ({tagv_mb_in[pt.ICACHE_NUM_WAYS-1:0]}), .dout({tagv_mb_ff[pt.ICACHE_NUM_WAYS-1:0]}));
640 :
641 : assign ifc_fetch_req_qual_bf = ifc_fetch_req_bf & ~((miss_state == CRIT_WRD_RDY) & flush_final_f) & ~stream_miss_f ;// & ~exu_flush_final ;
642 :
643 : assign ifc_fetch_req_f = ifc_fetch_req_f_raw & ~exu_flush_final ;
644 :
645 : rvdff_fpga #(1) ifu_iccm_acc_ff (.*, .clk(fetch_bf_f_c1_clk), .clken(fetch_bf_f_c1_clken), .rawclk(clk), .din(ifc_iccm_access_bf), .dout(ifc_iccm_access_f));
646 : rvdff_fpga #(1) ifu_iccm_reg_acc_ff (.*, .clk(fetch_bf_f_c1_clk), .clken(fetch_bf_f_c1_clken), .rawclk(clk), .din(ifc_region_acc_fault_final_bf), .dout(ifc_region_acc_fault_final_f));
647 : rvdff_fpga #(1) rgn_acc_ff (.*, .clk(fetch_bf_f_c1_clk), .clken(fetch_bf_f_c1_clken), .rawclk(clk), .din(ifc_region_acc_fault_bf), .dout(ifc_region_acc_fault_f));
648 :
649 :
650 : assign ifu_ic_req_addr_f[31:3] = {miss_addr[31:pt.ICACHE_BEAT_ADDR_HI+1] , ic_req_addr_bits_hi_3[pt.ICACHE_BEAT_ADDR_HI:3] };
651 : assign ifu_ic_mb_empty = (((miss_state == HIT_U_MISS) | (miss_state == STREAM)) & ~(bus_ifu_wr_en_ff & last_beat)) | ~miss_pending ;
652 : assign ifu_miss_state_idle = (miss_state == IDLE) ;
653 :
654 :
655 : assign sel_mb_addr = ((miss_pending & write_ic_16_bytes & ~uncacheable_miss_ff) | reset_tag_valid_for_miss) ;
656 : assign ifu_ic_rw_int_addr[31:1] = ({31{ sel_mb_addr}} & {imb_ff[31:pt.ICACHE_BEAT_ADDR_HI+1] , ic_wr_addr_bits_hi_3[pt.ICACHE_BEAT_ADDR_HI:3] , imb_ff[2:1]}) |
657 : ({31{~sel_mb_addr}} & ifc_fetch_addr_bf[31:1] ) ;
658 :
659 : assign sel_mb_status_addr = ((miss_pending & write_ic_16_bytes & ~uncacheable_miss_ff & last_beat & bus_ifu_wr_en_ff_q) | reset_tag_valid_for_miss) ;
660 : assign ifu_status_wr_addr[31:1] = ({31{ sel_mb_status_addr}} & {imb_ff[31:pt.ICACHE_BEAT_ADDR_HI+1] , ic_wr_addr_bits_hi_3[pt.ICACHE_BEAT_ADDR_HI:3] , imb_ff[2:1]}) |
661 : ({31{~sel_mb_status_addr}} & ifu_fetch_addr_int_f[31:1] ) ;
662 :
663 :
664 : assign ic_rw_addr[31:1] = ifu_ic_rw_int_addr[31:1] ;
665 :
666 :
667 : if (pt.ICACHE_ECC == 1) begin: icache_ecc_1
668 : logic [6:0] ic_wr_ecc;
669 : logic [6:0] ic_miss_buff_ecc;
670 : logic [141:0] ic_wr_16bytes_data ;
671 : logic [70:0] ifu_ic_debug_rd_data_in ;
672 :
673 : rvecc_encode_64 ic_ecc_encode_64_bus (
674 : .din (ifu_bus_rdata_ff[63:0]),
675 : .ecc_out(ic_wr_ecc[6:0]));
676 : rvecc_encode_64 ic_ecc_encode_64_buff (
677 : .din (ic_miss_buff_half[63:0]),
678 : .ecc_out(ic_miss_buff_ecc[6:0]));
679 :
680 : for (genvar i=0; i < pt.ICACHE_BANKS_WAY ; i++) begin : ic_wr_data_loop
681 : assign ic_wr_data[i][70:0] = ic_wr_16bytes_data[((71*i)+70): (71*i)];
682 : end
683 :
684 :
685 : assign ic_debug_wr_data[70:0] = {dec_tlu_ic_diag_pkt.icache_wrdata[70:0]} ;
686 : assign ic_error_start = ((|ic_eccerr[pt.ICACHE_BANKS_WAY-1:0]) & ic_act_hit_f) | ic_rd_parity_final_err;
687 :
688 :
689 :
690 : assign ifu_ic_debug_rd_data_in[70:0] = ic_debug_ict_array_sel_ff ? {2'b0,ictag_debug_rd_data[25:21],32'b0,ictag_debug_rd_data[20:0],{7-pt.ICACHE_STATUS_BITS{1'b0}}, way_status[pt.ICACHE_STATUS_BITS-1:0],3'b0,ic_debug_tag_val_rd_out} :
691 : ic_debug_rd_data[70:0];
692 :
693 : rvdffe #(71) ifu_debug_data_ff (.*,
694 : .en (debug_data_clken),
695 : .din ({
696 : ifu_ic_debug_rd_data_in[70:0]
697 : }),
698 : .dout({
699 : ifu_ic_debug_rd_data[70:0]
700 : })
701 : );
702 :
703 : assign ic_wr_16bytes_data[141:0] = ifu_bus_rid_ff[0] ? {ic_wr_ecc[6:0] , ifu_bus_rdata_ff[63:0] , ic_miss_buff_ecc[6:0] , ic_miss_buff_half[63:0] } :
704 : {ic_miss_buff_ecc[6:0] , ic_miss_buff_half[63:0] , ic_wr_ecc[6:0] , ifu_bus_rdata_ff[63:0] } ;
705 :
706 :
707 : end
708 : else begin : icache_parity_1
709 : logic [3:0] ic_wr_parity;
710 : logic [3:0] ic_miss_buff_parity;
711 : logic [135:0] ic_wr_16bytes_data ;
712 : logic [70:0] ifu_ic_debug_rd_data_in ;
713 : for (genvar i=0 ; i < 4 ; i++) begin : DATA_PGEN
714 : rveven_paritygen #(16) par_bus (.data_in (ifu_bus_rdata_ff[((16*i)+15):(16*i)]),
715 : .parity_out(ic_wr_parity[i]));
716 : rveven_paritygen #(16) par_buff (.data_in (ic_miss_buff_half[((16*i)+15):(16*i)]),
717 : .parity_out(ic_miss_buff_parity[i]));
718 : end
719 :
720 :
721 : for (genvar i=0; i < pt.ICACHE_BANKS_WAY ; i++) begin : ic_wr_data_loop
722 : assign ic_wr_data[i][70:0] = {3'b0, ic_wr_16bytes_data[((68*i)+67): (68*i)]};
723 : end
724 :
725 :
726 :
727 :
728 :
729 : assign ic_debug_wr_data[70:0] = {dec_tlu_ic_diag_pkt.icache_wrdata[70:0]} ;
730 : assign ic_error_start = ((|ic_parerr[pt.ICACHE_BANKS_WAY-1:0]) & ic_act_hit_f) | ic_rd_parity_final_err;
731 :
732 : assign ifu_ic_debug_rd_data_in[70:0] = ic_debug_ict_array_sel_ff ? {6'b0,ictag_debug_rd_data[21],32'b0,ictag_debug_rd_data[20:0],{7-pt.ICACHE_STATUS_BITS{1'b0}},way_status[pt.ICACHE_STATUS_BITS-1:0],3'b0,ic_debug_tag_val_rd_out} :
733 : ic_debug_rd_data[70:0] ;
734 :
735 : rvdffe #(71) ifu_debug_data_ff (.*,
736 : .en (debug_data_clken),
737 : .din ({
738 : ifu_ic_debug_rd_data_in[70:0]
739 : }),
740 : .dout({
741 : ifu_ic_debug_rd_data[70:0]
742 : })
743 : );
744 :
745 : assign ic_wr_16bytes_data[135:0] = ifu_bus_rid_ff[0] ? {ic_wr_parity[3:0] , ifu_bus_rdata_ff[63:0] , ic_miss_buff_parity[3:0] , ic_miss_buff_half[63:0] } :
746 : {ic_miss_buff_parity[3:0] , ic_miss_buff_half[63:0] , ic_wr_parity[3:0] , ifu_bus_rdata_ff[63:0] } ;
747 :
748 : end
749 :
750 :
751 : assign ifu_wr_data_comb_err = bus_ifu_wr_data_error_ff ;
752 : assign ifu_wr_cumulative_err = (ifu_wr_data_comb_err | ifu_wr_data_comb_err_ff) & ~reset_beat_cnt;
753 : assign ifu_wr_cumulative_err_data = ifu_wr_data_comb_err | ifu_wr_data_comb_err_ff ;
754 :
755 :
756 : assign sel_byp_data = (ic_crit_wd_rdy | (miss_state == STREAM) | (miss_state == CRIT_BYP_OK));
757 : assign sel_ic_data = ~(ic_crit_wd_rdy | (miss_state == STREAM) | (miss_state == CRIT_BYP_OK) | (miss_state == MISS_WAIT)) & ~fetch_req_iccm_f & ~ifc_region_acc_fault_final_f;
758 :
759 : if (pt.ICCM_ICACHE==1) begin: iccm_icache
760 : assign sel_iccm_data = fetch_req_iccm_f ;
761 :
762 : assign ic_final_data[63:0] = ({64{sel_byp_data | sel_iccm_data | sel_ic_data}} & {ic_rd_data[63:0]} ) ;
763 :
764 : assign ic_premux_data[63:0] = ({64{sel_byp_data }} & {ic_byp_data_only_new[63:0]} ) |
765 : ({64{sel_iccm_data}} & {iccm_rd_data[63:0]});
766 :
767 : assign ic_sel_premux_data = sel_iccm_data | sel_byp_data ;
768 : end
769 :
770 : if (pt.ICCM_ONLY == 1 ) begin: iccm_only
771 : assign sel_iccm_data = fetch_req_iccm_f ;
772 : assign ic_final_data[63:0] = ({64{sel_byp_data }} & {ic_byp_data_only_new[63:0]} ) |
773 : ({64{sel_iccm_data}} & {iccm_rd_data[63:0]});
774 : assign ic_premux_data = '0 ;
775 : assign ic_sel_premux_data = '0 ;
776 : end
777 :
778 : if (pt.ICACHE_ONLY == 1 ) begin: icache_only
779 : assign ic_final_data[63:0] = ({64{sel_byp_data | sel_ic_data}} & {ic_rd_data[63:0]} ) ;
780 : assign ic_premux_data[63:0] = ({64{sel_byp_data }} & {ic_byp_data_only_new[63:0]} ) ;
781 : assign ic_sel_premux_data = sel_byp_data ;
782 : end
783 :
784 :
785 : if (pt.NO_ICCM_NO_ICACHE == 1 ) begin: no_iccm_no_icache
786 : assign ic_final_data[63:0] = ({64{sel_byp_data }} & {ic_byp_data_only_new[63:0]} ) ;
787 : assign ic_premux_data = 0 ;
788 : assign ic_sel_premux_data = '0 ;
789 : end
790 :
791 :
792 : assign ifc_bus_acc_fault_f[1:0] = {2{ic_byp_hit_f}} & ifu_byp_data_err_f[1:0] ;
793 : assign ic_data_f[31:0] = ic_final_data[31:0];
794 :
795 :
796 :
797 : assign fetch_req_f_qual = ic_hit_f & ~exu_flush_final;
798 : assign ic_access_fault_f[1:0] = ({2{ifc_region_acc_fault_final_f}} | ifc_bus_acc_fault_f[1:0]) & {2{~exu_flush_final}};
799 : assign ic_access_fault_type_f[1:0] = |iccm_rd_ecc_double_err ? 2'b01 :
800 : ifc_region_acc_fault_f ? 2'b10 :
801 : ifc_region_acc_fault_memory_f ? 2'b11 : 2'b00 ;
802 :
803 : // right justified
804 :
805 : assign ic_fetch_val_f[1] = fetch_req_f_qual & ifu_bp_inst_mask_f & ~(vaddr_f[pt.ICACHE_BEAT_ADDR_HI:1] == {pt.ICACHE_BEAT_ADDR_HI{1'b1}}) & (err_stop_state != ERR_FETCH2);
806 : assign ic_fetch_val_f[0] = fetch_req_f_qual ;
807 : assign two_byte_instr = (ic_data_f[1:0] != 2'b11 ) ;
808 :
809 : /////////////////////////////////////////////////////////////////////////////////////
810 : // Create full buffer... //
811 : /////////////////////////////////////////////////////////////////////////////////////
812 985567 : logic [63:0] ic_miss_buff_data_in;
813 : assign ic_miss_buff_data_in[63:0] = ifu_bus_rsp_rdata[63:0];
814 :
815 : for (genvar i=0; i<pt.ICACHE_NUM_BEATS; i++) begin : wr_flop
816 :
817 : assign write_fill_data[i] = bus_ifu_wr_en & ( (pt.IFU_BUS_TAG)'(i) == ifu_bus_rsp_tag[pt.IFU_BUS_TAG-1:0]);
818 :
819 : rvdffe #(32) byp_data_0_ff (.*,
820 : .en (write_fill_data[i]),
821 : .din (ic_miss_buff_data_in[31:0]),
822 : .dout(ic_miss_buff_data[i*2][31:0])
823 : );
824 :
825 : rvdffe #(32) byp_data_1_ff (.*,
826 : .en (write_fill_data[i]),
827 : .din (ic_miss_buff_data_in[63:32]),
828 : .dout(ic_miss_buff_data[i*2+1][31:0])
829 : );
830 :
831 : assign ic_miss_buff_data_valid_in[i] = write_fill_data[i] ? 1'b1 : (ic_miss_buff_data_valid[i] & ~ic_act_miss_f) ;
832 :
833 : rvdff #(1) byp_data_valid_ff (.*,
834 : .clk (active_clk),
835 : .din (ic_miss_buff_data_valid_in[i]),
836 : .dout(ic_miss_buff_data_valid[i]));
837 :
838 : assign ic_miss_buff_data_error_in[i] = write_fill_data[i] ? bus_ifu_wr_data_error : (ic_miss_buff_data_error[i] & ~ic_act_miss_f) ;
839 :
840 : rvdff #(1) byp_data_error_ff (.*,
841 : .clk (active_clk),
842 : .din (ic_miss_buff_data_error_in[i] ),
843 : .dout(ic_miss_buff_data_error[i]));
844 : end
845 :
846 : /////////////////////////////////////////////////////////////////////////////////////
847 : // New bypass ready //
848 : /////////////////////////////////////////////////////////////////////////////////////
849 427896 : logic [pt.ICACHE_BEAT_ADDR_HI:1] bypass_index;
850 969738 : logic [pt.ICACHE_BEAT_ADDR_HI:3] bypass_index_5_3_inc;
851 5895357 : logic bypass_data_ready_in;
852 5881201 : logic ic_crit_wd_rdy_new_in;
853 :
854 : assign bypass_index[pt.ICACHE_BEAT_ADDR_HI:1] = imb_ff[pt.ICACHE_BEAT_ADDR_HI:1] ;
855 : assign bypass_index_5_3_inc[pt.ICACHE_BEAT_ADDR_HI:3] = bypass_index[pt.ICACHE_BEAT_ADDR_HI:3] + 1 ;
856 :
857 :
858 : assign bypass_data_ready_in = ((ic_miss_buff_data_valid_in[bypass_index[pt.ICACHE_BEAT_ADDR_HI:3]] & ~bypass_index[2] & ~bypass_index[1])) |
859 : ((ic_miss_buff_data_valid_in[bypass_index[pt.ICACHE_BEAT_ADDR_HI:3]] & ~bypass_index[2] & bypass_index[1])) |
860 : ((ic_miss_buff_data_valid_in[bypass_index[pt.ICACHE_BEAT_ADDR_HI:3]] & bypass_index[2] & ~bypass_index[1])) |
861 : ((ic_miss_buff_data_valid_in[bypass_index[pt.ICACHE_BEAT_ADDR_HI:3]] & ic_miss_buff_data_valid_in[bypass_index_5_3_inc[pt.ICACHE_BEAT_ADDR_HI:3]] & bypass_index[2] & bypass_index[1])) |
862 : ((ic_miss_buff_data_valid_in[bypass_index[pt.ICACHE_BEAT_ADDR_HI:3]] & (bypass_index[pt.ICACHE_BEAT_ADDR_HI:3] == {pt.ICACHE_BEAT_BITS{1'b1}}))) ;
863 :
864 :
865 :
866 : assign ic_crit_wd_rdy_new_in = ( bypass_data_ready_in & crit_wd_byp_ok_ff & uncacheable_miss_ff & ~exu_flush_final & ~ifu_bp_hit_taken_q_f) |
867 : ( crit_wd_byp_ok_ff & ~uncacheable_miss_ff & ~exu_flush_final & ~ifu_bp_hit_taken_q_f) |
868 : (ic_crit_wd_rdy_new_ff & ~fetch_req_icache_f & crit_wd_byp_ok_ff & ~exu_flush_final) ;
869 :
870 :
871 : assign byp_fetch_index[pt.ICACHE_BEAT_ADDR_HI:1] = ifu_fetch_addr_int_f[pt.ICACHE_BEAT_ADDR_HI:1] ;
872 : assign byp_fetch_index_0[pt.ICACHE_BEAT_ADDR_HI:2] = {ifu_fetch_addr_int_f[pt.ICACHE_BEAT_ADDR_HI:3],1'b0} ;
873 : assign byp_fetch_index_1[pt.ICACHE_BEAT_ADDR_HI:2] = {ifu_fetch_addr_int_f[pt.ICACHE_BEAT_ADDR_HI:3],1'b1} ;
874 : assign byp_fetch_index_inc[pt.ICACHE_BEAT_ADDR_HI:3] = ifu_fetch_addr_int_f[pt.ICACHE_BEAT_ADDR_HI:3]+1'b1 ;
875 : assign byp_fetch_index_inc_0[pt.ICACHE_BEAT_ADDR_HI:2] = {byp_fetch_index_inc[pt.ICACHE_BEAT_ADDR_HI:3], 1'b0} ;
876 : assign byp_fetch_index_inc_1[pt.ICACHE_BEAT_ADDR_HI:2] = {byp_fetch_index_inc[pt.ICACHE_BEAT_ADDR_HI:3], 1'b1} ;
877 :
878 : assign ifu_byp_data_err_new = (~ifu_fetch_addr_int_f[2] & ~ifu_fetch_addr_int_f[1] & ic_miss_buff_data_error[byp_fetch_index[pt.ICACHE_BEAT_ADDR_HI:3]] ) |
879 : (~ifu_fetch_addr_int_f[2] & ifu_fetch_addr_int_f[1] & ic_miss_buff_data_error[byp_fetch_index[pt.ICACHE_BEAT_ADDR_HI:3]] ) |
880 : ( ifu_fetch_addr_int_f[2] & ~ifu_fetch_addr_int_f[1] & ic_miss_buff_data_error[byp_fetch_index[pt.ICACHE_BEAT_ADDR_HI:3]] ) |
881 : ( ifu_fetch_addr_int_f[2] & ifu_fetch_addr_int_f[1] & (ic_miss_buff_data_error[byp_fetch_index_inc[pt.ICACHE_BEAT_ADDR_HI:3]] | ic_miss_buff_data_error[byp_fetch_index[pt.ICACHE_BEAT_ADDR_HI:3]] )) ;
882 :
883 : assign ifu_byp_data_err_f[1:0] = (ic_miss_buff_data_error[byp_fetch_index[pt.ICACHE_BEAT_ADDR_HI:3]] ) ? 2'b11 :
884 : ( ifu_fetch_addr_int_f[2] & ifu_fetch_addr_int_f[1] & ~(ic_miss_buff_data_error[byp_fetch_index[pt.ICACHE_BEAT_ADDR_HI:3]] ) & (~miss_wrap_f & ic_miss_buff_data_error[byp_fetch_index_inc[pt.ICACHE_BEAT_ADDR_HI:3]])) ? 2'b10 : 2'b00;
885 :
886 :
887 :
888 :
889 :
890 : assign ic_byp_data_only_pre_new[79:0] = ({80{~ifu_fetch_addr_int_f[2]}} & {ic_miss_buff_data[byp_fetch_index_inc_0][15:0],ic_miss_buff_data[byp_fetch_index_1][31:0] , ic_miss_buff_data[byp_fetch_index_0][31:0]}) |
891 : ({80{ ifu_fetch_addr_int_f[2]}} & {ic_miss_buff_data[byp_fetch_index_inc_1][15:0],ic_miss_buff_data[byp_fetch_index_inc_0][31:0] , ic_miss_buff_data[byp_fetch_index_1][31:0]}) ;
892 :
893 : assign ic_byp_data_only_new[79:0] = ~ifu_fetch_addr_int_f[1] ? {ic_byp_data_only_pre_new[79:0]} :
894 : {16'b0,ic_byp_data_only_pre_new[79:16]} ;
895 :
896 : assign miss_wrap_f = (imb_ff[pt.ICACHE_TAG_INDEX_LO] != ifu_fetch_addr_int_f[pt.ICACHE_TAG_INDEX_LO] ) ;
897 :
898 : assign miss_buff_hit_unq_f = ((ic_miss_buff_data_valid[byp_fetch_index[pt.ICACHE_BEAT_ADDR_HI:3]] & ~byp_fetch_index[2] & ~byp_fetch_index[1])) |
899 : ((ic_miss_buff_data_valid[byp_fetch_index[pt.ICACHE_BEAT_ADDR_HI:3]] & ~byp_fetch_index[2] & byp_fetch_index[1])) |
900 : ((ic_miss_buff_data_valid[byp_fetch_index[pt.ICACHE_BEAT_ADDR_HI:3]] & byp_fetch_index[2] & ~byp_fetch_index[1])) |
901 : ((ic_miss_buff_data_valid[byp_fetch_index[pt.ICACHE_BEAT_ADDR_HI:3]] & ic_miss_buff_data_valid[byp_fetch_index_inc[pt.ICACHE_BEAT_ADDR_HI:3]] & byp_fetch_index[2] & byp_fetch_index[1])) |
902 : ((ic_miss_buff_data_valid[byp_fetch_index[pt.ICACHE_BEAT_ADDR_HI:3]] & (byp_fetch_index[pt.ICACHE_BEAT_ADDR_HI:3] == {pt.ICACHE_BEAT_BITS{1'b1}}))) ;
903 :
904 : assign stream_hit_f = (miss_buff_hit_unq_f & ~miss_wrap_f ) & (miss_state==STREAM) ;
905 : assign stream_miss_f = ~(miss_buff_hit_unq_f & ~miss_wrap_f ) & (miss_state==STREAM) & ifc_fetch_req_f;
906 : assign stream_eol_f = (byp_fetch_index[pt.ICACHE_BEAT_ADDR_HI:2] == {pt.ICACHE_BEAT_BITS+1{1'b1}}) & ifc_fetch_req_f & stream_hit_f;
907 :
908 : assign crit_byp_hit_f = (miss_buff_hit_unq_f ) & ((miss_state == CRIT_WRD_RDY) | (miss_state==CRIT_BYP_OK)) ;
909 :
910 : /////////////////////////////////////////////////////////////////////////////////////
911 : // Figure out if you have the data to write. //
912 : /////////////////////////////////////////////////////////////////////////////////////
913 :
914 : assign other_tag[pt.IFU_BUS_TAG-1:0] = {ifu_bus_rid_ff[pt.IFU_BUS_TAG-1:1] , ~ifu_bus_rid_ff[0] } ;
915 : assign second_half_available = ic_miss_buff_data_valid[other_tag] ;
916 : assign write_ic_16_bytes = second_half_available & bus_ifu_wr_en_ff ;
917 : assign ic_miss_buff_half[63:0] = {ic_miss_buff_data[{other_tag,1'b1}],ic_miss_buff_data[{other_tag,1'b0}] } ;
918 :
919 :
920 : /////////////////////////////////////////////////////////////////////////////////////
921 : // Parity checking logic for Icache logic. //
922 : /////////////////////////////////////////////////////////////////////////////////////
923 :
924 :
925 : assign ic_rd_parity_final_err = ic_tag_perr & ~exu_flush_final & sel_ic_data & ~(ifc_region_acc_fault_final_f | (|ifc_bus_acc_fault_f)) &
926 : (fetch_req_icache_f & ~reset_all_tags & (~miss_pending | (miss_state==HIT_U_MISS)) & ~sel_mb_addr_ff);
927 :
928 0 : logic [pt.ICACHE_NUM_WAYS-1:0] perr_err_inv_way;
929 0 : logic [pt.ICACHE_INDEX_HI:pt.ICACHE_TAG_INDEX_LO] perr_ic_index_ff;
930 0 : logic perr_sel_invalidate;
931 8 : logic perr_sb_write_status;
932 :
933 :
934 : assign perr_err_inv_way[pt.ICACHE_NUM_WAYS-1:0] = {pt.ICACHE_NUM_WAYS{perr_sel_invalidate}} ;
935 : assign iccm_correct_ecc = (perr_state == ECC_CORR);
936 : assign dma_sb_err_state = (perr_state == DMA_SB_ERR);
937 : assign iccm_buf_correct_ecc = iccm_correct_ecc & ~dma_sb_err_state_ff;
938 :
939 :
940 :
941 : //////////////////////////////////// Create Parity Error State Machine ///////////////////////
942 : // Create Parity Error State Machine //
943 : // Create Parity Error State Machine //
944 : // Create Parity Error State Machine //
945 : //////////////////////////////////// Create Parity Error State Machine ///////////////////////
946 :
947 :
948 : // FIFO state machine
949 339 : always_comb begin : ERROR_SM
950 339 : perr_nxtstate = ERR_IDLE;
951 339 : perr_state_en = 1'b0;
952 339 : perr_sel_invalidate = 1'b0;
953 339 : perr_sb_write_status = 1'b0;
954 :
955 339 : case (perr_state)
956 28151593 : ERR_IDLE: begin : err_idle
957 28151593 : perr_nxtstate = iccm_dma_sb_error ? DMA_SB_ERR : (ic_error_start & ~exu_flush_final) ? IC_WFF : ECC_WFF;
958 28151593 : perr_state_en = (((iccm_error_start | ic_error_start) & ~dec_tlu_flush_lower_wb) | iccm_dma_sb_error) & ~dec_tlu_force_halt;
959 28151593 : perr_sb_write_status = perr_state_en;
960 : end
961 0 : IC_WFF: begin : icache_wff // All the I$ data and/or Tag errors ( parity/ECC ) will come to this state
962 0 : perr_nxtstate = ERR_IDLE;
963 0 : perr_state_en = dec_tlu_flush_lower_wb | dec_tlu_force_halt;
964 0 : perr_sel_invalidate = (dec_tlu_flush_err_wb & dec_tlu_flush_lower_wb);
965 : end
966 4 : ECC_WFF: begin : ecc_wff
967 4 : perr_nxtstate = ((~dec_tlu_flush_err_wb & dec_tlu_flush_lower_wb ) | dec_tlu_force_halt) ? ERR_IDLE : ECC_CORR;
968 4 : perr_state_en = dec_tlu_flush_lower_wb | dec_tlu_force_halt;
969 : end
970 0 : DMA_SB_ERR: begin : dma_sb_ecc
971 0 : perr_nxtstate = dec_tlu_force_halt ? ERR_IDLE : ECC_CORR;
972 0 : perr_state_en = 1'b1;
973 : end
974 4 : ECC_CORR: begin : ecc_corr
975 4 : perr_nxtstate = ERR_IDLE;
976 4 : perr_state_en = 1'b1;
977 : end
978 0 : default: begin : def_case
979 0 : perr_nxtstate = ERR_IDLE;
980 0 : perr_state_en = 1'b0;
981 0 : perr_sel_invalidate = 1'b0;
982 0 : perr_sb_write_status = 1'b0;
983 : end
984 : endcase
985 : end
986 :
987 : rvdffs #(($bits(perr_state_t))) perr_state_ff (.clk(active_clk), .din(perr_nxtstate), .dout({perr_state}), .en(perr_state_en), .*);
988 :
989 : //////////////////////////////////// Create stop fetch State Machine /////////////////////////
990 : //////////////////////////////////// Create stop fetch State Machine /////////////////////////
991 : //////////////////////////////////// Create stop fetch State Machine /////////////////////////
992 : //////////////////////////////////// Create stop fetch State Machine /////////////////////////
993 : //////////////////////////////////// Create stop fetch State Machine /////////////////////////
994 339 : always_comb begin : ERROR_STOP_FETCH
995 339 : err_stop_nxtstate = ERR_STOP_IDLE;
996 339 : err_stop_state_en = 1'b0;
997 339 : err_stop_fetch = 1'b0;
998 339 : iccm_correction_state = 1'b0;
999 :
1000 339 : case (err_stop_state)
1001 28151577 : ERR_STOP_IDLE: begin : err_stop_idle
1002 28151577 : err_stop_nxtstate = ERR_FETCH1;
1003 28151577 : err_stop_state_en = dec_tlu_flush_err_wb & (perr_state == ECC_WFF) & ~dec_tlu_force_halt;
1004 : end
1005 12 : ERR_FETCH1: begin : err_fetch1 // All the I$ data and/or Tag errors ( parity/ECC ) will come to this state
1006 12 : err_stop_nxtstate = (dec_tlu_flush_lower_wb | dec_tlu_i0_commit_cmt | dec_tlu_force_halt) ? ERR_STOP_IDLE : ((ifu_fetch_val[1:0] == 2'b11) | (ifu_fetch_val[0] & two_byte_instr)) ? ERR_STOP_FETCH : ifu_fetch_val[0] ? ERR_FETCH2 : ERR_FETCH1;
1007 12 : err_stop_state_en = dec_tlu_flush_lower_wb | dec_tlu_i0_commit_cmt | ifu_fetch_val[0] | ifu_bp_hit_taken_q_f | dec_tlu_force_halt;
1008 12 : err_stop_fetch = ((ifu_fetch_val[1:0] == 2'b11) | (ifu_fetch_val[0] & two_byte_instr)) & ~(exu_flush_final | dec_tlu_i0_commit_cmt);
1009 12 : iccm_correction_state = 1'b1;
1010 :
1011 : end
1012 0 : ERR_FETCH2: begin : err_fetch2 // All the I$ data and/or Tag errors ( parity/ECC ) will come to this state
1013 0 : err_stop_nxtstate = (dec_tlu_flush_lower_wb | dec_tlu_i0_commit_cmt | dec_tlu_force_halt) ? ERR_STOP_IDLE : ifu_fetch_val[0] ? ERR_STOP_FETCH : ERR_FETCH2;
1014 0 : err_stop_state_en = dec_tlu_flush_lower_wb | dec_tlu_i0_commit_cmt | ifu_fetch_val[0] | dec_tlu_force_halt ;
1015 0 : err_stop_fetch = ifu_fetch_val[0] & ~exu_flush_final & ~dec_tlu_i0_commit_cmt ;
1016 0 : iccm_correction_state = 1'b1;
1017 :
1018 : end
1019 12 : ERR_STOP_FETCH: begin : ecc_wff
1020 12 : err_stop_nxtstate = ( (dec_tlu_flush_lower_wb & ~dec_tlu_flush_err_wb) | dec_tlu_i0_commit_cmt | dec_tlu_force_halt) ? ERR_STOP_IDLE : dec_tlu_flush_err_wb ? ERR_FETCH1 : ERR_STOP_FETCH ;
1021 12 : err_stop_state_en = dec_tlu_flush_lower_wb | dec_tlu_i0_commit_cmt | dec_tlu_force_halt ;
1022 12 : err_stop_fetch = 1'b1;
1023 12 : iccm_correction_state = 1'b1;
1024 :
1025 : end
1026 : /*verilator coverage_off*/
1027 : default: begin : def_case
1028 : err_stop_nxtstate = ERR_STOP_IDLE;
1029 : err_stop_state_en = 1'b0;
1030 : err_stop_fetch = 1'b0 ;
1031 : iccm_correction_state = 1'b1;
1032 :
1033 : end
1034 : /*verilator coverage_on*/
1035 : endcase
1036 : end
1037 : rvdffs #(($bits(err_stop_state_t))) err_stop_state_ff (.clk(active_clk), .din(err_stop_nxtstate), .dout({err_stop_state}), .en(err_stop_state_en), .*);
1038 :
1039 :
1040 :
1041 : assign bus_ifu_bus_clk_en = ifu_bus_clk_en ;
1042 :
1043 : `ifdef RV_FPGA_OPTIMIZE
1044 : assign busclk = 1'b0;
1045 : assign busclk_force = 1'b0;
1046 : `else
1047 : rvclkhdr bus_clk_f(.en(bus_ifu_bus_clk_en), .l1clk(busclk), .*);
1048 : rvclkhdr bus_clk(.en(bus_ifu_bus_clk_en | dec_tlu_force_halt), .l1clk(busclk_force), .*);
1049 : `endif
1050 :
1051 :
1052 :
1053 : assign scnd_miss_req = scnd_miss_req_q & ~exu_flush_final;
1054 :
1055 : assign ifc_bus_ic_req_ff_in = (ic_act_miss_f | bus_cmd_req_hold | ifu_bus_cmd_valid) & ~dec_tlu_force_halt & ~((bus_cmd_beat_count== {pt.ICACHE_BEAT_BITS{1'b1}}) & ifu_bus_cmd_valid & ifu_bus_cmd_ready & miss_pending);
1056 :
1057 : rvdff_fpga #(1) bus_ic_req_ff2(.*, .clk(busclk_force), .clken(bus_ifu_bus_clk_en | dec_tlu_force_halt), .rawclk(clk), .din(ifc_bus_ic_req_ff_in), .dout(ifu_bus_cmd_valid));
1058 :
1059 : assign bus_cmd_req_in = (ic_act_miss_f | bus_cmd_req_hold) & ~bus_cmd_sent & ~dec_tlu_force_halt ; // hold until first command sent
1060 :
1061 :
1062 :
1063 : // AXI command signals
1064 : // Read Channel
1065 : assign ifu_axi_arvalid = ifu_bus_cmd_valid ;
1066 : assign ifu_axi_arid[pt.IFU_BUS_TAG-1:0] = ((pt.IFU_BUS_TAG)'(bus_rd_addr_count[pt.ICACHE_BEAT_BITS-1:0])) & {pt.IFU_BUS_TAG{ifu_bus_cmd_valid}};
1067 : assign ifu_axi_araddr[31:0] = {ifu_ic_req_addr_f[31:3],3'b0} & {32{ifu_bus_cmd_valid}};
1068 : assign ifu_axi_arsize[2:0] = 3'b011;
1069 : assign ifu_axi_arprot[2:0] = 3'b101;
1070 : assign ifu_axi_arcache[3:0] = 4'b1111;
1071 : assign ifu_axi_arregion[3:0] = ifu_ic_req_addr_f[31:28];
1072 : assign ifu_axi_arlen[7:0] = '0;
1073 : assign ifu_axi_arburst[1:0] = 2'b01;
1074 : assign ifu_axi_arqos[3:0] = '0;
1075 : assign ifu_axi_arlock = '0;
1076 : assign ifu_axi_rready = 1'b1;
1077 :
1078 : // Write Channel
1079 : assign ifu_axi_awvalid = '0 ;
1080 : assign ifu_axi_awid[pt.IFU_BUS_TAG-1:0] = '0 ;
1081 : assign ifu_axi_awaddr[31:0] = '0 ;
1082 : assign ifu_axi_awsize[2:0] = '0 ;
1083 : assign ifu_axi_awprot[2:0] = '0;
1084 : assign ifu_axi_awcache[3:0] = '0 ;
1085 : assign ifu_axi_awregion[3:0] = '0 ;
1086 : assign ifu_axi_awlen[7:0] = '0;
1087 : assign ifu_axi_awburst[1:0] = '0 ;
1088 : assign ifu_axi_awqos[3:0] = '0;
1089 : assign ifu_axi_awlock = '0;
1090 :
1091 : assign ifu_axi_wvalid = '0;
1092 : assign ifu_axi_wstrb[7:0] = '0;
1093 : assign ifu_axi_wdata[63:0] = '0;
1094 : assign ifu_axi_wlast = '0;
1095 : assign ifu_axi_bready = '0;
1096 :
1097 :
1098 : assign ifu_bus_arready_unq = ifu_axi_arready ;
1099 : assign ifu_bus_rvalid_unq = ifu_axi_rvalid ;
1100 : assign ifu_bus_arvalid = ifu_axi_arvalid ;
1101 :
1102 : rvdff_fpga #(1) bus_rdy_ff (.*, .clk(busclk), .clken(bus_ifu_bus_clk_en), .rawclk(clk), .din(ifu_bus_arready_unq), .dout(ifu_bus_arready_unq_ff));
1103 : rvdff_fpga #(1) bus_rsp_vld_ff (.*, .clk(busclk), .clken(bus_ifu_bus_clk_en), .rawclk(clk), .din(ifu_bus_rvalid_unq), .dout(ifu_bus_rvalid_unq_ff));
1104 : rvdff_fpga #(1) bus_cmd_ff (.*, .clk(busclk), .clken(bus_ifu_bus_clk_en), .rawclk(clk), .din(ifu_bus_arvalid), .dout(ifu_bus_arvalid_ff));
1105 : rvdff_fpga #(2) bus_rsp_cmd_ff (.*, .clk(busclk), .clken(bus_ifu_bus_clk_en), .rawclk(clk), .din(ifu_axi_rresp[1:0]), .dout(ifu_bus_rresp_ff[1:0]));
1106 : rvdff_fpga #(pt.IFU_BUS_TAG) bus_rsp_tag_ff (.*, .clk(busclk), .clken(bus_ifu_bus_clk_en), .rawclk(clk), .din(ifu_axi_rid[pt.IFU_BUS_TAG-1:0]),.dout(ifu_bus_rid_ff[pt.IFU_BUS_TAG-1:0]));
1107 : rvdffe #(64) bus_data_ff (.*, .clk(clk), .din(ifu_axi_rdata[63:0]), .dout(ifu_bus_rdata_ff[63:0]), .en(ifu_bus_clk_en & ifu_axi_rvalid));
1108 :
1109 : assign ifu_bus_cmd_ready = ifu_axi_arready ;
1110 : assign ifu_bus_rsp_valid = ifu_axi_rvalid ;
1111 : assign ifu_bus_rsp_ready = ifu_axi_rready ;
1112 : assign ifu_bus_rsp_tag[pt.IFU_BUS_TAG-1:0] = ifu_axi_rid[pt.IFU_BUS_TAG-1:0] ;
1113 : assign ifu_bus_rsp_rdata[63:0] = ifu_axi_rdata[63:0] ;
1114 : assign ifu_bus_rsp_opc[1:0] = {ifu_axi_rresp[1:0]} ;
1115 :
1116 :
1117 :
1118 :
1119 :
1120 :
1121 :
1122 :
1123 :
1124 : // Create write signals so we can write to the miss-buffer directly from the bus.
1125 :
1126 : assign ifu_bus_rvalid = ifu_bus_rsp_valid & bus_ifu_bus_clk_en ;
1127 :
1128 :
1129 :
1130 : assign ifu_bus_arready = ifu_bus_arready_unq & bus_ifu_bus_clk_en ;
1131 : assign ifu_bus_arready_ff = ifu_bus_arready_unq_ff & bus_ifu_bus_clk_en_ff ;
1132 :
1133 : assign ifu_bus_rvalid_ff = ifu_bus_rvalid_unq_ff & bus_ifu_bus_clk_en_ff ;
1134 : assign bus_cmd_sent = ifu_bus_arvalid & ifu_bus_arready & miss_pending & ~dec_tlu_force_halt;
1135 : assign bus_inc_data_beat_cnt = (bus_ifu_wr_en_ff & ~bus_last_data_beat & ~dec_tlu_force_halt) ;
1136 : assign bus_reset_data_beat_cnt = ic_act_miss_f | (bus_ifu_wr_en_ff & bus_last_data_beat) | dec_tlu_force_halt;
1137 : assign bus_hold_data_beat_cnt = ~bus_inc_data_beat_cnt & ~bus_reset_data_beat_cnt ;
1138 :
1139 : assign bus_new_data_beat_count[pt.ICACHE_BEAT_BITS-1:0] = ({pt.ICACHE_BEAT_BITS{bus_reset_data_beat_cnt}} & (pt.ICACHE_BEAT_BITS)'(unsigned'(0))) |
1140 : ({pt.ICACHE_BEAT_BITS{bus_inc_data_beat_cnt}} & (bus_data_beat_count[pt.ICACHE_BEAT_BITS-1:0] + {{pt.ICACHE_BEAT_BITS-1{1'b0}},1'b1})) |
1141 : ({pt.ICACHE_BEAT_BITS{bus_hold_data_beat_cnt}} & bus_data_beat_count[pt.ICACHE_BEAT_BITS-1:0]);
1142 :
1143 :
1144 : assign last_data_recieved_in = (bus_ifu_wr_en_ff & bus_last_data_beat & ~scnd_miss_req) | (last_data_recieved_ff & ~ic_act_miss_f) ;
1145 :
1146 :
1147 :
1148 : // Request Address Count
1149 : assign bus_new_rd_addr_count[pt.ICACHE_BEAT_BITS-1:0] = (~miss_pending ) ? imb_ff[pt.ICACHE_BEAT_ADDR_HI:3] :
1150 : ( scnd_miss_req_q ) ? imb_scnd_ff[pt.ICACHE_BEAT_ADDR_HI:3] :
1151 : ( bus_cmd_sent ) ? (bus_rd_addr_count[pt.ICACHE_BEAT_BITS-1:0] + 3'b001) :
1152 : bus_rd_addr_count[pt.ICACHE_BEAT_BITS-1:0];
1153 :
1154 : rvdff_fpga #(pt.ICACHE_BEAT_BITS) bus_rd_addr_ff (.*, .clk(busclk_reset), .clken (bus_ifu_bus_clk_en | ic_act_miss_f | dec_tlu_force_halt), .rawclk(clk), .din ({bus_new_rd_addr_count[pt.ICACHE_BEAT_BITS-1:0]}), .dout({bus_rd_addr_count[pt.ICACHE_BEAT_BITS-1:0]}));
1155 :
1156 :
1157 :
1158 : // command beat Count
1159 : assign bus_inc_cmd_beat_cnt = ifu_bus_cmd_valid & ifu_bus_cmd_ready & miss_pending & ~dec_tlu_force_halt;
1160 : assign bus_reset_cmd_beat_cnt_0 = (ic_act_miss_f & ~uncacheable_miss_in) | dec_tlu_force_halt ;
1161 : assign bus_reset_cmd_beat_cnt_secondlast = ic_act_miss_f & uncacheable_miss_in ;
1162 : assign bus_hold_cmd_beat_cnt = ~bus_inc_cmd_beat_cnt & ~(ic_act_miss_f | scnd_miss_req | dec_tlu_force_halt) ;
1163 : assign bus_cmd_beat_en = bus_inc_cmd_beat_cnt | ic_act_miss_f | dec_tlu_force_halt;
1164 :
1165 : assign bus_new_cmd_beat_count[pt.ICACHE_BEAT_BITS-1:0] = ({pt.ICACHE_BEAT_BITS{bus_reset_cmd_beat_cnt_0}} & (pt.ICACHE_BEAT_BITS)'(unsigned'(0)) ) |
1166 : ({pt.ICACHE_BEAT_BITS{bus_reset_cmd_beat_cnt_secondlast}} & (pt.ICACHE_BEAT_BITS)'(pt.ICACHE_SCND_LAST)) |
1167 : ({pt.ICACHE_BEAT_BITS{bus_inc_cmd_beat_cnt}} & (bus_cmd_beat_count[pt.ICACHE_BEAT_BITS-1:0] + {{pt.ICACHE_BEAT_BITS-1{1'b0}}, 1'b1})) |
1168 : ({pt.ICACHE_BEAT_BITS{bus_hold_cmd_beat_cnt}} & bus_cmd_beat_count[pt.ICACHE_BEAT_BITS-1:0]) ;
1169 :
1170 : `ifdef RV_FPGA_OPTIMIZE
1171 : assign busclk_reset = 1'b0;
1172 : `else
1173 : rvclkhdr bus_clk_reset(.en(bus_ifu_bus_clk_en | ic_act_miss_f | dec_tlu_force_halt), .l1clk(busclk_reset), .*);
1174 : `endif
1175 :
1176 :
1177 :
1178 : rvdffs_fpga #(pt.ICACHE_BEAT_BITS) bus_cmd_beat_ff (.*, .clk(busclk_reset), .clken (bus_ifu_bus_clk_en | ic_act_miss_f | dec_tlu_force_halt), .rawclk(clk), .en (bus_cmd_beat_en), .din ({bus_new_cmd_beat_count[pt.ICACHE_BEAT_BITS-1:0]}),
1179 : .dout({bus_cmd_beat_count[pt.ICACHE_BEAT_BITS-1:0]}));
1180 :
1181 :
1182 : assign bus_last_data_beat = uncacheable_miss_ff ? (bus_data_beat_count[pt.ICACHE_BEAT_BITS-1:0] == {{pt.ICACHE_BEAT_BITS-1{1'b0}},1'b1}) : (&bus_data_beat_count[pt.ICACHE_BEAT_BITS-1:0]);
1183 :
1184 : assign bus_ifu_wr_en = ifu_bus_rvalid & miss_pending ;
1185 : assign bus_ifu_wr_en_ff = ifu_bus_rvalid_ff & miss_pending ;
1186 : assign bus_ifu_wr_en_ff_q = ifu_bus_rvalid_ff & miss_pending & ~uncacheable_miss_ff & ~(|ifu_bus_rresp_ff[1:0]) & write_ic_16_bytes; // qualify with no-error conditions ;
1187 : assign bus_ifu_wr_en_ff_wo_err = ifu_bus_rvalid_ff & miss_pending & ~uncacheable_miss_ff;
1188 :
1189 :
1190 : rvdffie #(10) misc_ff
1191 : ( .*,
1192 : .clk(free_l2clk),
1193 : .din( {ic_act_miss_f, ifu_wr_cumulative_err,exu_flush_final, ic_crit_wd_rdy_new_in,bus_ifu_bus_clk_en, scnd_miss_req_in,bus_cmd_req_in, last_data_recieved_in,
1194 : ifc_dma_access_ok_d, dma_iccm_req}),
1195 : .dout({ic_act_miss_f_delayed,ifu_wr_data_comb_err_ff, flush_final_f,ic_crit_wd_rdy_new_ff,bus_ifu_bus_clk_en_ff,scnd_miss_req_q, bus_cmd_req_hold,last_data_recieved_ff,
1196 : ifc_dma_access_ok_prev,dma_iccm_req_f})
1197 : );
1198 :
1199 : rvdffie #(.WIDTH(pt.ICACHE_BEAT_BITS+5),.OVERRIDE(1)) misc1_ff
1200 : ( .*,
1201 : .clk(free_l2clk),
1202 : .din( {reset_ic_in,sel_mb_addr, bus_new_data_beat_count[pt.ICACHE_BEAT_BITS-1:0],ifc_region_acc_fault_memory_bf,ic_debug_rd_en, ic_debug_rd_en_ff}),
1203 : .dout({reset_ic_ff,sel_mb_addr_ff,bus_data_beat_count[pt.ICACHE_BEAT_BITS-1:0], ifc_region_acc_fault_memory_f, ic_debug_rd_en_ff,ifu_ic_debug_rd_data_valid})
1204 : );
1205 :
1206 : assign reset_tag_valid_for_miss = ic_act_miss_f_delayed & (miss_state == CRIT_BYP_OK) & ~uncacheable_miss_ff;
1207 : assign bus_ifu_wr_data_error = |ifu_bus_rsp_opc[1:0] & ifu_bus_rvalid & miss_pending;
1208 : assign bus_ifu_wr_data_error_ff = |ifu_bus_rresp_ff[1:0] & ifu_bus_rvalid_ff & miss_pending;
1209 :
1210 :
1211 : assign ic_crit_wd_rdy = ic_crit_wd_rdy_new_in | ic_crit_wd_rdy_new_ff ;
1212 : assign last_beat = bus_last_data_beat & bus_ifu_wr_en_ff;
1213 : assign reset_beat_cnt = bus_reset_data_beat_cnt ;
1214 :
1215 : // DMA
1216 : // Making sure that the dma_access is allowed when we have 2 back to back dma_access_ok. Also gating with current state == idle
1217 : assign ifc_dma_access_ok_d = ifc_dma_access_ok & ~iccm_correct_ecc & ~iccm_dma_sb_error;
1218 : assign ifc_dma_access_q_ok = ifc_dma_access_ok & ~iccm_correct_ecc & ifc_dma_access_ok_prev & (perr_state == ERR_IDLE) & ~iccm_dma_sb_error;
1219 : assign iccm_ready = ifc_dma_access_q_ok ;
1220 :
1221 55650 : logic [1:0] iccm_ecc_word_enable;
1222 :
1223 : if (pt.ICCM_ENABLE == 1 ) begin: iccm_enabled
1224 : logic [3:2] dma_mem_addr_ff ;
1225 : logic iccm_dma_rden ;
1226 :
1227 : logic iccm_dma_ecc_error_in;
1228 : logic [13:0] dma_mem_ecc;
1229 : logic [63:0] iccm_dma_rdata_in;
1230 : logic [31:0] iccm_dma_rdata_1_muxed;
1231 : logic [1:0] [31:0] iccm_corrected_data;
1232 : logic [1:0] [06:0] iccm_corrected_ecc;
1233 :
1234 :
1235 : logic [1:0] iccm_double_ecc_error;
1236 :
1237 :
1238 : logic [pt.ICCM_BITS-1:2] iccm_rw_addr_f;
1239 :
1240 : logic [31:0] iccm_corrected_data_f_mux;
1241 : logic [06:0] iccm_corrected_ecc_f_mux;
1242 : logic iccm_dma_rvalid_in;
1243 : logic [77:0] iccm_rdmux_data;
1244 : logic iccm_rd_ecc_single_err_hold_in ;
1245 : logic [2:0] dma_mem_tag_ff;
1246 :
1247 :
1248 :
1249 :
1250 : assign iccm_wren = (ifc_dma_access_q_ok & dma_iccm_req & dma_mem_write) | iccm_correct_ecc;
1251 : assign iccm_rden = (ifc_dma_access_q_ok & dma_iccm_req & ~dma_mem_write) | (ifc_iccm_access_bf & ifc_fetch_req_bf);
1252 : assign iccm_dma_rden = (ifc_dma_access_q_ok & dma_iccm_req & ~dma_mem_write) ;
1253 : assign iccm_wr_size[2:0] = {3{dma_iccm_req}} & dma_mem_sz[2:0] ;
1254 :
1255 : rvecc_encode iccm_ecc_encode0 (
1256 : .din(dma_mem_wdata[31:0]),
1257 : .ecc_out(dma_mem_ecc[6:0]));
1258 :
1259 : rvecc_encode iccm_ecc_encode1 (
1260 : .din(dma_mem_wdata[63:32]),
1261 : .ecc_out(dma_mem_ecc[13:7]));
1262 :
1263 : assign iccm_wr_data[77:0] = (iccm_correct_ecc & ~(ifc_dma_access_q_ok & dma_iccm_req)) ? {iccm_ecc_corr_data_ff[38:0], iccm_ecc_corr_data_ff[38:0]} :
1264 : {dma_mem_ecc[13:7],dma_mem_wdata[63:32], dma_mem_ecc[6:0],dma_mem_wdata[31:0]};
1265 :
1266 : assign iccm_dma_rdata_1_muxed[31:0] = dma_mem_addr_ff[2] ? iccm_corrected_data[0][31:0] : iccm_corrected_data[1][31:0] ;
1267 : assign iccm_dma_rdata_in[63:0] = iccm_dma_ecc_error_in ? {2{dma_mem_addr[31:0]}} : {iccm_dma_rdata_1_muxed[31:0], iccm_corrected_data[0]};
1268 : assign iccm_dma_ecc_error_in = |(iccm_double_ecc_error[1:0]);
1269 :
1270 : rvdffe #(64) dma_data_ff (.*, .clk(clk), .en(iccm_dma_rvalid_in), .din(iccm_dma_rdata_in[63:0]), .dout(iccm_dma_rdata[63:0]));
1271 : rvdffie #(11) dma_misc_bits (.*, .clk(free_l2clk), .din({dma_mem_tag[2:0],
1272 : dma_mem_tag_ff[2:0],
1273 : dma_mem_addr[3:2],
1274 : iccm_dma_rden,
1275 : iccm_dma_rvalid_in,
1276 : iccm_dma_ecc_error_in }),
1277 : .dout({dma_mem_tag_ff[2:0],
1278 : iccm_dma_rtag[2:0],
1279 : dma_mem_addr_ff[3:2],
1280 : iccm_dma_rvalid_in,
1281 : iccm_dma_rvalid,
1282 : iccm_dma_ecc_error }));
1283 :
1284 : assign iccm_rw_addr[pt.ICCM_BITS-1:1] = ( ifc_dma_access_q_ok & dma_iccm_req & ~iccm_correct_ecc) ? dma_mem_addr[pt.ICCM_BITS-1:1] :
1285 : (~(ifc_dma_access_q_ok & dma_iccm_req) & iccm_correct_ecc) ? {iccm_ecc_corr_index_ff[pt.ICCM_BITS-1:2],1'b0} : ifc_fetch_addr_bf[pt.ICCM_BITS-1:1] ;
1286 :
1287 :
1288 : assign iccm_dma_rd_ecc_single_err = iccm_dma_sb_error;
1289 : assign iccm_dma_rd_ecc_double_err = iccm_dma_rvalid && iccm_dma_ecc_error;
1290 :
1291 :
1292 : /////////////////////////////////////////////////////////////////////////////////////
1293 : // ECC checking logic for ICCM data. //
1294 : /////////////////////////////////////////////////////////////////////////////////////
1295 :
1296 : logic [3:0] ic_fetch_val_int_f;
1297 : logic [3:0] ic_fetch_val_shift_right;
1298 : assign ic_fetch_val_int_f[3:0] = {2'b00 , ic_fetch_val_f[1:0] } ;
1299 : assign ic_fetch_val_shift_right[3:0] = {ic_fetch_val_int_f << ifu_fetch_addr_int_f[1] } ;
1300 :
1301 : assign iccm_rdmux_data[77:0] = iccm_rd_data_ecc[77:0];
1302 : for (genvar i=0; i < 2 ; i++) begin : ICCM_ECC_CHECK
1303 : assign iccm_ecc_word_enable[i] = ((|ic_fetch_val_shift_right[(2*i+1):(2*i)] & ~exu_flush_final & sel_iccm_data) | iccm_dma_rvalid_in) & ~dec_tlu_core_ecc_disable;
1304 : rvecc_decode ecc_decode (
1305 : .en(iccm_ecc_word_enable[i]),
1306 : .sed_ded ( 1'b0 ), // 1 : means only detection
1307 : .din(iccm_rdmux_data[(39*i+31):(39*i)]),
1308 : .ecc_in(iccm_rdmux_data[(39*i+38):(39*i+32)]),
1309 : .dout(iccm_corrected_data[i][31:0]),
1310 : .ecc_out(iccm_corrected_ecc[i][6:0]),
1311 : .single_ecc_error(iccm_single_ecc_error[i]),
1312 : .double_ecc_error(iccm_double_ecc_error[i]));
1313 : end
1314 :
1315 : assign iccm_rd_ecc_single_err = (|iccm_single_ecc_error[1:0] ) & ifc_iccm_access_f & ifc_fetch_req_f;
1316 : assign iccm_rd_ecc_double_err[1:0] = ~ifu_fetch_addr_int_f[1] ? ({iccm_double_ecc_error[0], iccm_double_ecc_error[0]} ) & {2{ifc_iccm_access_f}} :
1317 : ({iccm_double_ecc_error[1], iccm_double_ecc_error[0]} ) & {2{ifc_iccm_access_f}} ;
1318 :
1319 : assign iccm_corrected_data_f_mux[31:0] = iccm_single_ecc_error[0] ? iccm_corrected_data[0] : iccm_corrected_data[1];
1320 : assign iccm_corrected_ecc_f_mux[6:0] = iccm_single_ecc_error[0] ? iccm_corrected_ecc[0] : iccm_corrected_ecc[1];
1321 :
1322 : assign iccm_ecc_write_status = ((iccm_rd_ecc_single_err & ~iccm_rd_ecc_single_err_ff) & ~exu_flush_final) | iccm_dma_sb_error;
1323 : assign iccm_rd_ecc_single_err_hold_in = (iccm_rd_ecc_single_err | iccm_rd_ecc_single_err_ff) & ~exu_flush_final ;
1324 : assign iccm_error_start = iccm_rd_ecc_single_err;
1325 : assign iccm_ecc_corr_index_in[pt.ICCM_BITS-1:2] = iccm_single_ecc_error[0] ? iccm_rw_addr_f[pt.ICCM_BITS-1:2] : iccm_rw_addr_f[pt.ICCM_BITS-1:2] + 1'b1 ;
1326 :
1327 : rvdffie #(pt.ICCM_BITS-1) iccm_index_f (.*, .clk(free_l2clk), .din({iccm_rw_addr[pt.ICCM_BITS-1:2],
1328 : iccm_rd_ecc_single_err_hold_in
1329 : }),
1330 : .dout({iccm_rw_addr_f[pt.ICCM_BITS-1:2],
1331 : iccm_rd_ecc_single_err_ff}));
1332 :
1333 : rvdffe #((39+(pt.ICCM_BITS-2))) ecc_dat0_ff (
1334 : .clk(clk),
1335 : .din({iccm_corrected_ecc_f_mux[6:0], iccm_corrected_data_f_mux[31:0],iccm_ecc_corr_index_in[pt.ICCM_BITS-1:2]}),
1336 : .dout({iccm_ecc_corr_data_ff[38:0] ,iccm_ecc_corr_index_ff[pt.ICCM_BITS-1:2]}),
1337 : .en(iccm_ecc_write_status),
1338 : .*
1339 : );
1340 :
1341 : end else begin : iccm_disabled
1342 : assign iccm_dma_rvalid = 1'b0 ;
1343 : assign iccm_dma_ecc_error = 1'b0 ;
1344 : assign iccm_dma_rdata[63:0] = '0 ;
1345 : assign iccm_single_ecc_error = '0 ;
1346 : assign iccm_dma_rtag = '0 ;
1347 :
1348 :
1349 :
1350 :
1351 :
1352 :
1353 : assign iccm_rd_ecc_single_err = 1'b0 ;
1354 : assign iccm_rd_ecc_double_err = '0 ;
1355 : assign iccm_rd_ecc_single_err_ff = 1'b0 ;
1356 : assign iccm_error_start = 1'b0;
1357 : assign iccm_ecc_corr_index_ff[pt.ICCM_BITS-1:2] = '0;
1358 : assign iccm_ecc_corr_data_ff[38:0] = '0;
1359 : assign iccm_ecc_write_status = '0;
1360 :
1361 :
1362 :
1363 :
1364 :
1365 :
1366 : end
1367 :
1368 :
1369 : ////// ICCM signals
1370 :
1371 :
1372 : assign ic_rd_en = (ifc_fetch_req_bf & ~ifc_fetch_uncacheable_bf & ~ifc_iccm_access_bf &
1373 : ~(((miss_state == STREAM) & ~miss_state_en) |
1374 : ((miss_state == CRIT_BYP_OK) & ~miss_state_en) |
1375 : ((miss_state == STALL_SCND_MISS) & ~miss_state_en) |
1376 : ((miss_state == MISS_WAIT) & ~miss_state_en) |
1377 : ((miss_state == CRIT_WRD_RDY) & ~miss_state_en) |
1378 : ((miss_state == CRIT_BYP_OK) & miss_state_en & (miss_nxtstate == MISS_WAIT)) )) |
1379 : ( ifc_fetch_req_bf & exu_flush_final & ~ifc_fetch_uncacheable_bf & ~ifc_iccm_access_bf ) ;
1380 :
1381 6693528 : logic ic_real_rd_wp_unused;
1382 : assign ic_real_rd_wp_unused = (ifc_fetch_req_bf & ~ifc_iccm_access_bf & ~ifc_region_acc_fault_final_bf & ~dec_tlu_fence_i_wb & ~stream_miss_f & ~ic_act_miss_f &
1383 : ~(((miss_state == STREAM) & ~miss_state_en) |
1384 : ((miss_state == CRIT_BYP_OK) & ~miss_state_en & ~(miss_nxtstate == MISS_WAIT)) |
1385 : ((miss_state == CRIT_BYP_OK) & miss_state_en & (miss_nxtstate == MISS_WAIT)) |
1386 : ((miss_state == MISS_WAIT) & ~miss_state_en) |
1387 : ((miss_state == STALL_SCND_MISS) & ~miss_state_en) |
1388 : ((miss_state == CRIT_WRD_RDY) & ~miss_state_en) |
1389 : ((miss_nxtstate == STREAM) & miss_state_en) |
1390 : ((miss_state == SCND_MISS) & ~miss_state_en))) |
1391 : (ifc_fetch_req_bf & ~ifc_iccm_access_bf & ~ifc_region_acc_fault_final_bf & ~dec_tlu_fence_i_wb & ~stream_miss_f & exu_flush_final) ;
1392 :
1393 :
1394 : assign ic_wr_en[pt.ICACHE_NUM_WAYS-1:0] = bus_ic_wr_en[pt.ICACHE_NUM_WAYS-1:0] & {pt.ICACHE_NUM_WAYS{write_ic_16_bytes}};
1395 : assign ic_write_stall = write_ic_16_bytes & ~((((miss_state== CRIT_BYP_OK) | ((miss_state==STREAM) & ~(exu_flush_final | ifu_bp_hit_taken_q_f | stream_eol_f ))) & ~(bus_ifu_wr_en_ff & last_beat & ~uncacheable_miss_ff)));
1396 :
1397 :
1398 :
1399 :
1400 : ///////////////////////////////////////////////////////////////
1401 : // Icache status and LRU
1402 : ///////////////////////////////////////////////////////////////
1403 5606 : logic [pt.ICACHE_NUM_WAYS-1:0] ic_tag_valid_unq;
1404 : if (pt.ICACHE_ENABLE == 1 ) begin: icache_enabled
1405 : logic [pt.ICACHE_INDEX_HI:pt.ICACHE_TAG_INDEX_LO] ifu_status_wr_addr_w_debug;
1406 : logic [pt.ICACHE_INDEX_HI:pt.ICACHE_TAG_INDEX_LO] ifu_status_wr_addr_ff ;
1407 : logic [pt.ICACHE_INDEX_HI:pt.ICACHE_TAG_INDEX_LO] ifu_ic_rw_int_addr_w_debug;
1408 : logic [pt.ICACHE_INDEX_HI:pt.ICACHE_TAG_INDEX_LO] ifu_ic_rw_int_addr_ff;
1409 : logic [pt.ICACHE_INDEX_HI:pt.ICACHE_TAG_INDEX_LO] perr_ic_index_ff;
1410 :
1411 : assign ic_valid = ~ifu_wr_cumulative_err_data & ~(reset_ic_in | reset_ic_ff) & ~reset_tag_valid_for_miss;
1412 :
1413 : assign ifu_status_wr_addr_w_debug[pt.ICACHE_INDEX_HI:pt.ICACHE_TAG_INDEX_LO] = ((ic_debug_rd_en | ic_debug_wr_en ) & ic_debug_tag_array) ?
1414 : ic_debug_addr[pt.ICACHE_INDEX_HI:pt.ICACHE_TAG_INDEX_LO] :
1415 : ifu_status_wr_addr[pt.ICACHE_INDEX_HI:pt.ICACHE_TAG_INDEX_LO];
1416 :
1417 : // status
1418 :
1419 : assign way_status_wr_en_w_debug = way_status_wr_en | (ic_debug_wr_en & ic_debug_tag_array);
1420 :
1421 : assign way_status_new_w_debug[pt.ICACHE_STATUS_BITS-1:0] = (ic_debug_wr_en & ic_debug_tag_array) ? (pt.ICACHE_STATUS_BITS == 1) ? ic_debug_wr_data[4] : ic_debug_wr_data[6:4] :
1422 : way_status_new[pt.ICACHE_STATUS_BITS-1:0] ;
1423 :
1424 : rvdffe #(.WIDTH(pt.ICACHE_INDEX_HI-pt.ICACHE_TAG_INDEX_LO+1),.OVERRIDE(1)) perr_dat_ff (.din(ifu_ic_rw_int_addr_ff[pt.ICACHE_INDEX_HI:pt.ICACHE_TAG_INDEX_LO]), .dout(perr_ic_index_ff[pt.ICACHE_INDEX_HI : pt.ICACHE_TAG_INDEX_LO]), .en(perr_sb_write_status), .*);
1425 :
1426 : rvdffie #(.WIDTH(pt.ICACHE_TAG_LO-pt.ICACHE_TAG_INDEX_LO+1+pt.ICACHE_STATUS_BITS),.OVERRIDE(1)) status_misc_ff
1427 : (.*,
1428 : .clk(free_l2clk),
1429 : .din({ ifu_status_wr_addr_w_debug[pt.ICACHE_INDEX_HI:pt.ICACHE_TAG_INDEX_LO], way_status_wr_en_w_debug, way_status_new_w_debug[pt.ICACHE_STATUS_BITS-1:0]}),
1430 : .dout({ifu_status_wr_addr_ff[pt.ICACHE_INDEX_HI:pt.ICACHE_TAG_INDEX_LO], way_status_wr_en_ff, way_status_new_ff[pt.ICACHE_STATUS_BITS-1:0]} )
1431 : );
1432 :
1433 : logic [(pt.ICACHE_TAG_DEPTH/8)-1 : 0] way_status_clken;
1434 : logic [(pt.ICACHE_TAG_DEPTH/8)-1 : 0] way_status_clk;
1435 :
1436 : for (genvar i=0 ; i<pt.ICACHE_TAG_DEPTH/8 ; i++) begin : CLK_GRP_WAY_STATUS
1437 : assign way_status_clken[i] = (ifu_status_wr_addr_ff[pt.ICACHE_INDEX_HI:pt.ICACHE_TAG_INDEX_LO+3] == i );
1438 : `ifdef RV_FPGA_OPTIMIZE
1439 : assign way_status_clk[i] = 1'b0;
1440 : `else
1441 : rvclkhdr way_status_cgc ( .en(way_status_clken[i]), .l1clk(way_status_clk[i]), .* );
1442 : `endif
1443 :
1444 :
1445 : for (genvar j=0 ; j<8 ; j++) begin : WAY_STATUS
1446 : rvdffs_fpga #(pt.ICACHE_STATUS_BITS) ic_way_status (.*,
1447 : .clk(way_status_clk[i]),
1448 : .clken(way_status_clken[i]),
1449 : .rawclk(clk),
1450 : .en(((ifu_status_wr_addr_ff[pt.ICACHE_TAG_INDEX_LO+2:pt.ICACHE_TAG_INDEX_LO] == j) & way_status_wr_en_ff)),
1451 : .din(way_status_new_ff[pt.ICACHE_STATUS_BITS-1:0]),
1452 : .dout(way_status_out[8*i+j]));
1453 : end // WAY_STATUS
1454 : end // CLK_GRP_WAY_STATUS
1455 :
1456 339 : always_comb begin : way_status_out_mux
1457 339 : way_status[pt.ICACHE_STATUS_BITS-1:0] = '0 ;
1458 339 : for (int j=0; j< pt.ICACHE_TAG_DEPTH; j++) begin : status_mux_loop
1459 28151601 : if (ifu_ic_rw_int_addr_ff[pt.ICACHE_INDEX_HI:pt.ICACHE_TAG_INDEX_LO] == (pt.ICACHE_TAG_LO-pt.ICACHE_TAG_INDEX_LO)'(j)) begin : mux_out
1460 28151601 : way_status[pt.ICACHE_STATUS_BITS-1:0] = way_status_out[j];
1461 : end
1462 : end
1463 : end
1464 :
1465 : assign ifu_ic_rw_int_addr_w_debug[pt.ICACHE_INDEX_HI:pt.ICACHE_TAG_INDEX_LO] = ((ic_debug_rd_en | ic_debug_wr_en ) & ic_debug_tag_array) ?
1466 : ic_debug_addr[pt.ICACHE_INDEX_HI:pt.ICACHE_TAG_INDEX_LO] :
1467 : ifu_ic_rw_int_addr[pt.ICACHE_INDEX_HI:pt.ICACHE_TAG_INDEX_LO];
1468 : assign ifu_tag_wren_w_debug[pt.ICACHE_NUM_WAYS-1:0] = ifu_tag_wren[pt.ICACHE_NUM_WAYS-1:0] | ic_debug_tag_wr_en[pt.ICACHE_NUM_WAYS-1:0] ;
1469 :
1470 : assign ic_valid_w_debug = (ic_debug_wr_en & ic_debug_tag_array) ? ic_debug_wr_data[0] : ic_valid;
1471 :
1472 : rvdffie #(pt.ICACHE_TAG_LO-pt.ICACHE_TAG_INDEX_LO+pt.ICACHE_NUM_WAYS+1) tag_addr_ff (.*,
1473 : .clk(free_l2clk),
1474 : .din({ifu_ic_rw_int_addr_w_debug[pt.ICACHE_INDEX_HI:pt.ICACHE_TAG_INDEX_LO],
1475 : ifu_tag_wren_w_debug[pt.ICACHE_NUM_WAYS-1:0],
1476 : ic_valid_w_debug}),
1477 : .dout({ifu_ic_rw_int_addr_ff[pt.ICACHE_INDEX_HI:pt.ICACHE_TAG_INDEX_LO],
1478 : ifu_tag_wren_ff[pt.ICACHE_NUM_WAYS-1:0],
1479 : ic_valid_ff})
1480 : );
1481 :
1482 :
1483 : logic [pt.ICACHE_NUM_WAYS-1:0] [pt.ICACHE_TAG_DEPTH-1:0] ic_tag_valid_out ;
1484 :
1485 : logic [(pt.ICACHE_TAG_DEPTH/32)-1:0] [pt.ICACHE_NUM_WAYS-1:0] tag_valid_clken ;
1486 : logic [(pt.ICACHE_TAG_DEPTH/32)-1:0] [pt.ICACHE_NUM_WAYS-1:0] tag_valid_clk ;
1487 :
1488 : for (genvar i=0 ; i<pt.ICACHE_TAG_DEPTH/32 ; i++) begin : CLK_GRP_TAG_VALID
1489 : for (genvar j=0; j<pt.ICACHE_NUM_WAYS; j++) begin : way_clken
1490 : if (pt.ICACHE_TAG_DEPTH == 32 ) begin
1491 : assign tag_valid_clken[i][j] = ifu_tag_wren_ff[j] | perr_err_inv_way[j] | reset_all_tags;
1492 : end else begin
1493 : assign tag_valid_clken[i][j] = (((ifu_ic_rw_int_addr_ff[pt.ICACHE_INDEX_HI:pt.ICACHE_TAG_INDEX_LO+5] == i ) & ifu_tag_wren_ff[j] ) |
1494 : ((perr_ic_index_ff [pt.ICACHE_INDEX_HI:pt.ICACHE_TAG_INDEX_LO+5] == i ) & perr_err_inv_way[j]) | reset_all_tags);
1495 : end
1496 :
1497 : `ifdef RV_FPGA_OPTIMIZE
1498 : assign tag_valid_clk[i][j] = 1'b0;
1499 : `else
1500 : rvclkhdr way_status_cgc ( .en(tag_valid_clken[i][j]), .l1clk(tag_valid_clk[i][j]), .* );
1501 : `endif
1502 :
1503 :
1504 :
1505 : for (genvar k=0 ; k<32 ; k++) begin : TAG_VALID
1506 : rvdffs_fpga #(1) ic_way_tagvalid_dup (.*,
1507 : .clk(tag_valid_clk[i][j]),
1508 : .clken(tag_valid_clken[i][j]),
1509 : .rawclk(clk),
1510 : .en(((ifu_ic_rw_int_addr_ff[pt.ICACHE_INDEX_HI:pt.ICACHE_TAG_INDEX_LO] == (k + 32*i)) & ifu_tag_wren_ff[j] ) |
1511 : ((perr_ic_index_ff [pt.ICACHE_INDEX_HI:pt.ICACHE_TAG_INDEX_LO] == (k + 32*i)) & perr_err_inv_way[j]) | reset_all_tags),
1512 : .din(ic_valid_ff & ~reset_all_tags & ~perr_sel_invalidate),
1513 : .dout(ic_tag_valid_out[j][32*i+k]));
1514 : end
1515 : end
1516 : end
1517 :
1518 :
1519 339 : always_comb begin : tag_valid_out_mux
1520 339 : ic_tag_valid_unq[pt.ICACHE_NUM_WAYS-1:0] = '0;
1521 339 : for (int j=0; j< pt.ICACHE_TAG_DEPTH; j++) begin : tag_valid_loop
1522 28151601 : if (ifu_ic_rw_int_addr_ff[pt.ICACHE_INDEX_HI:pt.ICACHE_TAG_INDEX_LO] == (pt.ICACHE_TAG_LO-pt.ICACHE_TAG_INDEX_LO)'(j)) begin : valid_out
1523 28151601 : for ( int k=0; k<pt.ICACHE_NUM_WAYS; k++) begin
1524 56303202 : ic_tag_valid_unq[k] |= ic_tag_valid_out[k][j];
1525 : end
1526 : end
1527 : end
1528 : end
1529 : // four-way set associative - three bits
1530 : // each bit represents one branch point in a binary decision tree; let 1
1531 : // represent that the left side has been referenced more recently than the
1532 : // right side, and 0 vice-versa
1533 : //
1534 : // are all 4 ways valid?
1535 : // / \
1536 : // | no, use an invalid way.
1537 : // |
1538 : // |
1539 : // bit_0 == 0? state | replace ref to | next state
1540 : // / \ ------+-------- -------+-----------
1541 : // y n x00 | way_0 way_0 | _11
1542 : // / \ x10 | way_1 way_1 | _01
1543 : // bit_1 == 0? bit_2 == 0? 0x1 | way_2 way_2 | 1_0
1544 : // / \ / \ 1x1 | way_3 way_3 | 0_0
1545 : // y n y n
1546 : // / \ / \ ('x' means don't care ('_' means unchanged)
1547 : // way_0 way_1 way_2 way_3 don't care)
1548 :
1549 : if (pt.ICACHE_NUM_WAYS == 4) begin: four_way_plru
1550 : assign replace_way_mb_any[3] = ( way_status_mb_ff[2] & way_status_mb_ff[0] & (&tagv_mb_ff[3:0])) |
1551 : (~tagv_mb_ff[3]& tagv_mb_ff[2] & tagv_mb_ff[1] & tagv_mb_ff[0]) ;
1552 : assign replace_way_mb_any[2] = (~way_status_mb_ff[2] & way_status_mb_ff[0] & (&tagv_mb_ff[3:0])) |
1553 : (~tagv_mb_ff[2]& tagv_mb_ff[1] & tagv_mb_ff[0]) ;
1554 : assign replace_way_mb_any[1] = ( way_status_mb_ff[1] & ~way_status_mb_ff[0] & (&tagv_mb_ff[3:0])) |
1555 : (~tagv_mb_ff[1]& tagv_mb_ff[0] ) ;
1556 : assign replace_way_mb_any[0] = (~way_status_mb_ff[1] & ~way_status_mb_ff[0] & (&tagv_mb_ff[3:0])) |
1557 : (~tagv_mb_ff[0] ) ;
1558 :
1559 : assign way_status_hit_new[pt.ICACHE_STATUS_BITS-1:0] = ({3{~exu_flush_final & ic_rd_hit[0]}} & {way_status[2] , 1'b1 , 1'b1}) |
1560 : ({3{~exu_flush_final & ic_rd_hit[1]}} & {way_status[2] , 1'b0 , 1'b1}) |
1561 : ({3{~exu_flush_final & ic_rd_hit[2]}} & {1'b1 ,way_status[1] , 1'b0}) |
1562 : ({3{~exu_flush_final & ic_rd_hit[3]}} & {1'b0 ,way_status[1] , 1'b0}) ;
1563 :
1564 : assign way_status_rep_new[pt.ICACHE_STATUS_BITS-1:0] = ({3{replace_way_mb_any[0]}} & {way_status_mb_ff[2] , 1'b1 , 1'b1}) |
1565 : ({3{replace_way_mb_any[1]}} & {way_status_mb_ff[2] , 1'b0 , 1'b1}) |
1566 : ({3{replace_way_mb_any[2]}} & {1'b1 ,way_status_mb_ff[1] , 1'b0}) |
1567 : ({3{replace_way_mb_any[3]}} & {1'b0 ,way_status_mb_ff[1] , 1'b0}) ;
1568 : end
1569 : else begin : two_ways_plru
1570 : assign replace_way_mb_any[0] = (~way_status_mb_ff & tagv_mb_ff[0] & tagv_mb_ff[1]) | ~tagv_mb_ff[0];
1571 : assign replace_way_mb_any[1] = ( way_status_mb_ff & tagv_mb_ff[0] & tagv_mb_ff[1]) | ~tagv_mb_ff[1] & tagv_mb_ff[0];
1572 : assign way_status_hit_new[pt.ICACHE_STATUS_BITS-1:0] = ic_rd_hit[0];
1573 : assign way_status_rep_new[pt.ICACHE_STATUS_BITS-1:0] = replace_way_mb_any[0];
1574 :
1575 : end
1576 : // Make sure to select the way_status_hit_new even when in hit_under_miss.
1577 : assign way_status_new[pt.ICACHE_STATUS_BITS-1:0] = (bus_ifu_wr_en_ff_q & last_beat ) ? way_status_rep_new[pt.ICACHE_STATUS_BITS-1:0] :
1578 : way_status_hit_new[pt.ICACHE_STATUS_BITS-1:0] ;
1579 :
1580 :
1581 : assign way_status_wr_en = (bus_ifu_wr_en_ff_q & last_beat) | ic_act_hit_f;
1582 :
1583 : for (genvar i=0; i<pt.ICACHE_NUM_WAYS; i++) begin : bus_wren_loop
1584 : assign bus_wren[i] = bus_ifu_wr_en_ff_q & replace_way_mb_any[i] & miss_pending ;
1585 : assign bus_wren_last[i] = bus_ifu_wr_en_ff_wo_err & replace_way_mb_any[i] & miss_pending & bus_last_data_beat;
1586 : assign ifu_tag_wren[i] = bus_wren_last[i] | wren_reset_miss[i];
1587 : assign wren_reset_miss[i] = replace_way_mb_any[i] & reset_tag_valid_for_miss ;
1588 :
1589 : end
1590 : assign bus_ic_wr_en[pt.ICACHE_NUM_WAYS-1:0] = bus_wren[pt.ICACHE_NUM_WAYS-1:0];
1591 :
1592 :
1593 : end else begin: icache_disabled
1594 : assign ic_tag_valid_unq[pt.ICACHE_NUM_WAYS-1:0] = '0;
1595 : assign way_status[pt.ICACHE_STATUS_BITS-1:0] = '0;
1596 : assign replace_way_mb_any[pt.ICACHE_NUM_WAYS-1:0] = '0;
1597 : assign way_status_hit_new[pt.ICACHE_STATUS_BITS-1:0] = '0;
1598 : assign way_status_rep_new[pt.ICACHE_STATUS_BITS-1:0] = '0;
1599 : assign way_status_new[pt.ICACHE_STATUS_BITS-1:0] = '0;
1600 : assign way_status_wr_en = '0;
1601 : assign bus_wren[pt.ICACHE_NUM_WAYS-1:0] = '0;
1602 : assign bus_ic_wr_en[pt.ICACHE_NUM_WAYS-1:0] = '0;
1603 :
1604 : end
1605 :
1606 : assign ic_tag_valid[pt.ICACHE_NUM_WAYS-1:0] = ic_tag_valid_unq[pt.ICACHE_NUM_WAYS-1:0] & {pt.ICACHE_NUM_WAYS{(~fetch_uncacheable_ff & ifc_fetch_req_f_raw) }} ;
1607 : assign ic_debug_tag_val_rd_out = |(ic_tag_valid_unq[pt.ICACHE_NUM_WAYS-1:0] & ic_debug_way_ff[pt.ICACHE_NUM_WAYS-1:0] & {pt.ICACHE_NUM_WAYS{ic_debug_rd_en_ff}}) ;
1608 : ///////////////////////////////////////////
1609 : // PMU signals
1610 : ///////////////////////////////////////////
1611 :
1612 : assign ifu_pmu_ic_miss_in = ic_act_miss_f ;
1613 : assign ifu_pmu_ic_hit_in = ic_act_hit_f ;
1614 : assign ifu_pmu_bus_error_in = |ifc_bus_acc_fault_f;
1615 : assign ifu_pmu_bus_trxn_in = bus_cmd_sent ;
1616 : assign ifu_pmu_bus_busy_in = ifu_bus_arvalid_ff & ~ifu_bus_arready_ff & miss_pending ;
1617 :
1618 : rvdffie #(9) ifu_pmu_sigs_ff (.*,
1619 : .clk (free_l2clk),
1620 : .din ({ifc_fetch_uncacheable_bf, ifc_fetch_req_qual_bf, dma_sb_err_state, dec_tlu_fence_i_wb,
1621 : ifu_pmu_ic_miss_in,
1622 : ifu_pmu_ic_hit_in,
1623 : ifu_pmu_bus_error_in,
1624 : ifu_pmu_bus_busy_in,
1625 : ifu_pmu_bus_trxn_in
1626 : }),
1627 : .dout({fetch_uncacheable_ff, ifc_fetch_req_f_raw, dma_sb_err_state_ff, reset_all_tags,
1628 : ifu_pmu_ic_miss,
1629 : ifu_pmu_ic_hit,
1630 : ifu_pmu_bus_error,
1631 : ifu_pmu_bus_busy,
1632 : ifu_pmu_bus_trxn
1633 : }));
1634 :
1635 :
1636 : ///////////////////////////////////////////////////////
1637 : // Cache debug logic //
1638 : ///////////////////////////////////////////////////////
1639 : assign ic_debug_addr[pt.ICACHE_INDEX_HI:3] = dec_tlu_ic_diag_pkt.icache_dicawics[pt.ICACHE_INDEX_HI-3:0] ;
1640 : assign ic_debug_way_enc[01:00] = dec_tlu_ic_diag_pkt.icache_dicawics[15:14] ;
1641 :
1642 :
1643 : assign ic_debug_tag_array = dec_tlu_ic_diag_pkt.icache_dicawics[16] ;
1644 : assign ic_debug_rd_en = dec_tlu_ic_diag_pkt.icache_rd_valid ;
1645 : assign ic_debug_wr_en = dec_tlu_ic_diag_pkt.icache_wr_valid ;
1646 :
1647 :
1648 : for (genvar i = 0; i < pt.ICACHE_NUM_WAYS; i = i + 1) begin : ic_debug_way_loop
1649 : assign ic_debug_way[i] = (ic_debug_way_enc == i[1:0]);
1650 : end
1651 :
1652 : assign ic_debug_tag_wr_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] ;
1653 :
1654 : assign ic_debug_ict_array_sel_in = ic_debug_rd_en & ic_debug_tag_array ;
1655 :
1656 : rvdff_fpga #(01+pt.ICACHE_NUM_WAYS) ifu_debug_sel_ff (.*, .clk (debug_c1_clk),
1657 : .clken(debug_c1_clken), .rawclk(clk),
1658 : .din ({ic_debug_ict_array_sel_in,
1659 : ic_debug_way[pt.ICACHE_NUM_WAYS-1:0]
1660 : }),
1661 : .dout({ic_debug_ict_array_sel_ff,
1662 : ic_debug_way_ff[pt.ICACHE_NUM_WAYS-1:0]
1663 : }));
1664 :
1665 :
1666 :
1667 :
1668 : assign debug_data_clken = ic_debug_rd_en_ff;
1669 :
1670 :
1671 0 : logic ACCESS0_okay;
1672 0 : logic ACCESS1_okay;
1673 0 : logic ACCESS2_okay;
1674 0 : logic ACCESS3_okay;
1675 0 : logic ACCESS4_okay;
1676 0 : logic ACCESS5_okay;
1677 0 : logic ACCESS6_okay;
1678 0 : logic ACCESS7_okay;
1679 :
1680 : assign ACCESS0_okay = pt.INST_ACCESS_ENABLE0 & ((({ifc_fetch_addr_bf[31:1],1'b0} | pt.INST_ACCESS_MASK0)) == (pt.INST_ACCESS_ADDR0 | pt.INST_ACCESS_MASK0));
1681 : assign ACCESS1_okay = pt.INST_ACCESS_ENABLE1 & ((({ifc_fetch_addr_bf[31:1],1'b0} | pt.INST_ACCESS_MASK1)) == (pt.INST_ACCESS_ADDR1 | pt.INST_ACCESS_MASK1));
1682 : assign ACCESS2_okay = pt.INST_ACCESS_ENABLE2 & ((({ifc_fetch_addr_bf[31:1],1'b0} | pt.INST_ACCESS_MASK2)) == (pt.INST_ACCESS_ADDR2 | pt.INST_ACCESS_MASK2));
1683 : assign ACCESS3_okay = pt.INST_ACCESS_ENABLE3 & ((({ifc_fetch_addr_bf[31:1],1'b0} | pt.INST_ACCESS_MASK3)) == (pt.INST_ACCESS_ADDR3 | pt.INST_ACCESS_MASK3));
1684 : assign ACCESS4_okay = pt.INST_ACCESS_ENABLE4 & ((({ifc_fetch_addr_bf[31:1],1'b0} | pt.INST_ACCESS_MASK4)) == (pt.INST_ACCESS_ADDR4 | pt.INST_ACCESS_MASK4));
1685 : assign ACCESS5_okay = pt.INST_ACCESS_ENABLE5 & ((({ifc_fetch_addr_bf[31:1],1'b0} | pt.INST_ACCESS_MASK5)) == (pt.INST_ACCESS_ADDR5 | pt.INST_ACCESS_MASK5));
1686 : assign ACCESS6_okay = pt.INST_ACCESS_ENABLE6 & ((({ifc_fetch_addr_bf[31:1],1'b0} | pt.INST_ACCESS_MASK6)) == (pt.INST_ACCESS_ADDR6 | pt.INST_ACCESS_MASK6));
1687 : assign ACCESS7_okay = pt.INST_ACCESS_ENABLE7 & ((({ifc_fetch_addr_bf[31:1],1'b0} | pt.INST_ACCESS_MASK7)) == (pt.INST_ACCESS_ADDR7 | pt.INST_ACCESS_MASK7));
1688 :
1689 :
1690 : // memory protection - equation to look identical to the LSU equation
1691 : if (pt.PMP_ENTRIES != 0) begin : g_ifc_access_check_pmp
1692 : assign ifc_region_acc_okay = ~ifu_pmp_error;
1693 : assign ifc_region_acc_fault_memory_bf = ~ifc_region_acc_okay & ifc_fetch_req_bf;
1694 : end
1695 : else begin : g_ifc_access_check
1696 : assign ifc_region_acc_okay = (~(|{pt.INST_ACCESS_ENABLE0,pt.INST_ACCESS_ENABLE1,pt.INST_ACCESS_ENABLE2,pt.INST_ACCESS_ENABLE3,pt.INST_ACCESS_ENABLE4,pt.INST_ACCESS_ENABLE5,pt.INST_ACCESS_ENABLE6,pt.INST_ACCESS_ENABLE7}))
1697 : | ACCESS0_okay
1698 : | ACCESS1_okay
1699 : | ACCESS2_okay
1700 : | ACCESS3_okay
1701 : | ACCESS4_okay
1702 : | ACCESS5_okay
1703 : | ACCESS6_okay
1704 : | ACCESS7_okay
1705 : ;
1706 :
1707 : assign ifc_region_acc_fault_memory_bf = ~ifc_iccm_access_bf & ~ifc_region_acc_okay & ifc_fetch_req_bf;
1708 : end
1709 :
1710 : assign ifc_region_acc_fault_final_bf = ifc_region_acc_fault_bf | ifc_region_acc_fault_memory_bf;
1711 :
1712 : endmodule // el2_ifu_mem_ctl
|