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"