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.38 100.00 89.52 100.00 100.00


Instance's subtree :
SCORELINECONDTOGGLEFSMBRANCHASSERT
96.93 97.64 92.83 100.00 99.37 94.83


Parent :
SCORELINECONDTOGGLEFSMBRANCHASSERTNAME
96.74 100.00 85.85 100.00 97.83 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.43 100.00 89.74 100.00 100.00


Instance's subtree :
SCORELINECONDTOGGLEFSMBRANCHASSERT
96.95 97.64 92.91 100.00 99.37 94.83


Parent :
SCORELINECONDTOGGLEFSMBRANCHASSERTNAME
98.87 100.00 94.34 100.00 100.00 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: T2 T3 T17  676 1/1 buf_addr_xor = read_buf[i].addr; Tests: T2 T3 T17  677 1/1 buf_rsp_err = buf_rsp_err | read_buf[i].err; Tests: T2 T3 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 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.23
491-79482.71

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 T2,T3,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 T2,T3,T17


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

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


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

Branches:
-1-StatusTests
1 Covered T20,T13,T39
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 T23,T15,T10
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 T2,T3,T18
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 T2,T3,T18
0 1 Covered T1,T2,T3
0 0 Covered T2,T3,T18


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

Branches:
-1--2-StatusTests
1 - Covered T2,T3,T18
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 T2,T3,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 T20,T13,T54
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 T2,T3,T17
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 T2,T3,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 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 T2,T3,T17
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 776511532 1675763 0 0
ExclusiveOps_A 776511532 774831282 0 0
ExclusiveProgHazard_A 776511532 774831282 0 0
ExclusiveState_A 776511532 774831282 0 0
ForwardCheck_A 776511532 3835871 0 0
IdleCheck_A 776511532 104103239 0 0
MaxBufs_A 2114 2114 0 0
OneHotAlloc_A 776511532 774831282 0 0
OneHotMatch_A 776511532 774831282 0 0
OneHotRspMatch_A 776511532 774831282 0 0
OneHotUpdate_A 776511532 774831282 0 0


BufferMatchEcc_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 776511532 1675763 0 0
T2 21696 369 0 0
T3 2448 5 0 0
T4 1780 0 0 0
T7 1944 0 0 0
T12 4004 10 0 0
T13 0 17 0 0
T14 0 872 0 0
T15 0 62 0 0
T17 3088 72 0 0
T18 3900 92 0 0
T19 4606 73 0 0
T20 2946 17 0 0
T23 14598 111 0 0
T51 0 656 0 0
T54 0 150 0 0
T59 0 66 0 0
T98 0 613 0 0

ExclusiveOps_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 776511532 774831282 0 0
T1 7812 7706 0 0
T2 21696 21556 0 0
T3 2448 2334 0 0
T4 1780 1680 0 0
T7 1944 1844 0 0
T12 4004 3888 0 0
T17 3088 2978 0 0
T18 3900 3732 0 0
T19 4606 4422 0 0
T20 2946 2676 0 0

ExclusiveProgHazard_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 776511532 774831282 0 0
T1 7812 7706 0 0
T2 21696 21556 0 0
T3 2448 2334 0 0
T4 1780 1680 0 0
T7 1944 1844 0 0
T12 4004 3888 0 0
T17 3088 2978 0 0
T18 3900 3732 0 0
T19 4606 4422 0 0
T20 2946 2676 0 0

ExclusiveState_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 776511532 774831282 0 0
T1 7812 7706 0 0
T2 21696 21556 0 0
T3 2448 2334 0 0
T4 1780 1680 0 0
T7 1944 1844 0 0
T12 4004 3888 0 0
T17 3088 2978 0 0
T18 3900 3732 0 0
T19 4606 4422 0 0
T20 2946 2676 0 0

