[i2c, dv] Updates for both i2c_agent and i2c_sanity

1) i2c_agent
  - Add knob to control target address mode (7-bit: current support, 10-bit: RFU)
  - Update agent to support re-programming registers from test
  - Remove unused macros

2) i2c_sanity
  - Support re-programming timing regs during tranceiving tran in i2c_sanity
  - Add knob to control target address mode

Signed-off-by: Tung Hoang <tung.hoang.290780@gmail.com>
diff --git a/hw/dv/sv/i2c_agent/i2c_agent_cfg.sv b/hw/dv/sv/i2c_agent/i2c_agent_cfg.sv
index 6c9fc7d..ff7dcec 100644
--- a/hw/dv/sv/i2c_agent/i2c_agent_cfg.sv
+++ b/hw/dv/sv/i2c_agent/i2c_agent_cfg.sv
@@ -4,13 +4,28 @@
 
 class i2c_agent_cfg extends dv_base_agent_cfg;
 
-  bit en_monitor  = 1'b1; // enable monitor
+  bit en_monitor = 1'b1; // enable monitor
+  i2c_target_addr_mode_e target_addr_mode = Addr7BitMode;
 
   timing_cfg_t    timing_cfg;
+
   virtual i2c_if  vif;
 
   `uvm_object_utils_begin(i2c_agent_cfg)
-    `uvm_field_int(en_monitor,    UVM_DEFAULT)
+    `uvm_field_int(en_monitor,                                UVM_DEFAULT)
+    `uvm_field_enum(i2c_target_addr_mode_e, target_addr_mode, UVM_DEFAULT)
+    `uvm_field_int(timing_cfg.tSetupStart,                    UVM_DEFAULT)
+    `uvm_field_int(timing_cfg.tHoldStart,                     UVM_DEFAULT)
+    `uvm_field_int(timing_cfg.tClockStart,                    UVM_DEFAULT)
+    `uvm_field_int(timing_cfg.tClockLow,                      UVM_DEFAULT)
+    `uvm_field_int(timing_cfg.tSetupBit,                      UVM_DEFAULT)
+    `uvm_field_int(timing_cfg.tClockPulse,                    UVM_DEFAULT)
+    `uvm_field_int(timing_cfg.tHoldBit,                       UVM_DEFAULT)
+    `uvm_field_int(timing_cfg.tClockStop,                     UVM_DEFAULT)
+    `uvm_field_int(timing_cfg.tSetupStop,                     UVM_DEFAULT)
+    `uvm_field_int(timing_cfg.tHoldStop,                      UVM_DEFAULT)
+    `uvm_field_int(timing_cfg.tTimeOut,                       UVM_DEFAULT)
+    `uvm_field_int(timing_cfg.enbTimeOut,                     UVM_DEFAULT)
   `uvm_object_utils_end
 
   `uvm_object_new
diff --git a/hw/dv/sv/i2c_agent/i2c_agent_pkg.sv b/hw/dv/sv/i2c_agent/i2c_agent_pkg.sv
index 7e6ba45..df6ebc8 100644
--- a/hw/dv/sv/i2c_agent/i2c_agent_pkg.sv
+++ b/hw/dv/sv/i2c_agent/i2c_agent_pkg.sv
@@ -2,6 +2,8 @@
 // Licensed under the Apache License, Version 2.0, see LICENSE for details.
 // SPDX-License-Identifier: Apache-2.0
 
+// I2C specification: https://www.nxp.com/docs/en/user-guide/UM10204.pdf
+
 package i2c_agent_pkg;
   // dep packages
   import uvm_pkg::*;
@@ -12,10 +14,6 @@
   `include "uvm_macros.svh"
   `include "dv_macros.svh"
 
-  // local macros
-  parameter uint I2C_ADDR_WIDTH = 7;
-  parameter uint I2C_DATA_WIDTH = 8;
-
   typedef enum logic [3:0] {
     None, DevAck, RdData
   } drv_type_e;
