Add baseline DV for I2C
diff --git a/hw/dv/sv/i2c_agent/README.md b/hw/dv/sv/i2c_agent/README.md
new file mode 100644
index 0000000..ca68b60
--- /dev/null
+++ b/hw/dv/sv/i2c_agent/README.md
@@ -0,0 +1,3 @@
+{{% lowrisc-doc-hdr I2C DV UVM Agent }}
+
+I2C DV UVM Agent is extended from DV library agent classes.
diff --git a/hw/dv/sv/i2c_agent/i2c_agent.core b/hw/dv/sv/i2c_agent/i2c_agent.core
new file mode 100644
index 0000000..48c6fa0
--- /dev/null
+++ b/hw/dv/sv/i2c_agent/i2c_agent.core
@@ -0,0 +1,28 @@
+CAPI=2:
+# Copyright lowRISC contributors.
+# Licensed under the Apache License, Version 2.0, see LICENSE for details.
+# SPDX-License-Identifier: Apache-2.0
+name: "lowrisc:dv:i2c_agent:0.1"
+description: "I2C DV UVM agent"
+filesets:
+  files_dv:
+    depend:
+      - lowrisc:dv:dv_utils
+      - lowrisc:dv:dv_lib
+    files:
+      - i2c_if.sv
+      - i2c_agent_pkg.sv
+      - i2c_agent_cfg.sv: {is_include_file: true}
+      - i2c_agent_cov.sv: {is_include_file: true}
+      - i2c_item.sv: {is_include_file: true}
+      - i2c_driver.sv: {is_include_file: true}
+      - i2c_monitor.sv: {is_include_file: true}
+      - i2c_agent.sv: {is_include_file: true}
+      - seq_lib/i2c_base_seq.sv: {is_include_file: true}
+      - seq_lib/i2c_seq_list.sv: {is_include_file: true}
+    file_type: systemVerilogSource
+
+targets:
+  default:
+    filesets:
+      - files_dv
diff --git a/hw/dv/sv/i2c_agent/i2c_agent.sv b/hw/dv/sv/i2c_agent/i2c_agent.sv
new file mode 100644
index 0000000..6148e9d
--- /dev/null
+++ b/hw/dv/sv/i2c_agent/i2c_agent.sv
@@ -0,0 +1,24 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+class i2c_agent extends dv_base_agent #(
+      .CFG_T          (i2c_agent_cfg),
+      .DRIVER_T       (i2c_driver),
+      .SEQUENCER_T    (i2c_sequencer),
+      .MONITOR_T      (i2c_monitor),
+      .COV_T          (i2c_agent_cov)
+  );
+
+  `uvm_component_utils(i2c_agent)
+
+  `uvm_component_new
+
+  function void build_phase(uvm_phase phase);
+    super.build_phase(phase);
+    // get i2c_if handle
+    if (!uvm_config_db#(virtual i2c_if)::get(this, "", "vif", cfg.vif))
+      `uvm_fatal(`gfn, "failed to get i2c_if handle from uvm_config_db")
+  endfunction
+
+endclass
diff --git a/hw/dv/sv/i2c_agent/i2c_agent_cfg.sv b/hw/dv/sv/i2c_agent/i2c_agent_cfg.sv
new file mode 100644
index 0000000..162bd2d
--- /dev/null
+++ b/hw/dv/sv/i2c_agent/i2c_agent_cfg.sv
@@ -0,0 +1,15 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+class i2c_agent_cfg extends dv_base_agent_cfg;
+
+// interface handle used by driver, monitor & the sequencer, via cfg handle
+  virtual i2c_if vif;
+
+  `uvm_object_utils_begin(i2c_agent_cfg)
+  `uvm_object_utils_end
+
+  `uvm_object_new
+
+endclass
diff --git a/hw/dv/sv/i2c_agent/i2c_agent_cov.sv b/hw/dv/sv/i2c_agent/i2c_agent_cov.sv
new file mode 100644
index 0000000..36a58f2
--- /dev/null
+++ b/hw/dv/sv/i2c_agent/i2c_agent_cov.sv
@@ -0,0 +1,18 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+class i2c_agent_cov extends dv_base_agent_cov #(i2c_agent_cfg);
+  `uvm_component_utils(i2c_agent_cov)
+
+  // the base class provides the following handles for use:
+  // i2c_agent_cfg: cfg
+
+  // covergroups
+
+  function new(string name, uvm_component parent);
+    super.new(name, parent);
+    // instantiate all covergroups here
+  endfunction : new
+
+endclass
diff --git a/hw/dv/sv/i2c_agent/i2c_agent_pkg.sv b/hw/dv/sv/i2c_agent/i2c_agent_pkg.sv
new file mode 100644
index 0000000..52188d0
--- /dev/null
+++ b/hw/dv/sv/i2c_agent/i2c_agent_pkg.sv
@@ -0,0 +1,37 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+package i2c_agent_pkg;
+  // dep packages
+  import uvm_pkg::*;
+  import dv_utils_pkg::*;
+  import dv_lib_pkg::*;
+
+  // macro includes
+  `include "uvm_macros.svh"
+  `include "dv_macros.svh"
+
+  // parameters
+
+  // local types
+  // forward declare classes to allow typedefs below
+  typedef class i2c_item;
+  typedef class i2c_agent_cfg;
+
+  // reuse dv_base_seqeuencer as is with the right parameter set
+  typedef dv_base_sequencer #(.ITEM_T     (i2c_item),
+                              .CFG_T      (i2c_agent_cfg)) i2c_sequencer;
+
+  // functions
+
+  // package sources
+  `include "i2c_item.sv"
+  `include "i2c_agent_cfg.sv"
+  `include "i2c_agent_cov.sv"
+  `include "i2c_driver.sv"
+  `include "i2c_monitor.sv"
+  `include "i2c_agent.sv"
+  `include "i2c_seq_list.sv"
+
+  endpackage: i2c_agent_pkg
diff --git a/hw/dv/sv/i2c_agent/i2c_device_driver.sv b/hw/dv/sv/i2c_agent/i2c_device_driver.sv
new file mode 100644
index 0000000..b13d19e
--- /dev/null
+++ b/hw/dv/sv/i2c_agent/i2c_device_driver.sv
@@ -0,0 +1,26 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+class i2c_device_driver extends i2c_driver;
+  `uvm_component_utils(i2c_device_driver)
+
+  // the base class provides the following handles for use:
+  // i2c_agent_cfg: cfg
+
+  `uvm_component_new
+
+  virtual task run_phase(uvm_phase phase);
+    // base class forks off reset_signals() and get_and_drive() tasks
+    super.run_phase(phase);
+  endtask
+
+  // reset signals
+  virtual task reset_signals();
+  endtask
+
+  // drive trans received from sequencer
+  virtual task get_and_drive();
+  endtask
+
+endclass
diff --git a/hw/dv/sv/i2c_agent/i2c_driver.sv b/hw/dv/sv/i2c_agent/i2c_driver.sv
new file mode 100644
index 0000000..a85b4d2
--- /dev/null
+++ b/hw/dv/sv/i2c_agent/i2c_driver.sv
@@ -0,0 +1,37 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+class i2c_driver extends dv_base_driver #(i2c_item, i2c_agent_cfg);
+  `uvm_component_utils(i2c_driver)
+
+  // the base class provides the following handles for use:
+  // i2c_agent_cfg: cfg
+
+  `uvm_component_new
+
+  virtual task run_phase(uvm_phase phase);
+    // base class forks off reset_signals() and get_and_drive() tasks
+    super.run_phase(phase);
+  endtask
+
+  // reset signals
+  virtual task reset_signals();
+  endtask
+
+  // drive trans received from sequencer
+  virtual task get_and_drive();
+    forever begin
+      seq_item_port.get_next_item(req);
+      $cast(rsp, req.clone());
+      rsp.set_id_info(req);
+      `uvm_info(`gfn, $sformatf("rcvd item:\n%0s", req.sprint()), UVM_HIGH)
+      // TODO: do the driving part
+      //
+      // send rsp back to seq
+      `uvm_info(`gfn, "item sent", UVM_HIGH)
+      seq_item_port.item_done(rsp);
+    end
+  endtask
+
+endclass
diff --git a/hw/dv/sv/i2c_agent/i2c_host_driver.sv b/hw/dv/sv/i2c_agent/i2c_host_driver.sv
new file mode 100644
index 0000000..9b82dd3
--- /dev/null
+++ b/hw/dv/sv/i2c_agent/i2c_host_driver.sv
@@ -0,0 +1,37 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+class i2c_host_driver extends i2c_driver;
+  `uvm_component_utils(i2c_host_driver)
+
+  // the base class provides the following handles for use:
+  // i2c_agent_cfg: cfg
+
+  `uvm_component_new
+
+  virtual task run_phase(uvm_phase phase);
+    // base class forks off reset_signals() and get_and_drive() tasks
+    super.run_phase(phase);
+  endtask
+
+  // reset signals
+  virtual task reset_signals();
+  endtask
+
+  // drive trans received from sequencer
+  virtual task get_and_drive();
+    forever begin
+      seq_item_port.get_next_item(req);
+      $cast(rsp, req.clone());
+      rsp.set_id_info(req);
+      `uvm_info(`gfn, $sformatf("rcvd item:\n%0s", req.sprint()), UVM_HIGH)
+      // TODO: do the driving part
+
+      // send rsp back to seq
+      `uvm_info(`gfn, "item sent", UVM_HIGH)
+      seq_item_port.item_done(rsp);
+    end
+  endtask
+
+endclass
diff --git a/hw/dv/sv/i2c_agent/i2c_if.sv b/hw/dv/sv/i2c_agent/i2c_if.sv
new file mode 100644
index 0000000..60c846a
--- /dev/null
+++ b/hw/dv/sv/i2c_agent/i2c_if.sv
@@ -0,0 +1,87 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+interface i2c_if ();
+  // interface pins
+  logic scl_i;
+  logic scl_o;
+  logic scl_en_o;
+  logic sda_i;
+  logic sda_o;
+  logic sda_en_o;
+
+  bit BusIsFree=1;
+
+/*
+  // debug signals (TBD)
+  int            SclFrequency;
+  int            SclClockPeriod;
+  int            SclMinFreq;
+  int            SclMaxFreq;
+  bus_speed_e    BusSpeed;
+
+  //Timing0
+  int            SclHighMinHoldTime;
+  int            SclLowMinHoldTime;
+  //Timing1
+  int            NormRiseTime;
+  int            NormFallTime;
+  //Timing2
+  int            StartMinSetupTime;
+  int            StartMinHoldTime;
+  //Timing3
+  int            DataMinSetupTime;
+  int            DataMinHoldTime;
+  //Timing4
+  int            StopMinSetupTime;
+  int            StartStopMinTime;
+  //Timing5
+  int            ClockStretchTimeout;
+  int            ClockStretchEnable;
+
+  function void set_set_bus_frequency(int SclFrequency_i);
+    SclFrequency = SclFrequency_i; //in kHz
+  if ( SclFrequency>0 && SclFrequency<=100 ) begin
+    bus_speed_e = I2cStdSpeed;
+    set_std_speed_timing();
+  end else if (m_sclFrequency>100 && m_sclFrequency<=400) begin
+    bus_speed_e = I2cFastSpeed;
+    set_fast_speed_timing();
+  end else if (m_sclFrequency>400 && m_sclFrequency<=3400) begin
+    bus_speed_e = I2cFastSpeedPlus;
+    set_fast_speed_plus_timing();
+  end else
+    `uvm_fatal("I2C:set_set_bus_frequency",
+               $psprintf("SCL frquency setting illegal : %d kHz",SclFrequency))
+
+  //Create a SCL with 1:1 duty cycle
+  m_sclLowTime     = ( 10 ** 6/(2 * SclFrequency) ) ;   // ns
+  m_sclHighTime    = m_sclLowTime;                      // ns
+  //Default bit set-up time is m_sclLowTime/2
+  m_sdaChangePoint = m_sclLowTime/2;                    // ns
+
+  m_sclClockPeriod = ( (10**9)/m_sclFrequency) / 1000;  // ns
+
+  endfunction
+
+ always @(negedge sda_in )  begin
+  //START condition
+  if (rst==0)
+   if (scl_in==1) begin
+    #m_fHdStaMin;
+    busIsFree<=0;
+   end
+ end
+ always @(posedge sda_in) begin
+  //STOP condition
+  if (rst==0) begin
+   if (scl_in==1) begin
+    #m_tBufMin;
+    busIsFree<=1;
+   end
+  end
+ end
+*/
+
+endinterface : i2c_if
diff --git a/hw/dv/sv/i2c_agent/i2c_item.sv b/hw/dv/sv/i2c_agent/i2c_item.sv
new file mode 100644
index 0000000..97153b4
--- /dev/null
+++ b/hw/dv/sv/i2c_agent/i2c_item.sv
@@ -0,0 +1,14 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+class i2c_item extends uvm_sequence_item;
+
+  // random variables
+
+  `uvm_object_utils_begin(i2c_item)
+  `uvm_object_utils_end
+
+  `uvm_object_new
+
+endclass
diff --git a/hw/dv/sv/i2c_agent/i2c_monitor.sv b/hw/dv/sv/i2c_agent/i2c_monitor.sv
new file mode 100644
index 0000000..8c6d30d
--- /dev/null
+++ b/hw/dv/sv/i2c_agent/i2c_monitor.sv
@@ -0,0 +1,43 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+class i2c_monitor extends dv_base_monitor #(
+    .ITEM_T (i2c_item),
+    .CFG_T  (i2c_agent_cfg),
+    .COV_T  (i2c_agent_cov)
+  );
+  `uvm_component_utils(i2c_monitor)
+
+  // the base class provides the following handles for use:
+  // i2c_agent_cfg: cfg
+  // i2c_agent_cov: cov
+  // uvm_analysis_port #(i2c_item): analysis_port
+
+  `uvm_component_new
+
+  function void build_phase(uvm_phase phase);
+    super.build_phase(phase);
+  endfunction
+
+  task run_phase(uvm_phase phase);
+    super.run_phase(phase);
+  endtask
+
+  // collect transactions forever - already forked in dv_base_moditor::run_phase
+  virtual protected task collect_trans(uvm_phase phase);
+    forever begin
+      // TODO: detect event
+
+      // TODO: sample the interface
+
+      // TODO: sample the covergroups
+
+      // TODO: write trans to analysis_port
+
+      // TODO: remove the line below: it is added to prevent zero delay loop in template code
+      #1us;
+    end
+  endtask
+
+endclass
diff --git a/hw/dv/sv/i2c_agent/seq_lib/i2c_base_seq.sv b/hw/dv/sv/i2c_agent/seq_lib/i2c_base_seq.sv
new file mode 100644
index 0000000..458d0ee
--- /dev/null
+++ b/hw/dv/sv/i2c_agent/seq_lib/i2c_base_seq.sv
@@ -0,0 +1,17 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+class i2c_base_seq extends dv_base_seq #(
+    .CFG_T       (i2c_agent_cfg),
+    .SEQUENCER_T (i2c_sequencer)
+  );
+  `uvm_object_utils(i2c_base_seq)
+
+  `uvm_object_new
+
+  virtual task body();
+    `uvm_fatal(`gtn, "Need to override this when you extend from this class!")
+  endtask
+
+endclass
diff --git a/hw/dv/sv/i2c_agent/seq_lib/i2c_seq_list.sv b/hw/dv/sv/i2c_agent/seq_lib/i2c_seq_list.sv
new file mode 100644
index 0000000..89f7fe7
--- /dev/null
+++ b/hw/dv/sv/i2c_agent/seq_lib/i2c_seq_list.sv
@@ -0,0 +1,5 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+`include "i2c_base_seq.sv"