ForwardCheck_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 776511532 3835871 0 0
T2 21696 437 0 0
T3 2448 5 0 0
T4 1780 0 0 0
T7 1944 0 0 0
T10 0 16 0 0
T12 4004 10 0 0
T15 0 107 0 0
T17 3088 0 0 0
T18 3900 54 0 0
T19 4606 0 0 0
T20 2946 9 0 0
T23 14598 47 0 0
T40 0 216 0 0
T51 0 1188 0 0
T58 0 32 0 0
T59 0 81 0 0
T98 0 913 0 0

IdleCheck_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 776511532 104103239 0 0
T1 3906 128 0 0
T2 21696 1371 0 0
T3 2448 143 0 0
T4 1780 128 0 0
T7 1944 132 0 0
T10 0 12 0 0
T12 4004 158 0 0
T13 0 35 0 0
T15 0 160 0 0
T17 3088 496 0 0
T18 3900 328 0 0
T19 4606 493 0 0
T20 2946 351 0 0
T23 7299 155 0 0
T51 0 1968 0 0
T54 0 350 0 0
T58 0 10 0 0

MaxBufs_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 2114 2114 0 0
T1 2 2 0 0
T2 2 2 0 0
T3 2 2 0 0
T4 2 2 0 0
T7 2 2 0 0
T12 2 2 0 0
T17 2 2 0 0
T18 2 2 0 0
T19 2 2 0 0
T20 2 2 0 0

OneHotAlloc_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 776511532 774831282 0 0
T1 7812 7706 0 0
T2 21696 21556 0 0
T3 2448 2334 0 0
T4 1780 1680 0 0
T7 1944 1844 0 0
T12 4004 3888 0 0
T17 3088 2978 0 0
T18 3900 3732 0 0
T19 4606 4422 0 0
T20 2946 2676 0 0

OneHotMatch_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 776511532 774831282 0 0
T1 7812 7706 0 0
T2 21696 21556 0 0
T3 2448 2334 0 0
T4 1780 1680 0 0
T7 1944 1844 0 0
T12 4004 3888 0 0
T17 3088 2978 0 0
T18 3900 3732 0 0
T19 4606 4422 0 0
T20 2946 2676 0 0

OneHotRspMatch_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 776511532 774831282 0 0
T1 7812 7706 0 0
T2 21696 21556 0 0
T3 2448 2334 0 0
T4 1780 1680 0 0
T7 1944 1844 0 0
T12 4004 3888 0 0
T17 3088 2978 0 0
T18 3900 3732 0 0
T19 4606 4422 0 0
T20 2946 2676 0 0

OneHotUpdate_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 776511532 774831282 0 0
T1 7812 7706 0 0
T2 21696 21556 0 0
T3 2448 2334 0 0
T4 1780 1680 0 0
T7 1944 1844 0 0
T12 4004 3888 0 0
T17 3088 2978 0 0
T18 3900 3732 0 0
T19 4606 4422 0 0
T20 2946 2676 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: T2 T18 T20  366 1/1 alloc_q <= alloc; Tests: T2 T18 T20  367 1/1 rd_attrs.addr <= addr_i[BusBankAddrW-1:LsbAddrBit]; Tests: T2 T18 T20  368 1/1 rd_attrs.descramble <= descramble_i; Tests: T2 T18 T20  369 1/1 rd_attrs.ecc <= ecc_i; Tests: T2 T18 T20  370 371 1/1 end else if (rd_done) begin Tests: T1 T2 T3  372 1/1 rd_busy <= 1'b0; Tests: T2 T18 T20  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: T20 T23 T13  604 1/1 end else if (calc_req_done) begin Tests: T1 T2 T3  605 1/1 calc_req_o <= 1'b0; Tests: T20 T23 T13  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: T2 T18 T20  676 1/1 buf_addr_xor = read_buf[i].addr; Tests: T2 T18 T20  677 1/1 buf_rsp_err = buf_rsp_err | read_buf[i].err; Tests: T2 T18 T20  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
Conditions45841089.52
Logical45841089.52
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-49192.40
494-79482.17

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 T2,T18,T20


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 T2,T18,T20


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

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


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

