Virtual Interface Issue !?!?

Hi all,

I know the concept of virtual interface and working fine for me in my project.

When I tried to write a simple example to explain about virtual interface to my peer, simply it doesn’t.

I have simple interface which is setting into virtual interface as like below.
config_db::set

module mem_top;
	// Import the UVM package
	import uvm_pkg::*;
	// Import the UVC that we have implemented
 	import mem_uvc_pkg::*;
	// TODO : import all the needed packages

	// Clock and reset signals
	reg clock;
	reg reset;
	
	// The Memory interface
	mem_if memif();
			
    // DUT instantiation
	RAM dut(memif);

	// start the test
	initial begin
		uvm_config_db#(virtual mem_if)::set(uvm_root::get(), "*", "memif", memif);
		run_test();
		//#1000 $finish;
	end
...
endmodule

config_db::get

class mem_env extends uvm_env;
 	// Virtual Interface variable
	protected virtual interface mem_if vif;

	// new - constructor
	function new(string name, uvm_component parent);
		super.new(name, parent);
	endfunction : new

 	// build_phase
	function void build_phase(uvm_phase phase);
		super.build_phase(phase);
		if(!uvm_config_db#(virtual mem_if)::get(this, "", "memif", vif))
			`uvm_fatal("NOVIF",{"virtual interface must be set for: ",get_full_name(),".vif"});
....
	endfunction : build_phase
 
endclass : mem_env

But I’m getting FATAL error saying that NOVIF: virtual interface must be set for .vif

What am I missing here??

John

When I use as below… it doesn’t work.

modeul mem_top;
...
	// start the test
	initial begin
		uvm_config_db#(virtual mem_if)::set(null, "mem_top", "memif", memif);
		run_test();
		//#1000 $finish;
	end
...
endmodule

This too doesn’t work.

modeul mem_top;
...
	// start the test
	initial begin
		uvm_config_db#(virtual mem_if)::set(uvm_root::get(), "mem_top", "memif", memif);
		run_test();
		//#1000 $finish;
	end
...
endmodule

When I use as below, it works… explain me why do we need to use wild matching “*”?
Confused with config databaase… how this matching works??

modeul mem_top;
...
	// start the test
	initial begin
		uvm_config_db#(virtual mem_if)::set(uvm_root::get(), "*", "memif", memif);
		run_test();
		//#1000 $finish;
	end
...
endmodule

John

In reply to John Verif:

Any reply on this??

I understood from the cookbook is that,

module mem_top;
...
initial begin
uvm_config_db#(virtual mem_if)::set(null, "*", "memif", memif);**//WORKS**
uvm_config_db#(virtual mem_if)::set(null, "mem_top.*", "memif", memif); **// DID NOT WORK [NOVIF]**
uvm_config_db#(virtual mem_if)::set(null, "mem_top.memif", "memif", memif); **// DID NOT WORK [NOVIF]**
uvm_config_db#(virtual mem_if)::set(uvm_root::get(), "*", "memif", memif); // WORKS
uvm_config_db#(virtual mem_if)::set(uvm_root::get(), "mem_top.*", "memif", memif); **// DID NOT WORK [NOVIF]**
uvm_config_db#(virtual mem_if)::set(uvm_root::get(), "mem_top.memif", "memif", memif); **// DID NOT WORK [NOVIF]**
run_test();
end
...
endmodule

Scope resolver resolves location of the provided type of “filed” in the config “database”.

Then, why we need to provide “*” to get the filed from the database?

John

Hello

Here is the code that I use and works for me:

module bb_tb ();
   ifc_ulpi ifc_ulpi();

initial
begin
   uvm_config_db#(virtual ifc_ulpi)::set(uvm_top, "", "ifc_ulpi", ifc_ulpi);
   run_test();
end
endmodule
class class_bb_test extends uvm_test;
   virtual ifc_ulpi ifc_ulpi;
   function void build_phase(uvm_phase phase);
      super.build_phase(phase);
      if (!uvm_config_db#(virtual ifc_ulpi)::get(this, "", "ifc_ulpi", this.ifc_ulpi))
         `uvm_fatal("NOVIF",{"virtual interface must be set for: ", get_full_name(),".ifc_ulpi"});

   endfunction
endclass

I think when you use uvm_top for the set it makes that entry visible from the top down to all lower level classes.

In reply to kkejser:

kkejser,

my question is that why we can not use “mem_top” in the scope, while setting. since my interface at the level of mem_top.

John

In reply to John Verif:

Try this…now you will get the issue…

module bb_tb ();
   ifc_ulpi ifc_ulpi();
 
initial
begin
   uvm_config_db#(virtual ifc_ulpi)::set(uvm_top, "bb_tb", "ifc_ulpi", ifc_ulpi);
   run_test();
end
endmodule

You seem to be confusing Verilog module names with class handles. The way the uvm_config_db does matching is based on the UVM component hierarchy via a set of strings which is based on the name string arguments used during the build/create process. There is an overall top level component which gets constructed at the beginning of the UVM execution, all other components are then folded underneath this according to the testbench hierarchy.

Virtual interfaces are a SV way of being able to pass a handle to a static interface. They are a special case.

The way I recommend you pass a virtual interface to the UVM classes via the top level is as follows:

module tb;

// Interface declaration
my_if dut_port_if();

initial begin
uvm_config_db #(virtual my_if)::set(null, “uvm_test_top”, “dut_port”, dut_port_if);
run_test();
end

endmodule: tb

About the arguments in the set call:

1st argument - This is expected to be a uvm_component handle, none exist in the tb module, so this should be null
2nd argument - This is the auto-generated name of the top level component in the testbench - i.e. the test class
3rd argument - Any string you like, but it’s the one you’ll use to look up the handle
4th argument - The virtual interface handle

See:
https://verificationacademy.com/cookbook/Config/VirtInterfaceConfigDb

In reply to mperyer:

Thanks mperyer for your clarifications.

1st argument - This is expected to be a uvm_component handle, none exist in the tb module, so this should be null - “YES”
2nd argument - This is the auto-generated name of the top level component in the testbench - i.e. the test class
I thought it was module top or module, where the type is defined. uvm_test_top makes sense but I’m getting error with uvm_test_top .
3rd argument - Any string you like, but it’s the one you’ll use to look up the handle
- Not sure, string which is type defined as interface or just any string
uvm_config_db #(virtual my_if)::set(null, “uvm_test_top”, “anystring”, dut_port_if);
do you think that this work?

4th argument - The virtual interface handle - “YES”

I tried as below and getting error…

initial begin
uvm_config_db#(virtual mem_if)::set(uvm_root::get(),"uvm_test_top","memif", memif); //did not work
uvm_config_db#(virtual mem_if)::set(uvm_root::get(),"*","memif", memif); //Works
run_test();
end
// build_phase
function void build_phase(uvm_phase phase);
super.build_phase(phase);
if(!uvm_config_db#(virtual mem_if)::get(this, "", "memif", vif))
 `uvm_fatal("NOVIF",{"virtual interface must be set for: ",get_full_name(),".vif"});

UVM_INFO @ 0: reporter [RNTST] Running test mem_test…
UVM_FATAL mem_env.sv(42) @ 0: uvm_test_top.memtb.memenv [NOVIF] virtual
interface must be set for: uvm_test_top.memtb.memenv.vif

In reply to John Verif:

3rd argument - Any string you like, but it’s the one you’ll use to look up the handle

  • Not sure, string which is type defined as interface or just any string
    uvm_config_db #(virtual my_if)::set(null, “uvm_test_top”, “anystring”, dut_port_if);
    do you think that this work?

anystring worked!!

I never tried before.

Note: anystring is just a string, which is not type defined anywhere.

initial begin
uvm_config_db#(virtual mem_if)::set(uvm_root::get(), "*", "anystring", memif); //works
run_test();
end

modified in env,agent,drvier,and monitor class

super.build_phase(phase);
if(!uvm_config_db#(virtual mem_if)::get(this, "", "anystring", vif))
    `uvm_fatal("NOVIF",{"virtual interface must be set for: ",get_full_name(),".vif"});