[dv, uvmdvgen] fixes for issue 434

- fixed base test to extend from cip_base_test if cip
- added -hi and -ha switches to indicate if interrupts / alerts are to
  be created in the testbench
- removed typedef for virtual sequencer if there are no agents (always create it)
diff --git a/util/uvmdvgen.py b/util/uvmdvgen.py
index 31c63cc..18c56f3 100755
--- a/util/uvmdvgen.py
+++ b/util/uvmdvgen.py
@@ -52,6 +52,20 @@
     )
 
     parser.add_argument(
+        "-hi",
+        "--has_interrupts",
+        default=False,
+        action='store_true',
+        help="""CIP has interrupts. Create interrupts interface in tb""")
+
+    parser.add_argument(
+        "-ha",
+        "--has_alerts",
+        default=False,
+        action='store_true',
+        help="""CIP has alerts. Create alerts interface in tb""")
+
+    parser.add_argument(
         "-ea",
         "--env_agents",
         nargs="+",
@@ -91,6 +105,8 @@
         if not args.env_agents: args.env_agents = []
         gen_env.gen_env(args.name, \
                         args.is_cip, \
+                        args.has_interrupts, \
+                        args.has_alerts, \
                         args.env_agents, \
                         args.env_outdir)
 
diff --git a/util/uvmdvgen/README.md b/util/uvmdvgen/README.md
index ce4c057..d4d87a1 100644
--- a/util/uvmdvgen/README.md
+++ b/util/uvmdvgen/README.md
@@ -27,10 +27,11 @@
 
 Running the tool with `-h` switch provides a brief description of all available
 switches.
-```
+```console
 $ util/uvmdvgen.py -h
-usage: uvmdvgen.py [-h] [-a] [-s] [-e] [-c] [-ea [name] [[name] ...]]
-                   [-ao [hw/dv/sv]] [-eo [hw/ip/<ip>/dv]]
+usage: uvmdvgen.py [-h] [-a] [-s] [-e] [-c] [-hi] [-ha]
+                   [-ea agt1 agt2 [agt1 agt2 ...]] [-ao [hw/dv/sv]]
+                   [-eo [hw/ip/<ip>/dv]]
                    [ip/block name]
 
 Command-line tool to autogenerate boilerplate DV testbench code extended from dv_lib / cip_lib
@@ -45,16 +46,19 @@
   -s, --has_separate_host_device_driver
                         IP / block agent creates a separate driver for host
                         and device modes. (ignored if -a switch is not passed)
-  -e, --gen_env         Generate testbench UVM environment code
+  -e, --gen_env         Generate testbench UVM env code
   -c, --is_cip          Is comportable IP - this will result in code being
                         extended from CIP library. If switch is not passed,
                         then the code will be extended from DV library
                         instead. (ignored if -e switch is not passed)
+  -hi, --has_interrupts
+                        CIP has interrupts. Create interrupts interface in tb
+  -ha, --has_alerts     CIP has alerts. Create alerts interface in tb
   -ea agt1 agt2 [agt1 agt2 ...], --env_agents agt1 agt2 [agt1 agt2 ...]
-                        Env creates an interface agent specified here. They are
-                        assumed to already exist. Note that the list is space-
-                        separated, and not comma-separated. (ignored if -e
-                        switch is not passed)
+                        Env creates an interface agent specified here. They
+                        are assumed to already exist. Note that the list is
+                        space-separated, and not comma-separated. (ignored if
+                        -e switch is not passed)
   -ao [hw/dv/sv], --agent_outdir [hw/dv/sv]
                         Path to place the agent code. A directory called
                         <name>_agent is created at this location. (default set
@@ -162,6 +166,12 @@
 as the argument passed for the name of the IP. The following is the list of
 files generated with a brief description of their contents:
 
+Switches to indicate whether the CIP DUT contains interrupts or alerts are
+provided by `-hi` and `-ha` respectively. By default, these are set to 'False'
+(don't create interrupts or alerts). When set, it will create `intr_if` and
+`alerts_if` in the testbench and set them into `uvm_config_db` for the
+`cip_base_env` to pick up.
+
 * **env/i2c_host_env_cfg**
 
   This is the env cfg object. It creates the downstream agent cfg objects that
@@ -287,36 +297,51 @@
 
 #### Examples
 
-```
-util/uvmdvgen.py i2c -a
+```console
+$ util/uvmdvgen.py i2c -a
 ```
 This will create `./i2c/i2c_agent` and place all sources there.
 
-```
-util/uvmdvgen.py jtag -a -ao hw/dv/sv
+```console
+$ util/uvmdvgen.py jtag -a -ao hw/dv/sv
 ```
 This will create `hw/dv/sv/jtag_agent` directory and place all the sources
 there.
 
-```
-util/uvmdvgen.py i2c -a -s -ao hw/dv/sv
+```console
+$ util/uvmdvgen.py i2c -a -s -ao hw/dv/sv
 ```
 This will create the I2C agent with separate 'host' mode and 'device' mode drivers.
 
+```console
+$ util/uvmdvgen.py i2c_host -e -c -hi -ea i2c -eo hw/ip/i2c_host/dv
 ```
-util/uvmdvgen.py i2c_host -e -c -ea i2c -eo hw/ip/i2c_host/dv
+This will create the complete i2c_host DV testbench extended from CIP lib and will
+instantiate `i2c_agent`. It will also create and hook up the interrupt interface
+in the testbench.
+
+```console
+$ util/uvmdvgen.py foo -e -c -hi -ha -ea foo -eo hw/ip/i2c_host/dv
+```
+This will create the complete foo DV testbench extended from CIP lib and
+will instantiate `foo_agent`. It will also create and hook up the interrupt interface
+as well as alerts interface in the testbench.
+
+```console
+$ util/uvmdvgen.py aes -e -c -ea i2c -eo hw/ip/i2c_host/dv
 ```
 This will create the complete i2c_host DV testbench extended from CIP lib and will
 instantiate `i2c_agent`.
 
-```
-util/uvmdvgen.py dma -e -eo hw/ip/dma/dv
+
+```console
+$ util/uvmdvgen.py dma -e -eo hw/ip/dma/dv
 ```
 This will create the complete dma DV testbench extended from DV lib. It does not
 instantiate any downstream agents due to absence of `-ea` switch.
 
-```
-util/uvmdvgen.py chip -e -ea uart i2c jtag -eo hw/top_earlgrey/dv
+```console
+$ util/uvmdvgen.py chip -e -ea uart i2c jtag -eo hw/top_earlgrey/dv
 ```
 This will create the complete chip testbench DV lib and will instantiate
 `uart_agent`, `i2c_agent` and `jtag_agent` in the env.
diff --git a/util/uvmdvgen/base_test.sv.tpl b/util/uvmdvgen/base_test.sv.tpl
index d713bdf..e1a6f83 100644
--- a/util/uvmdvgen/base_test.sv.tpl
+++ b/util/uvmdvgen/base_test.sv.tpl
@@ -2,10 +2,15 @@
 // Licensed under the Apache License, Version 2.0, see LICENSE for details.
 // SPDX-License-Identifier: Apache-2.0
 
+% if is_cip:
+class ${name}_base_test extends cip_base_test #(
+% else:
 class ${name}_base_test extends dv_base_test #(
+% endif
     .ENV_T(${name}_env),
     .CFG_T(${name}_env_cfg)
   );
+
   `uvm_component_utils(${name}_base_test)
   `uvm_component_new
 
diff --git a/util/uvmdvgen/env_cfg.sv.tpl b/util/uvmdvgen/env_cfg.sv.tpl
index fb13359..13ac2f0 100644
--- a/util/uvmdvgen/env_cfg.sv.tpl
+++ b/util/uvmdvgen/env_cfg.sv.tpl
@@ -30,9 +30,14 @@
 % endfor
 % if is_cip:
 
-    // set num_interrupts & num_alerts which will be used to create coverage and more
-    num_interrupts = ral.intr_state.get_n_used_bits();
-    num_alerts = 0;
+    // set num_interrupts & num_alerts
+    begin
+      uvm_reg rg = ral.get_reg_by_name("intr_state");
+      if (rg != null) begin
+        num_interrupts = ral.intr_state.get_n_used_bits();
+      end
+      num_alerts = 0;
+    end
 % endif
   endfunction
 
diff --git a/util/uvmdvgen/env_pkg.sv.tpl b/util/uvmdvgen/env_pkg.sv.tpl
index 8ad00a5..a5058c9 100644
--- a/util/uvmdvgen/env_pkg.sv.tpl
+++ b/util/uvmdvgen/env_pkg.sv.tpl
@@ -26,24 +26,6 @@
   parameter uint ADDR_MAP_SIZE   = ;
 
   // types
-% if env_agents == []:
-  // forward declare classes to allow typedefs below
-  typedef class ${name}_env_cfg;
-  typedef class ${name}_env_cov;
-
-% endif
-% if env_agents == [] and is_cip:
-  // reuse cip_base_virtual_seqeuencer as is with the right parameter set
-  typedef class cip_base_virtual_sequencer #(
-% elif env_agents == [] and not is_cip:
-  // reuse dv_base_virtual_seqeuencer as is with the right parameter set
-  typedef class dv_base_virtual_sequencer #(
-% endif
-% if env_agents == []:
-      .CFG_T(${name}_env_cfg),
-      .COV_T(${name}_env_cov)
-  ) ${name}_virtual_sequencer;
-% endif
 
   // functions
 
@@ -51,9 +33,7 @@
   `include "${name}_reg_block.sv"
   `include "${name}_env_cfg.sv"
   `include "${name}_env_cov.sv"
-% if env_agents != []:
   `include "${name}_virtual_sequencer.sv"
-% endif
   `include "${name}_scoreboard.sv"
   `include "${name}_env.sv"
   `include "${name}_vseq_list.sv"
diff --git a/util/uvmdvgen/gen_env.py b/util/uvmdvgen/gen_env.py
index 67981eb..7aa1d9c 100644
--- a/util/uvmdvgen/gen_env.py
+++ b/util/uvmdvgen/gen_env.py
@@ -10,7 +10,7 @@
 from pkg_resources import resource_filename
 
 
-def gen_env(name, is_cip, env_agents, root_dir):
+def gen_env(name, is_cip, has_interrupts, has_alerts, env_agents, root_dir):
     # yapf: disable
     # 4-tuple - sub-path, ip name, class name, file ext
     env_srcs = [('env',         name + '_', 'env_cfg',            '.sv'),
@@ -41,8 +41,6 @@
         src = tup[2]
         src_suffix = tup[3]
 
-        if env_agents == [] and src == "virtual_sequencer": continue
-
         ftpl = src + src_suffix + '.tpl'
         fname = src_prefix + src + src_suffix
 
@@ -53,7 +51,11 @@
         with open(path_dir + "/" + fname, 'w') as fout:
             try:
                 fout.write(
-                    tpl.render(name=name, is_cip=is_cip,
-                               env_agents=env_agents))
+                    tpl.render(
+                        name=name,
+                        is_cip=is_cip,
+                        has_interrupts=has_interrupts,
+                        has_alerts=has_alerts,
+                        env_agents=env_agents))
             except:
                 log.error(exceptions.text_error_template().render())
diff --git a/util/uvmdvgen/tb.sv.tpl b/util/uvmdvgen/tb.sv.tpl
index 15831b0..9bd5d84 100644
--- a/util/uvmdvgen/tb.sv.tpl
+++ b/util/uvmdvgen/tb.sv.tpl
@@ -15,15 +15,23 @@
 
   wire clk, rst_n;
 % if is_cip:
+% if has_interrupts:
   wire [NUM_MAX_INTERRUPTS-1:0] interrupts;
+% endif
+% if has_alerts:
   wire [NUM_MAX_ALERTS-1:0] alerts;
 % endif
+% endif
 
   // interfaces
   clk_rst_if clk_rst_if(.clk(clk), .rst_n(rst_n));
 % if is_cip:
+% if has_interrupts:
   pins_if #(NUM_MAX_INTERRUPTS) intr_if(interrupts);
+% endif
+% if has_alerts:
   pins_if #(NUM_MAX_ALERTS) alerts_if(alerts);
+% endif
   pins_if #(1) devmode_if();
   tl_if tl_if(.clk(clk), .rst_n(rst_n));
 % endif
@@ -52,8 +60,12 @@
     clk_rst_if.set_active();
     uvm_config_db#(virtual clk_rst_if)::set(null, "*.env", "clk_rst_vif", clk_rst_if);
 % if is_cip:
+% if has_interrupts:
     uvm_config_db#(intr_vif)::set(null, "*.env", "intr_vif", intr_if);
+% endif
+% if has_alerts:
     uvm_config_db#(alerts_vif)::set(null, "*.env", "alerts_vif", alerts_if);
+% endif
     uvm_config_db#(devmode_vif)::set(null, "*.env", "devmode_vif", devmode_if);
     uvm_config_db#(tlul_assert_vif)::set(null, "*.env", "tlul_assert_vif",
                                          tb.dut.tlul_assert_host);