Module Definition
dashboard | hierarchy | modlist | groups | tests | asserts



Module Instance : tb.dut.u_eflash.gen_flash_cores[1].u_core.u_rd

Instance :
SCORELINECONDTOGGLEFSMBRANCHASSERT
97.33 100.00 89.30 100.00 100.00


Instance's subtree :
SCORELINECONDTOGGLEFSMBRANCHASSERT
96.92 97.64 92.75 100.00 99.37 94.83


Parent :
SCORELINECONDTOGGLEFSMBRANCHASSERTNAME
94.76 96.63 85.85 100.00 91.30 100.00 gen_flash_cores[1].u_core


Subtrees :
NAMESCORELINECONDTOGGLEFSMBRANCHASSERT
gen_bufs[0].u_rd_buf 94.64 100.00 78.57 100.00 100.00
gen_bufs[1].u_rd_buf 94.64 100.00 78.57 100.00 100.00
gen_bufs[2].u_rd_buf 94.64 100.00 78.57 100.00 100.00
gen_bufs[3].u_rd_buf 94.64 100.00 78.57 100.00 100.00
gen_rd.gen_bus_words_intg[0].u_bus_intg 100.00 100.00
gen_rd.gen_bus_words_intg[0].u_prim_buf_intg 100.00 100.00
gen_rd.gen_bus_words_intg[1].u_bus_intg 100.00 100.00
gen_rd.gen_bus_words_intg[1].u_prim_buf_intg 100.00 100.00
u_addr_xor_storage 96.53 100.00 86.11 100.00 100.00
u_bus_inv_data_intg 0.00 0.00
u_dec 100.00 100.00 100.00
u_intg_buf 100.00 100.00
u_mask_storage 93.75 100.00 80.56 94.44 100.00
u_plain_enc 100.00 100.00
u_prim_buf_data_xor_out 100.00 100.00
u_rd_buf_dep 96.59 100.00 86.36 100.00 100.00
u_rd_storage 97.44 100.00 87.18 100.00 100.00 100.00
u_rsp_order_fifo 97.44 100.00 87.18 100.00 100.00 100.00
u_valid_random 92.50 92.31 97.69 100.00 80.00



Module Instance : tb.dut.u_eflash.gen_flash_cores[0].u_core.u_rd

Instance :
SCORELINECONDTOGGLEFSMBRANCHASSERT
97.49 100.00 89.96 100.00 100.00


Instance's subtree :
SCORELINECONDTOGGLEFSMBRANCHASSERT
96.97 97.64 92.99 100.00 99.37 94.83


Parent :
SCORELINECONDTOGGLEFSMBRANCHASSERTNAME
95.79 97.75 87.74 100.00 93.48 100.00 gen_flash_cores[0].u_core


Subtrees :
NAMESCORELINECONDTOGGLEFSMBRANCHASSERT
gen_bufs[0].u_rd_buf 94.64 100.00 78.57 100.00 100.00
gen_bufs[1].u_rd_buf 94.64 100.00 78.57 100.00 100.00
gen_bufs[2].u_rd_buf 94.64 100.00 78.57 100.00 100.00
gen_bufs[3].u_rd_buf 94.64 100.00 78.57 100.00 100.00
gen_rd.gen_bus_words_intg[0].u_bus_intg 100.00 100.00
gen_rd.gen_bus_words_intg[0].u_prim_buf_intg 100.00 100.00
gen_rd.gen_bus_words_intg[1].u_bus_intg 100.00 100.00
gen_rd.gen_bus_words_intg[1].u_prim_buf_intg 100.00 100.00
u_addr_xor_storage 96.53 100.00 86.11 100.00 100.00
u_bus_inv_data_intg 0.00 0.00
u_dec 100.00 100.00 100.00
u_intg_buf 100.00 100.00
u_mask_storage 93.75 100.00 80.56 94.44 100.00
u_plain_enc 100.00 100.00
u_prim_buf_data_xor_out 100.00 100.00
u_rd_buf_dep 96.59 100.00 86.36 100.00 100.00
u_rd_storage 97.44 100.00 87.18 100.00 100.00 100.00
u_rsp_order_fifo 97.44 100.00 87.18 100.00 100.00 100.00
u_valid_random 92.50 92.31 97.69 100.00 80.00

Line Coverage for Module : flash_phy_rd
Line No.TotalCoveredPercent
TOTAL133133100.00
CONT_ASSIGN13711100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14111100.00
CONT_ASSIGN14111100.00
CONT_ASSIGN14111100.00
CONT_ASSIGN14111100.00
CONT_ASSIGN14611100.00
CONT_ASSIGN14611100.00
CONT_ASSIGN14611100.00
CONT_ASSIGN14611100.00
CONT_ASSIGN15211100.00
CONT_ASSIGN15411100.00
CONT_ASSIGN15411100.00
CONT_ASSIGN15411100.00
CONT_ASSIGN18611100.00
CONT_ASSIGN19311100.00
CONT_ASSIGN19311100.00
CONT_ASSIGN19311100.00
CONT_ASSIGN19311100.00
CONT_ASSIGN19411100.00
CONT_ASSIGN19411100.00
CONT_ASSIGN19411100.00
CONT_ASSIGN19411100.00
CONT_ASSIGN19611100.00
CONT_ASSIGN19611100.00
CONT_ASSIGN19611100.00
CONT_ASSIGN19611100.00
CONT_ASSIGN21211100.00
CONT_ASSIGN21211100.00
CONT_ASSIGN21211100.00
CONT_ASSIGN21211100.00
CONT_ASSIGN21811100.00
CONT_ASSIGN21811100.00
CONT_ASSIGN21811100.00
CONT_ASSIGN21811100.00
CONT_ASSIGN22211100.00
CONT_ASSIGN22211100.00
CONT_ASSIGN22211100.00
CONT_ASSIGN22211100.00
CONT_ASSIGN22911100.00
CONT_ASSIGN23211100.00
ALWAYS25744100.00
CONT_ASSIGN29111100.00
CONT_ASSIGN29211100.00
CONT_ASSIGN30211100.00
CONT_ASSIGN30511100.00
CONT_ASSIGN30811100.00
CONT_ASSIGN32611100.00
CONT_ASSIGN33111100.00
ALWAYS3601212100.00
CONT_ASSIGN37711100.00
CONT_ASSIGN38211100.00
CONT_ASSIGN39311100.00
CONT_ASSIGN39911100.00
CONT_ASSIGN40711100.00
CONT_ASSIGN42811100.00
CONT_ASSIGN43211100.00
CONT_ASSIGN44211100.00
CONT_ASSIGN44511100.00
CONT_ASSIGN45111100.00
CONT_ASSIGN45611100.00
CONT_ASSIGN45911100.00
CONT_ASSIGN49111100.00
CONT_ASSIGN49411100.00
CONT_ASSIGN49711100.00
CONT_ASSIGN50111100.00
CONT_ASSIGN50311100.00
CONT_ASSIGN50411100.00
CONT_ASSIGN50511100.00
CONT_ASSIGN51311100.00
CONT_ASSIGN52111100.00
CONT_ASSIGN52311100.00
CONT_ASSIGN59711100.00
CONT_ASSIGN59811100.00
ALWAYS60066100.00
CONT_ASSIGN61011100.00
CONT_ASSIGN61411100.00
CONT_ASSIGN61711100.00
CONT_ASSIGN62411100.00
CONT_ASSIGN62811100.00
CONT_ASSIGN63611100.00
CONT_ASSIGN65411100.00
CONT_ASSIGN65911100.00
CONT_ASSIGN66411100.00
CONT_ASSIGN66411100.00
CONT_ASSIGN66411100.00
CONT_ASSIGN66411100.00
ALWAYS67088100.00
CONT_ASSIGN68311100.00
CONT_ASSIGN70411100.00
CONT_ASSIGN72411100.00
CONT_ASSIGN73611100.00
CONT_ASSIGN73811100.00
CONT_ASSIGN74411100.00
CONT_ASSIGN74511100.00
CONT_ASSIGN74711100.00
CONT_ASSIGN75111100.00
CONT_ASSIGN76211100.00
CONT_ASSIGN77511100.00
CONT_ASSIGN78711100.00
CONT_ASSIGN79011100.00
CONT_ASSIGN79411100.00
CONT_ASSIGN79711100.00
CONT_ASSIGN80011100.00