@@ -37,6 +35,11 @@
     bit [30:0]  tTimeOut;
   } timing_cfg_t;
 
+  typedef enum int {
+    Addr7BitMode  = 7,
+    Addr10BitMode = 10
+  } i2c_target_addr_mode_e;
+
   // forward declare classes to allow typedefs below
   typedef class i2c_item;
   typedef class i2c_agent_cfg;
diff --git a/hw/dv/sv/i2c_agent/i2c_device_driver.sv b/hw/dv/sv/i2c_agent/i2c_device_driver.sv
index a9e9cd9..362880e 100644
--- a/hw/dv/sv/i2c_agent/i2c_device_driver.sv
+++ b/hw/dv/sv/i2c_agent/i2c_device_driver.sv
@@ -6,11 +6,9 @@
   `uvm_component_utils(i2c_device_driver)
   `uvm_component_new
 
-  bit [I2C_DATA_WIDTH-1:0] data;
+  rand bit [7:0] rd_data;
 
-  rand bit [I2C_DATA_WIDTH-1:0] rd_data;
-
-  constraint rd_data_c { rd_data inside {[0 : ((1 << I2C_DATA_WIDTH) - 1)]}; }
+  constraint rd_data_c { rd_data inside {[0 : 127]}; }
 
   virtual task get_and_drive();
     i2c_item rsp_item;
