[dv/flash] Add partition read-only control to OTF sequences

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 dcddde9..0755427 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
@@ -69,6 +69,8 @@
   uint op_on_info1_partition_pc;  // Choose info1 partition.
   uint op_on_info2_partition_pc;  // Choose info2 partition.
 
+  bit avoid_ro_partitions; // Avoid partitions defined as read-only.
+
   bit op_readonly_on_info_partition;   // Make info  partition read-only.
   bit op_readonly_on_info1_partition;  // Make info1 partition read-only.
   bit op_readonly_on_info2_partition;  // Make info2 partition read-only.
@@ -203,6 +205,8 @@
     // info1 partition will be read-only by default
     op_readonly_on_info1_partition = 1;
 
+    avoid_ro_partitions = 0;
+
     op_erase_type_bank_pc = 20;
     op_prog_type_repair_pc = 10;
     op_max_words = 512;
diff --git a/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_derr_detect_vseq.sv b/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_derr_detect_vseq.sv
index 489b674..fecbbd9 100644
--- a/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_derr_detect_vseq.sv
+++ b/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_derr_detect_vseq.sv
@@ -30,8 +30,10 @@
           end else begin
             num = ctrl_info_num;
           end
+          // If the partition that selected configured as read-only, skip the program
+          sync_otf_wr_ro_part();
           randcase
-            1:prog_flash(ctrl, bank, num, fractions);
+            cfg.otf_wr_pct:prog_flash(ctrl, bank, num, fractions);
             1:read_flash(ctrl, bank, num, fractions);
           endcase
         end
diff --git a/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_filesystem_support_vseq.sv b/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_filesystem_support_vseq.sv
index b03c2ce..0f4b9e9 100644
--- a/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_filesystem_support_vseq.sv
+++ b/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_filesystem_support_vseq.sv
@@ -22,6 +22,9 @@
   virtual task body();
     int round;
 
+    // Don't select a partition defined as read-only
+    cfg.seq_cfg.avoid_ro_partitions = 1'b1;
+
     special_info_acc_c.constraint_mode(0);
     flash_program_data_c.constraint_mode(0);
 
diff --git a/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_intr_wr_vseq.sv b/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_intr_wr_vseq.sv
index f43b738..2d00fb3 100644
--- a/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_intr_wr_vseq.sv
+++ b/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_intr_wr_vseq.sv
@@ -16,6 +16,9 @@
     flash_op_t ctrl;
     int num, bank;
 
+    // Don't select a partition defined as read-only
+    cfg.seq_cfg.avoid_ro_partitions = 1'b1;
+
     flash_program_data_c.constraint_mode(0);
     repeat(100) begin
       `DV_CHECK_MEMBER_RANDOMIZE_FATAL(rand_op)
diff --git a/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_otf_base_vseq.sv b/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_otf_base_vseq.sv
index f379478..3873b7e 100644
--- a/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_otf_base_vseq.sv
+++ b/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_otf_base_vseq.sv
@@ -93,10 +93,18 @@
     solve rand_op.addr before rand_op.num_words;
 
     if (cfg.seq_cfg.op_readonly_on_info_partition) {
-      rand_op.partition == FlashPartInfo -> rand_op.op == flash_ctrl_pkg::FlashOpRead;
+      if (cfg.seq_cfg.avoid_ro_partitions) {
+        rand_op.partition != FlashPartInfo;
+      } else {
+        rand_op.partition == FlashPartInfo -> rand_op.op == flash_ctrl_pkg::FlashOpRead;
+      }
     }
     if (cfg.seq_cfg.op_readonly_on_info1_partition) {
-      rand_op.partition == FlashPartInfo1 -> rand_op.op == flash_ctrl_pkg::FlashOpRead;
+      if (cfg.seq_cfg.avoid_ro_partitions) {
+        rand_op.partition != FlashPartInfo1;
+      } else {
+        rand_op.partition == FlashPartInfo1 -> rand_op.op == flash_ctrl_pkg::FlashOpRead;
+      }
     }
 
     rand_op.partition dist { FlashPartData := 1, [FlashPartInfo:FlashPartInfo2] :/ 1};
@@ -120,6 +128,24 @@
     allow_spec_info_acc dist { 3'h7 := 1, 3'h0 := 1, [1:6] :/ 2};
   }
 
+  // If the partition that selected configured as read-only, set otf_wr_pct to 0 to make sure to
+  // not program those partitions.
+  int otf_wr_pct_temp, otf_bwr_pct_temp;
+  function void sync_otf_wr_ro_part();
+    if ((cfg.seq_cfg.op_readonly_on_info_partition &&
+         rand_op.partition == FlashPartInfo) ||
+        (cfg.seq_cfg.op_readonly_on_info1_partition &&
+         rand_op.partition == FlashPartInfo1)) begin
+      otf_wr_pct_temp = cfg.otf_wr_pct;
+      otf_bwr_pct_temp = cfg.otf_bwr_pct;
+      cfg.otf_wr_pct = 0;
+      cfg.otf_bwr_pct = 0;
+    end else begin
+      cfg.otf_wr_pct = otf_wr_pct_temp;
+      cfg.otf_bwr_pct = otf_bwr_pct_temp;
+    end
+  endfunction : sync_otf_wr_ro_part
+
   function void post_randomize();
     super.post_randomize();
     foreach (rand_regions[i]) begin
@@ -443,7 +469,7 @@
         `uvm_create_obj(flash_otf_item, exp_item)
 
         exp_item.cmd = flash_op;
