[dv/flash] Update erase-suspend test with read Signed-off-by: Eitan Shapira <eitanshapira89@gmail.com>
diff --git a/hw/ip/flash_ctrl/dv/env/flash_ctrl_seq_cfg.sv b/hw/ip/flash_ctrl/dv/env/flash_ctrl_seq_cfg.sv index b7aeea8..dcddde9 100644 --- a/hw/ip/flash_ctrl/dv/env/flash_ctrl_seq_cfg.sv +++ b/hw/ip/flash_ctrl/dv/env/flash_ctrl_seq_cfg.sv
@@ -100,6 +100,9 @@ // Timeout for erase transaction uint erase_timeout_ns; + // Expected time for the erase-suspend operation + uint erase_suspend_expected_time_ns; + // Timeout for read transaction uint read_timeout_ns; @@ -215,13 +218,15 @@ check_mem_post_tran = 1'b1; - prog_timeout_ns = 10_000_000; // 10ms + prog_timeout_ns = 10_000_000; // 10ms - read_timeout_ns = 10_000_000; // 10ms + read_timeout_ns = 100_000; // 100us - erase_timeout_ns = 120_000_000; // 120ms + erase_timeout_ns = 120_000_000; // 120ms - state_wait_timeout_ns = 500_000; // 500us + erase_suspend_expected_time_ns = 50_000; // 50us + + state_wait_timeout_ns = 500_000; // 500us en_init_keys_seeds = 1'b0; // Off
diff --git a/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_erase_suspend_vseq.sv b/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_erase_suspend_vseq.sv index 381b766..cc0628b 100644 --- a/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_erase_suspend_vseq.sv +++ b/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_erase_suspend_vseq.sv
@@ -28,17 +28,14 @@ // randomize memory cfg.seq_cfg.flash_init_set_pc = 0; - endfunction + // Flash ctrl operation data queue - used for programing or reading the flash. + data_q_t flash_op_data; + // Randomized flash ctrl operation. rand flash_op_t flash_op; - rand uint bank; - - // Constraint for banks. - constraint bank_c {bank inside {[0 : flash_ctrl_pkg::NumBanks - 1]};} - // Constraint address to be in relevant range for the selected partition. constraint addr_c { if (flash_op.partition != FlashPartData) { @@ -85,10 +82,7 @@ mp_regions[i].erase_en == MuBi4True; - mp_regions[i].scramble_en dist { - MuBi4False :/ (100 - cfg.seq_cfg.mp_region_scramble_en_pc), - MuBi4True :/ cfg.seq_cfg.mp_region_scramble_en_pc - }; + mp_regions[i].scramble_en == MuBi4False; mp_regions[i].ecc_en == MuBi4False; @@ -186,6 +180,9 @@ `DV_CHECK_RANDOMIZE_FATAL(this) reset_flash(); do_erase(); + // Check that the erase suspended by initiating a read to another page of the flash and make + // sure it completes in a reasonable time relevant for read - cfg.seq_cfg.read_timeout_ns. + check_erase_suspended(); // Check recovery by initiating an additional erase to the affected page and backdoor // verify it. // After an erase is suspended, the page must be erased before any other transaction can be @@ -205,7 +202,6 @@ // Configure the flash with scramble disable. foreach (mp_regions[k]) begin - mp_regions[k].scramble_en = 0; flash_ctrl_mp_region_cfg(k, mp_regions[k]); `uvm_info(`gfn, $sformatf("MP regions values %p", mp_regions[k]), UVM_HIGH) end @@ -223,7 +219,7 @@ flash_ctrl_bank_erase_cfg(.bank_erase_en(bank_erase_en)); // 1. Scenario - erase is not active - `uvm_info(`gfn, $sformatf("Scenario 1: erase is not active"), UVM_HIGH) + `uvm_info(`gfn, $sformatf("Scenario 1: Erase is not active"), UVM_HIGH) // Read data before writing csr_rd(.ptr(ral.erase_suspend), .value(data)); @@ -238,7 +234,7 @@ csr_rd_check(.ptr(ral.erase_suspend.req), .compare_value(0)); // 2. Scneario - Erase is in progress - `uvm_info(`gfn, $sformatf("2. Scenario - Erase is in progress"), UVM_HIGH) + `uvm_info(`gfn, $sformatf("Scenario 2: Erase is in progress"), UVM_HIGH) `uvm_info(`gfn, $sformatf("FLASH OP ERASE START OP: %0p", flash_op), UVM_HIGH) flash_ctrl_start_op(flash_op); @@ -250,36 +246,54 @@ // WAITING THAT ERASE SUSPEND REQ IS DONE AND REQ RETURNED TO ZERO `DV_SPINWAIT(do begin - csr_rd(.ptr(ral.erase_suspend), .value(data)); - `uvm_info(`gfn, $sformatf("ERASE SUSPEND REQ: %0p", data), UVM_HIGH) - end while (data == 1);, "ERASE SUSPEND TIMEOUT OCCURED!", cfg.seq_cfg.erase_timeout_ns) + csr_rd(.ptr(ral.erase_suspend), .value(data)); + `uvm_info(`gfn, $sformatf("ERASE SUSPEND REQ: %0p", data), UVM_HIGH) + end while (data == 1);, + "ERASE SUSPEND TIMEOUT OCCURED!", cfg.seq_cfg.erase_timeout_ns) - wait_flash_op_done(.timeout_ns(cfg.seq_cfg.erase_timeout_ns)); + wait_flash_op_done(.timeout_ns(cfg.seq_cfg.erase_suspend_expected_time_ns)); endtask : do_erase + // Check that the erase suspended by initiating a read to another page of the flash and make + // sure it completes in a reasonable time relevant for read - cfg.seq_cfg.read_timeout_ns. + // If the erase that suspended was bank-erase, make sure to read from the other bank. + task check_erase_suspended(); + flash_op_t flash_op_erase = flash_op; + `DV_CHECK_MEMBER_RANDOMIZE_WITH_FATAL(flash_op, + flash_op.partition != flash_op_erase.partition || + flash_op.addr[FlashMemAddrBankMsbBit-:(FlashBankWidth+FlashPageWidth)] != + flash_op_erase.addr[FlashMemAddrBankMsbBit-:(FlashBankWidth+FlashPageWidth)]; + if (flash_op_erase.erase_type == flash_ctrl_pkg::FlashEraseBank) { + flash_op.addr[FlashMemAddrBankMsbBit] != + flash_op_erase.addr[FlashMemAddrBankMsbBit]; + }) + flash_op.op = FlashOpRead; + `uvm_info(`gfn, $sformatf("START READ DIFFERENT PAGE TO CHECK THE ERASE IS SUSPENDED, op: %p", + flash_op), UVM_HIGH) + flash_ctrl_start_op(flash_op); + flash_ctrl_read(flash_op.num_words, flash_op_data, 1'b0); + wait_flash_op_done(.timeout_ns(cfg.seq_cfg.read_timeout_ns)); + flash_op = flash_op_erase; + endtask : check_erase_suspended + // Task to run another erase on the page in which the erase-suspend done and check it complete // successfully. // After an erase is suspended, the page must be erased before any other transaction can be // initiated to the selected page. task check_recovery(); - // Flash ctrl operation data queue - used for programing or reading the flash. - data_q_t flash_op_data; // Expected data. data_q_t exp_data; `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(flash_op_data, flash_op_data.size() == 0;) - cfg.clk_rst_vif.wait_clks($urandom_range(15, 30)); - - `uvm_info(`gfn, $sformatf("Starting flash_ctrl op: %p", flash_op), UVM_LOW) + `uvm_info(`gfn, $sformatf("START ERASE THE SAME PAGE TO CHECK RECOVERY flash_ctrl op: %p", + flash_op), UVM_HIGH) flash_ctrl_start_op(flash_op); exp_data = cfg.calculate_expected_data(flash_op, flash_op_data); - wait_flash_op_done(.timeout_ns(cfg.seq_cfg.erase_timeout_ns)); cfg.flash_mem_bkdr_erase_check(flash_op, exp_data); - endtask : check_recovery endclass : flash_ctrl_erase_suspend_vseq