@@ -26,7 +24,7 @@
         end
         RdData: begin
           `DV_CHECK_MEMBER_RANDOMIZE_FATAL(rd_data)
-          for (int i = I2C_DATA_WIDTH-1; i >= 0; i--) begin
+          for (int i = 7; i >= 0; i--) begin
             cfg.vif.device_send_bit(cfg.timing_cfg, rd_data[i]);
           end
           `uvm_info(`gfn, $sformatf("driver, trans %0d, byte %0d  %0b",
diff --git a/hw/dv/sv/i2c_agent/i2c_if.sv b/hw/dv/sv/i2c_agent/i2c_if.sv
index 46c8696..a96a1f8 100644
--- a/hw/dv/sv/i2c_agent/i2c_if.sv
+++ b/hw/dv/sv/i2c_agent/i2c_if.sv
@@ -21,7 +21,7 @@
     repeat (dly) @(posedge clk_i);
   endtask : wait_for_dly
 
-  task automatic wait_for_host_start(timing_cfg_t tc);
+  task automatic wait_for_host_start(ref timing_cfg_t tc);
     forever begin
       @(negedge sda_i);
       wait_for_dly(tc.tHoldStart);
@@ -31,8 +31,8 @@
     end
   endtask: wait_for_host_start
 
-  task automatic wait_for_host_rstart(timing_cfg_t tc,
-                                      output bit   rstart);
+  task automatic wait_for_host_rstart(ref timing_cfg_t tc,
+                                      output bit rstart);
     rstart = 1'b0;
     forever begin
       @(posedge scl_i && sda_i);
@@ -48,8 +48,8 @@
     end
   endtask: wait_for_host_rstart
 
-  task automatic wait_for_host_stop(timing_cfg_t tc,
-                                    output bit   stop);
+  task automatic wait_for_host_stop(ref timing_cfg_t tc,
+                                    output bit stop);
     stop = 1'b0;
     forever begin
       @(posedge scl_i);
@@ -76,7 +76,7 @@
     join
   endtask: wait_for_host_stop_or_rstart
 
-  task automatic wait_for_host_ack(timing_cfg_t tc);
+  task automatic wait_for_host_ack(ref timing_cfg_t tc);
     @(negedge sda_i);
     wait_for_dly(tc.tClockLow + tc.tSetupBit);
     forever begin
@@ -89,7 +89,7 @@
     wait_for_dly(tc.tHoldBit);
   endtask: wait_for_host_ack
 
-  task automatic wait_for_host_nack(timing_cfg_t tc);
+  task automatic wait_for_host_nack(ref timing_cfg_t tc);
     @(negedge sda_i);
     wait_for_dly(tc.tClockLow + tc.tSetupBit);
     forever begin
@@ -124,7 +124,7 @@
     join
   endtask: wait_for_host_ack_or_nack
 
-  task automatic wait_for_device_ack(timing_cfg_t tc);
+  task automatic wait_for_device_ack(ref timing_cfg_t tc);
     @(negedge sda_o && scl_o);
     wait_for_dly(tc.tSetupBit);
     forever begin
@@ -137,8 +137,10 @@
     wait_for_dly(tc.tHoldBit);
   endtask: wait_for_device_ack
 
-  task automatic device_send_ack(timing_cfg_t tc);
+  task automatic device_send_ack(ref timing_cfg_t tc);
     device_stretch_clk(tc);
+    sda_o = 1'b1;
+    wait_for_dly(tc.tClockLow);
     sda_o = 1'b0;
     wait_for_dly(tc.tSetupBit);
     @(posedge scl_i);
@@ -146,8 +148,9 @@
     sda_o = 1'b1;
   endtask: device_send_ack
 
-  task automatic device_send_bit(timing_cfg_t tc,
-                                 bit          bit_i);
+  task automatic device_send_bit(ref timing_cfg_t tc,
+                                 input bit bit_i);
+    device_stretch_clk(tc);
     sda_o = 1'b1;
     wait_for_dly(tc.tClockLow);
     sda_o = bit_i;
@@ -157,7 +160,7 @@
     sda_o = 1'b1;
   endtask: device_send_bit
 
-  task automatic device_stretch_clk(timing_cfg_t tc);
+  task automatic device_stretch_clk(ref timing_cfg_t tc);
     if (tc.enbTimeOut) begin
       scl_o = 1'b0;
       wait_for_dly(tc.tTimeOut);
@@ -165,9 +168,9 @@
     end
   endtask : device_stretch_clk
 
-  task automatic get_bit_data(string       src = "host",
-                              timing_cfg_t tc,
-                              output bit   bit_o); 
+  task automatic get_bit_data(string src = "host",
+                              ref timing_cfg_t tc,
+                              output bit bit_o);
     wait_for_dly(tc.tClockLow + tc.tSetupBit);
     @(posedge scl_i);
     bit_o = (src == "host") ? sda_i : sda_o;
diff --git a/hw/dv/sv/i2c_agent/i2c_item.sv b/hw/dv/sv/i2c_agent/i2c_item.sv
index 001f447..c7301a4 100644
--- a/hw/dv/sv/i2c_agent/i2c_item.sv
+++ b/hw/dv/sv/i2c_agent/i2c_item.sv
@@ -5,8 +5,8 @@
 class i2c_item extends uvm_sequence_item;
 
   // transaction data part
-  bit [I2C_DATA_WIDTH-1:0] data_q[$];
-  bit [I2C_ADDR_WIDTH-1:0] addr;
+  bit [7:0]                data_q[$];
+  bit [9:0]                addr; // enough to support both 7 & 10-bit target address
   int                      tran_id;
   int                      num_data;
   bus_op_e                 bus_op;
diff --git a/hw/dv/sv/i2c_agent/i2c_monitor.sv b/hw/dv/sv/i2c_agent/i2c_monitor.sv
index 6903306..4706a4f 100644
--- a/hw/dv/sv/i2c_agent/i2c_monitor.sv
+++ b/hw/dv/sv/i2c_agent/i2c_monitor.sv
@@ -13,8 +13,8 @@
   uvm_analysis_port #(i2c_item) wr_item_port;   // used to send complete wr_tran to sb
   uvm_analysis_port #(i2c_item) rd_item_port;   // used to send complete rd_tran to sb
 
-  local bit [I2C_DATA_WIDTH-1:0] mon_data;
-  local uint num_dut_tran;
+  local bit [7:0] mon_data;
+  local uint      num_dut_tran = 0;
   `uvm_component_new
 
   function void build_phase(uvm_phase phase);
@@ -22,7 +22,6 @@
     mon_item_port = new("mon_item_port", this);
     wr_item_port  = new("wr_item_port", this);
     rd_item_port  = new("rd_item_port", this);
-    num_dut_tran  = 0;
   endfunction : build_phase
 
   virtual task wait_for_reset_done();
@@ -39,92 +38,93 @@
   // collect transactions forever
   virtual protected task collect_thread(uvm_phase phase);
     i2c_item   complete_item;
-    i2c_item   partial_item;
+    i2c_item   mon_dut_item;
 
-    partial_item = i2c_item::type_id::create("partial_item", this);
+    mon_dut_item = i2c_item::type_id::create("mon_dut_item", this);
     forever begin
       if (cfg.en_monitor == 1'b1) begin
-        if (partial_item.stop || (!partial_item.stop && !partial_item.start && !partial_item.rstart)) begin
+        if (mon_dut_item.stop || (!mon_dut_item.stop && !mon_dut_item.start && !mon_dut_item.rstart)) begin
           cfg.vif.wait_for_host_start(cfg.timing_cfg);
           `uvm_info(`gfn, $sformatf("monitor, detect HOST START"), UVM_DEBUG)
         end else begin
-          partial_item.rstart = 1'b1;
+          mon_dut_item.rstart = 1'b1;
         end
         num_dut_tran++;
-        partial_item.start = 1'b1;
+        mon_dut_item.start = 1'b1;
         // issue address then rd/wr data
-        address_thread(partial_item, num_dut_tran);
-        if (partial_item.bus_op == BusOpRead) read_thread(partial_item);
-        else                              write_thread(partial_item);
+        address_thread(mon_dut_item, num_dut_tran);
+        if (mon_dut_item.bus_op == BusOpRead) read_thread(mon_dut_item);
+        else                                  write_thread(mon_dut_item);
         // send rsp_item to scoreboard
-        `downcast(complete_item, partial_item.clone());
+        `downcast(complete_item, mon_dut_item.clone());
         complete_item.stop = 1'b1;
         if (complete_item.bus_op == BusOpRead) rd_item_port.write(complete_item);
-        else                                 wr_item_port.write(complete_item);
-        `uvm_info(`gfn, $sformatf("\nmonitor, complete_item\n%s", complete_item.sprint()), UVM_DEBUG)
-        partial_item.clear_data();
+        else                                   wr_item_port.write(complete_item);
+        `uvm_info(`gfn, $sformatf("\nmonitor, complete_item\n%s",
+            complete_item.sprint()), UVM_DEBUG)
+        mon_dut_item.clear_data();
       end begin
         @(cfg.vif.clk_i);
       end
     end
   endtask: collect_thread
 
