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