Branches:
-1-StatusTests
1 Covered T39,T40,T55
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 T20,T23,T13
0 1 Covered T23,T15,T10
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 T2,T18,T23
0 1 Covered T20,T23,T13
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 T2,T18,T23
0 1 Covered T1,T2,T3
0 0 Covered T2,T18,T23


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

Branches:
-1--2-StatusTests
1 - Covered T2,T18,T23
0 1 Covered T20,T23,T13
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 T2,T18,T20
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 T54,T55,T175
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 T2,T18,T20
0 Covered T1,T2,T3


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

Branches:
-1-StatusTests
1 Covered T23,T13,T15
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 T2,T18,T20


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 T2,T18,T20


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 T2,T18,T20
0 0 1 Covered T2,T18,T20
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 T20,T23,T13
0 0 1 Covered T20,T23,T13
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 T2,T18,T20
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 388255766 812927 0 0
ExclusiveOps_A 388255766 387415641 0 0
ExclusiveProgHazard_A 388255766 387415641 0 0
ExclusiveState_A 388255766 387415641 0 0
ForwardCheck_A 388255766 1797841 0 0
IdleCheck_A 388255766 50673861 0 0
MaxBufs_A 1057 1057 0 0
OneHotAlloc_A 388255766 387415641 0 0
OneHotMatch_A 388255766 387415641 0 0
OneHotRspMatch_A 388255766 387415641 0 0
OneHotUpdate_A 388255766 387415641 0 0


BufferMatchEcc_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 388255766 812927 0 0
T2 10848 183 0 0
T3 1224 0 0 0
T4 890 0 0 0
T7 972 0 0 0
T12 2002 0 0 0
T13 0 3 0 0
T15 0 30 0 0
T17 1544 0 0 0
T18 1950 92 0 0
T19 2303 0 0 0
T20 1473 3 0 0
T23 7299 25 0 0
T51 0 656 0 0
T54 0 150 0 0
T59 0 66 0 0
T98 0 613 0 0

ExclusiveOps_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 388255766 387415641 0 0
T1 3906 3853 0 0
T2 10848 10778 0 0
T3 1224 1167 0 0
T4 890 840 0 0
T7 972 922 0 0
T12 2002 1944 0 0
T17 1544 1489 0 0
T18 1950 1866 0 0
T19 2303 2211 0 0
T20 1473 1338 0 0

ExclusiveProgHazard_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 388255766 387415641 0 0
T1 3906 3853 0 0
T2 10848 10778 0 0
T3 1224 1167 0 0
T4 890 840 0 0
T7 972 922 0 0
T12 2002 1944 0 0
T17 1544 1489 0 0
T18 1950 1866 0 0
T19 2303 2211 0 0
T20 1473 1338 0 0

ExclusiveState_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 388255766 387415641 0 0
T1 3906 3853 0 0
T2 10848 10778 0 0
T3 1224 1167 0 0
T4 890 840 0 0
T7 972 922 0 0
T12 2002 1944 0 0
T17 1544 1489 0 0
T18 1950 1866 0 0
T19 2303 2211 0 0
T20 1473 1338 0 0

ForwardCheck_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 388255766 1797841 0 0
T2 10848 215 0 0
T3 1224 0 0 0
T4 890 0 0 0
T7 972 0 0 0
T10 0 6 0 0
T12 2002 0 0 0
T15 0 65 0 0
T17 1544 0 0 0
T18 1950 54 0 0
T19 2303 0 0 0
T20 1473 0 0 0
T23 7299 3 0 0
T40 0 216 0 0
T51 0 656 0 0
T58 0 5 0 0
T59 0 81 0 0
T98 0 621 0 0

