View Full Version : two ovm_analysis_imp?
alain
03-07-2008, 12:18 PM
Hi,
I'm trying to write a module UVC that will read inputs through an analysis port, process them through a reference model, and compare with outputs it's also reading from an analysis port.
From what I understand, you can't have two analysis ports in a component, right? Only one write() function can be defined.
I can always have two separate monitors, each connected to their own analysis port, and writing to a fifo. Then the checker can read two fifos, run the model and compare.
Any other suggestion?
tfitz
03-07-2008, 12:24 PM
Hi Alain,
Take a look at the ovm_in_order_comparator for an example. You're right that any component can only implement one write() interface. The comparator instantiates two analysis_fifos (before and after), each of which has its own analysis_export that gets connected to an analysis_export in the comparator (before_export and after_export). The analysis_fifo is a useful tool. It's infinite length so you're guaranteed that the write() will always succeed, and your scoreboard can pull the transactions out of each fifo when needed.
Good luck,
-Tom
alain
03-07-2008, 12:52 PM
Hi Tom,
I looked at ovm_in_order_comparator. I want to make sure I understand the code correctly. Basically, you have to streams BEFORE and AFTER coming in. Instead of connecting them with ovm_analysis_imp, you connected them with ovm_analysis_export, which is then connected to an ovm_analysis_fifo, from which you pull the data, instead of being pushed from ovm_analysis_imp.
It means my ovm_analysis_export is going to be connected by the upper layers to a regular ovm_analysis_port.
Did I get it right?
Thanks for your help.
tfitz
03-07-2008, 01:32 PM
Basically, you have two streams BEFORE and AFTER coming in. Instead of connecting them with ovm_analysis_imp, you connected them with ovm_analysis_export, which is then connected to an ovm_analysis_fifo, from which you pull the data, instead of being pushed from ovm_analysis_imp.
Correct. In your scoreboard, you'll just do a get from the appropriate fifo. Remember that the "other side" of the analysis_fifo looks just like a regular tlm_fifo. In this case, the analysis_imps are hidden inside the analysis_fifos.
function void connect();
before_export.connect( before_fifo.analysis_export );
after_export.connect( after_fifo.analysis_export );
endfunction
It means my ovm_analysis_export is going to be connected by the upper layers to a regular ovm_analysis_port.
Did I get it right?
Yes. In the env, you'll instantiate your scoreboard and connect its before_export and after_export (or whatever you want to call them) to the appropriate analysis_port
class my_env extends ovm_env;
function void connect();
monitor1.analysis_port.connect(my_scbd.before_expo rt);
monitor2.analysis_port.connect(my_scbd.after_expor t);
endfunction
...
endclass
alain
03-07-2008, 01:46 PM
Correct. In your scoreboard, you'll just do a get from the appropriate fifo. Remember that the "other side" of the analysis_fifo looks just like a regular tlm_fifo. In this case, the analysis_imps are hidden inside the analysis_fifos.
Beautiful! In my case, the BEFORE and AFTER streams are different data types (there's a reference model in between), so I can't re-use the simple ovm_in_order_comparator, but I can borrow some code :-)
Maybe an ovm component that reads two types T1 and T2 and assembles them in a pair and feeds them to an analysis port would be useful?
Thanks for your help.
tfitz
03-07-2008, 01:52 PM
Maybe an ovm component that reads two types T1 and T2 and assembles them in a pair and feeds them to an analysis port would be useful?
Check out src/methodology/ovm_algorithmic_comparator.svh
It should be exactly what you want. The TRANSFORMER parameter is a "functor" that implements the transform() method that converts a 'b' to an 'a' which then goes into the embedded ovm_in_order_comparator.
There's also the ovm_class_pair that you could use to assemble a single transaction with both types in it. Then you're right, you could write the pair out to an analysis port.
Good luck,
-Tom
sasan
03-09-2008, 12:30 PM
The OVM class library allows you to have multiple ports in the same component.
I think we should first differentiate between imps and ports.
A transaction interface consists of an imp connector object that is linked with a port connector object. The component containing the imp iobject provides the implementaion (e.g., function write() for analysis ports), while the componnet containing the port object makes use of the implementation by calling the predefined method.
Now, you can have as many analysis port objects in one component as you'd like. However, using the default tansaction interface types provided in the OVM class library, you can have only one analysis imp object in a component.
But you can definitely create your own analysis imp types to have as many imp objects as you'd like in a single component.
To do this, you need to use macro ovm_analysis_imp_decl().
File src/tlm/tlm_defines.svh in the OVM release gives a small example, shown as a comment on the top.
I am working on a full-working example, to be included in the OVM book I am working on. So more information on this should be available soon.
tfitz
03-10-2008, 07:17 AM
The OVM class library allows you to have multiple ports in the same component.
I think we should first differentiate between imps and ports.
Conceptually, we've found that it's a bit easier to consider ports and exports. TLM ports define the set of methods used to communicate the transaction. The TLM export defines the implementation of those methods. The TLM imp is the lowest-level "export" that includes a little more magic to make the right things happen. Once you have an imp, you use exports to connect/pass them up the hierarchy.
A transaction interface consists of an imp connector object that is linked with a port connector object. The component containing the imp iobject provides the implementaion (e.g., function write() for analysis ports), while the component containing the port object makes use of the implementation by calling the predefined method.
Technically, the initiator component calls the predefined method of the port. Through the TLM connection
my.port.connect(your.export);
the implementation in the export (in this case, write()) gets called automatically.
Now, you can have as many analysis port objects in one component as you'd like. However, using the default tansaction interface types provided in the OVM class library, you can have only one analysis imp object in a component.
True. Each analysis_port in the initiator typically writes a different transaction to be considered for a different purpose. Because analysis_ports may have multiple analysis_exports connected to them, it is never necessary to write the same transaction to multiple analysis_ports.
But you can definitely create your own analysis imp types to have as many imp objects as you'd like in a single component.
To do this, you need to use macro ovm_analysis_imp_decl().
File src/tlm/tlm_defines.svh in the OVM release gives a small example, shown as a comment on the top.
I am working on a full-working example, to be included in the OVM book I am working on. So more information on this should be available soon.
As with other macros, there are tradeoffs to using the ovm_*_decl macros Sasan mentions. Debugability and namespace pollution are two of the big ones. Off the top of my head, there are only two cases where you'd need multiple analysis_imps. The first is in a scoreboard which we've shown above can actually be handled quite easily by using analysis_fifos and binding the analysis_fifo exports to exports in your scoreboard component.
The other case might be where you have a single component in which you want to perform different analysis operations on different transaction streams. For example, a subscriber that has two covergroups, each of which will record information about two different transaction streams. The problem with multiple write implementations in this case is that each of these coverage operations is less reusable.
Our recommendation would be to create a subscriber to handle each coverage operation (or whatever you're doing). Then you can wrap these, if necessary, in a higher level component and pass the analysis implementations up as separate exports just like the ovm_*_comparator() classes. That way, each of the subscribers is a standalone component that can be reused if needed and you still have the "joint" implementation component available if you really need it.
ssharath
09-23-2008, 04:16 AM
Check out src/methodology/ovm_algorithmic_comparator.svh
It should be exactly what you want. The TRANSFORMER parameter is a "functor" that implements the transform() method that converts a 'b' to an 'a' which then goes into the embedded ovm_in_order_comparator.
There's also the ovm_class_pair that you could use to assemble a single transaction with both types in it. Then you're right, you could write the pair out to an analysis port.
Good luck,
-Tom
Tom,
The above solution is not good from reusable point of view. I want to give you an example and how you will handle this.
I already have AXI and AHB interface level UVC's ( monitors included of course!! ) and I am testing AXI to AHB conversion lets say. So I can't modify how the puts I have to do.
One crude solution would be, have 2 scoredboard classes which will just do the gets ( write function ) from the monitors and put it in a local fifo. Then a third scoreboard which contains the instances of the above 2 scoreboard will make use of the fifo and then do comparison. But this doesn't look like a good solution to me.
Is there a better way to handle this in OVM?
Thanks.
tfitz
09-29-2008, 08:19 AM
Tom,
The above solution is not good from reusable point of view. I want to give you an example and how you will handle this.
I already have AXI and AHB interface level UVC's ( monitors included of course!! ) and I am testing AXI to AHB conversion lets say. So I can't modify how the puts I have to do.
One crude solution would be, have 2 scoredboard classes which will just do the gets ( write function ) from the monitors and put it in a local fifo. Then a third scoreboard which contains the instances of the above 2 scoreboard will make use of the fifo and then do comparison. But this doesn't look like a good solution to me.
Is there a better way to handle this in OVM?
Thanks.
Assuming that each of the OVCs (note the new term) can provide a transaction stream via an analysis_port - and you may have to extend your current OVC to do it - then you can use the ovm_algorithmic_comparator as I described. All you have to do it define the transform method to convert an AXI to AHB or vice-versa.
I don't know what you mean by "So I can't modify how the puts I have to do."
ssharath
09-29-2008, 08:25 AM
Assuming that each of the OVCs (note the new term) can provide a transaction stream via an analysis_port - and you may have to extend your current OVC to do it - then you can use the ovm_algorithmic_comparator as I described. All you have to do it define the transform method to convert an AXI to AHB or vice-versa.
I don't know what you mean by "So I can't modify how the puts I have to do."
Basically I meant that I didn't want to the transformation. Since the each I-OVC will be developed by different teams, I would ideally want to just connect my analysis_imports to the monitor ports just like we did in AVM.
Thanks for the reply.
tfitz
09-29-2008, 08:48 AM
You can have a scoreboard that has different types of analysis_exports - one AXI and one AHB. The transform() method is used to make it easier then to reuse the ovm_in_order_comparator, but it's not strictly necessary. You can define your own compare() method that takes two arguments - one AXI and one AHB - and then have a simple scoreboard that pulls each transaction and compares them. No transformation is required and each particular scoreboard defines what it means to compare transactions of the different types.
desperado
03-06-2009, 11:29 PM
HI all,,
At the MONITOR side its enough we declare a ovm_analysis_port and put the transactions rite ??
// These are the steps i tried below which learned from the other threads
// Is the connections the proper usage, correct me plz if had made any // // mistake
// Declaration in monitor1 side
ovm_analysis_port #(ctl_item) itd_port;
itd_port.write(transaction1);
// Declaration in monitor2 side
ovm_analysis_port #(ctl_item) ofd_port;
ofd_port.write(transaction2);
// Declarations inside the scoreboard, both export and fifo.
ovm_analysis_fifo #(ctl_item) on_itd_fifo;
ovm_analysis_fifo #(ctl_item) on_ofd_fifo;
ovm_analysis_export #(ctl_item) on_itd_export;
ovm_analysis_export #(ctl_item) on_ofd_export;
// void connect to connect the export and the fifo
function void connect;
on_itd_export.connect(on_itd_fifo.analysis_export) ;
on_otd_export.connect(on_otd_fifo.analysis_export) ;
endfunction
// Connections inside environment
ctl_mon_itd0.itd_port.connect(ctl_scoreboard0.on_i td_export);
ctl_mon_ofd0.ofd_port.connect(ctl_scoreboard0.on_o fd_export);
thanks,
Desperado:cool:
Powered by vBulletin™ Version 4.0.3 Copyright © 2010 vBulletin Solutions, Inc. All rights reserved.