[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