136 logic [BankAddrW-1:0] flash_word_addr; 137 1/1 assign flash_word_addr = addr_i[BusBankAddrW-1:LsbAddrBit]; Tests: T1 T2 T3  138 139 for (genvar i = 0; i < NumBuf; i++) begin: gen_buf_states 140 4/4 assign buf_valid[i] = read_buf[i].attr == Valid; Tests: T1 T2 T3  | T1 T2 T3  | T1 T2 T3  | T1 T2 T3  141 4/4 assign buf_wip[i] = read_buf[i].attr == Wip; Tests: T1 T2 T3  | T1 T2 T3  | T1 T2 T3  | T1 T2 T3  142 143 // if a buffer is valid and contains an error, it should be considered 144 // invalid as long as there are no pending responses already waiting 145 // on that buffer. 146 4/4 assign buf_invalid[i] = (read_buf[i].attr == Invalid) | Tests: T1 T2 T3  | T1 T2 T3  | T1 T2 T3  | T1 T2 T3  147 (read_buf[i].attr == Valid & 148 read_buf[i].err & 149 ~buf_dependency[i]); 150 end 151 152 1/1 assign buf_invalid_alloc[0] = buf_invalid[0]; Tests: T1 T2 T3  153 for (genvar i = 1; i < NumBuf; i++) begin: gen_inv_alloc_bufs 154 3/3 assign buf_invalid_alloc[i] = buf_invalid[i] & ~|buf_invalid[i-1:0]; Tests: T1 T2 T3  | T1 T2 T3  | T1 T2 T3  155 end 156 157 // a prim arbiter is used to somewhat fairly select among the valid buffers 158 logic [1:0] dummy_data [NumBuf]; 159 for (genvar i = 0; i < NumBuf; i++) begin: gen_dummy 160 assign dummy_data[i] = '0; 161 end 162 163 prim_arbiter_tree #( 164 .N(NumBuf), 165 .DW(2), 166 .EnDataPort(1'b0) 167 ) u_valid_random ( 168 .clk_i, 169 .rst_ni, 170 .req_chk_i(1'b0), // Valid is allowed to drop without ready. 171 // If there is an invalid buffer, always allocate from that one first 172 // If all buffers have a dependency to an in-flight transaction, do not 173 // allocate and wait for the dependencies to end. 174 // If none of the above are true, THEN pick a buffer from the current valid 175 // buffers that DO NOT have an ongoing dependency. 176 .req_i(|buf_invalid_alloc | all_buf_dependency ? '0 : buf_valid & ~buf_dependency), 177 .data_i(dummy_data), 178 .gnt_o(buf_valid_alloc), 179 .idx_o(), 180 .valid_o(), 181 .data_o(), 182 .ready_i(req_o & ack_i & no_match) 183 ); 184 185 // which buffer to allocate upon a new transaction 186 1/1 assign buf_alloc = |buf_invalid_alloc ? buf_invalid_alloc : buf_valid_alloc; Tests: T1 T2 T3  187 188 // do not attempt to generate match unless the transaction is relevant 189 for (genvar i = 0; i < NumBuf; i++) begin: gen_buf_match 190 logic part_match; 191 logic info_sel_match; 192 193 4/4 assign part_match = read_buf[i].part == part_i; Tests: T1 T2 T3  | T1 T2 T3  | T1 T2 T3  | T1 T2 T3  194 4/4 assign info_sel_match = read_buf[i].info_sel == info_sel_i; Tests: T1 T2 T3  | T1 T2 T3  | T1 T2 T3  | T1 T2 T3  195 196 4/4 assign buf_match[i] = req_i & Tests: T1 T2 T3  | T1 T2 T3  | T1 T2 T3  | T1 T2 T3  197 buf_en_q & 198 (buf_valid[i] | buf_wip[i]) & 199 (read_buf[i].addr == flash_word_addr) & 200 ~read_buf[i].err & 201 part_match & 202 info_sel_match; 203 204 // A data hazard should never happen to a wip buffer because it implies 205 // that a read is in progress, so a hazard operation cannot start. 206 // If bank erase, all buffers must be flushed. 207 // If page erase, only if the buffer lands in the same page. 208 // If program, only if it's the same flash word. 209 logic word_addr_match; 210 logic page_addr_match; 211 212 4/4 assign word_addr_match = (read_buf[i].addr == flash_word_addr) & Tests: T1 T2 T3  | T1 T2 T3  | T1 T2 T3  | T1 T2 T3  213 part_match & 214 info_sel_match; 215 216 // the read buffer address in on flash word boundary 217 // while the incoming address in on the bus word boundary 218 4/4 assign page_addr_match = (read_buf[i].addr[WordW +: PageW] == addr_i[BusWordW +: PageW]) & Tests: T1 T2 T3  | T1 T2 T3  | T1 T2 T3  | T1 T2 T3  219 part_match & 220 info_sel_match; 221 222 4/4 assign data_hazard[i] = buf_valid[i] & Tests: T1 T2 T3  | T1 T2 T3  | T1 T2 T3  | T1 T2 T3  223 (bk_erase_i | 224 (prog_i & word_addr_match) | 225 (pg_erase_i & page_addr_match)); 226 227 end 228 229 1/1 assign no_match = ~|buf_match; Tests: T1 T2 T3  230 231 // if new request does not match anything, allocate 232 1/1 assign alloc = no_match ? {NumBuf{req_i & buf_en_q}} & buf_alloc : '0; Tests: T1 T2 T3  233 234 // read buffers 235 // allocate sets state to Wip 236 // update sets state to valid 237 // wipe sets state to invalid - this comes from prog 238 for (genvar i = 0; i < NumBuf; i++) begin: gen_bufs 239 flash_phy_rd_buffers u_rd_buf ( 240 .clk_i, 241 .rst_ni, 242 .en_i(buf_en_q), 243 .alloc_i(rdy_o & alloc[i]), 244 .update_i(update[i]), 245 .err_i(muxed_err), 246 .wipe_i(data_hazard[i]), 247 .addr_i(flash_word_addr), 248 .part_i(part_i), 249 .info_sel_i(info_sel_i), 250 .data_i(muxed_data), 251 .out_o(read_buf[i]) 252 ); 253 end 254 255 // The buffer enable is allowed to change when the entire read pipeline is idle 256 always_ff @(posedge clk_i or negedge rst_ni) begin 257 1/1 if (!rst_ni) begin Tests: T1 T2 T3  258 1/1 buf_en_q <= 1'b0; Tests: T1 T2 T3  259 1/1 end else if (idle_o) begin Tests: T1 T2 T3  260 1/1 buf_en_q <= buf_en_i; Tests: T1 T2 T3  261 end MISSING_ELSE 262 end 263 264 ///////////////////////////////// 265 // Flash read stage 266 ///////////////////////////////// 267 268 // Flash read stage determines if the transactions are accepted. 269 // 270 // The response fifo is written to when a transaction initiates a flash read OR when a match 271 // is hit. The information written is just the allocated buffer that would have satisfied the 272 // transaction, as well as bits that indicate which part of the buffer is the right return data 273 // 274 // This allows a hit transaction to match in-order, and unblock later transactions to begin 275 // reading from the flash primitive 276 277 rsp_fifo_entry_t rsp_fifo_wdata, rsp_fifo_rdata; 278 logic rsp_fifo_rdy; 279 logic rsp_fifo_vld; 280 281 // saved attributes on flash read 282 logic [NumBuf-1:0] alloc_q; 283 rd_attr_t rd_attrs; 284 285 // read complete 286 // since done is broadcast to all the modules, need to know we are actually active 287 logic rd_start; 288 logic rd_busy; 289 logic rd_done; 290 291 1/1 assign rd_start = req_o & ack_i; Tests: T1 T2 T3  292 1/1 assign rd_done = rd_busy & done_i; Tests: T1 T2 T3  293 294 // scramble stage ready 295 logic scramble_stage_rdy; 296 297 // mask calculation done 298 logic calc_req_done; 299 300 // if buffer allocated, that is the return source 301 // if buffer matched, that is the return source 302 1/1 assign rsp_fifo_wdata.buf_sel = |alloc ? buf_alloc : buf_match; Tests: T1 T2 T3  303 304 logic rsp_order_fifo_wr; 305 1/1 assign rsp_order_fifo_wr = req_i && rdy_o; Tests: T1 T2 T3  306 307 logic rsp_order_fifo_rd; 308 1/1 assign rsp_order_fifo_rd = rsp_fifo_vld & data_valid_o; Tests: T1 T2 T3  309 310 flash_phy_rd_buf_dep u_rd_buf_dep ( 311 .clk_i, 312 .rst_ni, 313 .en_i(buf_en_q), 314 .fifo_wr_i(rsp_order_fifo_wr), 315 .fifo_rd_i(rsp_order_fifo_rd), 316 .wr_buf_i(rsp_fifo_wdata.buf_sel), 317 .rd_buf_i(rsp_fifo_rdata.buf_sel), 318 .dependency_o(buf_dependency), 319 .all_dependency_o(all_buf_dependency) 320 ); 321 322 // If width is the same, word_sel is unused 323 if (WidthMultiple == 1) begin : gen_single_word_sel 324 assign rsp_fifo_wdata.word_sel = '0; 325 end else begin : gen_word_sel 326 1/1 assign rsp_fifo_wdata.word_sel = addr_i[0 +: LsbAddrBit]; Tests: T1 T2 T3  327 end 328 329 // store the ecc configuration for this transaction until 330 // response is ready to be sent. 331 1/1 assign rsp_fifo_wdata.intg_ecc_en = ecc_i; Tests: T1 T2 T3  332 333 // response order FIFO 334 logic rsp_order_fifo_err; 335 prim_fifo_sync #( 336 .Width (RspOrderFifoWidth), 337 .Pass (0), 338 .Depth (RspOrderDepth), 339 .Secure (1'b1) // SEC_CM: FIFO.CTR.REDUN 340 ) u_rsp_order_fifo ( 341 .clk_i, 342 .rst_ni, 343 .clr_i (1'b0), 344 .wvalid_i(rsp_order_fifo_wr), 345 .wready_o(rsp_fifo_rdy), 346 .wdata_i (rsp_fifo_wdata), 347 .depth_o (), 348 .full_o (), 349 .rvalid_o(rsp_fifo_vld), 350 .rready_i(data_valid_o), // pop when a match has been found 351 .rdata_o (rsp_fifo_rdata), 352 .err_o (rsp_order_fifo_err) 353 ); 354 355 // Consider converting this to a FIFO for better matching 356 // The rd_busy flag is effectively a "full" flag anyways of a single 357 // entry. 358 logic flash_rdy; 359 always_ff @(posedge clk_i or negedge rst_ni) begin 360 1/1 if (!rst_ni) begin Tests: T1 T2 T3  361 1/1 alloc_q <= '0; Tests: T1 T2 T3  362 1/1 rd_attrs <= '0; Tests: T1 T2 T3  363 1/1 rd_busy <= '0; Tests: T1 T2 T3  364 1/1 end else if (rd_start) begin Tests: T1 T2 T3  365 1/1 rd_busy <= 1'b1; Tests: T1 T2 T3  366 1/1 alloc_q <= alloc; Tests: T1 T2 T3  367 1/1 rd_attrs.addr <= addr_i[BusBankAddrW-1:LsbAddrBit]; Tests: T1 T2 T3  368 1/1 rd_attrs.descramble <= descramble_i; Tests: T1 T2 T3  369 1/1 rd_attrs.ecc <= ecc_i; Tests: T1 T2 T3  370 371 1/1 end else if (rd_done) begin Tests: T1 T2 T3  372 1/1 rd_busy <= 1'b0; Tests: T1 T2 T3  373 end MISSING_ELSE 374 end 375 376 // flash is ready to accept another transaction 377 1/1 assign flash_rdy = ~rd_busy | rd_done; Tests: T1 T2 T3  378 379 // read stages are ready when both the response fifo and the 380 // data / mask fifos have space for new entries 381 logic rd_stages_rdy; 382 1/1 assign rd_stages_rdy = rsp_fifo_rdy & scramble_stage_rdy; Tests: T1 T2 T3  383 384 // When buffer enable changes, we want to hold off new requests 385 // until the request is absorbed. buf_en_q is allowed to change 386 // only when the entire read pipeline is idle, however, during that 387 // same cycle there could be a new incoming request. 388 // 389 // We back pressure here instead of waiting for a period of idle + no 390 // request because it potentially means a storm of accesses could 391 // prevent the buffer enable from taking effect. 392 logic no_buf_en_change; 393 1/1 assign no_buf_en_change = (buf_en_q == buf_en_i); Tests: T1 T2 T3  394 395 // If no buffers matched, accept only if flash is ready and there is space 396 // If buffer is matched, accept as long as there is space in the rsp fifo 397 // If all buffers are currently allocated or have a dependency, wait until 398 // at least 1 dependency has cleared. 399 1/1 assign rdy_o = (no_match ? ack_i & flash_rdy & rd_stages_rdy : rd_stages_rdy) & Tests: T1 T2 T3  400 ~all_buf_dependency & no_buf_en_change & 401 // If the current read requires descrambling, wait for the 402 // mask calculation to finish before accepting the next request. 403 (calc_req_o ? calc_req_done : 1'b1); 404 405 // issue a transaction to flash only if there is space in read stages, 406 // there is no buffer match and flash is not currently busy. 407 1/1 assign req_o = req_i & no_buf_en_change & flash_rdy & rd_stages_rdy & no_match & Tests: T1 T2 T3  408 // If the current read requires descrambling, wait for the 409 // mask calculation to finish before accepting the next request. 410 (calc_req_o ? calc_req_done : 1'b1); 411 412 ///////////////////////////////// 413 // Handling Reliability ECC 414 ///////////////////////////////// 415 416 // only uncorrectable errors are passed on to the fabric 417 logic data_err; 418 419 // scrambled data must pass through ECC first 420 logic valid_ecc; 421 logic ecc_multi_err; 422 logic ecc_single_err; 423 logic [PlainDataWidth-1:0] data_ecc_chk; 424 logic [PlainDataWidth-1:0] data_int; 425 logic data_erased; 426 427 // this ECC check is for reliability ECC 428 1/1 assign valid_ecc = rd_done && rd_attrs.ecc; Tests: T1 T2 T3  429 430 // When all bits are 1, the data has been erased 431 // This check is only valid when read data returns. 432 1/1 assign data_erased = rd_done & (data_i == {FullDataWidth{1'b1}}); Tests: T1 T2 T3  433 434 prim_secded_hamming_76_68_dec u_dec ( 435 .data_i(data_i), 436 .data_o(data_ecc_chk), 437 .syndrome_o(), 438 .err_o({ecc_multi_err, ecc_single_err}) 439 ); 440 441 // send out error indication when ecc is enabled 442 1/1 assign data_err = valid_ecc & ecc_multi_err; Tests: T1 T2 T3  443 444 // reliability ECC errors cause both in-band and out-of-band errors 445 1/1 assign relbl_ecc_err_o = data_err; Tests: T1 T2 T3  446 447 // If there is a detected multi-bit error or a single bit error, always return the 448 // ECC corrected result (even though it is possibly wrong). 449 // There is no data error of any kind (specifically when multi_err is disabled), just 450 // return the raw data so that it can be debugged. 451 1/1 assign data_int = data_err | ecc_single_err_o ? Tests: T1 T2 T3  452 data_ecc_chk : 453 data_i[PlainDataWidth-1:0]; 454 455 // send out error indication when ecc is enabled 456 1/1 assign ecc_single_err_o = valid_ecc & ecc_single_err; Tests: T1 T2 T3  457 458 // ecc address return is always the full flash word 459 1/1 assign ecc_addr_o = {rd_attrs.addr, {LsbAddrBit{1'b0}}}; Tests: T1 T2 T3  460 461 ///////////////////////////////// 462 // De-scrambling stage 463 ///////////////////////////////// 464 465 // Even on ECC error, progress through the stage normally 466 467 logic fifo_data_ready; 468 logic fifo_data_valid; 469 logic fifo_forward_pop; 470 logic rd_and_mask_fifo_pop; 471 logic mask_valid; 472 logic [PlainDataWidth-1:0] fifo_data; 473 logic [DataWidth-1:0] mask; 474 logic addr_xor_fifo_rdy; 475 logic [BankAddrW-1:0] fifo_addr_xor; 476 logic data_fifo_rdy; 477 logic mask_fifo_rdy; 478 logic descram; 479 logic dropmsk; 480 logic forward; 481 logic descram_q; 482 logic dropmsk_q; 483 logic forward_q; 484 logic hint_forward; 485 logic hint_dropmsk; 486 logic hint_descram; 487 logic data_err_q; 488 logic [NumBuf-1:0] alloc_q2; 489 logic [1:0] unused_rd_depth, unused_mask_depth, unused_addr_xor_depth; 490 491 1/1 assign scramble_stage_rdy = data_fifo_rdy & mask_fifo_rdy & addr_xor_fifo_rdy; Tests: T1 T2 T3  492 493 // descramble is only required if the location is scramble enabled AND it is not erased. 494 1/1 assign descram = rd_done & rd_attrs.descramble & ~data_erased; Tests: T1 T2 T3  495 496 // If the location is scramble enabled but has been erased, we'll need to drop the computed mask. 497 1/1 assign dropmsk = rd_done & rd_attrs.descramble & data_erased; Tests: T1 T2 T3  498 499 // data is forwarded whenever it does not require descrambling and there are no entries in the 500 // FIFO to ensure the current read cannot run ahead of the descramble. 501 1/1 assign forward = rd_done & ~descram & ~fifo_data_valid; Tests: T1 T2 T3  502 503 1/1 assign hint_descram = fifo_data_valid & descram_q; Tests: T1 T2 T3  504 1/1 assign hint_dropmsk = fifo_data_valid & dropmsk_q; Tests: T1 T2 T3  505 1/1 assign hint_forward = fifo_data_valid & forward_q; Tests: T1 T2 T3  506 507 // Data is consumed when: 508 // 1. If the location is scramble enabled: 509 // a) When descrambling completes. 510 // b) As soon as the mask computation finishes, in case the mask is to be dropped. 511 // 2. If the location is not scramble enabled: 512 // - As soon as the data is ready from the FIFO. For the forwarding case, see below. 513 1/1 assign fifo_data_ready = hint_descram ? descramble_req_o & descramble_ack_i : Tests: T1 T2 T3  514 hint_dropmsk ? mask_valid : fifo_data_valid; 515 516 // In the case of forwarding, the storage FIFOs are bypassed but still pushed. Once the forwarded 517 // entries arrive at the output of the read FIFO, we need to drop them. If a mask has been 518 // computed that is not used (e.g. because of erasing a location that is scramble enabled), wait 519 // for the mask computation to be done and then drop the forwarded data together with the 520 // corresponding mask. 521 1/1 assign fifo_forward_pop = hint_forward & (hint_dropmsk ? mask_valid : 1'b1); Tests: T1 T2 T3  522 523 1/1 assign rd_and_mask_fifo_pop = fifo_data_ready | fifo_forward_pop; Tests: T1 T2 T3  524 525 // See comment above on how FIFO popping can be improved in the future 526 logic rd_stage_fifo_err; 527 prim_fifo_sync #( 528 .Width (PlainDataWidth + 4 + NumBuf), 529 .Pass (0), 530 .Depth (2), 531 .OutputZeroIfEmpty (1), 532 .Secure (1'b1) // SEC_CM: FIFO.CTR.REDUN 533 ) u_rd_storage ( 534 .clk_i, 535 .rst_ni, 536 .clr_i (1'b0), 537 .wvalid_i(rd_done), 538 .wready_o(data_fifo_rdy), 539 .wdata_i ({alloc_q, descram, dropmsk, forward, data_err, data_int}), 540 .depth_o (unused_rd_depth), 541 .full_o (), 542 .rvalid_o(fifo_data_valid), 543 .rready_i(rd_and_mask_fifo_pop), 544 .rdata_o ({alloc_q2, descram_q, dropmsk_q, forward_q, data_err_q, fifo_data}), 545 .err_o (rd_stage_fifo_err) 546 ); 547 548 // storage for mask calculations 549 prim_fifo_sync #( 550 .Width (DataWidth), 551 .Pass (0), 552 .Depth (2), 553 .OutputZeroIfEmpty (1) 554 ) u_mask_storage ( 555 .clk_i, 556 .rst_ni, 557 .clr_i (1'b0), 558 .wvalid_i(calc_req_done), 559 .wready_o(mask_fifo_rdy), 560 .wdata_i (mask_i), 561 .depth_o (unused_mask_depth), 562 .full_o (), 563 .rvalid_o(mask_valid), 564 .rready_i(rd_and_mask_fifo_pop), 565 .rdata_o (mask), 566 .err_o () 567 ); 568 569 prim_fifo_sync #( 570 .Width (BankAddrW), 571 .Pass (0), 572 .Depth (RspOrderDepth), 573 .OutputZeroIfEmpty (1) 574 ) u_addr_xor_storage ( 575 .clk_i, 576 .rst_ni, 577 .clr_i (1'b0), 578 .wvalid_i(rsp_order_fifo_wr), 579 .wready_o(addr_xor_fifo_rdy), 580 .wdata_i (flash_word_addr), 581 .depth_o (unused_addr_xor_depth), 582 .full_o (), 583 .rvalid_o(), 584 .rready_i(data_valid_o), 585 .rdata_o (fifo_addr_xor), 586 .err_o () 587 ); 588 589 // generate the mask calculation request 590 // mask calculation is done in parallel to the read stage 591 // calc_req_o is done after req_o is accepted so that most of the 592 // cycle can be allocated to mask calculation logic. req_o, 593 // unlike calc_req_o, asserts the same cycle the transaction is 594 // received, so much of the timing may have already been lost to 595 // transaction routing. 596 logic calc_req_start; 597 1/1 assign calc_req_start = req_o & ack_i & descramble_i; Tests: T1 T2 T3  598 1/1 assign calc_req_done = calc_req_o & calc_ack_i; Tests: T1 T2 T3  599 always_ff @(posedge clk_i or negedge rst_ni) begin 600 1/1 if (!rst_ni) begin Tests: T1 T2 T3  601 1/1 calc_req_o <= '0; Tests: T1 T2 T3  602 1/1 end else if (calc_req_start) begin Tests: T1 T2 T3  603 1/1 calc_req_o <= 1'b1; Tests: T1 T2 T3  604 1/1 end else if (calc_req_done) begin Tests: T1 T2 T3  605 1/1 calc_req_o <= 1'b0; Tests: T1 T2 T3  606 end MISSING_ELSE 607 end 608 609 // operand to gf_mult 610 1/1 assign calc_addr_o = rd_attrs.addr; Tests: T1 T2 T3  611 612 // generate the descramble request whenever both stages are available 613 // and there is a need to descramble 614 1/1 assign descramble_req_o = fifo_data_valid & mask_valid & hint_descram; Tests: T1 T2 T3  615 616 // scrambled data to de-scramble 617 1/1 assign scrambled_data_o = fifo_data[DataWidth-1:0] ^ mask; Tests: T1 T2 T3  618 619 // muxed responses 620 // When "forward" is true, there is nothing ahead in the pipeline, directly feed data 621 // and error forward. 622 // When "forward" is not true, take the output from the descramble stage, which is 623 // dependent on the scramble hint. 624 1/1 assign muxed_data = forward ? data_int : Tests: T1 T2 T3  625 hint_descram ? {fifo_data[PlainDataWidth-1 -: PlainIntgWidth], 626 descrambled_data_i ^ mask} : 627 fifo_data; 628 1/1 assign muxed_err = forward ? data_err : Tests: T1 T2 T3  629 ~hint_forward ? data_err_q : '0; 630 631 // muxed data valid 632 // if no de-scramble required, return data on read complete 633 // if data is all empty (erased), also return data on read complete 634 // if descramble is required, return data when descrambler finishes 635 // if descramble is not required, but there are transactions ahead, return from fifo when ready 636 1/1 assign data_valid = forward | ~hint_forward & fifo_data_ready; Tests: T1 T2 T3  637 638 639 ///////////////////////////////// 640 // Response 641 ///////////////////////////////// 642 643 logic flash_rsp_match; 644 logic [NumBuf-1:0] buf_rsp_match; 645 logic [PlainDataWidth-1:0] buf_rsp_data; 646 logic [BankAddrW-1:0] buf_addr_xor; 647 logic buf_rsp_err; 648 649 650 // update buffers 651 // When forwarding, update entry stored in alloc_q 652 // When de-scrambling however, the contents of alloc_q may have already updated to the next read, 653 // so a different pointer is used. 654 1/1 assign update = forward ? alloc_q : Tests: T1 T2 T3  655 ~hint_forward & fifo_data_ready ? alloc_q2 : '0; 656 657 // match in flash response when allocated buffer is the same as top of response fifo 658 // if read buffers are not enabled, do not check buffer selection 659 1/1 assign flash_rsp_match = rsp_fifo_vld & data_valid & Tests: T1 T2 T3  660 (~buf_en_q | rsp_fifo_rdata.buf_sel == update); 661 662 // match in buf response when there is a valid buffer that is the same as top of response fifo 663 for (genvar i = 0; i < NumBuf; i++) begin: gen_buf_rsp_match 664 4/4 assign buf_rsp_match[i] = buf_en_q & rsp_fifo_vld & Tests: T1 T2 T3  | T1 T2 T3  | T1 T2 T3  | T1 T2 T3  665 (rsp_fifo_rdata.buf_sel[i] & buf_valid[i]); 666 end 667 668 // select among the buffers 669 always_comb begin 670 1/1 buf_rsp_data = muxed_data; Tests: T1 T2 T3  671 1/1 buf_rsp_err = '0; Tests: T1 T2 T3  672 1/1 buf_addr_xor = '0; Tests: T1 T2 T3  673 1/1 for (int i = 0; i < NumBuf; i++) begin Tests: T1 T2 T3  674 1/1 if (buf_rsp_match[i]) begin Tests: T1 T2 T3  675 1/1 buf_rsp_data = read_buf[i].data; Tests: T3 T16 T8  676 1/1 buf_addr_xor = read_buf[i].addr; Tests: T3 T16 T8  677 1/1 buf_rsp_err = buf_rsp_err | read_buf[i].err; Tests: T3 T16 T8  678 end MISSING_ELSE 679 end 680 end 681 682 logic [PlainDataWidth-1:0] data_out_muxed; 683 1/1 assign data_out_muxed = |buf_rsp_match ? buf_rsp_data : muxed_data; Tests: T1 T2 T3  684 685 logic [BusFullWidth-1:0] data_out_intg; 686 if (WidthMultiple == 1) begin : gen_width_one_rd 687 // When multiple is 1, just pass the read through directly 688 logic unused_word_sel; 689 690 // use the tlul integrity module directly for bus integrity 691 // SEC_CM: MEM.BUS.INTEGRITY 692 tlul_data_integ_enc u_bus_intg ( 693 .data_i(data_out_muxed[DataWidth-1:0]), 694 .data_intg_o(data_out_intg) 695 ); 696 697 assign unused_word_sel = rsp_fifo_rdata.word_sel; 698 699 end else begin : gen_rd 700 // Re-arrange data into packed array to pick the correct one 701 logic [WidthMultiple-1:0][BusWidth-1:0] bus_words_packed; 702 logic [WidthMultiple-1:0][BusFullWidth-1:0] bus_words_packed_intg; 703 logic [WidthMultiple-1:0][BusFullWidth-1:0] bus_words_packed_intg_buf; 704 1/1 assign bus_words_packed = data_out_muxed[DataWidth-1:0]; Tests: T1 T2 T3  705 706 for (genvar i = 0; i < WidthMultiple; i++) begin: gen_bus_words_intg 707 // use the tlul integrity module directly for bus integrity 708 // SEC_CM: MEM.BUS.INTEGRITY 709 tlul_data_integ_enc u_bus_intg ( 710 .data_i(bus_words_packed[i]), 711 .data_intg_o(bus_words_packed_intg[i]) 712 ); 713 714 // This primitive is used to place a size-only constraint on the 715 // buffers to act as a synthesis optimization barrier. 716 prim_buf #( 717 .Width(BusFullWidth) 718 ) u_prim_buf_intg ( 719 .in_i(bus_words_packed_intg[i]), 720 .out_o(bus_words_packed_intg_buf[i]) 721 ); 722 end 723 // Mux based on selected word. 724 1/1 assign data_out_intg = bus_words_packed_intg_buf[rsp_fifo_rdata.word_sel]; Tests: T1 T2 T3  725 726 end 727 728 // On a data_err_o, send back '1 with data integrity tag on top of this data. 729 logic [BusFullWidth-1:0] inv_data_integ; 730 tlul_data_integ_enc u_bus_inv_data_intg ( 731 .data_i({BusWidth{1'b1}}), 732 .data_intg_o(inv_data_integ) 733 ); 734 735 logic [BusFullWidth-1:0] data_out_pre_xor; 736 1/1 assign data_out_pre_xor = data_err_o ? inv_data_integ : data_out_intg; Tests: T1 T2 T3  737 738 1/1 assign data_ctrl_o = data_out_pre_xor; Tests: T1 T2 T3  739 740 logic [BusBankAddrW-1:0] addr_xor_muxed; 741 logic [BusBankAddrW-1:0] fifo_addr_xor_muxed; 742 logic [BusBankAddrW-1:0] buf_addr_xor_muxed; 743 744 1/1 assign fifo_addr_xor_muxed = {fifo_addr_xor, rsp_fifo_rdata.word_sel}; Tests: T1 T2 T3  745 1/1 assign buf_addr_xor_muxed = {buf_addr_xor, rsp_fifo_rdata.word_sel}; Tests: T1 T2 T3  746 747 1/1 assign addr_xor_muxed = |buf_rsp_match ? buf_addr_xor_muxed : fifo_addr_xor_muxed; Tests: T1 T2 T3  748 749 logic [BusWidth-1:0] data_out_xor; 750 logic [BusWidth-1:0] data_out_xor_buf; 751 1/1 assign data_out_xor = Tests: T1 T2 T3  752 data_out_pre_xor[BusWidth-1:0] ^ {{(BusWidth-BusBankAddrW){1'b0}}, addr_xor_muxed}; 753 754 // Buffer to ensure that synthesis tool does not optimize the XOR. 755 prim_buf #( 756 .Width(BusWidth) 757 ) u_prim_buf_data_xor_out ( 758 .in_i(data_out_xor), 759 .out_o(data_out_xor_buf) 760 ); 761 762 1/1 assign data_host_o = {data_out_pre_xor[BusFullWidth-1:BusWidth], data_out_xor_buf}; Tests: T1 T2 T3  763 764 // add plaintext decoding here 765 // plaintext error 766 logic intg_err_pre, intg_err; 767 logic [DataWidth-1:0] unused_data; 768 logic [3:0] unused_intg; 769 logic [3:0] truncated_intg; 770 771 prim_secded_hamming_72_64_enc u_plain_enc ( 772 .data_i(data_out_muxed[DataWidth-1:0]), 773 .data_o({unused_intg, truncated_intg, unused_data}) 774 ); 775 1/1 assign intg_err_pre = rsp_fifo_rdata.intg_ecc_en ? Tests: T1 T2 T3  776 truncated_intg != data_out_muxed[DataWidth +: PlainIntgWidth] : 777 '0; 778 779 prim_sec_anchor_buf #( 780 .Width(1) 781 ) u_intg_buf ( 782 .in_i(intg_err_pre), 783 .out_o(intg_err) 784 ); 785 786 // whenever the response is coming from the buffer, the error is never set 787 1/1 assign data_valid_o = flash_rsp_match | (|buf_rsp_match); Tests: T1 T2 T3  788 789 // integrity and reliability ECC errors always cause in band errors 790 1/1 assign data_err_o = data_valid_o & (muxed_err | intg_err | (|buf_rsp_match & buf_rsp_err)) | Tests: T1 T2 T3  791 arb_err_i; 792 793 // integrity ECC error can also cause out of band alert 794 1/1 assign intg_ecc_err_o = data_valid_o & intg_err; Tests: T1 T2 T3  795 796 // the entire read pipeline is idle when there are no responses to return and no 797 1/1 assign idle_o = ~rsp_fifo_vld; Tests: T1 T2 T3  798 799 // if any fifo shows an integrity error 800 1/1 assign fifo_err_o = |{rsp_order_fifo_err, rd_stage_fifo_err}; Tests: T1 T2 T3 

