[dv/otp_ctrl] OTP write_blank_error support [PART6]

This PR cleans up the stress_all and stress_all_with_rand_reset
sequences to support write_blank_error.
To avoid previous sequence dai_wr affects next sequence, this PR wipes
the OTP memory after one sequence finishes running.

Signed-off-by: Cindy Chen <chencindy@opentitan.org>
diff --git a/hw/ip/otp_ctrl/dv/env/otp_ctrl_scoreboard.sv b/hw/ip/otp_ctrl/dv/env/otp_ctrl_scoreboard.sv
index 522002d..a270508 100644
--- a/hw/ip/otp_ctrl/dv/env/otp_ctrl_scoreboard.sv
+++ b/hw/ip/otp_ctrl/dv/env/otp_ctrl_scoreboard.sv
@@ -61,6 +61,7 @@
   task run_phase(uvm_phase phase);
     super.run_phase(phase);
     fork
+      process_wipe_mem();
       process_otp_power_up();
       process_lc_esc();
       process_lc_prog_req();
@@ -72,6 +73,36 @@
     join_none
   endtask
 
+  // Once sequence uses backdoor method to clear memory, this task resets internal otp_a and
+  // resets `cfg.backdoor_clear_mem` to 0.
+  virtual task process_wipe_mem();
+    forever begin
+      @(posedge cfg.backdoor_clear_mem) begin
+        bit [SCRAMBLE_DATA_SIZE-1:0] data = descramble_data(0, Secret0Idx);
+        otp_a        = '{default:0};
+        otp_lc_data  = '{default:0};
+        // secret partitions have been scrambled before writing to OTP.
+        // here calculate the pre-srambled raw data when clearing internal OTP to all 0s.
+        for (int i = SECRET0_START_ADDR; i <= SECRET0_END_ADDR; i++) begin
+          otp_a[i] = ((i - SECRET0_START_ADDR) % 2) ? data[SCRAMBLE_DATA_SIZE-1:TL_DW] :
+                                                      data[TL_DW-1:0];
+        end
+        data = descramble_data(0, Secret1Idx);
+        for (int i = SECRET1_START_ADDR; i <= SECRET1_END_ADDR; i++) begin
+          otp_a[i] = ((i - SECRET1_START_ADDR) % 2) ? data[SCRAMBLE_DATA_SIZE-1:TL_DW] :
+                                                      data[TL_DW-1:0];
+        end
+        data = descramble_data(0, Secret2Idx);
+        for (int i = SECRET2_START_ADDR; i <= SECRET2_END_ADDR; i++) begin
+          otp_a[i] = ((i - SECRET2_START_ADDR) % 2) ? data[SCRAMBLE_DATA_SIZE-1:TL_DW] :
+                                                      data[TL_DW-1:0];
+        end
+        `uvm_info(`gfn, "clear internal memory and digest", UVM_HIGH)
+        cfg.backdoor_clear_mem = 0;
+      end
+    end
+  endtask
+
   // This task process the following logic in during otp_power_up:
   // 1. After reset deasserted, otp access is locked until pwr_otp_done_o is set
   // 2. After reset deasserted, if power otp_init request is on, and if testbench uses backdoor to
@@ -79,31 +110,6 @@
   virtual task process_otp_power_up();
     if (cfg.en_scb) begin
       forever begin
-        @(posedge cfg.otp_ctrl_vif.pwr_otp_init_i) begin
-          if (cfg.backdoor_clear_mem) begin
-            bit [SCRAMBLE_DATA_SIZE-1:0] data = descramble_data(0, Secret0Idx);
-            otp_a        = '{default:0};
-            otp_lc_data  = '{default:0};
-            // secret partitions have been scrambled before writing to OTP.
-            // here calculate the pre-srambled raw data when clearing internal OTP to all 0s.
-            for (int i = SECRET0_START_ADDR; i <= SECRET0_END_ADDR; i++) begin
-              otp_a[i] = ((i - SECRET0_START_ADDR) % 2) ? data[SCRAMBLE_DATA_SIZE-1:TL_DW] :
-                                                          data[TL_DW-1:0];
-            end
-            data = descramble_data(0, Secret1Idx);
-            for (int i = SECRET1_START_ADDR; i <= SECRET1_END_ADDR; i++) begin
-              otp_a[i] = ((i - SECRET1_START_ADDR) % 2) ? data[SCRAMBLE_DATA_SIZE-1:TL_DW] :
-                                                          data[TL_DW-1:0];
-            end
-            data = descramble_data(0, Secret2Idx);
-            for (int i = SECRET2_START_ADDR; i <= SECRET2_END_ADDR; i++) begin
-              otp_a[i] = ((i - SECRET2_START_ADDR) % 2) ? data[SCRAMBLE_DATA_SIZE-1:TL_DW] :
-                                                          data[TL_DW-1:0];
-            end
-            predict_digest_csrs();
-            `uvm_info(`gfn, "clear internal memory and digest", UVM_HIGH)
-          end
-        end
         @(posedge cfg.otp_ctrl_vif.pwr_otp_done_o || cfg.under_reset ||
                   cfg.otp_ctrl_vif.alert_reqs) begin
           if (!cfg.under_reset && !cfg.otp_ctrl_vif.alert_reqs) begin
diff --git a/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_base_vseq.sv b/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_base_vseq.sv
index c20923e..9bbe9ec 100644
--- a/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_base_vseq.sv
+++ b/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_base_vseq.sv
@@ -65,15 +65,24 @@
   // setup basic otp_ctrl features
   virtual task otp_ctrl_init();
     // reset memory to avoid readout X
-    cfg.mem_bkdr_util_h.clear_mem();
-    cfg.backdoor_clear_mem = 1;
-    used_dai_addr_q.delete();
+    clear_otp_memory();
     lc_state = 0;
     lc_cnt   = 0;
   endtask
 
-  // some registers won't set to default value until otp_init is done
+  virtual function void clear_otp_memory();
+    cfg.mem_bkdr_util_h.clear_mem();
+    cfg.backdoor_clear_mem = 1;
+    used_dai_addr_q.delete();
+  endfunction
+
+  // Overide this task for otp_ctrl_common_vseq and otp_ctrl_stress_all_with_rand_reset_vseq
+  // 1). Some registers won't set to default value until otp_init is done
+  // 2). Clear memory for next sequence to run. This can avoid ECC injection error and
+  //     write_blank error
   virtual task read_and_check_all_csrs_after_reset();
+    cfg.otp_ctrl_vif.drive_lc_escalate_en(lc_ctrl_pkg::Off);
+    clear_otp_memory();
     otp_pwr_init();
     super.read_and_check_all_csrs_after_reset();
   endtask
diff --git a/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_smoke_vseq.sv b/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_smoke_vseq.sv
index ebc8d38..6701747 100644
--- a/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_smoke_vseq.sv
+++ b/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_smoke_vseq.sv
@@ -77,6 +77,13 @@
     check_lc_err();
   endtask
 
+  // Used for stress_all sequence to clear OTP internal memory before going to next test.
+  // This can avoid unexpected ECC injection errors or write_blank errors.
+  virtual task post_start();
+    super.post_start();
+    clear_otp_memory();
+  endtask
+
   virtual task check_lc_err();
     fork
       forever begin