-        exp_item.dq = cfg.calculate_expected_data(flash_op, flash_program_data);
+        exp_item.dq = flash_program_data;
         exp_item.region = my_region;
         // Scramble data
         exp_item.scramble(otp_addr_key, otp_data_key, flash_op.otf_addr);
diff --git a/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_oversize_error_vseq.sv b/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_oversize_error_vseq.sv
index fa3eaf9..f9427e9 100644
--- a/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_oversize_error_vseq.sv
+++ b/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_oversize_error_vseq.sv
@@ -30,6 +30,8 @@
           end else begin
             num = ctrl_info_num;
           end
+          // If the partition that selected configured as read-only, skip the program
+          sync_otf_wr_ro_part();
           randcase
             cfg.otf_wr_pct:prog_flash(ctrl, bank, num, fractions);
             cfg.otf_rd_pct:read_flash(ctrl, bank, num, fractions);
diff --git a/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_prog_reset_vseq.sv b/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_prog_reset_vseq.sv
index 5b49a64..f05f42e 100644
--- a/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_prog_reset_vseq.sv
+++ b/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_prog_reset_vseq.sv
@@ -40,6 +40,10 @@
     int num, bank, iter;
     int state_long_timeout_ns = 10000000; // 10ms
     int state_timeout_ns = 100000; // 100us
+
+    // Don't select a partition defined as read-only
+    cfg.seq_cfg.avoid_ro_partitions = 1'b1;
+
     cfg.m_tl_agent_cfg.check_tl_errs = 0;
     cfg.m_tl_agent_cfgs["flash_ctrl_eflash_reg_block"].check_tl_errs = 0;
 
diff --git a/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_rw_evict_vseq.sv b/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_rw_evict_vseq.sv
index 22f8b00..767fbae 100644
--- a/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_rw_evict_vseq.sv
+++ b/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_rw_evict_vseq.sv
@@ -16,6 +16,10 @@
 
     flash_op_t init_ctrl;
     flash_dv_part_e part;
+
+    // Don't select a partition defined as read-only
+    cfg.seq_cfg.avoid_ro_partitions = 1'b1;
+
     bank = $urandom_range(0, 1);
 
     fork
diff --git a/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_rw_rnd_wd_vseq.sv b/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_rw_rnd_wd_vseq.sv
index 0742d60..6bd8a9d 100644
--- a/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_rw_rnd_wd_vseq.sv
+++ b/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_rw_rnd_wd_vseq.sv
@@ -43,8 +43,10 @@
               num = 128 / fractions;
             end
           end
+          // If the partition that selected configured as read-only, skip the program
+          sync_otf_wr_ro_part();
           randcase
-            1:prog_flash(ctrl, bank, num, fractions);
+            cfg.otf_wr_pct:prog_flash(ctrl, bank, num, fractions);
             1:read_flash(ctrl, bank, num, fractions);
           endcase
         end
diff --git a/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_rw_vseq.sv b/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_rw_vseq.sv
index 5402c4e..71f2eab 100644
--- a/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_rw_vseq.sv
+++ b/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_rw_vseq.sv
@@ -9,7 +9,6 @@
   int num, bank;
 
   virtual task body();
-    int otf_wr_pct_temp;
     cfg.clk_rst_vif.wait_clks(5);
 
     fork
