View Full Version : OVM wrapper for Verilog Bfms??
anantv
03-05-2008, 11:11 PM
Hi All
Nice to have an active forum for OVM!!!!
Just I have started looking into OVM & System Verilog.
It would be of great help, if anyone provides me with an approach/example/process steps on how to develop OVM wrapper for an existing verilog bfm like AVM?
Thanks in advance.
regards
TVAR
dave_59
03-06-2008, 10:46 AM
TVAR,
You can continue to use the process described in chapter 9 of the AVM cookbook (http://www.mentor.com/go/cookbook).
At the recent DVCON'08, I gave a paper that presents an alternative by using abstract classes. I have attached that paper and would like any feedback if you find it useful.
Dave
anantv
03-06-2008, 11:23 PM
Hi Dave,
Thanks for the DVCon'08 paper & details.
Non-availability of OVM Cookbook, has triggered me to post "OVM Wrapper for verilog Bfms??" question.
So far I have been using the legacy verilog BFM in AVM environment as per the Chapter 9 of AVM Cookbook.
I don't want to change/modify the internals of the legacy verilog BFM such as the tasks & functions, internal transaction queues..etc.
Hence I have created a system verilog interface based module wrapper around the legacy verilog BFM.
Then I have created an Interface with a class consisting of virtual task calls through hierarchical reference to the internal tasks of the legacy verilog BFM.
This interface does not contain the BFM signals only their task calls and creates an instance of that class.
This interface is assigned to a virtual interface instance in the Driver/Stimulus generator class for driving the stimulus to the legacy verilog BFM.
This method (AVM class based wrapper ) works well & good, but still I have to use hierarchical referencing to access the internal tasks of the legacy verilog BFM.
Coming to the abstract base class method suggested in your paper, we are going to directly access the DUT signals instead of hierarchical referencing.
This seems to be good as far as the tasks in the concrete BFM class are NOT virtual and hierarchically calling internal tasks of the legacy verilog BFM.
This means that those tasks should be implemented in the current scope only.
This may add more code complexity & calls for change in the architecture of the legacy verilog BFM.
In my case, How can I directly call the internal tasks of the legacy BFM from the top module?
Please provide me your valuable suggestions on the same.
Thanks & Regards,
TVAR
dave_59
03-07-2008, 01:03 PM
In my case, How can I directly call the internal tasks of the legacy BFM from the top module?
I guess I'm having trouble understanding what is about the OVM that is preventing you from doing what you did in the AVM.
I'll try to explain using the examples in the paper using OVM terminology. Let's say this is your legacy BFM module:
module UART_Tx(output logic line);
int NBits;
time BitPeriod;
task setNBits(input int N);
if (N>0 && N<=10) NBits = N;
endtask : setNBits
task setBitPeriod(input time T);
if (T>0) BitPeriod = T;
endtask : setBitPeriod
task send(input logic [9:0] d);
...
endtask : send
endmodule : UART_TxAnd your legacy testbench looked like:
module top;
wire line;
UART_DUT u_dut(line);
UART_TX u_tx(line);
endmodule
module test;
initial begin
top.U_tx.setNBits(8);
top.U_tx.setNPeriod(100);
top.U_tx.send(8);
repeat (30)
top.U_tx.send($random);
...
endmoduleNow here's the abstract class definition, defined as an ovm_object so it can be passed through a config object
package UART_pkg;
virtual class UART_BFM extends ovm_pkg::ovm_object;
pure virtual task setNBits(input int N);
pure virtual task setBitPeriod(input time T);
pure virtual task send(input logic [9:0] d);
function new(string name);
super.new(name);
endfunction
endclass
endpackage : UART_pkg
Now in module test, or anywhere other than in a package, you define the concrete class, and register the config object:
module test;
class U_TX extends UART_pkg::UART_BFM;
task setNBits(input int N);
TB_top.U_tx.setNBits(N);
endtask
task setBitPeriod(input time T);
TB_top.U_tx.setNPeriod(100);
endtask
…
function new(string name);
super.new(name);
endfunction
endclass
U_TX u_tx=new("U_TX");
initial set_config_object("driver_path","BFM",u_tx,0); // 0 - means don't clone
endmodule
Then in your driver (or monitor/whatever) you would use get_config_object to retrieve your handle:
import uart_pkg::*;
import ovm_pkg::*;
class uart_driver extends ovm_component;
uart_bfm bfm_h;
function void configure();
ovm_object h;
assert (!get_config_object("BFM",h) else ovm_report_error(...);
$cast(bfm_h = h);
endfunction
task that_does_something(...);
...
bfm_h.send(data);
…
endtask
endclass
Dave
anantv
03-11-2008, 02:11 AM
Hi Dave,
Thanks for the detailed example.
I was able to work with Virtual Interface based approach in both AVM/OVM.
As the abstract base class method seems advantageous,according to your example, I have tried Abstract base class method.
I have placed the concrete base class & config object in the testbench module.
My simulation failed at $cast in the driver class with "BAD POINTER ACCESS" error. (Questasim 6.3d)
Error at the bolded line:
mport ovm_pkg::*;
class uart_driver extends ovm_component;
uart_bfm bfm_h;
function void configure();
ovm_object h;
assert (!get_config_object("BFM",h) else ovm_report_error(...);
$cast(bfm_h,h);
endfunction
task that_does_something(...);
...
bfm_h.send(data);
…
endtask
endclass
[/code]Dave[/QUOTE]
It is NOT able to cast the ovm_object 'h' to the object of the concrete base class 'bfm_h'.
Please provide me your suggestoins.
dave_59
03-11-2008, 07:47 AM
Is h null before you do the $cast? I have to admit I didn't try the example before posting, since it had a lot of ...'s in it. (The example in the paper does work!). I'll try to fill it out and get it working. I would help if you could attach the example as you typed it.
Dave
anantv
03-11-2008, 08:41 AM
Hi Dave,
I do have a clarification with your example.
We can't create an object of an abstract base class.
Hence how can I get an object of the abstract base class defined in the package?
Refer first bolded line.
import ovm_pkg::*;
class uart_driver extends ovm_component;
uart_bfm bfm_h;
function void configure();
ovm_object h;
assert (!get_config_object("BFM",h) else ovm_report_error(...);
$cast(bfm_h,h);
endfunction
task that_does_something(...);
...
bfm_h.send(data);
…
endtask
endclass
[/code]Dave
[/QUOTE]
dave_59
03-11-2008, 09:07 AM
Hi Dave,
I do have a clarification with your example.
We can't create an object of an abstract base class.
Hence how can I get an object of the abstract base class defined in the package?
That is correct, you can't construct an object of an abstract base class. But you can extend an abstract class and construct that class, and assign that object to a handle of an abstract class.
umery
03-12-2008, 02:31 PM
Hi Anantv, Dave_59,
There is another method being discussed for module based bfms (not AVM) that may be useful for Anant to look at.
http://www.ovmworld.org/forums/showthread.php?t=100
Umer
dave_59
03-13-2008, 10:15 PM
I have a completed example that actually does something. See attached.
Dave
anantv
03-14-2008, 12:08 PM
Hi Dave,
Thanks for the detailed example, which helped me to understand the approach clearly.
Hi Umery,
Thanks for referring to the thread:
http://ovmworld.org/forums/showthread.php?t=109
This gives another approach for the same.
Thanks to all.
Powered by vBulletin™ Version 4.0.3 Copyright © 2010 vBulletin Solutions, Inc. All rights reserved.