IdleCheck_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 388255766 50673861 0 0
T2 10848 613 0 0
T3 1224 0 0 0
T4 890 0 0 0
T7 972 0 0 0
T10 0 12 0 0
T12 2002 0 0 0
T13 0 35 0 0
T15 0 160 0 0
T17 1544 0 0 0
T18 1950 200 0 0
T19 2303 0 0 0
T20 1473 23 0 0
T23 7299 155 0 0
T51 0 1968 0 0
T54 0 350 0 0
T58 0 10 0 0

MaxBufs_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 1057 1057 0 0
T1 1 1 0 0
T2 1 1 0 0
T3 1 1 0 0
T4 1 1 0 0
T7 1 1 0 0
T12 1 1 0 0
T17 1 1 0 0
T18 1 1 0 0
T19 1 1 0 0
T20 1 1 0 0

OneHotAlloc_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 388255766 387415641 0 0
T1 3906 3853 0 0
T2 10848 10778 0 0
T3 1224 1167 0 0
T4 890 840 0 0
T7 972 922 0 0
T12 2002 1944 0 0
T17 1544 1489 0 0
T18 1950 1866 0 0
T19 2303 2211 0 0
T20 1473 1338 0 0

OneHotMatch_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 388255766 387415641 0 0
T1 3906 3853 0 0
T2 10848 10778 0 0
T3 1224 1167 0 0
T4 890 840 0 0
T7 972 922 0 0
T12 2002 1944 0 0
T17 1544 1489 0 0
T18 1950 1866 0 0
T19 2303 2211 0 0
T20 1473 1338 0 0

OneHotRspMatch_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 388255766 387415641 0 0
T1 3906 3853 0 0
T2 10848 10778 0 0
T3 1224 1167 0 0
T4 890 840 0 0
T7 972 922 0 0
T12 2002 1944 0 0
T17 1544 1489 0 0
T18 1950 1866 0 0
T19 2303 2211 0 0
T20 1473 1338 0 0

OneHotUpdate_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 388255766 387415641 0 0
T1 3906 3853 0 0
T2 10848 10778 0 0
T3 1224 1167 0 0
T4 890 840 0 0
T7 972 922 0 0
T12 2002 1944 0 0
T17 1544 1489 0 0
T18 1950 1866 0 0
T19 2303 2211 0 0
T20 1473 1338 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: T2 T3 T17  676 1/1 buf_addr_xor = read_buf[i].addr; Tests: T2 T3 T17  677 1/1 buf_rsp_err = buf_rsp_err | read_buf[i].err; Tests: T2 T3 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[0].u_core.u_rd
TotalCoveredPercent
Conditions45841189.74
Logical45841189.74
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-49192.40
494-79482.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 T2,T3,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 T2,T3,T17


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

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


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

Branches:
-1-StatusTests
1 Covered T20,T13,T39
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 T23,T15,T10
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 T2,T3,T12
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 T2,T3,T12
0 1 Covered T1,T2,T3
0 0 Covered T2,T3,T12


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

Branches:
-1--2-StatusTests
1 - Covered T2,T3,T12
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 T2,T3,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 T20,T13,T54
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 T2,T3,T17
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 T2,T3,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 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 T2,T3,T17
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 388255766 862836 0 0
ExclusiveOps_A 388255766 387415641 0 0
ExclusiveProgHazard_A 388255766 387415641 0 0
ExclusiveState_A 388255766 387415641 0 0
ForwardCheck_A 388255766 2038030 0 0
IdleCheck_A 388255766 53429378 0 0
MaxBufs_A 1057 1057 0 0
OneHotAlloc_A 388255766 387415641 0 0
OneHotMatch_A 388255766 387415641 0 0
OneHotRspMatch_A 388255766 387415641 0 0
OneHotUpdate_A 388255766 387415641 0 0


BufferMatchEcc_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 388255766 862836 0 0
T2 10848 186 0 0
T3 1224 5 0 0
T4 890 0 0 0
T7 972 0 0 0
T12 2002 10 0 0
T13 0 14 0 0
T14 0 872 0 0
T15 0 32 0 0
T17 1544 72 0 0
T18 1950 0 0 0
T19 2303 73 0 0
T20 1473 14 0 0
T23 7299 86 0 0