@@ -24,16 +23,7 @@
             num = ctrl_info_num;
           end
           // If the partition that selected configured as read-only, skip the program
-          if ((cfg.otf_wr_pct != 0) &&
-              ((cfg.seq_cfg.op_readonly_on_info_partition &&
-                rand_op.partition == FlashPartInfo) ||
-               (cfg.seq_cfg.op_readonly_on_info1_partition &&
-                rand_op.partition == FlashPartInfo1))) begin
-            otf_wr_pct_temp = cfg.otf_wr_pct;
-            cfg.otf_wr_pct = 0;
-          end else begin
-            cfg.otf_wr_pct = otf_wr_pct_temp;
-          end
+          sync_otf_wr_ro_part();
           randcase
             cfg.otf_wr_pct:prog_flash(ctrl, bank, num, fractions);
             cfg.otf_rd_pct:read_flash(ctrl, bank, num, fractions);
diff --git a/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_wo_vseq.sv b/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_wo_vseq.sv
index 4c8a34a..9b7e591 100644
--- a/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_wo_vseq.sv
+++ b/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_wo_vseq.sv
@@ -11,6 +11,9 @@
     flash_op_t ctrl;
     int num, bank;
 
+    // Don't select a partition defined as read-only
+    cfg.seq_cfg.avoid_ro_partitions = 1'b1;
+
     flash_program_data_c.constraint_mode(0);
 
     repeat(100) begin
diff --git a/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_wr_path_intg_vseq.sv b/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_wr_path_intg_vseq.sv
index dd1c765..43ac217 100644
--- a/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_wr_path_intg_vseq.sv
+++ b/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_wr_path_intg_vseq.sv
@@ -13,6 +13,9 @@
     string path = "tb.dut.u_prog_fifo.wdata_i[38]";
     int    state_timeout_ns = 100000; // 100us
 
+    // Don't select a partition defined as read-only
+    cfg.seq_cfg.avoid_ro_partitions = 1'b1;
+
     repeat(5) begin
       flash_otf_region_cfg(.scr_mode(scr_ecc_cfg), .ecc_mode(scr_ecc_cfg));
       `uvm_info(`gfn, "Assert write path err", UVM_LOW)
diff --git a/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_write_rnd_wd_vseq.sv b/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_write_rnd_wd_vseq.sv
index 369e59b..7644790 100644
--- a/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_write_rnd_wd_vseq.sv
+++ b/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_write_rnd_wd_vseq.sv
@@ -14,6 +14,9 @@
     int num, bank;
     int mywd;
 
+    // Don't select a partition defined as read-only
+    cfg.seq_cfg.avoid_ro_partitions = 1'b1;
+
     num = 1;
     flash_program_data_c.constraint_mode(0);
     repeat(100) begin
diff --git a/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_write_word_sweep_vseq.sv b/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_write_word_sweep_vseq.sv
index cafb0ea..61593fe 100644
--- a/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_write_word_sweep_vseq.sv
+++ b/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_write_word_sweep_vseq.sv
@@ -13,6 +13,10 @@
     int num, bank;
     int mywd;
 
+    // Don't select a partition defined as read-only
+    cfg.seq_cfg.avoid_ro_partitions = 1'b1;
+
+    `DV_CHECK_MEMBER_RANDOMIZE_FATAL(rand_op)
     ctrl = rand_op;
     bank = rand_op.addr[OTFBankId];
     num = 1;
diff --git a/hw/ip/flash_ctrl/dv/flash_ctrl_base_sim_cfg.hjson b/hw/ip/flash_ctrl/dv/flash_ctrl_base_sim_cfg.hjson
index 08552a0..4d1d968 100644
--- a/hw/ip/flash_ctrl/dv/flash_ctrl_base_sim_cfg.hjson
+++ b/hw/ip/flash_ctrl/dv/flash_ctrl_base_sim_cfg.hjson
@@ -274,7 +274,8 @@
     {
       name: flash_ctrl_derr_detect
       uvm_test_seq: flash_ctrl_derr_detect_vseq
-      run_opts: ["+scb_otf_en=1", "+ecc_mode=3", "+derr_pct=1", "+rerun=5"]
+      run_opts: ["+scb_otf_en=1", "+ecc_mode=3", "+derr_pct=1",
+                 "+rerun=5", "+otf_wr_pct=1"]
       reseed: 5
     }
     {