[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/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);