-  virtual protected task address_thread(i2c_item partial_item, uint id);
+  virtual protected task address_thread(i2c_item mon_dut_item, uint id);
     i2c_item clone_item;
     bit rw_req = 1'b0;
-    
+
     // sample address and r/w bit
-    partial_item.tran_id = id;
-    for (int i = I2C_ADDR_WIDTH-1; i >= 0; i--) begin
-      cfg.vif.get_bit_data("host", cfg.timing_cfg, partial_item.addr[i]);
+    mon_dut_item.tran_id = id;
+    for (int i = cfg.target_addr_mode - 1; i >= 0; i--) begin
+      cfg.vif.get_bit_data("host", cfg.timing_cfg, mon_dut_item.addr[i]);
     end
     cfg.vif.get_bit_data("host", cfg.timing_cfg, rw_req);
-    partial_item.bus_op = (rw_req) ? BusOpRead : BusOpWrite;
+    mon_dut_item.bus_op = (rw_req) ? BusOpRead : BusOpWrite;
     // get ack after transmitting address
-    partial_item.drv_type = DevAck;
-    `downcast(clone_item, partial_item.clone());
+    mon_dut_item.drv_type = DevAck;
+    `downcast(clone_item, mon_dut_item.clone());
     mon_item_port.write(clone_item);
     cfg.vif.wait_for_device_ack(cfg.timing_cfg);
     `uvm_info(`gfn, $sformatf("monitor, address, detect TARGET ACK"), UVM_DEBUG)
   endtask : address_thread
 
