View Full Version : Interface hookup with Hierarchy of Components
skootamota
03-01-2008, 04:10 PM
I'm wondering if the only way to connect an interface through a hierarchy of components is as an argument to new().
I looked into the connect methods but they don't seem to solve the issue. They work if you have one sub component, but if you had more sub components, each one a component of the other.
ie: with the following component tree
TOP
A B
C D E F
G H I J
The only way I see being able to pass an interface through to component G for example is with an interface argument to new() of each component (A,C and G). With the avm-cookbook examples they are hooked up with the connect() method, but, that doesn't work if you have many components.
Am I missing something, or is this just the way it is.
kurts
03-01-2008, 11:28 PM
With OVM, you can use the configuration database to store a handle to a virtual interface, then directly get the interface wherever you need it. No need to pass it through hierarchy levels.
Just assign the virtual interface to a data member of a class derived from ovm_object, then in your top level module do something like
wrapper_obj_handle.v_if = real_if;
set_config_object("*","virtual_if",wrapper_obj_handle, 0);
It's important that you add the 0 argument to prevent cloning. Then wherever you need the virtual interface, just do this:
ovm_object base_obj;
...
void'(get_config_object("virtual_if",base_obj));
$cast(wrapper_obj_handle, base_obj);
local_v_if_handle = wrapper_obj_handle.v_if;
-Kurt
dave_59
03-01-2008, 11:58 PM
In the AVM, people have been using a registry objects (an associative array indexed by a string, typically); in the OVM you can use a config object. The functionality is effectively the same. You extend a base class object with an object that has a member which is a virtual interface handle set to the interface instance that needs to be passed down. For example
class ovm_config_object #(type T=int) extends ovm_object; // In the AVM this could be any common base class
T m;
function new(T t);
m = t;
endfunction
endclass
typedef virtual my_if #(whatever) my_vif;
ovm_config_object #(my_vif) cfg_obj = new(my_if_inst1);
In the AVM you would do something like
base_class registry[string];
registry["my_G_driver"] = cfg_obj;In the OVM, you would do something like
set_config_object("path_to_my_G_driver", "vif_handle", cfg_obj);
Dave
skootamota
03-03-2008, 04:45 PM
Thanks,
Also, from the xbus example, I see now that they are using an assign_vi function to hook up the interface.
Steve
mglasser
03-04-2008, 07:35 PM
Steve,
Both the wrapper methodology described by Kurt and Dave and assign_vi() are viable ways of connecting virtual interfaces to verification components. Both have their pros and cons.
Wrapper methodology:
* pros: the location of the component receiving the connection (calling get_config_object doesn't have to be known by the component providing the interface (the one calling set_config_object).
cons: requires you to build a special wrapper object and assign virtual interfaces to it.
assign_vi() methodology:
* pros: The connection is made with a single function call
* cons: You need to have a reference to the verification component to which you wish to make the VI connection; or each parent needs to call assign_vi() on a child to pass the VI down through multiple levels of hierarchy
In the case where you need to make connections to more than one virtual interface you will have to create multiple variants of the assign_vi() function, one for each connection.
By and large I would say the wrapper methodology is more general. However, the assign_vi() methodology is good for straightfoward situations where you are connecting a single VI and through a small number of hierarchy levels.
sasan
03-09-2008, 08:12 PM
Using assign_vi() is generally preferred over a class wrapper.
The reason is that a virtual interface is needed only where the verification environment connects with the DUV. In a well-structured verirfication environment, this connecting layer is abstracted in an interface verification component (IVC). Now an interface verification component is something that you usually buy from an IP vendor (PCIe VIP, USB VIP, etc. are all interface verification components). So from the perspective of packaging a VIP, it is more user-friendly to provide function assign_vi() for initializing the virtual interface inside the VIP. The reason for this preference is that first, if the configuration methods are used to initialize a wrapper inside the VIP during hierarchy construction (i.e., when function build() is called), then changing the virtual interface wrapper inside the VIP will be difficult, if not impossible, after the environment is constructed. Some may argue that changing the wrapper after the hierarchy is constructed may not be necessary, but this is a flexibility that is lost when wrappers are used. A second issue is that, using a wrapper requires creating extra objects (i.e., the wrapper) which basically adds an extra step for deploying a VIP, which is not preferred since the general goal is to mimize the steps required to deploy a VIP.
So, given that using assign_vi() is preferred when making VIPs, then it is good to remain consistent with that approach and use assign_vi() even if you're making your own environment from scratch.
Sasan
dave_59
03-09-2008, 10:38 PM
Sasan,
I don't see how using the configuration methods makes anything less flexible as the whole point of the configurations methods are to make things, well, more configuarable.
Also, there are three choices being presented here and in this thread (http://www.ovmworld.org/forums/showthread.php?p=350#post350): the assign_vi method, the class wrapper around a virtual interface, and the abstract class which doesn't use a virtual interface at all. Another point about using an abstract class makes the entire testbench unaware if it is communicating with a statically instantiated DUT (i.e. a module or an SV interface) or a class based abstraction of the DUT.
Dave
ankit1
03-10-2008, 12:15 AM
Hi Dave,
Can't we use "function import connection()" for hierarchical classes?
Regards,
Ankit
skootamota
06-29-2008, 02:37 PM
If we have an interface instantiated in the top level testbench. Why do we use the assign_vi tasks to hook it up to a local interface signal in the first place? From what I can tell I can reference anything in the top level testbench module, within any of the classes, so if I have an interface myif in the top tb module, I can reference any of the signals in myif, just with myif.<somesig>. What am I missing?
Seve H.
kurts
06-29-2008, 03:28 PM
There are two reasons why you want to avoid having hierarchical paths embedded in your class-based code.
First, It insulates your class-based code from a dependency on a particular hierarchical path.
Even if the path is at the top of the design now, it may not still be at the top in the next follow-on design, and you will still want to reuse your class-based code.
It is a best practice to avoid embedding non-reusable things like hierarchical paths in your code. While you can't completely eliminate non-reusable things (e.g. you still have to connect the local virtual interface to an actual one), the best practice is to isolate and minimize the non-reusable stuff.
Second, if you have a hierarchical path in your code, that code cannot be placed in a package, which is exactly where you should put your class-based code for best reuse.
There are several options to accomplish the connection of the actual interface to the virtual one in a reusable way. I'm not a big fan of using "assign_vi". I know that's the way that the xbus example uses, and that's pretty much the only example people have to go on right now. Other ways have been discussed here in the forums.
One other way is use a object wrapper around the virtual interface and use set/get_config_object. This was discussed in this thread: http://www.ovmworld.org/forums/showthread.php?p=316#post316
Another, simpler way is to just declare the virtual interface in a package and assign to it directly and treat is as a global variable.
And yet another, interesting way is to forego the use of interfaces completely, and use a class-based approach. Dave Rich has described this approach in a paper, and has provided a link to the paper and an example in this thread:
http://www.ovmworld.org/forums/showthread.php?t=100
-Kurt
In the AVM, people have been using a registry objects (an associative array indexed by a string, typically); in the OVM you can use a config object. The functionality is effectively the same. You extend a base class object with an object that has a member which is a virtual interface handle set to the interface instance that needs to be passed down. For example
class ovm_config_object #(type T=int) extends ovm_object; // In the AVM this could be any common base class
T m;
function new(T t);
m = t;
endfunction
endclass
typedef virtual my_if #(whatever) my_vif;
ovm_config_object #(my_vif) cfg_obj = new(my_if_inst1);
In the AVM you would do something like
base_class registry[string];
registry["my_G_driver"] = cfg_obj;In the OVM, you would do something like
set_config_object("path_to_my_G_driver", "vif_handle", cfg_obj);Dave
Hi What is done in driver or monitor in order to use ovm_config_object? What I did is 1)adding a ovm_config_object declaration in a driver or monitor and 2) directly use it in driver/monitor's run task. But what I got from Questa is " 'addr' is not a field or method in '/top/my_monitor::collect_transactions/this*.ovm_config_object*.m'" while addr is one signal of my_if. So what is wrong?
dave_59
11-16-2009, 11:50 PM
Look at this thread and see if it answers your question
757
Thank you Dave. I followed Shunty's step 3 but Questa tells me that
driver_if = wrapper.v_intf; is illegal assignment during loading. And there is a "fatal" after that, which says "Virtual interface resolution cannot find a matching instance of interface". Why step 3 doesn't work for my case? (BTW, For the first two steps, I followed your advice. and my interface is parameterized,
interface my_if #( parameter integer G_ADDR_WIDTH = 8,
parameter integer G_DATA_WIDTH = 32); )
dave_59
11-17-2009, 12:31 AM
CMM,
It is hard to tell you what could be wrong without seeing more of your code. You need to show all your declarations, and where they are declared. The ovm_config_object needs to be visible to both your driver, and the place where you issue your set_config_object. Also, if your interface is parametrized, The virtual interface declaration has to be made with the same parameters.
You should contact your local Mentor support if you are not able to share code in this forum.
Dave
my wrapper is
class wb_if_wrapper #(type T=int) extends ovm_object;
T m;
function new(string name="");
super.new(name);
endfunction
endclass : wb_if_wrapper
in my monitor file, I have the following codes:
...
virtual wb_if #(.G_ADDR_WIDTH(G_ADDR_WIDTH), .G_DATA_WIDTH (G_DATA_WIDTH)) m_wb_if;
wb_if_wrapper #(virtual wb_if) m_wb_if_wrapper;
...
...
`ovm_component_utils_begin(monitor)
`ovm_field_object(m_wb_if_wrapper, OVM_ALL_ON)
`ovm_component_utils_end
...
...
virtual function void build();
super.build();
m_wb_if = m_wb_if_wrapper.m; -> This is the illegal assignment.
endfunction
in the top file,
wb_if #(.G_ADDR_WIDTH(ADDR_WID), .G_DATA_WIDTH(DATA_WID))wb_if_inst();
typedef virtual wb_if #(.G_ADDR_WIDTH(ADDR_WID), .G_DATA_WIDTH(DATA_WID)) vintf_t;
wb_if_wrapper #(vintf_t) m_wb_if_wrapper = new("m_wb_if_wrapper");
initial begin
...
m_wb_if_wrapper.m = wb_if_inst;
set_config_object("*","m_wb_if_wrapper", m_wb_if_wrapper, 0);
run_test();
end
dave_59
11-17-2009, 01:02 AM
CMM,
The problem is you did not parametrize the virtual interface declaration in your monitor to match your virtual interface declaration in the top file . Note the difference between the two m_wb_if_wrapper declarations.
Dave
Hi,
I changed
wb_if_wrapper #(virtual wb_if) m_wb_if_wrapper;
in monitor file to
wb_if_wrapper #(virtual wb_if#(.G_ADDR_WIDTH(G_ADDR_WIDTH), .G_DATA_WIDTH(G_DATA_WIDTH))) m_wb_if_wrapper;
there is no illegal assignment error. but still the fatal exists.
http://www.ovmworld.org/forums/showthread.php?t=245 seems to answer this fatal problem, but I can't find -permit_unmatched_virtual_intf option in Questa 6.5 reference manual. Is it replaced by some other methods?
dave_59
11-17-2009, 10:21 PM
It is a 'hidden' switch. You shouldn't need it. The error is telling you that the parameters in your interface instance do not match the parameters you are passing down to your virtual interface variable. You're going to need to show even more code that shows how the paramters are passed down.
Dave
Questa 6.4c seems not be able to recognize this hidden option.
I checked my monitor and top, I set the default value 8 for G_ADDR_WIDTH and 32 for G_DATA_WIDTH everywhere
I also tried not to parameterize the interface, loading errors disappear.
I find that hidden switch quite useful, because after I add it to my vsim, the simulation runs as expected. Maybe it's good to turn it from hidden to default. :)
in 6.5c, there is no need to add the hidden option. It really turns to default.
Powered by vBulletin™ Version 4.0.3 Copyright © 2010 vBulletin Solutions, Inc. All rights reserved.