PDA

View Full Version : ovm_transaction is not an ovm_report_object



ggorman
02-29-2008, 01:13 PM
I can see the reasoning that an ovm_transaction is usually a small data type that is instantiated so many times throughout a test that you might not want the overhead of ovm_report. But what if I want an ovm_tansaction with report capability?

A transaction to my dut is much more than simply an address and data, for instance. My class to represent a transaction has over 50 properties -- and one of those properties is another class that has 35 properties.

We have a .print() method for this class which will need ovm_report, but it doesn't have access to that. I know that the workaround is to have the class return a string for the caller to pass to ovm_report; but the print() result for the 50+ properties is many lines long.

Also 85 properties to randomize is cumbersome. We've changed some of the randomizing to occur in post_randomize because it was too much for the constraint solver. This post_randomize routine has error and debug messages to print; butcanno because it doesn't have access to ovm_report.

I could make this an ovm_component instead, but it really is a transaction and I'll want to make a sequence of these, and an ovm_sequence is not an ovm_component.

Maybe we need an ovm_report_transaction ?

George Gorman

mglasser
02-29-2008, 02:11 PM
Hi George,

There are a couple of ways around the problem. One is the way you suggest -- to create an ovm_report_transaction. That would make available the messaging interface to all transactions of that type.

Another way is to use the global reporter object to send reports. The global reporter is a small class derived from ovm_report_object and it can be used anywhere where you need it, such as in a transaction or in a module. E.g.



_global_reporter.ovm_report_info("id", "message");


A third way would be to create your own reporter and include it amongst the properties in your transaction. E.g.



class my_reporter extends ovm_report_object;
...
endclass

class producer extends ovm_threaded_component;
...
task run();
my_reporter r = new(); // create reporter object
transaction t;

for(int i = 0; i < 100; i++) begin
t = new();
t.reporter = r; // put the reporter into the transaction object
put_port.put(t);
end
endtask

Then, in methods on your transaction object or wherever you need to, you can use the local reporter to print messages.


t.reporter.ovm_report_info("id", "message");

The nice thing about this is that you can customize the behavior of the local reporter indpendently of another component or transaction.

-- Mark

ggorman
02-29-2008, 02:40 PM
Hi Mark,

Your second solution sounds like the transaction class would require the existance of an external _global_reporter? And wouldn't work in a testbench that doesn't create one?

I like your third approach though. If I'm understanding you correctly, it's that I'm instantiating a reporter inside of my transaction -- so retrofitting my ovm_transaction type into somethiung that looks much like what I had envisioned as an ovm_report_transaction, but it's still really an ovm_transaction. With my ovm_report_transaction solution, we'd also need an ovm_report_sequence and so on .. could get ugly.

Thanks -- George

dave_59
02-29-2008, 04:27 PM
George,

The global reporter has already been created inside the ovm_pkg and in fact you can just do


ovm_report_info("id", "message");A slight variation of option three is to just use the report handler of the component creating the transaction instead of constructing a new one. This has been successfully used in the AVM.




class my_transaction extends ovm_transaction;
ovm_report_object reporter;
...
endclass

class ...

task run();
transaction t;

for(int i = 0; i < 100; i++) begin
t = new();
t.reporter = this; // put the reporter into the transaction object
put_port.put(t);
end
endtaskDave