-  virtual protected task read_thread(i2c_item partial_item);
+  virtual protected task read_thread(i2c_item mon_dut_item);
     i2c_item clone_item;
     
-    partial_item.stop   = 1'b0;
-    partial_item.rstart = 1'b0;
-    partial_item.ack    = 1'b0;
-    partial_item.nack   = 1'b0;
-    while (!partial_item.stop && !partial_item.rstart) begin
+    mon_dut_item.stop   = 1'b0;
+    mon_dut_item.rstart = 1'b0;
+    mon_dut_item.ack    = 1'b0;
+    mon_dut_item.nack   = 1'b0;
+    while (!mon_dut_item.stop && !mon_dut_item.rstart) begin
       fork
         begin : iso_fork_read
           fork
             begin
               // ask driver response read data
-              partial_item.drv_type = RdData;
-              `downcast(clone_item, partial_item.clone());
+              mon_dut_item.drv_type = RdData;
+              `downcast(clone_item, mon_dut_item.clone());
               mon_item_port.write(clone_item);
               // sample read data
-              for (int i = I2C_DATA_WIDTH-1; i >= 0; i--) begin
+              for (int i = 7; i >= 0; i--) begin
                 cfg.vif.get_bit_data("device", cfg.timing_cfg, mon_data[i]);
                 `uvm_info(`gfn, $sformatf("monitor, rd_data, trans %0d, byte %0d, bit[%0d] %0b",
-                    partial_item.tran_id, partial_item.num_data+1, i, mon_data[i]), UVM_DEBUG)
+                    mon_dut_item.tran_id, mon_dut_item.num_data+1, i, mon_data[i]), UVM_DEBUG)
               end
-              partial_item.data_q.push_back(mon_data);
-              partial_item.num_data++;
+              mon_dut_item.data_q.push_back(mon_data);
+              mon_dut_item.num_data++;
               // sample host ack/nack (in the last byte, nack can be issue if rcont is set)
-              cfg.vif.wait_for_host_ack_or_nack(cfg.timing_cfg, partial_item.ack, partial_item.nack);
-              `DV_CHECK_NE_FATAL({partial_item.ack, partial_item.nack}, 2'b11)
+              cfg.vif.wait_for_host_ack_or_nack(cfg.timing_cfg, mon_dut_item.ack, mon_dut_item.nack);
+              `DV_CHECK_NE_FATAL({mon_dut_item.ack, mon_dut_item.nack}, 2'b11)
               `uvm_info(`gfn, $sformatf("monitor, detect HOST %s",
-                  (partial_item.ack) ? "ACK" : "NO_ACK"), UVM_DEBUG)
+                  (mon_dut_item.ack) ? "ACK" : "NO_ACK"), UVM_DEBUG)
             end
             begin
               cfg.vif.wait_for_host_stop_or_rstart(cfg.timing_cfg,
-                                                   partial_item.rstart,
-                                                   partial_item.stop);
-              `DV_CHECK_NE_FATAL({partial_item.rstart, partial_item.stop}, 2'b11)
+                                                   mon_dut_item.rstart,
+                                                   mon_dut_item.stop);
+              `DV_CHECK_NE_FATAL({mon_dut_item.rstart, mon_dut_item.stop}, 2'b11)
               `uvm_info(`gfn, $sformatf("monitor, rd_data, detect HOST %s",
-                  (partial_item.stop) ? "STOP" : "RSTART"), UVM_DEBUG)
+                  (mon_dut_item.stop) ? "STOP" : "RSTART"), UVM_DEBUG)
             end
           join_any
           disable fork;
