[dv/flash_ctrl] Added some configs to flash_ctrl_seq_cfg & rand_ops_vseq

Signed-off-by: Eitan Shapira <eitan.shapira@nuvoton.com>
diff --git a/hw/ip/flash_ctrl/dv/env/flash_ctrl_env_cfg.sv b/hw/ip/flash_ctrl/dv/env/flash_ctrl_env_cfg.sv
index 30a227d..2baaeb8 100644
--- a/hw/ip/flash_ctrl/dv/env/flash_ctrl_env_cfg.sv
+++ b/hw/ip/flash_ctrl/dv/env/flash_ctrl_env_cfg.sv
@@ -31,8 +31,9 @@
     m_eflash_tl_agent_cfg = tl_agent_cfg::type_id::create("m_eflash_tl_agent_cfg");
     m_eflash_tl_agent_cfg.if_mode = dv_utils_pkg::Host;
 
-    // create the seq_cfg
+    // create the seq_cfg and call configure
     seq_cfg = flash_ctrl_seq_cfg::type_id::create("seq_cfg");
+    seq_cfg.configure();
 
     // set num_interrupts & num_alerts
     begin
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 317f808..6479818 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
@@ -10,48 +10,122 @@
 
   // Maximun number of times the vseq is randomized and rerun.
   // TODO: This should move to `dv_base_seq_cfg`.
-  uint max_num_trans = 20;
+  uint max_num_trans;
 
   // Memory protection configuration.
-  uint num_en_mp_regions = flash_ctrl_pkg::MpRegions;
+  uint num_en_mp_regions;
 
   // This enables memory protection regions to overlap.
-  bit allow_mp_region_overlap = 1'b0;
+  bit allow_mp_region_overlap;
+
+  // When this knob is NOT FlashOpInvalid (default) the selected operation will be the only operation to run in the test (FlashOpRead, FlashOpProgram, FlashOpErase).
+  flash_ctrl_pkg::flash_op_e flash_only_op;
 
   // Weights to enable read / program and erase for each mem region.
   // TODO: Should these be per region?
-  uint mp_region_read_en_pc = 50;
-  uint mp_region_program_en_pc = 50;
-  uint mp_region_erase_en_pc = 50;
-  uint mp_region_data_partition_pc = 50;
-  uint mp_region_max_pages = 32;
+  uint mp_region_read_en_pc;
+  uint mp_region_program_en_pc;
+  uint mp_region_erase_en_pc;
+  uint mp_region_data_partition_pc;
+  uint mp_region_max_pages;
 
   // Knob to control bank level erasability.
-  uint bank_erase_en_pc = 50;
+  uint bank_erase_en_pc;
 
   // Default region knobs.
-  uint default_region_read_en_pc    = 50;
-  uint default_region_program_en_pc = 50;
-  uint default_region_erase_en_pc   = 50;
+  uint default_region_read_en_pc;
+  uint default_region_program_en_pc;
+  uint default_region_erase_en_pc;
 
   // Control the number of flash ops.
-  uint max_flash_ops_per_cfg = 50;
+  uint max_flash_ops_per_cfg;
 
   // Flash ctrl op randomization knobs.
   
   // Partition select. Make sure to keep sum equals to 100.
-  uint op_on_data_partition_pc = 100; // Choose data partition.
-  uint op_on_info_partition_pc = 0;   // Choose info partition.
-  uint op_on_info1_partition_pc = 0;  // Choose info1 partition.
-  uint op_on_red_partition_pc = 0;    // Choose redundancy partition.
+  uint op_on_data_partition_pc;  // Choose data partition.
+  uint op_on_info_partition_pc;  // Choose info partition.
+  uint op_on_info1_partition_pc; // Choose info1 partition.
+  uint op_on_red_partition_pc;   // Choose redundancy partition.
 
-  uint op_erase_type_bank_pc = 0;
-  uint op_max_words = 512;
-  bit  op_allow_invalid = 1'b0;
+  bit op_readonly_on_info_partition;  // Make info partition read-only.
+  bit op_readonly_on_info1_partition; // Make info1 partition read-only.
+
+
+  uint op_erase_type_bank_pc;
+  uint op_max_words;
+  bit  op_allow_invalid;
 
   // Poll fifo status before writing to prog_fifo / reading from rd_fifo.