ExclusiveOps_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 388255766 387415641 0 0
T1 3906 3853 0 0
T2 10848 10778 0 0
T3 1224 1167 0 0
T4 890 840 0 0
T7 972 922 0 0
T12 2002 1944 0 0
T17 1544 1489 0 0
T18 1950 1866 0 0
T19 2303 2211 0 0
T20 1473 1338 0 0

ExclusiveProgHazard_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 388255766 387415641 0 0
T1 3906 3853 0 0
T2 10848 10778 0 0
T3 1224 1167 0 0
T4 890 840 0 0
T7 972 922 0 0
T12 2002 1944 0 0
T17 1544 1489 0 0
T18 1950 1866 0 0
T19 2303 2211 0 0
T20 1473 1338 0 0

ExclusiveState_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 388255766 387415641 0 0
T1 3906 3853 0 0
T2 10848 10778 0 0
T3 1224 1167 0 0
T4 890 840 0 0
T7 972 922 0 0
T12 2002 1944 0 0
T17 1544 1489 0 0
T18 1950 1866 0 0
T19 2303 2211 0 0
T20 1473 1338 0 0

ForwardCheck_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 388255766 2038030 0 0
T2 10848 222 0 0
T3 1224 5 0 0
T4 890 0 0 0
T7 972 0 0 0
T10 0 10 0 0
T12 2002 10 0 0
T15 0 42 0 0
T17 1544 0 0 0
T18 1950 0 0 0
T19 2303 0 0 0
T20 1473 9 0 0
T23 7299 44 0 0
T51 0 532 0 0
T58 0 27 0 0
T98 0 292 0 0

IdleCheck_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 388255766 53429378 0 0
T1 3906 128 0 0
T2 10848 758 0 0
T3 1224 143 0 0
T4 890 128 0 0
T7 972 132 0 0
T12 2002 158 0 0
T17 1544 496 0 0
T18 1950 128 0 0
T19 2303 493 0 0
T20 1473 328 0 0

MaxBufs_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 1057 1057 0 0
T1 1 1 0 0
T2 1 1 0 0
T3 1 1 0 0
T4 1 1 0 0
T7 1 1 0 0
T12 1 1 0 0
T17 1 1 0 0
T18 1 1 0 0
T19 1 1 0 0
T20 1 1 0 0

OneHotAlloc_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 388255766 387415641 0 0
T1 3906 3853 0 0
T2 10848 10778 0 0
T3 1224 1167 0 0
T4 890 840 0 0
T7 972 922 0 0
T12 2002 1944 0 0
T17 1544 1489 0 0
T18 1950 1866 0 0
T19 2303 2211 0 0
T20 1473 1338 0 0

OneHotMatch_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 388255766 387415641 0 0
T1 3906 3853 0 0
T2 10848 10778 0 0
T3 1224 1167 0 0
T4 890 840 0 0
T7 972 922 0 0
T12 2002 1944 0 0
T17 1544 1489 0 0
T18 1950 1866 0 0
T19 2303 2211 0 0
T20 1473 1338 0 0

OneHotRspMatch_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 388255766 387415641 0 0
T1 3906 3853 0 0
T2 10848 10778 0 0
T3 1224 1167 0 0
T4 890 840 0 0
T7 972 922 0 0
T12 2002 1944 0 0
T17 1544 1489 0 0
T18 1950 1866 0 0
T19 2303 2211 0 0
T20 1473 1338 0 0

OneHotUpdate_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 388255766 387415641 0 0
T1 3906 3853 0 0
T2 10848 10778 0 0
T3 1224 1167 0 0
T4 890 840 0 0
T7 972 922 0 0
T12 2002 1944 0 0
T17 1544 1489 0 0
T18 1950 1866 0 0
T19 2303 2211 0 0
T20 1473 1338 0 0

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