@@ -133,34 +133,34 @@
     end
   endtask : read_thread
 
-  virtual protected task write_thread(i2c_item partial_item);
+  virtual protected task write_thread(i2c_item mon_dut_item);
     i2c_item clone_item;
 
-    partial_item.stop   = 1'b0;
-    partial_item.rstart = 1'b0;
-    while (!partial_item.stop && !partial_item.rstart) begin
+    mon_dut_item.stop   = 1'b0;
+    mon_dut_item.rstart = 1'b0;
+    while (!mon_dut_item.stop && !mon_dut_item.rstart) begin
       fork
         begin : iso_fork_write
           fork
             begin
               // ask driver's response a write request
-              for (int i = I2C_DATA_WIDTH-1; i >= 0; i--) begin
+              for (int i = 7; i >= 0; i--) begin
                 cfg.vif.get_bit_data("host", cfg.timing_cfg, mon_data[i]);
               end
-              partial_item.num_data++;
-              partial_item.data_q.push_back(mon_data);
-              partial_item.drv_type = DevAck;
-              `downcast(clone_item, partial_item.clone());
+              mon_dut_item.num_data++;
+              mon_dut_item.data_q.push_back(mon_data);
+              mon_dut_item.drv_type = DevAck;
+              `downcast(clone_item, mon_dut_item.clone());
               mon_item_port.write(clone_item);
               cfg.vif.wait_for_device_ack(cfg.timing_cfg);
             end
             begin
               cfg.vif.wait_for_host_stop_or_rstart(cfg.timing_cfg,
-                                                   partial_item.rstart,
-                                                   partial_item.stop);
-              `DV_CHECK_NE_FATAL({partial_item.rstart, partial_item.stop}, 2'b11)
+                                                   mon_dut_item.rstart,
+                                                   mon_dut_item.stop);
+              `DV_CHECK_NE_FATAL({mon_dut_item.rstart, mon_dut_item.stop}, 2'b11)
               `uvm_info(`gfn, $sformatf("monitor, wr_data, detect HOST %s %0b",
-                  (partial_item.stop) ? "STOP" : "RSTART", partial_item.stop), UVM_DEBUG)
+                  (mon_dut_item.stop) ? "STOP" : "RSTART", mon_dut_item.stop), UVM_DEBUG)
             end
           join_any
           disable fork;
@@ -185,3 +185,4 @@
 
   endtask : process_reset
 endclass : i2c_monitor
+
diff --git a/hw/ip/i2c/dv/env/i2c_env_cfg.sv b/hw/ip/i2c/dv/env/i2c_env_cfg.sv
index e7a0dd8..7d6a78f 100644
--- a/hw/ip/i2c/dv/env/i2c_env_cfg.sv
+++ b/hw/ip/i2c/dv/env/i2c_env_cfg.sv
@@ -4,6 +4,8 @@
 
 class i2c_env_cfg extends cip_base_env_cfg #(.RAL_T(i2c_reg_block));
 
+  i2c_target_addr_mode_e target_addr_mode = Addr7BitMode;
+
   // TODO: various knobs to enable certain routines
   bit do_rd_overflow  = 1'b0;
   bit do_wr_overflow  = 1'b0;
diff --git a/hw/ip/i2c/dv/env/i2c_env_pkg.sv b/hw/ip/i2c/dv/env/i2c_env_pkg.sv
index b97bbc4..5804cc9 100644
--- a/hw/ip/i2c/dv/env/i2c_env_pkg.sv
+++ b/hw/ip/i2c/dv/env/i2c_env_pkg.sv
@@ -47,7 +47,7 @@
   parameter uint I2C_MIN_TIMING  = 1;     // at least 1
   parameter uint I2C_MAX_TIMING  = 5;
   parameter uint I2C_TIME_RANGE  = I2C_MAX_TIMING - I2C_MIN_TIMING;