Cond Coverage for Module : flash_phy_rd
TotalCoveredPercent
Conditions45841390.17
Logical45841390.17
Non-Logical00
Event00

This module contains a very large number of conditions, so the report has been split into multiple pages, by source line number. Click on the line number range in the table below to see the condition coverage for that section of the module.
Line numbersPercent
140-45693.54
491-79481.95

Branch Coverage for Module : flash_phy_rd
Line No.TotalCoveredPercent
Branches 43 43 100.00
TERNARY 186 2 2 100.00
TERNARY 232 2 2 100.00
TERNARY 302 2 2 100.00
TERNARY 451 2 2 100.00
TERNARY 513 3 3 100.00
TERNARY 624 3 3 100.00
TERNARY 628 3 3 100.00
TERNARY 654 3 3 100.00
TERNARY 683 2 2 100.00
TERNARY 736 2 2 100.00
TERNARY 747 2 2 100.00
TERNARY 775 2 2 100.00
TERNARY 167 2 2 100.00
IF 257 3 3 100.00
IF 360 4 4 100.00
IF 600 4 4 100.00
IF 674 2 2 100.00


186 assign buf_alloc = |buf_invalid_alloc ? buf_invalid_alloc : buf_valid_alloc; -1- ==> ==>

Branches:
-1-StatusTests
1 Covered T1,T2,T3
0 Covered T3,T16,T8


232 assign alloc = no_match ? {NumBuf{req_i & buf_en_q}} & buf_alloc : '0; -1- ==> ==>

Branches:
-1-StatusTests
1 Covered T1,T2,T3
0 Covered T3,T16,T8


302 assign rsp_fifo_wdata.buf_sel = |alloc ? buf_alloc : buf_match; -1- ==> ==>

Branches:
-1-StatusTests
1 Covered T3,T16,T8
0 Covered T1,T2,T3


451 assign data_int = data_err | ecc_single_err_o ? -1- ==> ==>

Branches:
-1-StatusTests
1 Covered T34,T36,T65
0 Covered T1,T2,T3


513 assign fifo_data_ready = hint_descram ? descramble_req_o & descramble_ack_i : -1- ==> 514 hint_dropmsk ? mask_valid : fifo_data_valid; -2- ==> ==>

Branches:
-1--2-StatusTests
1 - Covered T1,T2,T3
0 1 Covered T10,T11,T27
0 0 Covered T1,T2,T3


