Can an interface pass a reference to itself?

Is there any way for an interface to pass a reference to itself and one of its modports once it is instantiated? This code doesn’t work, but this is an example of what I’m trying to do.

interface clk_if();
   logic clk;
   logic reset;

   modport master (input clk, reset);
 
   // Instantiate driver
   clk_driver driver = new(NAME, null, this.master);
endinterface;

clk_driver is an OVM component in which I’m receiving and using the interface by way of a virtual interface.

Of course, this. doesn’t work and I don’t know of any other identifier to allow the interface to pass a reference to itself. Using just master causes a compile error…

(vlog-2110) Illegal reference to non-variable "master".

I expect there probably isn’t a way to reference modports from inside the interface and for the interface to pass a reference to itself. I don’t want to pass the reference from outside the interface (many examples of that exist), so another solution is to instantiate a smaller interface inside this one and then pass a reference to that smaller interface. It’d be cool if the interface could pass a reference to its own modport somehow though.

When you instantiate the interface in a module you put a reference to it, i.e. a virtual interface, into a virtual interface containter, put the container into the configuration database, and then have the component retrieve the container and thus the virtual interface through the configuration system.

A virtual interface container is an ovm_object that contains a virtual interface. E.g.

class vif_container extends ovm_object;

virtual my_interface_type vif;

endclass

Since the vif_container is derived from ovm_object it can be stored into the configuration database using set_config_object. You can find an example of virtual interface containers in the OVM Cookbook example kit in 06_reuse/02_RTL.

I have to ask, why do you need to instantiate a component inside an interface?

– Mark

One other question to ask is if you construct this driver class inside your interface, how to expect to communicate with the rest of your OVM environment without a hierarchical reference?

My suggestion is to avoid the use of a virtual interface and use an abstract class instead. I have the basic idea attached as an example. The class does not need to be purely abstract; it just needs virtual methods that will overridden by extending a class in your interface. The factory is used to create a lookup by string name of that class.

Dave

Sorry for making the filename of my example the same as an existing OVM class name. I hope that does not confuse things.

Mark and Dave,

Thanks for the ideas, help, and the example. The abstract class worked perfectly and accomplished the minimization of instantiation code like I wanted.

Dave, no confusion on the example name, thanks for the example, that got me going in the right direction.

Mark, the reason I want to instantiate a component inside an interface is to reduce the amount of code required for each instantiation of my drivers/monitors. I find most of my drivers/monitors are so closely tied to the pins they drive that instantiating them without those connections isn’t ever necessary. Thus, whenever I instantiate a driver or monitor, I was finding myself instantiating the driver, the monitor, the interface to hook the pins to the DUT, passing the interface to the driver/monitor, then connecting the driver/monitor to the sequencer. That was fine the first time I did it, but when I need to lay down a dozen instantiations, it gets to be alot of manually written connection code. I was shooting for a way to instantiate the interface (which can be connected to the DUT pins) and then instantiate an agent in my OVM environment and have them connect “automatically”. By using the abstract class and passing in a unique string as a parameter, I accomplished this. (The unique string has to be passed to both the interface and the agent to make the connection, which is fine for me.) Hope that makes my intent a little clearer.

For anyone who tries this in the future, one thing to note. If you use the ovm_component_registry call (or ovm_object_registry… I ended up using the component call), and you want to use OVM field macros, you need to use the ovm_field_utils_begin**, **ovm_field_utils_end. This is explained in the OVM reference if you look up `ovm_field_utils_begin, but I thought I’d mention it anyway.