-  parameter uint I2C_TIMEOUT_ENB = 1;
+  parameter uint I2C_TIMEOUT_ENB = 0;  // TODO: temporaly disable
   parameter uint I2C_MIN_TIMEOUT = 1;
   parameter uint I2C_MAX_TIMEOUT = 2;
   parameter uint I2C_IDLE_TIME   = 1200;
diff --git a/hw/ip/i2c/dv/env/i2c_scoreboard.sv b/hw/ip/i2c/dv/env/i2c_scoreboard.sv
index 12f5ef0..ec380f5 100644
--- a/hw/ip/i2c/dv/env/i2c_scoreboard.sv
+++ b/hw/ip/i2c/dv/env/i2c_scoreboard.sv
@@ -250,7 +250,7 @@
     if (cfg.en_scb) begin
       str = {$sformatf("\n\n*** SCOREBOARD CHECK\n")};
       str = {str, $sformatf("    - Total checked trans   %0d\n", num_exp_tran)};
-      `uvm_info(`gfn, $sformatf("%s", str), UVM_LOW)
+      `uvm_info(`gfn, $sformatf("%s", str), UVM_DEBUG)
     end
   endfunction : report_phase
 
diff --git a/hw/ip/i2c/dv/env/seq_lib/i2c_base_vseq.sv b/hw/ip/i2c/dv/env/seq_lib/i2c_base_vseq.sv
index e8dfef8..36e1d8b 100644
--- a/hw/ip/i2c/dv/env/seq_lib/i2c_base_vseq.sv
+++ b/hw/ip/i2c/dv/env/seq_lib/i2c_base_vseq.sv
@@ -24,7 +24,7 @@
   rand uint                   num_wr_bytes;
   rand uint                   num_rd_bytes;
   rand bit   [7:0]            wr_data;
-  rand bit   [6:0]            addr;
+  rand bit   [9:0]            addr;  // support both 7-bit and 10-bit target address
   rand bit                    rw_bit;
   i2c_item                    fmt_item;
 
@@ -128,6 +128,16 @@
     end
   endtask : host_init
 
+  virtual task check_host_idle();
+    bit fmtempty, hostidle;
+    bit [TL_DW-1:0] reg_val;
+    do begin
+      csr_rd(.ptr(ral.status), .value(reg_val));
+      fmtempty = bit'(get_field_val(ral.status.fmtempty, reg_val));
+      hostidle = bit'(get_field_val(ral.status.hostidle, reg_val));
+    end while (!fmtempty || !hostidle);
+  endtask : check_host_idle
+
   function automatic void get_timing_values();
     // derived timing parameters
     timing_cfg.enbTimeOut  = e_timeout;
@@ -161,14 +171,19 @@
     cfg.m_i2c_agent_cfg.timing_cfg = timing_cfg;
     // set time to stop test
     cfg.m_i2c_agent_cfg.ok_to_end_delay_ns = DELAY_FOR_EOT_NS;
+    // config target address mode of agent to the same
+    cfg.m_i2c_agent_cfg.target_addr_mode = cfg.target_addr_mode;
   endtask : program_timing_regs
 
   virtual task program_format_flag(i2c_item item, string msg="");