-  uint poll_fifo_status_pc = 30;
+  uint poll_fifo_status_pc;
 
   `uvm_object_new
 
+  // Set partition select percentages. Make sure to keep sum equals to 100.
+  virtual function void set_partition_pc(uint sel_data_part_pc = 100,
+                                         uint sel_info_part_pc = 0,
+                                         uint sel_info1_part_pc = 0,
+                                         uint sel_red_part_pc = 0);
+
+    `DV_CHECK_EQ(sel_data_part_pc + sel_info_part_pc + sel_info1_part_pc + sel_red_part_pc, 100,
+                        $sformatf("Error! sum of arguments must be 100. Be aware of arguments \
+default values - 100 for data partition and 0 for all the others. Arguments current value: \
+sel_data_part_pc=%0d , sel_info_part_pc=%0d , sel_info1_part_pc=%0d , sel_red_part_pc=%0d",
+                                   sel_data_part_pc, sel_info_part_pc, sel_info1_part_pc,
+                                   sel_red_part_pc))
+
+    op_on_data_partition_pc = sel_data_part_pc;   // Percenteges to choose data partition.
+    op_on_info_partition_pc = sel_info_part_pc;   // Percenteges to choose info partition.
+    op_on_info1_partition_pc = sel_info1_part_pc; // Percenteges to choose info1 partition.
+    op_on_red_partition_pc = sel_red_part_pc;     // Percenteges to choose redundancy partition.
+
+  endfunction : set_partition_pc
+
+
+  virtual function void configure();
+    max_num_trans = 20;
+
+    // Memory protection configuration.
+    num_en_mp_regions = flash_ctrl_pkg::MpRegions;
+
+    // This enables memory protection regions to overlap.
+    allow_mp_region_overlap = 1'b0;
+
+    // Weights to enable read / program and erase for each mem region.
+    // TODO: Should these be per region?
+    mp_region_read_en_pc = 50;
+    mp_region_program_en_pc = 50;
+    mp_region_erase_en_pc = 50;
+    mp_region_data_partition_pc = 50;
+    mp_region_max_pages = 32;
+
+    // Knob to control bank level erasability.
+    bank_erase_en_pc = 50;
+
+    // Default region knobs.
+    default_region_read_en_pc    = 50;
+    default_region_program_en_pc = 50;
+    default_region_erase_en_pc   = 50;
+
+    // When this knob is not FlashOpInvalid the selected operation will be the only operation to run in the test (FlashOpRead, FlashOpProgram, FlashOpErase).
+    flash_only_op = FlashOpInvalid;
+
+    // Control the number of flash ops.
+    max_flash_ops_per_cfg = 50;
+
+    // Flash ctrl op randomization knobs.
+    op_readonly_on_info_partition = 0; // Make info partition read-only.
+    op_readonly_on_info1_partition = 0; // Make info1 partition read-only.
+
+    op_erase_type_bank_pc = 0;
+    op_max_words = 512;
+    op_allow_invalid = 1'b0;
+
+    // Poll fifo status before writing to prog_fifo / reading from rd_fifo.
+    poll_fifo_status_pc = 30;
+
+    set_partition_pc();
+
+  endfunction : configure
+
 endclass
diff --git a/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_rand_ops_vseq.sv b/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_rand_ops_vseq.sv
index d21c0fa..e73bb9f 100644
--- a/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_rand_ops_vseq.sv
+++ b/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_rand_ops_vseq.sv
@@ -20,6 +20,7 @@
   rand flash_op_t flash_op;
 
   constraint flash_op_c {
+    solve flash_op.partition before flash_op.op;
     solve flash_op.op before flash_op.erase_type;
     solve flash_op.op before flash_op.num_words;
     solve flash_op.addr before flash_op.num_words ;
@@ -30,6 +31,10 @@
       flash_op.op != flash_ctrl_pkg::FlashOpInvalid;
     }
 
+    if (cfg.seq_cfg.flash_only_op != flash_ctrl_pkg::FlashOpInvalid) {
+      flash_op.op == cfg.seq_cfg.flash_only_op;
+    }
+    
     (flash_op.op == flash_ctrl_pkg::FlashOpErase) ->
         flash_op.erase_type dist {
           flash_ctrl_pkg::FlashErasePage :/ (100 - cfg.seq_cfg.op_erase_type_bank_pc),
@@ -43,6 +48,15 @@
       FlashPartRed   :/ cfg.seq_cfg.op_on_red_partition_pc
     };
 
+    if (cfg.seq_cfg.op_readonly_on_info_partition) {
+      flash_op.partition == FlashPartInfo ->
+        flash_op.op == flash_ctrl_pkg::FlashOpRead;
+    }
+    if (cfg.seq_cfg.op_readonly_on_info1_partition) {
+      flash_op.partition == FlashPartInfo1 ->
+        flash_op.op == flash_ctrl_pkg::FlashOpRead;
+    }
+
     if (flash_op.op inside {flash_ctrl_pkg::FlashOpRead, flash_ctrl_pkg::FlashOpProgram}) {
       flash_op.num_words inside {
         [1:FlashNumBusWords - flash_op.addr[TL_AW-1:TL_SZW]]