624 assign muxed_data = forward ? data_int : -1- ==> 625 hint_descram ? {fifo_data[PlainDataWidth-1 -: PlainIntgWidth], -2- ==> ==>

Branches:
-1--2-StatusTests
1 - Covered T3,T8,T6
0 1 Covered T1,T2,T3
0 0 Covered T1,T2,T3


628 assign muxed_err = forward ? data_err : -1- ==> 629 ~hint_forward ? data_err_q : '0; -2- ==> ==>

Branches:
-1--2-StatusTests
1 - Covered T3,T8,T6
0 1 Covered T1,T2,T3
0 0 Covered T3,T8,T6


654 assign update = forward ? alloc_q : -1- ==> 655 ~hint_forward & fifo_data_ready ? alloc_q2 : '0; -2- ==> ==>

Branches:
-1--2-StatusTests
1 - Covered T3,T8,T6
0 1 Covered T1,T2,T3
0 0 Covered T1,T2,T3


683 assign data_out_muxed = |buf_rsp_match ? buf_rsp_data : muxed_data; -1- ==> ==>

Branches:
-1-StatusTests
1 Covered T3,T16,T8
0 Covered T1,T2,T3


736 assign data_out_pre_xor = data_err_o ? inv_data_integ : data_out_intg; -1- ==> ==>

Branches:
-1-StatusTests
1 Covered T59,T11,T34
0 Covered T1,T2,T3


747 assign addr_xor_muxed = |buf_rsp_match ? buf_addr_xor_muxed : fifo_addr_xor_muxed; -1- ==> ==>

Branches:
-1-StatusTests
1 Covered T3,T16,T8
0 Covered T1,T2,T3


775 assign intg_err_pre = rsp_fifo_rdata.intg_ecc_en ? -1- ==> ==>

Branches:
-1-StatusTests
1 Covered T1,T2,T3
0 Covered T1,T2,T3


167 ) u_valid_random ( 168 .clk_i, 169 .rst_ni, 170 .req_chk_i(1'b0), // Valid is allowed to drop without ready. 171 // If there is an invalid buffer, always allocate from that one first 172 // If all buffers have a dependency to an in-flight transaction, do not 173 // allocate and wait for the dependencies to end. 174 // If none of the above are true, THEN pick a buffer from the current valid 175 // buffers that DO NOT have an ongoing dependency. 176 .req_i(|buf_invalid_alloc | all_buf_dependency ? '0 : buf_valid & ~buf_dependency), -1- ==> ==>

Branches:
-1-StatusTests
1 Covered T1,T2,T3
0 Covered T3,T16,T8


257 if (!rst_ni) begin -1- 258 buf_en_q <= 1'b0; ==> 259 end else if (idle_o) begin -2- 260 buf_en_q <= buf_en_i; ==> 261 end MISSING_ELSE ==>

Branches:
-1--2-StatusTests
1 - Covered T1,T2,T3
0 1 Covered T1,T2,T3
0 0 Covered T1,T2,T3


360 if (!rst_ni) begin -1- 361 alloc_q <= '0; ==> 362 rd_attrs <= '0; 363 rd_busy <= '0; 364 end else if (rd_start) begin -2- 365 rd_busy <= 1'b1; ==> 366 alloc_q <= alloc; 367 rd_attrs.addr <= addr_i[BusBankAddrW-1:LsbAddrBit]; 368 rd_attrs.descramble <= descramble_i; 369 rd_attrs.ecc <= ecc_i; 370 371 end else if (rd_done) begin -3- 372 rd_busy <= 1'b0; ==> 373 end MISSING_ELSE ==>

Branches:
-1--2--3-StatusTests
1 - - Covered T1,T2,T3
0 1 - Covered T1,T2,T3
0 0 1 Covered T1,T2,T3
0 0 0 Covered T1,T2,T3


600 if (!rst_ni) begin -1- 601 calc_req_o <= '0; ==> 602 end else if (calc_req_start) begin -2- 603 calc_req_o <= 1'b1; ==> 604 end else if (calc_req_done) begin -3- 605 calc_req_o <= 1'b0; ==> 606 end MISSING_ELSE ==>

Branches:
-1--2--3-StatusTests
1 - - Covered T1,T2,T3
0 1 - Covered T1,T2,T3
0 0 1 Covered T1,T2,T3
0 0 0 Covered T1,T2,T3


674 if (buf_rsp_match[i]) begin -1- 675 buf_rsp_data = read_buf[i].data; ==> 676 buf_addr_xor = read_buf[i].addr; 677 buf_rsp_err = buf_rsp_err | read_buf[i].err; 678 end MISSING_ELSE ==>

Branches:
-1-StatusTests
1 Covered T3,T16,T8
0 Covered T1,T2,T3


Assert Coverage for Module : flash_phy_rd
TotalAttemptedPercentSucceeded/MatchedPercent
Assertions 11 11 100.00 11 100.00
Cover properties 0 0 0
Cover sequences 0 0 0
Total 11 11 100.00 11 100.00




Assertion Details

NameAttemptsReal SuccessesFailuresIncomplete
BufferMatchEcc_A 665750786 1691317 0 0
ExclusiveOps_A 665750786 664017318 0 0
ExclusiveProgHazard_A 665750786 664017318 0 0
ExclusiveState_A 665750786 664017318 0 0
ForwardCheck_A 665750786 3837370 0 0
IdleCheck_A 665750786 99773327 0 0
MaxBufs_A 2052 2052 0 0
OneHotAlloc_A 665750786 664017318 0 0
OneHotMatch_A 665750786 664017318 0 0
OneHotRspMatch_A 665750786 664017318 0 0
OneHotUpdate_A 665750786 664017318 0 0


BufferMatchEcc_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 665750786 1691317 0 0
T3 2283 72 0 0
T4 4375 0 0 0
T5 1250 0 0 0
T6 1746 7 0 0
T8 102564 502 0 0
T9 4220 10 0 0
T10 1263 4 0 0
T11 468 0 0 0
T15 949 0 0 0
T16 3668 72 0 0
T17 3690 72 0 0
T19 0 47 0 0
T20 2210 5 0 0
T24 0 18 0 0
T27 0 94 0 0
T28 0 616 0 0
T33 1654 0 0 0
T34 0 33 0 0
T36 0 186 0 0
T59 1169 0 0 0
T64 0 372 0 0

ExclusiveOps_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 665750786 664017318 0 0
T1 2950 2722 0 0
T2 7388 7200 0 0
T3 4566 4388 0 0
T4 8750 7704 0 0
T5 2500 2302 0 0
T6 1746 1552 0 0
T8 102564 102464 0 0
T15 1898 1772 0 0
T16 3668 3490 0 0
T17 3690 3492 0 0

ExclusiveProgHazard_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 665750786 664017318 0 0
T1 2950 2722 0 0
T2 7388 7200 0 0
T3 4566 4388 0 0
T4 8750 7704 0 0
T5 2500 2302 0 0
T6 1746 1552 0 0
T8 102564 102464 0 0
T15 1898 1772 0 0
T16 3668 3490 0 0
T17 3690 3492 0 0

ExclusiveState_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 665750786 664017318 0 0
T1 2950 2722 0 0
T2 7388 7200 0 0
T3 4566 4388 0 0
T4 8750 7704 0 0
T5 2500 2302 0 0
T6 1746 1552 0 0
T8 102564 102464 0 0
T15 1898 1772 0 0
T16 3668 3490 0 0
T17 3690 3492 0 0

ForwardCheck_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 665750786 3837370 0 0
T3 2283 74 0 0
T4 4375 0 0 0
T5 1250 0 0 0
T6 1746 9 0 0
T8 102564 588 0 0
T9 4220 10 0 0
T10 1263 20 0 0
T11 468 4 0 0
T15 949 0 0 0
T16 1834 0 0 0
T17 3690 74 0 0
T19 0 148 0 0
T20 2210 5 0 0
T24 0 21 0 0
T27 0 86 0 0
T28 0 616 0 0
T33 1654 0 0 0
T34 0 12 0 0
T36 0 186 0 0
T59 1169 0 0 0
T66 1241 0 0 0

IdleCheck_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 665750786 99773327 0 0
T1 1475 256 0 0
T2 3694 128 0 0
T3 2283 348 0 0
T4 4375 768 0 0
T5 1250 128 0 0
T6 1746 153 0 0
T8 102564 1806 0 0
T9 2110 0 0 0
T10 1263 10 0 0
T11 468 4 0 0
T15 949 128 0 0
T16 3668 496 0 0
T17 3690 348 0 0
T19 0 251 0 0
T20 1105 0 0 0
T27 0 109 0 0
T33 1654 0 0 0
T34 0 26 0 0
T36 0 558 0 0
T59 1169 0 0 0
T64 0 178 0 0

MaxBufs_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 2052 2052 0 0
T1 2 2 0 0
T2 2 2 0 0
T3 2 2 0 0
T4 2 2 0 0
T5 2 2 0 0
T6 2 2 0 0
T8 2 2 0 0
T15 2 2 0 0
T16 2 2 0 0
T17 2 2 0 0

OneHotAlloc_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 665750786 664017318 0 0
T1 2950 2722 0 0
T2 7388 7200 0 0
T3 4566 4388 0 0
T4 8750 7704 0 0
T5 2500 2302 0 0
T6 1746 1552 0 0
T8 102564 102464 0 0
T15 1898 1772 0 0
T16 3668 3490 0 0
T17 3690 3492 0 0

OneHotMatch_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 665750786 664017318 0 0
T1 2950 2722 0 0
T2 7388 7200 0 0
T3 4566 4388 0 0
T4 8750 7704 0 0
T5 2500 2302 0 0
T6 1746 1552 0 0
T8 102564 102464 0 0
T15 1898 1772 0 0
T16 3668 3490 0 0
T17 3690 3492 0 0

OneHotRspMatch_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 665750786 664017318 0 0
T1 2950 2722 0 0
T2 7388 7200 0 0
T3 4566 4388 0 0
T4 8750 7704 0 0
T5 2500 2302 0 0
T6 1746 1552 0 0
T8 102564 102464 0 0
T15 1898 1772 0 0
T16 3668 3490 0 0
T17 3690 3492 0 0

OneHotUpdate_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 665750786 664017318 0 0
T1 2950 2722 0 0
T2 7388 7200 0 0
T3 4566 4388 0 0
T4 8750 7704 0 0
T5 2500 2302 0 0
T6 1746 1552 0 0
T8 102564 102464 0 0
T15 1898 1772 0 0
T16 3668 3490 0 0
T17 3690 3492 0 0

Line Coverage for Instance : tb.dut.u_eflash.gen_flash_cores[1].u_core.u_rd
Line No.TotalCoveredPercent
TOTAL133133100.00
CONT_ASSIGN13711100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14111100.00
CONT_ASSIGN14111100.00
CONT_ASSIGN14111100.00
CONT_ASSIGN14111100.00
CONT_ASSIGN14611100.00
CONT_ASSIGN14611100.00
CONT_ASSIGN14611100.00
CONT_ASSIGN14611100.00
CONT_ASSIGN15211100.00
CONT_ASSIGN15411100.00
CONT_ASSIGN15411100.00
CONT_ASSIGN15411100.00
CONT_ASSIGN18611100.00
CONT_ASSIGN19311100.00
CONT_ASSIGN19311100.00
CONT_ASSIGN19311100.00
CONT_ASSIGN19311100.00
CONT_ASSIGN19411100.00
CONT_ASSIGN19411100.00
CONT_ASSIGN19411100.00
CONT_ASSIGN19411100.00
CONT_ASSIGN19611100.00
CONT_ASSIGN19611100.00
CONT_ASSIGN19611100.00
CONT_ASSIGN19611100.00
CONT_ASSIGN21211100.00
CONT_ASSIGN21211100.00
CONT_ASSIGN21211100.00
CONT_ASSIGN21211100.00
CONT_ASSIGN21811100.00
CONT_ASSIGN21811100.00
CONT_ASSIGN21811100.00
CONT_ASSIGN21811100.00
CONT_ASSIGN22211100.00
CONT_ASSIGN22211100.00
CONT_ASSIGN22211100.00
CONT_ASSIGN22211100.00
CONT_ASSIGN22911100.00
CONT_ASSIGN23211100.00
ALWAYS25744100.00
CONT_ASSIGN29111100.00
CONT_ASSIGN29211100.00
CONT_ASSIGN30211100.00
CONT_ASSIGN30511100.00
CONT_ASSIGN30811100.00
CONT_ASSIGN32611100.00
CONT_ASSIGN33111100.00
ALWAYS3601212100.00
CONT_ASSIGN37711100.00
CONT_ASSIGN38211100.00
CONT_ASSIGN39311100.00
CONT_ASSIGN39911100.00
CONT_ASSIGN40711100.00
CONT_ASSIGN42811100.00
CONT_ASSIGN43211100.00
CONT_ASSIGN44211100.00
CONT_ASSIGN44511100.00
CONT_ASSIGN45111100.00
CONT_ASSIGN45611100.00
CONT_ASSIGN45911100.00
CONT_ASSIGN49111100.00
CONT_ASSIGN49411100.00
CONT_ASSIGN49711100.00
CONT_ASSIGN50111100.00
CONT_ASSIGN50311100.00
CONT_ASSIGN50411100.00
CONT_ASSIGN50511100.00
CONT_ASSIGN51311100.00
CONT_ASSIGN52111100.00
CONT_ASSIGN52311100.00
CONT_ASSIGN59711100.00
CONT_ASSIGN59811100.00
ALWAYS60066100.00
CONT_ASSIGN61011100.00
CONT_ASSIGN61411100.00
CONT_ASSIGN61711100.00
CONT_ASSIGN62411100.00
CONT_ASSIGN62811100.00
CONT_ASSIGN63611100.00
CONT_ASSIGN65411100.00
CONT_ASSIGN65911100.00
CONT_ASSIGN66411100.00
CONT_ASSIGN66411100.00
CONT_ASSIGN66411100.00
CONT_ASSIGN66411100.00
ALWAYS67088100.00
CONT_ASSIGN68311100.00
CONT_ASSIGN70411100.00
CONT_ASSIGN72411100.00
CONT_ASSIGN73611100.00
CONT_ASSIGN73811100.00
CONT_ASSIGN74411100.00
CONT_ASSIGN74511100.00
CONT_ASSIGN74711100.00
CONT_ASSIGN75111100.00
CONT_ASSIGN76211100.00
CONT_ASSIGN77511100.00
CONT_ASSIGN78711100.00
CONT_ASSIGN79011100.00
CONT_ASSIGN79411100.00
CONT_ASSIGN79711100.00
CONT_ASSIGN80011100.00

136 logic [BankAddrW-1:0] flash_word_addr; 137 1/1 assign flash_word_addr = addr_i[BusBankAddrW-1:LsbAddrBit]; Tests: T1 T2 T3  138 139 for (genvar i = 0; i < NumBuf; i++) begin: gen_buf_states 140 4/4 assign buf_valid[i] = read_buf[i].attr == Valid; Tests: T1 T2 T3  | T1 T2 T3  | T1 T2 T3  | T1 T2 T3  141 4/4 assign buf_wip[i] = read_buf[i].attr == Wip; Tests: T1 T2 T3  | T1 T2 T3  | T1 T2 T3  | T1 T2 T3  142 143 // if a buffer is valid and contains an error, it should be considered 144 // invalid as long as there are no pending responses already waiting 145 // on that buffer. 146 4/4 assign buf_invalid[i] = (read_buf[i].attr == Invalid) | Tests: T1 T2 T3  | T1 T2 T3  | T1 T2 T3  | T1 T2 T3  147 (read_buf[i].attr == Valid & 148 read_buf[i].err & 149 ~buf_dependency[i]); 150 end 151 152 1/1 assign buf_invalid_alloc[0] = buf_invalid[0]; Tests: T1 T2 T3  153 for (genvar i = 1; i < NumBuf; i++) begin: gen_inv_alloc_bufs 154 3/3 assign buf_invalid_alloc[i] = buf_invalid[i] & ~|buf_invalid[i-1:0]; Tests: T1 T2 T3  | T1 T2 T3  | T1 T2 T3  155 end 156 157 // a prim arbiter is used to somewhat fairly select among the valid buffers 158 logic [1:0] dummy_data [NumBuf]; 159 for (genvar i = 0; i < NumBuf; i++) begin: gen_dummy 160 assign dummy_data[i] = '0; 161 end 162 163 prim_arbiter_tree #( 164 .N(NumBuf), 165 .DW(2), 166 .EnDataPort(1'b0) 167 ) u_valid_random ( 168 .clk_i, 169 .rst_ni, 170 .req_chk_i(1'b0), // Valid is allowed to drop without ready. 171 // If there is an invalid buffer, always allocate from that one first 172 // If all buffers have a dependency to an in-flight transaction, do not 173 // allocate and wait for the dependencies to end. 174 // If none of the above are true, THEN pick a buffer from the current valid 175 // buffers that DO NOT have an ongoing dependency. 176 .req_i(|buf_invalid_alloc | all_buf_dependency ? '0 : buf_valid & ~buf_dependency), 177 .data_i(dummy_data), 178 .gnt_o(buf_valid_alloc), 179 .idx_o(), 180 .valid_o(), 181 .data_o(), 182 .ready_i(req_o & ack_i & no_match) 183 ); 184 185 // which buffer to allocate upon a new transaction 186 1/1 assign buf_alloc = |buf_invalid_alloc ? buf_invalid_alloc : buf_valid_alloc; Tests: T1 T2 T3  187 188 // do not attempt to generate match unless the transaction is relevant 189 for (genvar i = 0; i < NumBuf; i++) begin: gen_buf_match 190 logic part_match; 191 logic info_sel_match; 192 193 4/4 assign part_match = read_buf[i].part == part_i; Tests: T1 T2 T3  | T1 T2 T3  | T1 T2 T3  | T1 T2 T3  194 4/4 assign info_sel_match = read_buf[i].info_sel == info_sel_i; Tests: T1 T2 T3  | T1 T2 T3  | T1 T2 T3  | T1 T2 T3  195 196 4/4 assign buf_match[i] = req_i & Tests: T1 T2 T3  | T1 T2 T3  | T1 T2 T3  | T1 T2 T3  197 buf_en_q & 198 (buf_valid[i] | buf_wip[i]) & 199 (read_buf[i].addr == flash_word_addr) & 200 ~read_buf[i].err & 201 part_match & 202 info_sel_match; 203 204 // A data hazard should never happen to a wip buffer because it implies 205 // that a read is in progress, so a hazard operation cannot start. 206 // If bank erase, all buffers must be flushed. 207 // If page erase, only if the buffer lands in the same page. 208 // If program, only if it's the same flash word. 209 logic word_addr_match; 210 logic page_addr_match; 211 212 4/4 assign word_addr_match = (read_buf[i].addr == flash_word_addr) & Tests: T1 T2 T3  | T1 T2 T3  | T1 T2 T3  | T1 T2 T3  213 part_match & 214 info_sel_match; 215 216 // the read buffer address in on flash word boundary 217 // while the incoming address in on the bus word boundary 218 4/4 assign page_addr_match = (read_buf[i].addr[WordW +: PageW] == addr_i[BusWordW +: PageW]) & Tests: T1 T2 T3  | T1 T2 T3  | T1 T2 T3  | T1 T2 T3  219 part_match & 220 info_sel_match; 221 222 4/4 assign data_hazard[i] = buf_valid[i] & Tests: T1 T2 T3  | T1 T2 T3  | T1 T2 T3  | T1 T2 T3  223 (bk_erase_i | 224 (prog_i & word_addr_match) | 225 (pg_erase_i & page_addr_match)); 226 227 end 228 229 1/1 assign no_match = ~|buf_match; Tests: T1 T2 T3  230 231 // if new request does not match anything, allocate 232 1/1 assign alloc = no_match ? {NumBuf{req_i & buf_en_q}} & buf_alloc : '0; Tests: T1 T2 T3  233 234 // read buffers 235 // allocate sets state to Wip 236 // update sets state to valid 237 // wipe sets state to invalid - this comes from prog 238 for (genvar i = 0; i < NumBuf; i++) begin: gen_bufs 239 flash_phy_rd_buffers u_rd_buf ( 240 .clk_i, 241 .rst_ni, 242 .en_i(buf_en_q), 243 .alloc_i(rdy_o & alloc[i]), 244 .update_i(update[i]), 245 .err_i(muxed_err), 246 .wipe_i(data_hazard[i]), 247 .addr_i(flash_word_addr), 248 .part_i(part_i), 249 .info_sel_i(info_sel_i), 250 .data_i(muxed_data), 251 .out_o(read_buf[i]) 252 ); 253 end 254 255 // The buffer enable is allowed to change when the entire read pipeline is idle 256 always_ff @(posedge clk_i or negedge rst_ni) begin 257 1/1 if (!rst_ni) begin Tests: T1 T2 T3  258 1/1 buf_en_q <= 1'b0; Tests: T1 T2 T3  259 1/1 end else if (idle_o) begin Tests: T1 T2 T3  260 1/1 buf_en_q <= buf_en_i; Tests: T1 T2 T3  261 end MISSING_ELSE 262 end 263 264 ///////////////////////////////// 265 // Flash read stage 266 ///////////////////////////////// 267 268 // Flash read stage determines if the transactions are accepted. 269 // 270 // The response fifo is written to when a transaction initiates a flash read OR when a match 271 // is hit. The information written is just the allocated buffer that would have satisfied the 272 // transaction, as well as bits that indicate which part of the buffer is the right return data 273 // 274 // This allows a hit transaction to match in-order, and unblock later transactions to begin 275 // reading from the flash primitive 276 277 rsp_fifo_entry_t rsp_fifo_wdata, rsp_fifo_rdata; 278 logic rsp_fifo_rdy; 279 logic rsp_fifo_vld; 280 281 // saved attributes on flash read 282 logic [NumBuf-1:0] alloc_q; 283 rd_attr_t rd_attrs; 284 285 // read complete 286 // since done is broadcast to all the modules, need to know we are actually active 287 logic rd_start; 288 logic rd_busy; 289 logic rd_done; 290 291 1/1 assign rd_start = req_o & ack_i; Tests: T1 T2 T3  292 1/1 assign rd_done = rd_busy & done_i; Tests: T1 T2 T3  293 294 // scramble stage ready 295 logic scramble_stage_rdy; 296 297 // mask calculation done 298 logic calc_req_done; 299 300 // if buffer allocated, that is the return source 301 // if buffer matched, that is the return source 302 1/1 assign rsp_fifo_wdata.buf_sel = |alloc ? buf_alloc : buf_match; Tests: T1 T2 T3  303 304 logic rsp_order_fifo_wr; 305 1/1 assign rsp_order_fifo_wr = req_i && rdy_o; Tests: T1 T2 T3  306 307 logic rsp_order_fifo_rd; 308 1/1 assign rsp_order_fifo_rd = rsp_fifo_vld & data_valid_o; Tests: T1 T2 T3  309 310 flash_phy_rd_buf_dep u_rd_buf_dep ( 311 .clk_i, 312 .rst_ni, 313 .en_i(buf_en_q), 314 .fifo_wr_i(rsp_order_fifo_wr), 315 .fifo_rd_i(rsp_order_fifo_rd), 316 .wr_buf_i(rsp_fifo_wdata.buf_sel), 317 .rd_buf_i(rsp_fifo_rdata.buf_sel), 318 .dependency_o(buf_dependency), 319 .all_dependency_o(all_buf_dependency) 320 ); 321 322 // If width is the same, word_sel is unused 323 if (WidthMultiple == 1) begin : gen_single_word_sel 324 assign rsp_fifo_wdata.word_sel = '0; 325 end else begin : gen_word_sel 326 1/1 assign rsp_fifo_wdata.word_sel = addr_i[0 +: LsbAddrBit]; Tests: T1 T2 T3  327 end 328 329 // store the ecc configuration for this transaction until 330 // response is ready to be sent. 331 1/1 assign rsp_fifo_wdata.intg_ecc_en = ecc_i; Tests: T1 T2 T3  332 333 // response order FIFO 334 logic rsp_order_fifo_err; 335 prim_fifo_sync #( 336 .Width (RspOrderFifoWidth), 337 .Pass (0), 338 .Depth (RspOrderDepth), 339 .Secure (1'b1) // SEC_CM: FIFO.CTR.REDUN 340 ) u_rsp_order_fifo ( 341 .clk_i, 342 .rst_ni, 343 .clr_i (1'b0), 344 .wvalid_i(rsp_order_fifo_wr), 345 .wready_o(rsp_fifo_rdy), 346 .wdata_i (rsp_fifo_wdata), 347 .depth_o (), 348 .full_o (), 349 .rvalid_o(rsp_fifo_vld), 350 .rready_i(data_valid_o), // pop when a match has been found 351 .rdata_o (rsp_fifo_rdata), 352 .err_o (rsp_order_fifo_err) 353 ); 354 355 // Consider converting this to a FIFO for better matching 356 // The rd_busy flag is effectively a "full" flag anyways of a single 357 // entry. 358 logic flash_rdy; 359 always_ff @(posedge clk_i or negedge rst_ni) begin 360 1/1 if (!rst_ni) begin Tests: T1 T2 T3  361 1/1 alloc_q <= '0; Tests: T1 T2 T3  362 1/1 rd_attrs <= '0; Tests: T1 T2 T3  363 1/1 rd_busy <= '0; Tests: T1 T2 T3  364 1/1 end else if (rd_start) begin Tests: T1 T2 T3  365 1/1 rd_busy <= 1'b1; Tests: T16 T8 T17  366 1/1 alloc_q <= alloc; Tests: T16 T8 T17  367 1/1 rd_attrs.addr <= addr_i[BusBankAddrW-1:LsbAddrBit]; Tests: T16 T8 T17  368 1/1 rd_attrs.descramble <= descramble_i; Tests: T16 T8 T17  369 1/1 rd_attrs.ecc <= ecc_i; Tests: T16 T8 T17  370 371 1/1 end else if (rd_done) begin Tests: T1 T2 T3  372 1/1 rd_busy <= 1'b0; Tests: T16 T8 T17  373 end MISSING_ELSE 374 end 375 376 // flash is ready to accept another transaction 377 1/1 assign flash_rdy = ~rd_busy | rd_done; Tests: T1 T2 T3  378 379 // read stages are ready when both the response fifo and the 380 // data / mask fifos have space for new entries 381 logic rd_stages_rdy; 382 1/1 assign rd_stages_rdy = rsp_fifo_rdy & scramble_stage_rdy; Tests: T1 T2 T3  383 384 // When buffer enable changes, we want to hold off new requests 385 // until the request is absorbed. buf_en_q is allowed to change 386 // only when the entire read pipeline is idle, however, during that 387 // same cycle there could be a new incoming request. 388 // 389 // We back pressure here instead of waiting for a period of idle + no 390 // request because it potentially means a storm of accesses could 391 // prevent the buffer enable from taking effect. 392 logic no_buf_en_change; 393 1/1 assign no_buf_en_change = (buf_en_q == buf_en_i); Tests: T1 T2 T3  394 395 // If no buffers matched, accept only if flash is ready and there is space 396 // If buffer is matched, accept as long as there is space in the rsp fifo 397 // If all buffers are currently allocated or have a dependency, wait until 398 // at least 1 dependency has cleared. 399 1/1 assign rdy_o = (no_match ? ack_i & flash_rdy & rd_stages_rdy : rd_stages_rdy) & Tests: T1 T2 T3  400 ~all_buf_dependency & no_buf_en_change & 401 // If the current read requires descrambling, wait for the 402 // mask calculation to finish before accepting the next request. 403 (calc_req_o ? calc_req_done : 1'b1); 404 405 // issue a transaction to flash only if there is space in read stages, 406 // there is no buffer match and flash is not currently busy. 407 1/1 assign req_o = req_i & no_buf_en_change & flash_rdy & rd_stages_rdy & no_match & Tests: T1 T2 T3  408 // If the current read requires descrambling, wait for the 409 // mask calculation to finish before accepting the next request. 410 (calc_req_o ? calc_req_done : 1'b1); 411 412 ///////////////////////////////// 413 // Handling Reliability ECC 414 ///////////////////////////////// 415 416 // only uncorrectable errors are passed on to the fabric 417 logic data_err; 418 419 // scrambled data must pass through ECC first 420 logic valid_ecc; 421 logic ecc_multi_err; 422 logic ecc_single_err; 423 logic [PlainDataWidth-1:0] data_ecc_chk; 424 logic [PlainDataWidth-1:0] data_int; 425 logic data_erased; 426 427 // this ECC check is for reliability ECC 428 1/1 assign valid_ecc = rd_done && rd_attrs.ecc; Tests: T1 T2 T3  429 430 // When all bits are 1, the data has been erased 431 // This check is only valid when read data returns. 432 1/1 assign data_erased = rd_done & (data_i == {FullDataWidth{1'b1}}); Tests: T1 T2 T3  433 434 prim_secded_hamming_76_68_dec u_dec ( 435 .data_i(data_i), 436 .data_o(data_ecc_chk), 437 .syndrome_o(), 438 .err_o({ecc_multi_err, ecc_single_err}) 439 ); 440 441 // send out error indication when ecc is enabled 442 1/1 assign data_err = valid_ecc & ecc_multi_err; Tests: T1 T2 T3  443 444 // reliability ECC errors cause both in-band and out-of-band errors 445 1/1 assign relbl_ecc_err_o = data_err; Tests: T1 T2 T3  446 447 // If there is a detected multi-bit error or a single bit error, always return the 448 // ECC corrected result (even though it is possibly wrong). 449 // There is no data error of any kind (specifically when multi_err is disabled), just 450 // return the raw data so that it can be debugged. 451 1/1 assign data_int = data_err | ecc_single_err_o ? Tests: T1 T2 T3  452 data_ecc_chk : 453 data_i[PlainDataWidth-1:0]; 454 455 // send out error indication when ecc is enabled 456 1/1 assign ecc_single_err_o = valid_ecc & ecc_single_err; Tests: T1 T2 T3  457 458 // ecc address return is always the full flash word 459 1/1 assign ecc_addr_o = {rd_attrs.addr, {LsbAddrBit{1'b0}}}; Tests: T1 T2 T3  460 461 ///////////////////////////////// 462 // De-scrambling stage 463 ///////////////////////////////// 464 465 // Even on ECC error, progress through the stage normally 466 467 logic fifo_data_ready; 468 logic fifo_data_valid; 469 logic fifo_forward_pop; 470 logic rd_and_mask_fifo_pop; 471 logic mask_valid; 472 logic [PlainDataWidth-1:0] fifo_data; 473 logic [DataWidth-1:0] mask; 474 logic addr_xor_fifo_rdy; 475 logic [BankAddrW-1:0] fifo_addr_xor; 476 logic data_fifo_rdy; 477 logic mask_fifo_rdy; 478 logic descram; 479 logic dropmsk; 480 logic forward; 481 logic descram_q; 482 logic dropmsk_q; 483 logic forward_q; 484 logic hint_forward; 485 logic hint_dropmsk; 486 logic hint_descram; 487 logic data_err_q; 488 logic [NumBuf-1:0] alloc_q2; 489 logic [1:0] unused_rd_depth, unused_mask_depth, unused_addr_xor_depth; 490 491 1/1 assign scramble_stage_rdy = data_fifo_rdy & mask_fifo_rdy & addr_xor_fifo_rdy; Tests: T1 T2 T3  492 493 // descramble is only required if the location is scramble enabled AND it is not erased. 494 1/1 assign descram = rd_done & rd_attrs.descramble & ~data_erased; Tests: T1 T2 T3  495 496 // If the location is scramble enabled but has been erased, we'll need to drop the computed mask. 497 1/1 assign dropmsk = rd_done & rd_attrs.descramble & data_erased; Tests: T1 T2 T3  498 499 // data is forwarded whenever it does not require descrambling and there are no entries in the 500 // FIFO to ensure the current read cannot run ahead of the descramble. 501 1/1 assign forward = rd_done & ~descram & ~fifo_data_valid; Tests: T1 T2 T3  502 503 1/1 assign hint_descram = fifo_data_valid & descram_q; Tests: T1 T2 T3  504 1/1 assign hint_dropmsk = fifo_data_valid & dropmsk_q; Tests: T1 T2 T3  505 1/1 assign hint_forward = fifo_data_valid & forward_q; Tests: T1 T2 T3  506 507 // Data is consumed when: 508 // 1. If the location is scramble enabled: 509 // a) When descrambling completes. 510 // b) As soon as the mask computation finishes, in case the mask is to be dropped. 511 // 2. If the location is not scramble enabled: 512 // - As soon as the data is ready from the FIFO. For the forwarding case, see below. 513 1/1 assign fifo_data_ready = hint_descram ? descramble_req_o & descramble_ack_i : Tests: T1 T2 T3  514 hint_dropmsk ? mask_valid : fifo_data_valid; 515 516 // In the case of forwarding, the storage FIFOs are bypassed but still pushed. Once the forwarded 517 // entries arrive at the output of the read FIFO, we need to drop them. If a mask has been 518 // computed that is not used (e.g. because of erasing a location that is scramble enabled), wait 519 // for the mask computation to be done and then drop the forwarded data together with the 520 // corresponding mask. 521 1/1 assign fifo_forward_pop = hint_forward & (hint_dropmsk ? mask_valid : 1'b1); Tests: T1 T2 T3  522 523 1/1 assign rd_and_mask_fifo_pop = fifo_data_ready | fifo_forward_pop; Tests: T1 T2 T3  524 525 // See comment above on how FIFO popping can be improved in the future 526 logic rd_stage_fifo_err; 527 prim_fifo_sync #( 528 .Width (PlainDataWidth + 4 + NumBuf), 529 .Pass (0), 530 .Depth (2), 531 .OutputZeroIfEmpty (1), 532 .Secure (1'b1) // SEC_CM: FIFO.CTR.REDUN 533 ) u_rd_storage ( 534 .clk_i, 535 .rst_ni, 536 .clr_i (1'b0), 537 .wvalid_i(rd_done), 538 .wready_o(data_fifo_rdy), 539 .wdata_i ({alloc_q, descram, dropmsk, forward, data_err, data_int}), 540 .depth_o (unused_rd_depth), 541 .full_o (), 542 .rvalid_o(fifo_data_valid), 543 .rready_i(rd_and_mask_fifo_pop), 544 .rdata_o ({alloc_q2, descram_q, dropmsk_q, forward_q, data_err_q, fifo_data}), 545 .err_o (rd_stage_fifo_err) 546 ); 547 548 // storage for mask calculations 549 prim_fifo_sync #( 550 .Width (DataWidth), 551 .Pass (0), 552 .Depth (2), 553 .OutputZeroIfEmpty (1) 554 ) u_mask_storage ( 555 .clk_i, 556 .rst_ni, 557 .clr_i (1'b0), 558 .wvalid_i(calc_req_done), 559 .wready_o(mask_fifo_rdy), 560 .wdata_i (mask_i), 561 .depth_o (unused_mask_depth), 562 .full_o (), 563 .rvalid_o(mask_valid), 564 .rready_i(rd_and_mask_fifo_pop), 565 .rdata_o (mask), 566 .err_o () 567 ); 568 569 prim_fifo_sync #( 570 .Width (BankAddrW), 571 .Pass (0), 572 .Depth (RspOrderDepth), 573 .OutputZeroIfEmpty (1) 574 ) u_addr_xor_storage ( 575 .clk_i, 576 .rst_ni, 577 .clr_i (1'b0), 578 .wvalid_i(rsp_order_fifo_wr), 579 .wready_o(addr_xor_fifo_rdy), 580 .wdata_i (flash_word_addr), 581 .depth_o (unused_addr_xor_depth), 582 .full_o (), 583 .rvalid_o(), 584 .rready_i(data_valid_o), 585 .rdata_o (fifo_addr_xor), 586 .err_o () 587 ); 588 589 // generate the mask calculation request 590 // mask calculation is done in parallel to the read stage 591 // calc_req_o is done after req_o is accepted so that most of the 592 // cycle can be allocated to mask calculation logic. req_o, 593 // unlike calc_req_o, asserts the same cycle the transaction is 594 // received, so much of the timing may have already been lost to 595 // transaction routing. 596 logic calc_req_start; 597 1/1 assign calc_req_start = req_o & ack_i & descramble_i; Tests: T1 T2 T3  598 1/1 assign calc_req_done = calc_req_o & calc_ack_i; Tests: T1 T2 T3  599 always_ff @(posedge clk_i or negedge rst_ni) begin 600 1/1 if (!rst_ni) begin Tests: T1 T2 T3  601 1/1 calc_req_o <= '0; Tests: T1 T2 T3  602 1/1 end else if (calc_req_start) begin Tests: T1 T2 T3  603 1/1 calc_req_o <= 1'b1; Tests: T16 T10 T11  604 1/1 end else if (calc_req_done) begin Tests: T1 T2 T3  605 1/1 calc_req_o <= 1'b0; Tests: T16 T10 T11  606 end MISSING_ELSE 607 end 608 609 // operand to gf_mult 610 1/1 assign calc_addr_o = rd_attrs.addr; Tests: T1 T2 T3  611 612 // generate the descramble request whenever both stages are available 613 // and there is a need to descramble 614 1/1 assign descramble_req_o = fifo_data_valid & mask_valid & hint_descram; Tests: T1 T2 T3  615 616 // scrambled data to de-scramble 617 1/1 assign scrambled_data_o = fifo_data[DataWidth-1:0] ^ mask; Tests: T1 T2 T3  618 619 // muxed responses 620 // When "forward" is true, there is nothing ahead in the pipeline, directly feed data 621 // and error forward. 622 // When "forward" is not true, take the output from the descramble stage, which is 623 // dependent on the scramble hint. 624 1/1 assign muxed_data = forward ? data_int : Tests: T1 T2 T3  625 hint_descram ? {fifo_data[PlainDataWidth-1 -: PlainIntgWidth], 626 descrambled_data_i ^ mask} : 627 fifo_data; 628 1/1 assign muxed_err = forward ? data_err : Tests: T1 T2 T3  629 ~hint_forward ? data_err_q : '0; 630 631 // muxed data valid 632 // if no de-scramble required, return data on read complete 633 // if data is all empty (erased), also return data on read complete 634 // if descramble is required, return data when descrambler finishes 635 // if descramble is not required, but there are transactions ahead, return from fifo when ready 636 1/1 assign data_valid = forward | ~hint_forward & fifo_data_ready; Tests: T1 T2 T3  637 638 639 ///////////////////////////////// 640 // Response 641 ///////////////////////////////// 642 643 logic flash_rsp_match; 644 logic [NumBuf-1:0] buf_rsp_match; 645 logic [PlainDataWidth-1:0] buf_rsp_data; 646 logic [BankAddrW-1:0] buf_addr_xor; 647 logic buf_rsp_err; 648 649 650 // update buffers 651 // When forwarding, update entry stored in alloc_q 652 // When de-scrambling however, the contents of alloc_q may have already updated to the next read, 653 // so a different pointer is used. 654 1/1 assign update = forward ? alloc_q : Tests: T1 T2 T3  655 ~hint_forward & fifo_data_ready ? alloc_q2 : '0; 656 657 // match in flash response when allocated buffer is the same as top of response fifo 658 // if read buffers are not enabled, do not check buffer selection 659 1/1 assign flash_rsp_match = rsp_fifo_vld & data_valid & Tests: T1 T2 T3  660 (~buf_en_q | rsp_fifo_rdata.buf_sel == update); 661 662 // match in buf response when there is a valid buffer that is the same as top of response fifo 663 for (genvar i = 0; i < NumBuf; i++) begin: gen_buf_rsp_match 664 4/4 assign buf_rsp_match[i] = buf_en_q & rsp_fifo_vld & Tests: T1 T2 T3  | T1 T2 T3  | T1 T2 T3  | T1 T2 T3  665 (rsp_fifo_rdata.buf_sel[i] & buf_valid[i]); 666 end 667 668 // select among the buffers 669 always_comb begin 670 1/1 buf_rsp_data = muxed_data; Tests: T1 T2 T3  671 1/1 buf_rsp_err = '0; Tests: T1 T2 T3  672 1/1 buf_addr_xor = '0; Tests: T1 T2 T3  673 1/1 for (int i = 0; i < NumBuf; i++) begin Tests: T1 T2 T3  674 1/1 if (buf_rsp_match[i]) begin Tests: T1 T2 T3  675 1/1 buf_rsp_data = read_buf[i].data; Tests: T16 T8 T17  676 1/1 buf_addr_xor = read_buf[i].addr; Tests: T16 T8 T17  677 1/1 buf_rsp_err = buf_rsp_err | read_buf[i].err; Tests: T16 T8 T17  678 end MISSING_ELSE 679 end 680 end 681 682 logic [PlainDataWidth-1:0] data_out_muxed; 683 1/1 assign data_out_muxed = |buf_rsp_match ? buf_rsp_data : muxed_data; Tests: T1 T2 T3  684 685 logic [BusFullWidth-1:0] data_out_intg; 686 if (WidthMultiple == 1) begin : gen_width_one_rd 687 // When multiple is 1, just pass the read through directly 688 logic unused_word_sel; 689 690 // use the tlul integrity module directly for bus integrity 691 // SEC_CM: MEM.BUS.INTEGRITY 692 tlul_data_integ_enc u_bus_intg ( 693 .data_i(data_out_muxed[DataWidth-1:0]), 694 .data_intg_o(data_out_intg) 695 ); 696 697 assign unused_word_sel = rsp_fifo_rdata.word_sel; 698 699 end else begin : gen_rd 700 // Re-arrange data into packed array to pick the correct one 701 logic [WidthMultiple-1:0][BusWidth-1:0] bus_words_packed; 702 logic [WidthMultiple-1:0][BusFullWidth-1:0] bus_words_packed_intg; 703 logic [WidthMultiple-1:0][BusFullWidth-1:0] bus_words_packed_intg_buf; 704 1/1 assign bus_words_packed = data_out_muxed[DataWidth-1:0]; Tests: T1 T2 T3  705 706 for (genvar i = 0; i < WidthMultiple; i++) begin: gen_bus_words_intg 707 // use the tlul integrity module directly for bus integrity 708 // SEC_CM: MEM.BUS.INTEGRITY 709 tlul_data_integ_enc u_bus_intg ( 710 .data_i(bus_words_packed[i]), 711 .data_intg_o(bus_words_packed_intg[i]) 712 ); 713 714 // This primitive is used to place a size-only constraint on the 715 // buffers to act as a synthesis optimization barrier. 716 prim_buf #( 717 .Width(BusFullWidth) 718 ) u_prim_buf_intg ( 719 .in_i(bus_words_packed_intg[i]), 720 .out_o(bus_words_packed_intg_buf[i]) 721 ); 722 end 723 // Mux based on selected word. 724 1/1 assign data_out_intg = bus_words_packed_intg_buf[rsp_fifo_rdata.word_sel]; Tests: T1 T2 T3  725 726 end 727 728 // On a data_err_o, send back '1 with data integrity tag on top of this data. 729 logic [BusFullWidth-1:0] inv_data_integ; 730 tlul_data_integ_enc u_bus_inv_data_intg ( 731 .data_i({BusWidth{1'b1}}), 732 .data_intg_o(inv_data_integ) 733 ); 734 735 logic [BusFullWidth-1:0] data_out_pre_xor; 736 1/1 assign data_out_pre_xor = data_err_o ? inv_data_integ : data_out_intg; Tests: T1 T2 T3  737 738 1/1 assign data_ctrl_o = data_out_pre_xor; Tests: T1 T2 T3  739 740 logic [BusBankAddrW-1:0] addr_xor_muxed; 741 logic [BusBankAddrW-1:0] fifo_addr_xor_muxed; 742 logic [BusBankAddrW-1:0] buf_addr_xor_muxed; 743 744 1/1 assign fifo_addr_xor_muxed = {fifo_addr_xor, rsp_fifo_rdata.word_sel}; Tests: T1 T2 T3  745 1/1 assign buf_addr_xor_muxed = {buf_addr_xor, rsp_fifo_rdata.word_sel}; Tests: T1 T2 T3  746 747 1/1 assign addr_xor_muxed = |buf_rsp_match ? buf_addr_xor_muxed : fifo_addr_xor_muxed; Tests: T1 T2 T3  748 749 logic [BusWidth-1:0] data_out_xor; 750 logic [BusWidth-1:0] data_out_xor_buf; 751 1/1 assign data_out_xor = Tests: T1 T2 T3  752 data_out_pre_xor[BusWidth-1:0] ^ {{(BusWidth-BusBankAddrW){1'b0}}, addr_xor_muxed}; 753 754 // Buffer to ensure that synthesis tool does not optimize the XOR. 755 prim_buf #( 756 .Width(BusWidth) 757 ) u_prim_buf_data_xor_out ( 758 .in_i(data_out_xor), 759 .out_o(data_out_xor_buf) 760 ); 761 762 1/1 assign data_host_o = {data_out_pre_xor[BusFullWidth-1:BusWidth], data_out_xor_buf}; Tests: T1 T2 T3  763 764 // add plaintext decoding here 765 // plaintext error 766 logic intg_err_pre, intg_err; 767 logic [DataWidth-1:0] unused_data; 768 logic [3:0] unused_intg; 769 logic [3:0] truncated_intg; 770 771 prim_secded_hamming_72_64_enc u_plain_enc ( 772 .data_i(data_out_muxed[DataWidth-1:0]), 773 .data_o({unused_intg, truncated_intg, unused_data}) 774 ); 775 1/1 assign intg_err_pre = rsp_fifo_rdata.intg_ecc_en ? Tests: T1 T2 T3  776 truncated_intg != data_out_muxed[DataWidth +: PlainIntgWidth] : 777 '0; 778 779 prim_sec_anchor_buf #( 780 .Width(1) 781 ) u_intg_buf ( 782 .in_i(intg_err_pre), 783 .out_o(intg_err) 784 ); 785 786 // whenever the response is coming from the buffer, the error is never set 787 1/1 assign data_valid_o = flash_rsp_match | (|buf_rsp_match); Tests: T1 T2 T3  788 789 // integrity and reliability ECC errors always cause in band errors 790 1/1 assign data_err_o = data_valid_o & (muxed_err | intg_err | (|buf_rsp_match & buf_rsp_err)) | Tests: T1 T2 T3  791 arb_err_i; 792 793 // integrity ECC error can also cause out of band alert 794 1/1 assign intg_ecc_err_o = data_valid_o & intg_err; Tests: T1 T2 T3  795 796 // the entire read pipeline is idle when there are no responses to return and no 797 1/1 assign idle_o = ~rsp_fifo_vld; Tests: T1 T2 T3  798 799 // if any fifo shows an integrity error 800 1/1 assign fifo_err_o = |{rsp_order_fifo_err, rd_stage_fifo_err}; Tests: T1 T2 T3 

Cond Coverage for Instance : tb.dut.u_eflash.gen_flash_cores[1].u_core.u_rd
TotalCoveredPercent
Conditions45840989.30
Logical45840989.30
Non-Logical00
Event00

This module contains a very large number of conditions, so the report has been split into multiple pages, by source line number. Click on the line number range in the table below to see the condition coverage for that section of the module.
Line numbersPercent
140-45692.31
491-79481.95

Branch Coverage for Instance : tb.dut.u_eflash.gen_flash_cores[1].u_core.u_rd
Line No.TotalCoveredPercent
Branches 43 43 100.00
TERNARY 186 2 2 100.00
TERNARY 232 2 2 100.00
TERNARY 302 2 2 100.00
TERNARY 451 2 2 100.00
TERNARY 513 3 3 100.00
TERNARY 624 3 3 100.00
TERNARY 628 3 3 100.00
TERNARY 654 3 3 100.00
TERNARY 683 2 2 100.00
TERNARY 736 2 2 100.00
TERNARY 747 2 2 100.00
TERNARY 775 2 2 100.00
TERNARY 167 2 2 100.00
IF 257 3 3 100.00
IF 360 4 4 100.00
IF 600 4 4 100.00
IF 674 2 2 100.00


186 assign buf_alloc = |buf_invalid_alloc ? buf_invalid_alloc : buf_valid_alloc; -1- ==> ==>

Branches:
-1-StatusTests
1 Covered T1,T2,T3
0 Covered T16,T8,T17


232 assign alloc = no_match ? {NumBuf{req_i & buf_en_q}} & buf_alloc : '0; -1- ==> ==>

Branches:
-1-StatusTests
1 Covered T1,T2,T3
0 Covered T16,T8,T17


302 assign rsp_fifo_wdata.buf_sel = |alloc ? buf_alloc : buf_match; -1- ==> ==>

Branches:
-1-StatusTests
1 Covered T16,T8,T17
0 Covered T1,T2,T3


451 assign data_int = data_err | ecc_single_err_o ? -1- ==> ==>

Branches:
-1-StatusTests
1 Covered T36,T51,T52
0 Covered T1,T2,T3


513 assign fifo_data_ready = hint_descram ? descramble_req_o & descramble_ack_i : -1- ==> 514 hint_dropmsk ? mask_valid : fifo_data_valid; -2- ==> ==>

Branches:
-1--2-StatusTests
1 - Covered T16,T34,T27
0 1 Covered T10,T11,T19
0 0 Covered T1,T2,T3


624 assign muxed_data = forward ? data_int : -1- ==> 625 hint_descram ? {fifo_data[PlainDataWidth-1 -: PlainIntgWidth], -2- ==> ==>

Branches:
-1--2-StatusTests
1 - Covered T8,T17,T10
0 1 Covered T16,T34,T27
0 0 Covered T1,T2,T3


628 assign muxed_err = forward ? data_err : -1- ==> 629 ~hint_forward ? data_err_q : '0; -2- ==> ==>

Branches:
-1--2-StatusTests
1 - Covered T8,T17,T10
0 1 Covered T1,T2,T3
0 0 Covered T8,T17,T10


654 assign update = forward ? alloc_q : -1- ==> 655 ~hint_forward & fifo_data_ready ? alloc_q2 : '0; -2- ==> ==>

Branches:
-1--2-StatusTests
1 - Covered T8,T17,T10
0 1 Covered T16,T34,T27
0 0 Covered T1,T2,T3


683 assign data_out_muxed = |buf_rsp_match ? buf_rsp_data : muxed_data; -1- ==> ==>

Branches:
-1-StatusTests
1 Covered T16,T8,T17
0 Covered T1,T2,T3


736 assign data_out_pre_xor = data_err_o ? inv_data_integ : data_out_intg; -1- ==> ==>

Branches:
-1-StatusTests
1 Covered T64,T61,T39
0 Covered T1,T2,T3


747 assign addr_xor_muxed = |buf_rsp_match ? buf_addr_xor_muxed : fifo_addr_xor_muxed; -1- ==> ==>

Branches:
-1-StatusTests
1 Covered T16,T8,T17
0 Covered T1,T2,T3


775 assign intg_err_pre = rsp_fifo_rdata.intg_ecc_en ? -1- ==> ==>

Branches:
-1-StatusTests
1 Covered T16,T17,T10
0 Covered T1,T2,T3


167 ) u_valid_random ( 168 .clk_i, 169 .rst_ni, 170 .req_chk_i(1'b0), // Valid is allowed to drop without ready. 171 // If there is an invalid buffer, always allocate from that one first 172 // If all buffers have a dependency to an in-flight transaction, do not 173 // allocate and wait for the dependencies to end. 174 // If none of the above are true, THEN pick a buffer from the current valid 175 // buffers that DO NOT have an ongoing dependency. 176 .req_i(|buf_invalid_alloc | all_buf_dependency ? '0 : buf_valid & ~buf_dependency), -1- ==> ==>

Branches:
-1-StatusTests
1 Covered T1,T2,T3
0 Covered T16,T8,T17


257 if (!rst_ni) begin -1- 258 buf_en_q <= 1'b0; ==> 259 end else if (idle_o) begin -2- 260 buf_en_q <= buf_en_i; ==> 261 end MISSING_ELSE ==>

Branches:
-1--2-StatusTests
1 - Covered T1,T2,T3
0 1 Covered T1,T2,T3
0 0 Covered T16,T8,T17


360 if (!rst_ni) begin -1- 361 alloc_q <= '0; ==> 362 rd_attrs <= '0; 363 rd_busy <= '0; 364 end else if (rd_start) begin -2- 365 rd_busy <= 1'b1; ==> 366 alloc_q <= alloc; 367 rd_attrs.addr <= addr_i[BusBankAddrW-1:LsbAddrBit]; 368 rd_attrs.descramble <= descramble_i; 369 rd_attrs.ecc <= ecc_i; 370 371 end else if (rd_done) begin -3- 372 rd_busy <= 1'b0; ==> 373 end MISSING_ELSE ==>

Branches:
-1--2--3-StatusTests
1 - - Covered T1,T2,T3
0 1 - Covered T16,T8,T17
0 0 1 Covered T16,T8,T17
0 0 0 Covered T1,T2,T3


600 if (!rst_ni) begin -1- 601 calc_req_o <= '0; ==> 602 end else if (calc_req_start) begin -2- 603 calc_req_o <= 1'b1; ==> 604 end else if (calc_req_done) begin -3- 605 calc_req_o <= 1'b0; ==> 606 end MISSING_ELSE ==>

Branches:
-1--2--3-StatusTests
1 - - Covered T1,T2,T3
0 1 - Covered T16,T10,T11
0 0 1 Covered T16,T10,T11
0 0 0 Covered T1,T2,T3


674 if (buf_rsp_match[i]) begin -1- 675 buf_rsp_data = read_buf[i].data; ==> 676 buf_addr_xor = read_buf[i].addr; 677 buf_rsp_err = buf_rsp_err | read_buf[i].err; 678 end MISSING_ELSE ==>

Branches:
-1-StatusTests
1 Covered T16,T8,T17
0 Covered T1,T2,T3


Assert Coverage for Instance : tb.dut.u_eflash.gen_flash_cores[1].u_core.u_rd
TotalAttemptedPercentSucceeded/MatchedPercent
Assertions 11 11 100.00 11 100.00
Cover properties 0 0 0
Cover sequences 0 0 0
Total 11 11 100.00 11 100.00




Assertion Details

NameAttemptsReal SuccessesFailuresIncomplete
BufferMatchEcc_A 332875393 683398 0 0
ExclusiveOps_A 332875393 332008659 0 0
ExclusiveProgHazard_A 332875393 332008659 0 0
ExclusiveState_A 332875393 332008659 0 0
ForwardCheck_A 332875393 1673032 0 0
IdleCheck_A 332875393 48054797 0 0
MaxBufs_A 1026 1026 0 0
OneHotAlloc_A 332875393 332008659 0 0
OneHotMatch_A 332875393 332008659 0 0
OneHotRspMatch_A 332875393 332008659 0 0
OneHotUpdate_A 332875393 332008659 0 0


BufferMatchEcc_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 332875393 683398 0 0
T6 873 0 0 0
T8 51282 282 0 0
T9 2110 0 0 0
T10 1263 0 0 0
T11 468 0 0 0
T16 1834 72 0 0
T17 1845 72 0 0
T19 0 19 0 0
T20 1105 0 0 0
T24 0 18 0 0
T27 0 23 0 0
T28 0 616 0 0
T33 1654 0 0 0
T34 0 6 0 0
T36 0 186 0 0
T59 1169 0 0 0
T64 0 74 0 0

ExclusiveOps_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 332875393 332008659 0 0
T1 1475 1361 0 0
T2 3694 3600 0 0
T3 2283 2194 0 0
T4 4375 3852 0 0
T5 1250 1151 0 0
T6 873 776 0 0
T8 51282 51232 0 0
T15 949 886 0 0
T16 1834 1745 0 0
T17 1845 1746 0 0

ExclusiveProgHazard_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 332875393 332008659 0 0
T1 1475 1361 0 0
T2 3694 3600 0 0
T3 2283 2194 0 0
T4 4375 3852 0 0
T5 1250 1151 0 0
T6 873 776 0 0
T8 51282 51232 0 0
T15 949 886 0 0
T16 1834 1745 0 0
T17 1845 1746 0 0

ExclusiveState_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 332875393 332008659 0 0
T1 1475 1361 0 0
T2 3694 3600 0 0
T3 2283 2194 0 0
T4 4375 3852 0 0
T5 1250 1151 0 0
T6 873 776 0 0
T8 51282 51232 0 0
T15 949 886 0 0
T16 1834 1745 0 0
T17 1845 1746 0 0

ForwardCheck_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 332875393 1673032 0 0
T6 873 0 0 0
T8 51282 338 0 0
T9 2110 0 0 0
T10 1263 5 0 0
T11 468 2 0 0
T17 1845 74 0 0
T19 0 116 0 0
T20 1105 0 0 0
T24 0 21 0 0
T27 0 31 0 0
T28 0 616 0 0
T33 1654 0 0 0
T34 0 6 0 0
T36 0 186 0 0
T59 1169 0 0 0
T66 1241 0 0 0

IdleCheck_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 332875393 48054797 0 0
T6 873 0 0 0
T8 51282 958 0 0
T9 2110 0 0 0
T10 1263 10 0 0
T11 468 4 0 0
T16 1834 368 0 0
T17 1845 220 0 0
T19 0 251 0 0
T20 1105 0 0 0
T27 0 109 0 0
T33 1654 0 0 0
T34 0 26 0 0
T36 0 558 0 0
T59 1169 0 0 0
T64 0 178 0 0

MaxBufs_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 1026 1026 0 0
T1 1 1 0 0
T2 1 1 0 0
T3 1 1 0 0
T4 1 1 0 0
T5 1 1 0 0
T6 1 1 0 0
T8 1 1 0 0
T15 1 1 0 0
T16 1 1 0 0
T17 1 1 0 0

OneHotAlloc_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 332875393 332008659 0 0
T1 1475 1361 0 0
T2 3694 3600 0 0
T3 2283 2194 0 0
T4 4375 3852 0 0
T5 1250 1151 0 0
T6 873 776 0 0
T8 51282 51232 0 0
T15 949 886 0 0
T16 1834 1745 0 0
T17 1845 1746 0 0

OneHotMatch_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 332875393 332008659 0 0
T1 1475 1361 0 0
T2 3694 3600 0 0
T3 2283 2194 0 0
T4 4375 3852 0 0
T5 1250 1151 0 0
T6 873 776 0 0
T8 51282 51232 0 0
T15 949 886 0 0
T16 1834 1745 0 0
T17 1845 1746 0 0

OneHotRspMatch_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 332875393 332008659 0 0
T1 1475 1361 0 0
T2 3694 3600 0 0
T3 2283 2194 0 0
T4 4375 3852 0 0
T5 1250 1151 0 0
T6 873 776 0 0
T8 51282 51232 0 0
T15 949 886 0 0
T16 1834 1745 0 0
T17 1845 1746 0 0

OneHotUpdate_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 332875393 332008659 0 0
T1 1475 1361 0 0
T2 3694 3600 0 0
T3 2283 2194 0 0
T4 4375 3852 0 0
T5 1250 1151 0 0
T6 873 776 0 0
T8 51282 51232 0 0
T15 949 886 0 0
T16 1834 1745 0 0
T17 1845 1746 0 0

Line Coverage for Instance : tb.dut.u_eflash.gen_flash_cores[0].u_core.u_rd
Line No.TotalCoveredPercent
TOTAL133133100.00
CONT_ASSIGN13711100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14111100.00
CONT_ASSIGN14111100.00
CONT_ASSIGN14111100.00
CONT_ASSIGN14111100.00
CONT_ASSIGN14611100.00
CONT_ASSIGN14611100.00
CONT_ASSIGN14611100.00
CONT_ASSIGN14611100.00
CONT_ASSIGN15211100.00
CONT_ASSIGN15411100.00
CONT_ASSIGN15411100.00
CONT_ASSIGN15411100.00
CONT_ASSIGN18611100.00
CONT_ASSIGN19311100.00
CONT_ASSIGN19311100.00
CONT_ASSIGN19311100.00
CONT_ASSIGN19311100.00
CONT_ASSIGN19411100.00
CONT_ASSIGN19411100.00
CONT_ASSIGN19411100.00
CONT_ASSIGN19411100.00
CONT_ASSIGN19611100.00
CONT_ASSIGN19611100.00
CONT_ASSIGN19611100.00
CONT_ASSIGN19611100.00
CONT_ASSIGN21211100.00
CONT_ASSIGN21211100.00
CONT_ASSIGN21211100.00
CONT_ASSIGN21211100.00
CONT_ASSIGN21811100.00
CONT_ASSIGN21811100.00
CONT_ASSIGN21811100.00
CONT_ASSIGN21811100.00
CONT_ASSIGN22211100.00
CONT_ASSIGN22211100.00
CONT_ASSIGN22211100.00
CONT_ASSIGN22211100.00
CONT_ASSIGN22911100.00
CONT_ASSIGN23211100.00
ALWAYS25744100.00
CONT_ASSIGN29111100.00
CONT_ASSIGN29211100.00
CONT_ASSIGN30211100.00
CONT_ASSIGN30511100.00
CONT_ASSIGN30811100.00
CONT_ASSIGN32611100.00
CONT_ASSIGN33111100.00
ALWAYS3601212100.00
CONT_ASSIGN37711100.00
CONT_ASSIGN38211100.00
CONT_ASSIGN39311100.00
CONT_ASSIGN39911100.00
CONT_ASSIGN40711100.00
CONT_ASSIGN42811100.00
CONT_ASSIGN43211100.00
CONT_ASSIGN44211100.00
CONT_ASSIGN44511100.00
CONT_ASSIGN45111100.00
CONT_ASSIGN45611100.00
CONT_ASSIGN45911100.00
CONT_ASSIGN49111100.00
CONT_ASSIGN49411100.00
CONT_ASSIGN49711100.00
CONT_ASSIGN50111100.00
CONT_ASSIGN50311100.00
CONT_ASSIGN50411100.00
CONT_ASSIGN50511100.00
CONT_ASSIGN51311100.00
CONT_ASSIGN52111100.00
CONT_ASSIGN52311100.00
CONT_ASSIGN59711100.00
CONT_ASSIGN59811100.00
ALWAYS60066100.00
CONT_ASSIGN61011100.00
CONT_ASSIGN61411100.00
CONT_ASSIGN61711100.00
CONT_ASSIGN62411100.00
CONT_ASSIGN62811100.00
CONT_ASSIGN63611100.00
CONT_ASSIGN65411100.00
CONT_ASSIGN65911100.00
CONT_ASSIGN66411100.00
CONT_ASSIGN66411100.00
CONT_ASSIGN66411100.00
CONT_ASSIGN66411100.00
ALWAYS67088100.00
CONT_ASSIGN68311100.00
CONT_ASSIGN70411100.00
CONT_ASSIGN72411100.00
CONT_ASSIGN73611100.00
CONT_ASSIGN73811100.00
CONT_ASSIGN74411100.00
CONT_ASSIGN74511100.00
CONT_ASSIGN74711100.00
CONT_ASSIGN75111100.00
CONT_ASSIGN76211100.00
CONT_ASSIGN77511100.00
CONT_ASSIGN78711100.00
CONT_ASSIGN79011100.00
CONT_ASSIGN79411100.00
CONT_ASSIGN79711100.00
CONT_ASSIGN80011100.00

136 logic [BankAddrW-1:0] flash_word_addr; 137 1/1 assign flash_word_addr = addr_i[BusBankAddrW-1:LsbAddrBit]; Tests: T1 T2 T3  138 139 for (genvar i = 0; i < NumBuf; i++) begin: gen_buf_states 140 4/4 assign buf_valid[i] = read_buf[i].attr == Valid; Tests: T1 T2 T3  | T1 T2 T3  | T1 T2 T3  | T1 T2 T3  141 4/4 assign buf_wip[i] = read_buf[i].attr == Wip; Tests: T1 T2 T3  | T1 T2 T3  | T1 T2 T3  | T1 T2 T3  142 143 // if a buffer is valid and contains an error, it should be considered 144 // invalid as long as there are no pending responses already waiting 145 // on that buffer. 146 4/4 assign buf_invalid[i] = (read_buf[i].attr == Invalid) | Tests: T1 T2 T3  | T1 T2 T3  | T1 T2 T3  | T1 T2 T3  147 (read_buf[i].attr == Valid & 148 read_buf[i].err & 149 ~buf_dependency[i]); 150 end 151 152 1/1 assign buf_invalid_alloc[0] = buf_invalid[0]; Tests: T1 T2 T3  153 for (genvar i = 1; i < NumBuf; i++) begin: gen_inv_alloc_bufs 154 3/3 assign buf_invalid_alloc[i] = buf_invalid[i] & ~|buf_invalid[i-1:0]; Tests: T1 T2 T3  | T1 T2 T3  | T1 T2 T3  155 end 156 157 // a prim arbiter is used to somewhat fairly select among the valid buffers 158 logic [1:0] dummy_data [NumBuf]; 159 for (genvar i = 0; i < NumBuf; i++) begin: gen_dummy 160 assign dummy_data[i] = '0; 161 end 162 163 prim_arbiter_tree #( 164 .N(NumBuf), 165 .DW(2), 166 .EnDataPort(1'b0) 167 ) u_valid_random ( 168 .clk_i, 169 .rst_ni, 170 .req_chk_i(1'b0), // Valid is allowed to drop without ready. 171 // If there is an invalid buffer, always allocate from that one first 172 // If all buffers have a dependency to an in-flight transaction, do not 173 // allocate and wait for the dependencies to end. 174 // If none of the above are true, THEN pick a buffer from the current valid 175 // buffers that DO NOT have an ongoing dependency. 176 .req_i(|buf_invalid_alloc | all_buf_dependency ? '0 : buf_valid & ~buf_dependency), 177 .data_i(dummy_data), 178 .gnt_o(buf_valid_alloc), 179 .idx_o(), 180 .valid_o(), 181 .data_o(), 182 .ready_i(req_o & ack_i & no_match) 183 ); 184 185 // which buffer to allocate upon a new transaction 186 1/1 assign buf_alloc = |buf_invalid_alloc ? buf_invalid_alloc : buf_valid_alloc; Tests: T1 T2 T3  187 188 // do not attempt to generate match unless the transaction is relevant 189 for (genvar i = 0; i < NumBuf; i++) begin: gen_buf_match 190 logic part_match; 191 logic info_sel_match; 192 193 4/4 assign part_match = read_buf[i].part == part_i; Tests: T1 T2 T3  | T1 T2 T3  | T1 T2 T3  | T1 T2 T3  194 4/4 assign info_sel_match = read_buf[i].info_sel == info_sel_i; Tests: T1 T2 T3  | T1 T2 T3  | T1 T2 T3  | T1 T2 T3  195 196 4/4 assign buf_match[i] = req_i & Tests: T1 T2 T3  | T1 T2 T3  | T1 T2 T3  | T1 T2 T3  197 buf_en_q & 198 (buf_valid[i] | buf_wip[i]) & 199 (read_buf[i].addr == flash_word_addr) & 200 ~read_buf[i].err & 201 part_match & 202 info_sel_match; 203 204 // A data hazard should never happen to a wip buffer because it implies 205 // that a read is in progress, so a hazard operation cannot start. 206 // If bank erase, all buffers must be flushed. 207 // If page erase, only if the buffer lands in the same page. 208 // If program, only if it's the same flash word. 209 logic word_addr_match; 210 logic page_addr_match; 211 212 4/4 assign word_addr_match = (read_buf[i].addr == flash_word_addr) & Tests: T1 T2 T3  | T1 T2 T3  | T1 T2 T3  | T1 T2 T3  213 part_match & 214 info_sel_match; 215 216 // the read buffer address in on flash word boundary 217 // while the incoming address in on the bus word boundary 218 4/4 assign page_addr_match = (read_buf[i].addr[WordW +: PageW] == addr_i[BusWordW +: PageW]) & Tests: T1 T2 T3  | T1 T2 T3  | T1 T2 T3  | T1 T2 T3  219 part_match & 220 info_sel_match; 221 222 4/4 assign data_hazard[i] = buf_valid[i] & Tests: T1 T2 T3  | T1 T2 T3  | T1 T2 T3  | T1 T2 T3  223 (bk_erase_i | 224 (prog_i & word_addr_match) | 225 (pg_erase_i & page_addr_match)); 226 227 end 228 229 1/1 assign no_match = ~|buf_match; Tests: T1 T2 T3  230 231 // if new request does not match anything, allocate 232 1/1 assign alloc = no_match ? {NumBuf{req_i & buf_en_q}} & buf_alloc : '0; Tests: T1 T2 T3  233 234 // read buffers 235 // allocate sets state to Wip 236 // update sets state to valid 237 // wipe sets state to invalid - this comes from prog 238 for (genvar i = 0; i < NumBuf; i++) begin: gen_bufs 239 flash_phy_rd_buffers u_rd_buf ( 240 .clk_i, 241 .rst_ni, 242 .en_i(buf_en_q), 243 .alloc_i(rdy_o & alloc[i]), 244 .update_i(update[i]), 245 .err_i(muxed_err), 246 .wipe_i(data_hazard[i]), 247 .addr_i(flash_word_addr), 248 .part_i(part_i), 249 .info_sel_i(info_sel_i), 250 .data_i(muxed_data), 251 .out_o(read_buf[i]) 252 ); 253 end 254 255 // The buffer enable is allowed to change when the entire read pipeline is idle 256 always_ff @(posedge clk_i or negedge rst_ni) begin 257 1/1 if (!rst_ni) begin Tests: T1 T2 T3  258 1/1 buf_en_q <= 1'b0; Tests: T1 T2 T3  259 1/1 end else if (idle_o) begin Tests: T1 T2 T3  260 1/1 buf_en_q <= buf_en_i; Tests: T1 T2 T3  261 end MISSING_ELSE 262 end 263 264 ///////////////////////////////// 265 // Flash read stage 266 ///////////////////////////////// 267 268 // Flash read stage determines if the transactions are accepted. 269 // 270 // The response fifo is written to when a transaction initiates a flash read OR when a match 271 // is hit. The information written is just the allocated buffer that would have satisfied the 272 // transaction, as well as bits that indicate which part of the buffer is the right return data 273 // 274 // This allows a hit transaction to match in-order, and unblock later transactions to begin 275 // reading from the flash primitive 276 277 rsp_fifo_entry_t rsp_fifo_wdata, rsp_fifo_rdata; 278 logic rsp_fifo_rdy; 279 logic rsp_fifo_vld; 280 281 // saved attributes on flash read 282 logic [NumBuf-1:0] alloc_q; 283 rd_attr_t rd_attrs; 284 285 // read complete 286 // since done is broadcast to all the modules, need to know we are actually active 287 logic rd_start; 288 logic rd_busy; 289 logic rd_done; 290 291 1/1 assign rd_start = req_o & ack_i; Tests: T1 T2 T3  292 1/1 assign rd_done = rd_busy & done_i; Tests: T1 T2 T3  293 294 // scramble stage ready 295 logic scramble_stage_rdy; 296 297 // mask calculation done 298 logic calc_req_done; 299 300 // if buffer allocated, that is the return source 301 // if buffer matched, that is the return source 302 1/1 assign rsp_fifo_wdata.buf_sel = |alloc ? buf_alloc : buf_match; Tests: T1 T2 T3  303 304 logic rsp_order_fifo_wr; 305 1/1 assign rsp_order_fifo_wr = req_i && rdy_o; Tests: T1 T2 T3  306 307 logic rsp_order_fifo_rd; 308 1/1 assign rsp_order_fifo_rd = rsp_fifo_vld & data_valid_o; Tests: T1 T2 T3  309 310 flash_phy_rd_buf_dep u_rd_buf_dep ( 311 .clk_i, 312 .rst_ni, 313 .en_i(buf_en_q), 314 .fifo_wr_i(rsp_order_fifo_wr), 315 .fifo_rd_i(rsp_order_fifo_rd), 316 .wr_buf_i(rsp_fifo_wdata.buf_sel), 317 .rd_buf_i(rsp_fifo_rdata.buf_sel), 318 .dependency_o(buf_dependency), 319 .all_dependency_o(all_buf_dependency) 320 ); 321 322 // If width is the same, word_sel is unused 323 if (WidthMultiple == 1) begin : gen_single_word_sel 324 assign rsp_fifo_wdata.word_sel = '0; 325 end else begin : gen_word_sel 326 1/1 assign rsp_fifo_wdata.word_sel = addr_i[0 +: LsbAddrBit]; Tests: T1 T2 T3  327 end 328 329 // store the ecc configuration for this transaction until 330 // response is ready to be sent. 331 1/1 assign rsp_fifo_wdata.intg_ecc_en = ecc_i; Tests: T1 T2 T3  332 333 // response order FIFO 334 logic rsp_order_fifo_err; 335 prim_fifo_sync #( 336 .Width (RspOrderFifoWidth), 337 .Pass (0), 338 .Depth (RspOrderDepth), 339 .Secure (1'b1) // SEC_CM: FIFO.CTR.REDUN 340 ) u_rsp_order_fifo ( 341 .clk_i, 342 .rst_ni, 343 .clr_i (1'b0), 344 .wvalid_i(rsp_order_fifo_wr), 345 .wready_o(rsp_fifo_rdy), 346 .wdata_i (rsp_fifo_wdata), 347 .depth_o (), 348 .full_o (), 349 .rvalid_o(rsp_fifo_vld), 350 .rready_i(data_valid_o), // pop when a match has been found 351 .rdata_o (rsp_fifo_rdata), 352 .err_o (rsp_order_fifo_err) 353 ); 354 355 // Consider converting this to a FIFO for better matching 356 // The rd_busy flag is effectively a "full" flag anyways of a single 357 // entry. 358 logic flash_rdy; 359 always_ff @(posedge clk_i or negedge rst_ni) begin 360 1/1 if (!rst_ni) begin Tests: T1 T2 T3  361 1/1 alloc_q <= '0; Tests: T1 T2 T3  362 1/1 rd_attrs <= '0; Tests: T1 T2 T3  363 1/1 rd_busy <= '0; Tests: T1 T2 T3  364 1/1 end else if (rd_start) begin Tests: T1 T2 T3  365 1/1 rd_busy <= 1'b1; Tests: T1 T2 T3  366 1/1 alloc_q <= alloc; Tests: T1 T2 T3  367 1/1 rd_attrs.addr <= addr_i[BusBankAddrW-1:LsbAddrBit]; Tests: T1 T2 T3  368 1/1 rd_attrs.descramble <= descramble_i; Tests: T1 T2 T3  369 1/1 rd_attrs.ecc <= ecc_i; Tests: T1 T2 T3  370 371 1/1 end else if (rd_done) begin Tests: T1 T2 T3  372 1/1 rd_busy <= 1'b0; Tests: T1 T2 T3  373 end MISSING_ELSE 374 end 375 376 // flash is ready to accept another transaction 377 1/1 assign flash_rdy = ~rd_busy | rd_done; Tests: T1 T2 T3  378 379 // read stages are ready when both the response fifo and the 380 // data / mask fifos have space for new entries 381 logic rd_stages_rdy; 382 1/1 assign rd_stages_rdy = rsp_fifo_rdy & scramble_stage_rdy; Tests: T1 T2 T3  383 384 // When buffer enable changes, we want to hold off new requests 385 // until the request is absorbed. buf_en_q is allowed to change 386 // only when the entire read pipeline is idle, however, during that 387 // same cycle there could be a new incoming request. 388 // 389 // We back pressure here instead of waiting for a period of idle + no 390 // request because it potentially means a storm of accesses could 391 // prevent the buffer enable from taking effect. 392 logic no_buf_en_change; 393 1/1 assign no_buf_en_change = (buf_en_q == buf_en_i); Tests: T1 T2 T3  394 395 // If no buffers matched, accept only if flash is ready and there is space 396 // If buffer is matched, accept as long as there is space in the rsp fifo 397 // If all buffers are currently allocated or have a dependency, wait until 398 // at least 1 dependency has cleared. 399 1/1 assign rdy_o = (no_match ? ack_i & flash_rdy & rd_stages_rdy : rd_stages_rdy) & Tests: T1 T2 T3  400 ~all_buf_dependency & no_buf_en_change & 401 // If the current read requires descrambling, wait for the 402 // mask calculation to finish before accepting the next request. 403 (calc_req_o ? calc_req_done : 1'b1); 404 405 // issue a transaction to flash only if there is space in read stages, 406 // there is no buffer match and flash is not currently busy. 407 1/1 assign req_o = req_i & no_buf_en_change & flash_rdy & rd_stages_rdy & no_match & Tests: T1 T2 T3  408 // If the current read requires descrambling, wait for the 409 // mask calculation to finish before accepting the next request. 410 (calc_req_o ? calc_req_done : 1'b1); 411 412 ///////////////////////////////// 413 // Handling Reliability ECC 414 ///////////////////////////////// 415 416 // only uncorrectable errors are passed on to the fabric 417 logic data_err; 418 419 // scrambled data must pass through ECC first 420 logic valid_ecc; 421 logic ecc_multi_err; 422 logic ecc_single_err; 423 logic [PlainDataWidth-1:0] data_ecc_chk; 424 logic [PlainDataWidth-1:0] data_int; 425 logic data_erased; 426 427 // this ECC check is for reliability ECC 428 1/1 assign valid_ecc = rd_done && rd_attrs.ecc; Tests: T1 T2 T3  429 430 // When all bits are 1, the data has been erased 431 // This check is only valid when read data returns. 432 1/1 assign data_erased = rd_done & (data_i == {FullDataWidth{1'b1}}); Tests: T1 T2 T3  433 434 prim_secded_hamming_76_68_dec u_dec ( 435 .data_i(data_i), 436 .data_o(data_ecc_chk), 437 .syndrome_o(), 438 .err_o({ecc_multi_err, ecc_single_err}) 439 ); 440 441 // send out error indication when ecc is enabled 442 1/1 assign data_err = valid_ecc & ecc_multi_err; Tests: T1 T2 T3  443 444 // reliability ECC errors cause both in-band and out-of-band errors 445 1/1 assign relbl_ecc_err_o = data_err; Tests: T1 T2 T3  446 447 // If there is a detected multi-bit error or a single bit error, always return the 448 // ECC corrected result (even though it is possibly wrong). 449 // There is no data error of any kind (specifically when multi_err is disabled), just 450 // return the raw data so that it can be debugged. 451 1/1 assign data_int = data_err | ecc_single_err_o ? Tests: T1 T2 T3  452 data_ecc_chk : 453 data_i[PlainDataWidth-1:0]; 454 455 // send out error indication when ecc is enabled 456 1/1 assign ecc_single_err_o = valid_ecc & ecc_single_err; Tests: T1 T2 T3  457 458 // ecc address return is always the full flash word 459 1/1 assign ecc_addr_o = {rd_attrs.addr, {LsbAddrBit{1'b0}}}; Tests: T1 T2 T3  460 461 ///////////////////////////////// 462 // De-scrambling stage 463 ///////////////////////////////// 464 465 // Even on ECC error, progress through the stage normally 466 467 logic fifo_data_ready; 468 logic fifo_data_valid; 469 logic fifo_forward_pop; 470 logic rd_and_mask_fifo_pop; 471 logic mask_valid; 472 logic [PlainDataWidth-1:0] fifo_data; 473 logic [DataWidth-1:0] mask; 474 logic addr_xor_fifo_rdy; 475 logic [BankAddrW-1:0] fifo_addr_xor; 476 logic data_fifo_rdy; 477 logic mask_fifo_rdy; 478 logic descram; 479 logic dropmsk; 480 logic forward; 481 logic descram_q; 482 logic dropmsk_q; 483 logic forward_q; 484 logic hint_forward; 485 logic hint_dropmsk; 486 logic hint_descram; 487 logic data_err_q; 488 logic [NumBuf-1:0] alloc_q2; 489 logic [1:0] unused_rd_depth, unused_mask_depth, unused_addr_xor_depth; 490 491 1/1 assign scramble_stage_rdy = data_fifo_rdy & mask_fifo_rdy & addr_xor_fifo_rdy; Tests: T1 T2 T3  492 493 // descramble is only required if the location is scramble enabled AND it is not erased. 494 1/1 assign descram = rd_done & rd_attrs.descramble & ~data_erased; Tests: T1 T2 T3  495 496 // If the location is scramble enabled but has been erased, we'll need to drop the computed mask. 497 1/1 assign dropmsk = rd_done & rd_attrs.descramble & data_erased; Tests: T1 T2 T3  498 499 // data is forwarded whenever it does not require descrambling and there are no entries in the 500 // FIFO to ensure the current read cannot run ahead of the descramble. 501 1/1 assign forward = rd_done & ~descram & ~fifo_data_valid; Tests: T1 T2 T3  502 503 1/1 assign hint_descram = fifo_data_valid & descram_q; Tests: T1 T2 T3  504 1/1 assign hint_dropmsk = fifo_data_valid & dropmsk_q; Tests: T1 T2 T3  505 1/1 assign hint_forward = fifo_data_valid & forward_q; Tests: T1 T2 T3  506 507 // Data is consumed when: 508 // 1. If the location is scramble enabled: 509 // a) When descrambling completes. 510 // b) As soon as the mask computation finishes, in case the mask is to be dropped. 511 // 2. If the location is not scramble enabled: 512 // - As soon as the data is ready from the FIFO. For the forwarding case, see below. 513 1/1 assign fifo_data_ready = hint_descram ? descramble_req_o & descramble_ack_i : Tests: T1 T2 T3  514 hint_dropmsk ? mask_valid : fifo_data_valid; 515 516 // In the case of forwarding, the storage FIFOs are bypassed but still pushed. Once the forwarded 517 // entries arrive at the output of the read FIFO, we need to drop them. If a mask has been 518 // computed that is not used (e.g. because of erasing a location that is scramble enabled), wait 519 // for the mask computation to be done and then drop the forwarded data together with the 520 // corresponding mask. 521 1/1 assign fifo_forward_pop = hint_forward & (hint_dropmsk ? mask_valid : 1'b1); Tests: T1 T2 T3  522 523 1/1 assign rd_and_mask_fifo_pop = fifo_data_ready | fifo_forward_pop; Tests: T1 T2 T3  524 525 // See comment above on how FIFO popping can be improved in the future 526 logic rd_stage_fifo_err; 527 prim_fifo_sync #( 528 .Width (PlainDataWidth + 4 + NumBuf), 529 .Pass (0), 530 .Depth (2), 531 .OutputZeroIfEmpty (1), 532 .Secure (1'b1) // SEC_CM: FIFO.CTR.REDUN 533 ) u_rd_storage ( 534 .clk_i, 535 .rst_ni, 536 .clr_i (1'b0), 537 .wvalid_i(rd_done), 538 .wready_o(data_fifo_rdy), 539 .wdata_i ({alloc_q, descram, dropmsk, forward, data_err, data_int}), 540 .depth_o (unused_rd_depth), 541 .full_o (), 542 .rvalid_o(fifo_data_valid), 543 .rready_i(rd_and_mask_fifo_pop), 544 .rdata_o ({alloc_q2, descram_q, dropmsk_q, forward_q, data_err_q, fifo_data}), 545 .err_o (rd_stage_fifo_err) 546 ); 547 548 // storage for mask calculations 549 prim_fifo_sync #( 550 .Width (DataWidth), 551 .Pass (0), 552 .Depth (2), 553 .OutputZeroIfEmpty (1) 554 ) u_mask_storage ( 555 .clk_i, 556 .rst_ni, 557 .clr_i (1'b0), 558 .wvalid_i(calc_req_done), 559 .wready_o(mask_fifo_rdy), 560 .wdata_i (mask_i), 561 .depth_o (unused_mask_depth), 562 .full_o (), 563 .rvalid_o(mask_valid), 564 .rready_i(rd_and_mask_fifo_pop), 565 .rdata_o (mask), 566 .err_o () 567 ); 568 569 prim_fifo_sync #( 570 .Width (BankAddrW), 571 .Pass (0), 572 .Depth (RspOrderDepth), 573 .OutputZeroIfEmpty (1) 574 ) u_addr_xor_storage ( 575 .clk_i, 576 .rst_ni, 577 .clr_i (1'b0), 578 .wvalid_i(rsp_order_fifo_wr), 579 .wready_o(addr_xor_fifo_rdy), 580 .wdata_i (flash_word_addr), 581 .depth_o (unused_addr_xor_depth), 582 .full_o (), 583 .rvalid_o(), 584 .rready_i(data_valid_o), 585 .rdata_o (fifo_addr_xor), 586 .err_o () 587 ); 588 589 // generate the mask calculation request 590 // mask calculation is done in parallel to the read stage 591 // calc_req_o is done after req_o is accepted so that most of the 592 // cycle can be allocated to mask calculation logic. req_o, 593 // unlike calc_req_o, asserts the same cycle the transaction is 594 // received, so much of the timing may have already been lost to 595 // transaction routing. 596 logic calc_req_start; 597 1/1 assign calc_req_start = req_o & ack_i & descramble_i; Tests: T1 T2 T3  598 1/1 assign calc_req_done = calc_req_o & calc_ack_i; Tests: T1 T2 T3  599 always_ff @(posedge clk_i or negedge rst_ni) begin 600 1/1 if (!rst_ni) begin Tests: T1 T2 T3  601 1/1 calc_req_o <= '0; Tests: T1 T2 T3  602 1/1 end else if (calc_req_start) begin Tests: T1 T2 T3  603 1/1 calc_req_o <= 1'b1; Tests: T1 T2 T3  604 1/1 end else if (calc_req_done) begin Tests: T1 T2 T3  605 1/1 calc_req_o <= 1'b0; Tests: T1 T2 T3  606 end MISSING_ELSE 607 end 608 609 // operand to gf_mult 610 1/1 assign calc_addr_o = rd_attrs.addr; Tests: T1 T2 T3  611 612 // generate the descramble request whenever both stages are available 613 // and there is a need to descramble 614 1/1 assign descramble_req_o = fifo_data_valid & mask_valid & hint_descram; Tests: T1 T2 T3  615 616 // scrambled data to de-scramble 617 1/1 assign scrambled_data_o = fifo_data[DataWidth-1:0] ^ mask; Tests: T1 T2 T3  618 619 // muxed responses 620 // When "forward" is true, there is nothing ahead in the pipeline, directly feed data 621 // and error forward. 622 // When "forward" is not true, take the output from the descramble stage, which is 623 // dependent on the scramble hint. 624 1/1 assign muxed_data = forward ? data_int : Tests: T1 T2 T3  625 hint_descram ? {fifo_data[PlainDataWidth-1 -: PlainIntgWidth], 626 descrambled_data_i ^ mask} : 627 fifo_data; 628 1/1 assign muxed_err = forward ? data_err : Tests: T1 T2 T3  629 ~hint_forward ? data_err_q : '0; 630 631 // muxed data valid 632 // if no de-scramble required, return data on read complete 633 // if data is all empty (erased), also return data on read complete 634 // if descramble is required, return data when descrambler finishes 635 // if descramble is not required, but there are transactions ahead, return from fifo when ready 636 1/1 assign data_valid = forward | ~hint_forward & fifo_data_ready; Tests: T1 T2 T3  637 638 639 ///////////////////////////////// 640 // Response 641 ///////////////////////////////// 642 643 logic flash_rsp_match; 644 logic [NumBuf-1:0] buf_rsp_match; 645 logic [PlainDataWidth-1:0] buf_rsp_data; 646 logic [BankAddrW-1:0] buf_addr_xor; 647 logic buf_rsp_err; 648 649 650 // update buffers 651 // When forwarding, update entry stored in alloc_q 652 // When de-scrambling however, the contents of alloc_q may have already updated to the next read, 653 // so a different pointer is used. 654 1/1 assign update = forward ? alloc_q : Tests: T1 T2 T3  655 ~hint_forward & fifo_data_ready ? alloc_q2 : '0; 656 657 // match in flash response when allocated buffer is the same as top of response fifo 658 // if read buffers are not enabled, do not check buffer selection 659 1/1 assign flash_rsp_match = rsp_fifo_vld & data_valid & Tests: T1 T2 T3  660 (~buf_en_q | rsp_fifo_rdata.buf_sel == update); 661 662 // match in buf response when there is a valid buffer that is the same as top of response fifo 663 for (genvar i = 0; i < NumBuf; i++) begin: gen_buf_rsp_match 664 4/4 assign buf_rsp_match[i] = buf_en_q & rsp_fifo_vld & Tests: T1 T2 T3  | T1 T2 T3  | T1 T2 T3  | T1 T2 T3  665 (rsp_fifo_rdata.buf_sel[i] & buf_valid[i]); 666 end 667 668 // select among the buffers 669 always_comb begin 670 1/1 buf_rsp_data = muxed_data; Tests: T1 T2 T3  671 1/1 buf_rsp_err = '0; Tests: T1 T2 T3  672 1/1 buf_addr_xor = '0; Tests: T1 T2 T3  673 1/1 for (int i = 0; i < NumBuf; i++) begin Tests: T1 T2 T3  674 1/1 if (buf_rsp_match[i]) begin Tests: T1 T2 T3  675 1/1 buf_rsp_data = read_buf[i].data; Tests: T3 T8 T6  676 1/1 buf_addr_xor = read_buf[i].addr; Tests: T3 T8 T6  677 1/1 buf_rsp_err = buf_rsp_err | read_buf[i].err; Tests: T3 T8 T6  678 end MISSING_ELSE 679 end 680 end 681 682 logic [PlainDataWidth-1:0] data_out_muxed; 683 1/1 assign data_out_muxed = |buf_rsp_match ? buf_rsp_data : muxed_data; Tests: T1 T2 T3  684 685 logic [BusFullWidth-1:0] data_out_intg; 686 if (WidthMultiple == 1) begin : gen_width_one_rd 687 // When multiple is 1, just pass the read through directly 688 logic unused_word_sel; 689 690 // use the tlul integrity module directly for bus integrity 691 // SEC_CM: MEM.BUS.INTEGRITY 692 tlul_data_integ_enc u_bus_intg ( 693 .data_i(data_out_muxed[DataWidth-1:0]), 694 .data_intg_o(data_out_intg) 695 ); 696 697 assign unused_word_sel = rsp_fifo_rdata.word_sel; 698 699 end else begin : gen_rd 700 // Re-arrange data into packed array to pick the correct one 701 logic [WidthMultiple-1:0][BusWidth-1:0] bus_words_packed; 702 logic [WidthMultiple-1:0][BusFullWidth-1:0] bus_words_packed_intg; 703 logic [WidthMultiple-1:0][BusFullWidth-1:0] bus_words_packed_intg_buf; 704 1/1 assign bus_words_packed = data_out_muxed[DataWidth-1:0]; Tests: T1 T2 T3  705 706 for (genvar i = 0; i < WidthMultiple; i++) begin: gen_bus_words_intg 707 // use the tlul integrity module directly for bus integrity 708 // SEC_CM: MEM.BUS.INTEGRITY 709 tlul_data_integ_enc u_bus_intg ( 710 .data_i(bus_words_packed[i]), 711 .data_intg_o(bus_words_packed_intg[i]) 712 ); 713 714 // This primitive is used to place a size-only constraint on the 715 // buffers to act as a synthesis optimization barrier. 716 prim_buf #( 717 .Width(BusFullWidth) 718 ) u_prim_buf_intg ( 719 .in_i(bus_words_packed_intg[i]), 720 .out_o(bus_words_packed_intg_buf[i]) 721 ); 722 end 723 // Mux based on selected word. 724 1/1 assign data_out_intg = bus_words_packed_intg_buf[rsp_fifo_rdata.word_sel]; Tests: T1 T2 T3  725 726 end 727 728 // On a data_err_o, send back '1 with data integrity tag on top of this data. 729 logic [BusFullWidth-1:0] inv_data_integ; 730 tlul_data_integ_enc u_bus_inv_data_intg ( 731 .data_i({BusWidth{1'b1}}), 732 .data_intg_o(inv_data_integ) 733 ); 734 735 logic [BusFullWidth-1:0] data_out_pre_xor; 736 1/1 assign data_out_pre_xor = data_err_o ? inv_data_integ : data_out_intg; Tests: T1 T2 T3  737 738 1/1 assign data_ctrl_o = data_out_pre_xor; Tests: T1 T2 T3  739 740 logic [BusBankAddrW-1:0] addr_xor_muxed; 741 logic [BusBankAddrW-1:0] fifo_addr_xor_muxed; 742 logic [BusBankAddrW-1:0] buf_addr_xor_muxed; 743 744 1/1 assign fifo_addr_xor_muxed = {fifo_addr_xor, rsp_fifo_rdata.word_sel}; Tests: T1 T2 T3  745 1/1 assign buf_addr_xor_muxed = {buf_addr_xor, rsp_fifo_rdata.word_sel}; Tests: T1 T2 T3  746 747 1/1 assign addr_xor_muxed = |buf_rsp_match ? buf_addr_xor_muxed : fifo_addr_xor_muxed; Tests: T1 T2 T3  748 749 logic [BusWidth-1:0] data_out_xor; 750 logic [BusWidth-1:0] data_out_xor_buf; 751 1/1 assign data_out_xor = Tests: T1 T2 T3  752 data_out_pre_xor[BusWidth-1:0] ^ {{(BusWidth-BusBankAddrW){1'b0}}, addr_xor_muxed}; 753 754 // Buffer to ensure that synthesis tool does not optimize the XOR. 755 prim_buf #( 756 .Width(BusWidth) 757 ) u_prim_buf_data_xor_out ( 758 .in_i(data_out_xor), 759 .out_o(data_out_xor_buf) 760 ); 761 762 1/1 assign data_host_o = {data_out_pre_xor[BusFullWidth-1:BusWidth], data_out_xor_buf}; Tests: T1 T2 T3  763 764 // add plaintext decoding here 765 // plaintext error 766 logic intg_err_pre, intg_err; 767 logic [DataWidth-1:0] unused_data; 768 logic [3:0] unused_intg; 769 logic [3:0] truncated_intg; 770 771 prim_secded_hamming_72_64_enc u_plain_enc ( 772 .data_i(data_out_muxed[DataWidth-1:0]), 773 .data_o({unused_intg, truncated_intg, unused_data}) 774 ); 775 1/1 assign intg_err_pre = rsp_fifo_rdata.intg_ecc_en ? Tests: T1 T2 T3  776 truncated_intg != data_out_muxed[DataWidth +: PlainIntgWidth] : 777 '0; 778 779 prim_sec_anchor_buf #( 780 .Width(1) 781 ) u_intg_buf ( 782 .in_i(intg_err_pre), 783 .out_o(intg_err) 784 ); 785 786 // whenever the response is coming from the buffer, the error is never set 787 1/1 assign data_valid_o = flash_rsp_match | (|buf_rsp_match); Tests: T1 T2 T3  788 789 // integrity and reliability ECC errors always cause in band errors 790 1/1 assign data_err_o = data_valid_o & (muxed_err | intg_err | (|buf_rsp_match & buf_rsp_err)) | Tests: T1 T2 T3  791 arb_err_i; 792 793 // integrity ECC error can also cause out of band alert 794 1/1 assign intg_ecc_err_o = data_valid_o & intg_err; Tests: T1 T2 T3  795 796 // the entire read pipeline is idle when there are no responses to return and no 797 1/1 assign idle_o = ~rsp_fifo_vld; Tests: T1 T2 T3  798 799 // if any fifo shows an integrity error 800 1/1 assign fifo_err_o = |{rsp_order_fifo_err, rd_stage_fifo_err}; Tests: T1 T2 T3 

Cond Coverage for Instance : tb.dut.u_eflash.gen_flash_cores[0].u_core.u_rd
TotalCoveredPercent
Conditions45841289.96
Logical45841289.96
Non-Logical00
Event00

This module contains a very large number of conditions, so the report has been split into multiple pages, by source line number. Click on the line number range in the table below to see the condition coverage for that section of the module.
Line numbersPercent
140-45693.23
491-79481.95

Branch Coverage for Instance : tb.dut.u_eflash.gen_flash_cores[0].u_core.u_rd
Line No.TotalCoveredPercent
Branches 43 43 100.00
TERNARY 186 2 2 100.00
TERNARY 232 2 2 100.00
TERNARY 302 2 2 100.00
TERNARY 451 2 2 100.00
TERNARY 513 3 3 100.00
TERNARY 624 3 3 100.00
TERNARY 628 3 3 100.00
TERNARY 654 3 3 100.00
TERNARY 683 2 2 100.00
TERNARY 736 2 2 100.00
TERNARY 747 2 2 100.00
TERNARY 775 2 2 100.00
TERNARY 167 2 2 100.00
IF 257 3 3 100.00
IF 360 4 4 100.00
IF 600 4 4 100.00
IF 674 2 2 100.00


186 assign buf_alloc = |buf_invalid_alloc ? buf_invalid_alloc : buf_valid_alloc; -1- ==> ==>

Branches:
-1-StatusTests
1 Covered T1,T2,T3
0 Covered T3,T8,T6


232 assign alloc = no_match ? {NumBuf{req_i & buf_en_q}} & buf_alloc : '0; -1- ==> ==>

Branches:
-1-StatusTests
1 Covered T1,T2,T3
0 Covered T3,T8,T6


302 assign rsp_fifo_wdata.buf_sel = |alloc ? buf_alloc : buf_match; -1- ==> ==>

Branches:
-1-StatusTests
1 Covered T3,T8,T6
0 Covered T1,T2,T3


451 assign data_int = data_err | ecc_single_err_o ? -1- ==> ==>

Branches:
-1-StatusTests
1 Covered T34,T36,T65
0 Covered T1,T2,T3


513 assign fifo_data_ready = hint_descram ? descramble_req_o & descramble_ack_i : -1- ==> 514 hint_dropmsk ? mask_valid : fifo_data_valid; -2- ==> ==>

Branches:
-1--2-StatusTests
1 - Covered T1,T2,T3
0 1 Covered T10,T11,T27
0 0 Covered T1,T2,T3


624 assign muxed_data = forward ? data_int : -1- ==> 625 hint_descram ? {fifo_data[PlainDataWidth-1 -: PlainIntgWidth], -2- ==> ==>

Branches:
-1--2-StatusTests
1 - Covered T3,T8,T6
0 1 Covered T1,T2,T3
0 0 Covered T1,T2,T3


628 assign muxed_err = forward ? data_err : -1- ==> 629 ~hint_forward ? data_err_q : '0; -2- ==> ==>

Branches:
-1--2-StatusTests
1 - Covered T3,T8,T6
0 1 Covered T1,T2,T3
0 0 Covered T3,T8,T6


654 assign update = forward ? alloc_q : -1- ==> 655 ~hint_forward & fifo_data_ready ? alloc_q2 : '0; -2- ==> ==>

Branches:
-1--2-StatusTests
1 - Covered T3,T8,T6
0 1 Covered T1,T2,T3
0 0 Covered T1,T2,T3


683 assign data_out_muxed = |buf_rsp_match ? buf_rsp_data : muxed_data; -1- ==> ==>

Branches:
-1-StatusTests
1 Covered T3,T8,T6
0 Covered T1,T2,T3


736 assign data_out_pre_xor = data_err_o ? inv_data_integ : data_out_intg; -1- ==> ==>

Branches:
-1-StatusTests
1 Covered T59,T11,T34
0 Covered T1,T2,T3


747 assign addr_xor_muxed = |buf_rsp_match ? buf_addr_xor_muxed : fifo_addr_xor_muxed; -1- ==> ==>

Branches:
-1-StatusTests
1 Covered T3,T8,T6
0 Covered T1,T2,T3


775 assign intg_err_pre = rsp_fifo_rdata.intg_ecc_en ? -1- ==> ==>

Branches:
-1-StatusTests
1 Covered T1,T2,T3
0 Covered T1,T2,T3


167 ) u_valid_random ( 168 .clk_i, 169 .rst_ni, 170 .req_chk_i(1'b0), // Valid is allowed to drop without ready. 171 // If there is an invalid buffer, always allocate from that one first 172 // If all buffers have a dependency to an in-flight transaction, do not 173 // allocate and wait for the dependencies to end. 174 // If none of the above are true, THEN pick a buffer from the current valid 175 // buffers that DO NOT have an ongoing dependency. 176 .req_i(|buf_invalid_alloc | all_buf_dependency ? '0 : buf_valid & ~buf_dependency), -1- ==> ==>

Branches:
-1-StatusTests
1 Covered T1,T2,T3
0 Covered T3,T8,T6


257 if (!rst_ni) begin -1- 258 buf_en_q <= 1'b0; ==> 259 end else if (idle_o) begin -2- 260 buf_en_q <= buf_en_i; ==> 261 end MISSING_ELSE ==>

Branches:
-1--2-StatusTests
1 - Covered T1,T2,T3
0 1 Covered T1,T2,T3
0 0 Covered T1,T2,T3


360 if (!rst_ni) begin -1- 361 alloc_q <= '0; ==> 362 rd_attrs <= '0; 363 rd_busy <= '0; 364 end else if (rd_start) begin -2- 365 rd_busy <= 1'b1; ==> 366 alloc_q <= alloc; 367 rd_attrs.addr <= addr_i[BusBankAddrW-1:LsbAddrBit]; 368 rd_attrs.descramble <= descramble_i; 369 rd_attrs.ecc <= ecc_i; 370 371 end else if (rd_done) begin -3- 372 rd_busy <= 1'b0; ==> 373 end MISSING_ELSE ==>

Branches:
-1--2--3-StatusTests
1 - - Covered T1,T2,T3
0 1 - Covered T1,T2,T3
0 0 1 Covered T1,T2,T3
0 0 0 Covered T1,T2,T3


600 if (!rst_ni) begin -1- 601 calc_req_o <= '0; ==> 602 end else if (calc_req_start) begin -2- 603 calc_req_o <= 1'b1; ==> 604 end else if (calc_req_done) begin -3- 605 calc_req_o <= 1'b0; ==> 606 end MISSING_ELSE ==>

Branches:
-1--2--3-StatusTests
1 - - Covered T1,T2,T3
0 1 - Covered T1,T2,T3
0 0 1 Covered T1,T2,T3
0 0 0 Covered T1,T2,T3


674 if (buf_rsp_match[i]) begin -1- 675 buf_rsp_data = read_buf[i].data; ==> 676 buf_addr_xor = read_buf[i].addr; 677 buf_rsp_err = buf_rsp_err | read_buf[i].err; 678 end MISSING_ELSE ==>

Branches:
-1-StatusTests
1 Covered T3,T8,T6
0 Covered T1,T2,T3


Assert Coverage for Instance : tb.dut.u_eflash.gen_flash_cores[0].u_core.u_rd
TotalAttemptedPercentSucceeded/MatchedPercent
Assertions 11 11 100.00 11 100.00
Cover properties 0 0 0
Cover sequences 0 0 0
Total 11 11 100.00 11 100.00




Assertion Details

NameAttemptsReal SuccessesFailuresIncomplete
BufferMatchEcc_A 332875393 1007919 0 0
ExclusiveOps_A 332875393 332008659 0 0
ExclusiveProgHazard_A 332875393 332008659 0 0
ExclusiveState_A 332875393 332008659 0 0
ForwardCheck_A 332875393 2164338 0 0
IdleCheck_A 332875393 51718530 0 0
MaxBufs_A 1026 1026 0 0
OneHotAlloc_A 332875393 332008659 0 0
OneHotMatch_A 332875393 332008659 0 0
OneHotRspMatch_A 332875393 332008659 0 0
OneHotUpdate_A 332875393 332008659 0 0


BufferMatchEcc_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 332875393 1007919 0 0
T3 2283 72 0 0
T4 4375 0 0 0
T5 1250 0 0 0
T6 873 7 0 0
T8 51282 220 0 0
T9 2110 10 0 0
T10 0 4 0 0
T15 949 0 0 0
T16 1834 0 0 0
T17 1845 0 0 0
T19 0 28 0 0
T20 1105 5 0 0
T27 0 71 0 0
T34 0 27 0 0
T64 0 298 0 0

ExclusiveOps_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 332875393 332008659 0 0
T1 1475 1361 0 0
T2 3694 3600 0 0
T3 2283 2194 0 0
T4 4375 3852 0 0
T5 1250 1151 0 0
T6 873 776 0 0
T8 51282 51232 0 0
T15 949 886 0 0
T16 1834 1745 0 0
T17 1845 1746 0 0

ExclusiveProgHazard_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 332875393 332008659 0 0
T1 1475 1361 0 0
T2 3694 3600 0 0
T3 2283 2194 0 0
T4 4375 3852 0 0
T5 1250 1151 0 0
T6 873 776 0 0
T8 51282 51232 0 0
T15 949 886 0 0
T16 1834 1745 0 0
T17 1845 1746 0 0

ExclusiveState_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 332875393 332008659 0 0
T1 1475 1361 0 0
T2 3694 3600 0 0
T3 2283 2194 0 0
T4 4375 3852 0 0
T5 1250 1151 0 0
T6 873 776 0 0
T8 51282 51232 0 0
T15 949 886 0 0
T16 1834 1745 0 0
T17 1845 1746 0 0

ForwardCheck_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 332875393 2164338 0 0
T3 2283 74 0 0
T4 4375 0 0 0
T5 1250 0 0 0
T6 873 9 0 0
T8 51282 250 0 0
T9 2110 10 0 0
T10 0 15 0 0
T11 0 2 0 0
T15 949 0 0 0
T16 1834 0 0 0
T17 1845 0 0 0
T19 0 32 0 0
T20 1105 5 0 0
T27 0 55 0 0
T34 0 6 0 0

IdleCheck_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 332875393 51718530 0 0
T1 1475 256 0 0
T2 3694 128 0 0
T3 2283 348 0 0
T4 4375 768 0 0
T5 1250 128 0 0
T6 873 153 0 0
T8 51282 848 0 0
T15 949 128 0 0
T16 1834 128 0 0
T17 1845 128 0 0

MaxBufs_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 1026 1026 0 0
T1 1 1 0 0
T2 1 1 0 0
T3 1 1 0 0
T4 1 1 0 0
T5 1 1 0 0
T6 1 1 0 0
T8 1 1 0 0
T15 1 1 0 0
T16 1 1 0 0
T17 1 1 0 0

OneHotAlloc_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 332875393 332008659 0 0
T1 1475 1361 0 0
T2 3694 3600 0 0
T3 2283 2194 0 0
T4 4375 3852 0 0
T5 1250 1151 0 0
T6 873 776 0 0
T8 51282 51232 0 0
T15 949 886 0 0
T16 1834 1745 0 0
T17 1845 1746 0 0

OneHotMatch_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 332875393 332008659 0 0
T1 1475 1361 0 0
T2 3694 3600 0 0
T3 2283 2194 0 0
T4 4375 3852 0 0
T5 1250 1151 0 0
T6 873 776 0 0
T8 51282 51232 0 0
T15 949 886 0 0
T16 1834 1745 0 0
T17 1845 1746 0 0

OneHotRspMatch_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 332875393 332008659 0 0
T1 1475 1361 0 0
T2 3694 3600 0 0
T3 2283 2194 0 0
T4 4375 3852 0 0
T5 1250 1151 0 0
T6 873 776 0 0
T8 51282 51232 0 0
T15 949 886 0 0
T16 1834 1745 0 0
T17 1845 1746 0 0

OneHotUpdate_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 332875393 332008659 0 0
T1 1475 1361 0 0
T2 3694 3600 0 0
T3 2283 2194 0 0
T4 4375 3852 0 0
T5 1250 1151 0 0
T6 873 776 0 0
T8 51282 51232 0 0
T15 949 886 0 0
T16 1834 1745 0 0
T17 1845 1746 0 0

0% 10% 20% 30% 40% 50% 60% 70% 80% 90% 100%