-    bit [TL_DW-1:0] reg_val;
-
     csr_spinwait(.ptr(ral.status.fmtfull), .exp_data(1'b0));
-    reg_val = {19'd0, item.nakok, item.rcont, item.read, item.stop, item.start, item.fbyte};
-    csr_wr(.csr(ral.fdata), .value(reg_val));
+    ral.fdata.nakok.set(item.nakok);
+    ral.fdata.rcont.set(item.rcont);
+    ral.fdata.read.set(item.read);
+    ral.fdata.stop.set(item.stop);
+    ral.fdata.start.set(item.start);
+    ral.fdata.fbyte.set(item.fbyte);
+    csr_update(.csr(ral.fdata));
     `DV_CHECK_MEMBER_RANDOMIZE_FATAL(fmt_fifo_access_dly)
     cfg.m_i2c_agent_cfg.vif.wait_for_dly(fmt_fifo_access_dly);
     print_format_flag(item, msg);
diff --git a/hw/ip/i2c/dv/env/seq_lib/i2c_rx_tx_vseq.sv b/hw/ip/i2c/dv/env/seq_lib/i2c_rx_tx_vseq.sv
index 283aa3d..2805080 100644
--- a/hw/ip/i2c/dv/env/seq_lib/i2c_rx_tx_vseq.sv
+++ b/hw/ip/i2c/dv/env/seq_lib/i2c_rx_tx_vseq.sv
@@ -26,16 +26,20 @@
   endtask : host_init
 
   virtual task host_send_trans(int num_trans);
-    bit   last_tran;
+    bit last_tran;
 
     // setup config
     force_use_incorrect_config = 1'b0;
     fmt_item = new("fmt_item");
-    `DV_CHECK_RANDOMIZE_FATAL(this)
-    get_timing_values();
-    program_timing_regs();
-
     for (uint cur_tran = 1; cur_tran <= num_trans; cur_tran++) begin
+      // re-programming timing registers for the first transaction
+      // or when the previous transaction is completed
+      if (fmt_item.stop || cur_tran == 1) begin
+        `DV_CHECK_RANDOMIZE_FATAL(this)
+        get_timing_values();
+        program_timing_regs();
+      end
+
       last_tran = (cur_tran == num_trans) ? 1'b1 : 1'b0;
       // not program address for chained reads
       host_program_target_address();
@@ -46,18 +50,25 @@
       `uvm_info(`gfn, $sformatf("finish sending %s transaction, %0s at the end,  %0d/%0d, ",
           (rw_bit) ? "read" : "write",
           (fmt_item.stop) ? "stop" : "rstart", cur_tran, num_trans), UVM_DEBUG)
+
+      // check a completed transaction is programmed to the host/dut (stop bit must be issued)
+      // and check if the host/dut is in idle before allow re-programming the timing registers
+      if (fmt_item.stop) begin
+        check_host_idle();
+      end
     end
   endtask : host_send_trans
 
   virtual task host_program_target_address();
-    // programm fmt flags for address
     `DV_CHECK_MEMBER_RANDOMIZE_FATAL(fmt_item)
     fmt_item.start = 1'b1;
     fmt_item.stop  = 1'b0;
     fmt_item.read  = 1'b0;
-    `DV_CHECK_MEMBER_RANDOMIZE_FATAL(addr)
-    `DV_CHECK_MEMBER_RANDOMIZE_FATAL(rw_bit)
-    fmt_item.fbyte = (rw_bit) ? {addr, BusOpRead} : {addr, BusOpWrite};
+    if (cfg.target_addr_mode == Addr7BitMode) begin
+      fmt_item.fbyte = (rw_bit) ? {addr[6:0], BusOpRead} : {addr[6:0], BusOpWrite};
+    end else begin // Addr10BitMode
+      fmt_item.fbyte = (rw_bit) ? {addr[9:0], BusOpRead} : {addr[9:0], BusOpWrite};
+    end
     program_format_flag(fmt_item, "host_program_target_address");
   endtask : host_program_target_address
 
@@ -104,7 +115,7 @@
       fmt_item.fbyte = wr_data;
       // last write byte of last  tran., stop flag must be set to issue stop bit
       // last write byte of other tran., stop is randomly set/unset to issue stop/rstart bit
-      fmt_item.stop  = (i != num_wr_bytes) ? 1'b0 : ((last_tran) ? 1'b1 : fmt_item.stop);
+      fmt_item.stop = (i != num_wr_bytes) ? 1'b0 : ((last_tran) ? 1'b1 : fmt_item.stop);
       program_format_flag(fmt_item, "host_write_trans");
     end
   endtask : host_write_trans