DUAL TOP UVM Architecture Issue

Hi,

I am trying the Dual Top UVM Architecture as provided in the UVM cookbook and struggling with the configuration database where my test-case unable to get the required interface from the configuration database. I am using EDA Playground to compile and simulate my design. Please ignore the run_phase task for now as that is still under development.

On the HDL side, I am doing something like this:

module hdl_top; 

`include "timescale.sv" 

// Instantitate the pin interfaces 
dut_if dut_if1(); 

// Instantiate the BFM Interfaces 
dut_driver_bfm dut_drv_bfm (dut_if1); 
dut_monitor_bfm dut_mon_bfm (dut_if1); 

// DUT instantiation 
dut DUT (dut_if1); 

initial 
begin 
impot uvm_pkg::uvm_config_db; 
uvm_config_db #(virtual dut_if)::set(null, "uvm_test_top", "DUT_IF", dut_if1); 
uvm_config_db #(virtual dut_driver_bfm) ::set(null, "uvm_test_top", "DUT_DRV_BFM", dut_drv_bfm); 
uvm_config_db #(virtual dut_monitor_bfm) ::set(null, "uvm_test_top", "DUT_MON_BFM", dut_mon_bfm); 
endmodule 

On the HVL side I have a configuration object which is coded as follows:

class dut_agent_config extends uvm_object; 

// UVM factory registration macro 
`uvm_object_utils(dut_agent_config) 

// BFM virtual interfaces 
virtual dut_driver_bfm drv_bfm; 
virtual dut_monitor_bfm mon_bfm; 
virtual dut_if dut_vif; 

// Standard UVM Methods 
function new( string name = "dut_agent_config"); 
super.new( name ); 
endfunction 

static function dut_agent_config get_config(uvm_component c); 

dut_agent_config t; 
if (!uvm_config_db#(dut_agent_config)::get(c, "", "dut_agent_config", t) ) 
`uvm_fatal("CONFIG_LOAD", "Cannot get() configuration dut_agent_config from uvm_config_db. Have you set() it?") 
return t; 
endfunction 

endclass: dut_agent_config

My test-case is as follows:

class my_test extends uvm_test; 
`uvm_component_utils(my_test) 

my_env m_env; 
my_sequence seq; 
dut_agent_config dut_agent_config_0; 

function new(string name, uvm_component parent); 
super.new(name, parent); 
endfunction 

function void set_dut_agent_config_params(); 
dut_agent_config_0 = new(); 

if(!uvm_config_db #(virtual dut_if)::get(this, "", "DUT_IF", dut_agent_config_0.dut_vif)) 
begin 
`uvm_fatal("BAD_CONFIG", "Cannot get() interface DUT_IF from uvm_config_db. Have you set() it?") 
end 

if(!uvm_config_db #(virtual dut_driver_bfm)::get(this, "", "DUT_DRV_BFM", dut_agent_config_0.drv_bfm)) 
begin 
`uvm_fatal("BAD_CONFIG", "Cannot get() interface DUT_DRV_BFM from uvm_config_db. Have you set() it?") end 

if(!uvm_config_db #(virtual dut_monitor_bfm)::get(this, "", "DUT_MON_BFM", dut_agent_config_0.mon_bfm)) 
begin 
`uvm_fatal("BAD_CONFIG", "Cannot get() interface MON_DRV_BFM from uvm_config_db. Have you set() it?") 
end 

uvm_config_db #(dut_agent_config)::set(this, "*", "dut_agent_config", dut_agent_config_0); 

endfunction: set_dut_agent_config_params 

function void build_phase(uvm_phase phase); 

uvm_top.print_topology(); 
//factory.print(); 
print_config(1, 1); 
uvm_config_db #(int)::dump(); 

set_dut_agent_config_params(); 
m_env = my_env::type_id::create("m_env", this); 
seq = my_sequence::type_id::create("seq"); 

endfunction 

task run_phase(uvm_phase phase); 

if( !seq.randomize() ) `uvm_error("", "Randomize failed") 
seq.starting_phase = phase; seq.start( m_env.m_agent.m_sequencer); 
endtask 

endclass: my_test

I am getting the following error:

UVM_FATAL my_test.sv(20) @ 0: uvm_test_top [BAD_CONFIG] Cannot get() interface DUT_IF from uvm_config_db. Have you set() it?

This is my first chance of trying out a dual top level architecture. Can you please help with this?

Thanks,

-Shahid

In reply to Shahid Khokher:

Please try a wildcard (*) instead of uvm_test_top.

In reply to chr_sue:

You mean change

uvm_config_db #(virtual dut_if)::set(null, "uvm_test_top", "DUT_IF", dut_if1);

to

uvm_config_db #(virtual dut_if)::set(null, "*", "DUT_IF", dut_if1);

In reply to Shahid Khokher:

Thanks chr_sue for your response. I tried the suggested change but it did not help.

In reply to Shahid Khokher:

What is trhe error message you get?

In reply to Shahid Khokher:

In reply to Shahid Khokher:
Thanks chr_sue for your response. I tried the suggested change but it did not help.

I have identified your problem. You are passing your interfaces to your config_db in hdl_top. IIn hvl_top you are starting run_test, which makes an instance of your UVM environment. Now it looks like you are perfromimh the get tp the config_db earlier than making the set.
I’m not sure if there is a well-defined order top toplevels in the simulator are processed.

In reply to chr_sue:

This is wrong. The run_test() task is designed so that all of the simulation initial blocks are executed prior to starting the build_phase(). This is done specifically to ensure that all config_db:set() calls are completed prior to the UVM environment calling get() in uvm_test_top.

The EDA playground link is no longer available for review, but you should make sure that both hvl_top and hdl_top are executed as top level modules. Also, try different simulators as it is possible that issues may be masked by the simulator you have selected.

In reply to cgales:

Thanks all but I figured out the issue a couple of hours ago. I was not sure about how EDA playground compiles the provided HDL and HVL blocks. EDA play ground gives you a default design.sv file, which should be the top level for the static part of the TB. My HDL top level contents should have gone inside this design.sv module instead of being in a new hdl_top.sv file. Previously I had put my DUT inside the design.sv file.