Callbacks
Table of Contents
What is Callback?
Callbacks are empty methods with a call to them.
Before Starting with UVM Callbacks, It is good to go through SystemVerilog Callback.
Where callbacks can be implemented?
Callbacks can be implemented in an object or component.
What are the benefits of callback?
Different flavors of the component can be obtained by customizing the empty callback methods.
About UVM Callbacks
UVM provides a set of classes, methods, and macros to implement the callbacks.
Only the required callback methods are explained here.
Callback Example
With a simple driver example will see to UVM Callback.
Below are components of example,
- Driver
- Environment
- Test
The driver has drive() task, which revives the seq_item and drives to DUT (Current example code doesn’t have any logic to receive and drive seq_item).
In this example,
With help of callback, will add pre_drive() and post_drive() callbacks.
TestBench without callbacks
Driver
class driver extends uvm_component; `uvm_component_utils(driver) function new(string name, uvm_component parent); super.new(name,parent); endfunction task run_phase(uvm_phase phase); drive_pkt(); endtask task drive_pkt(); `uvm_info("DRIVER","Inside drive_pkt method",UVM_LOW); endtask endclass
Environment
class environment extends uvm_env; driver driv; `uvm_component_utils(environment) function new(string name, uvm_component parent); super.new(name,parent); endfunction function void build_phase(uvm_phase phase); super.build_phase(phase); driv = driver::type_id::create("driv", this); endfunction endclass
TestCase
class basic_test extends uvm_test; environment env; `uvm_component_utils(basic_test) function new(string name = "basic_test", uvm_component parent=null); super.new(name,parent); endfunction function void build_phase(uvm_phase phase); super.build_phase(phase); env = environment::type_id::create("env", this); endfunction endclass
Simulator Output:
UVM_INFO @ 0: reporter [RNTST] Running test basic_test... UVM_INFO driver.sv(18) @ 0: uvm_test_top.env.driv [DRIVER] Inside drive_pkt method
TestBench with callbacks
For easy understanding will see through below steps,
- Adding callback support
- Implementing the callback methods
- Using callback
Adding Callback Support
In order to have user-defined callbacks,
- User has to write user-defined callback class by extending the uvm_callback class
class driver_callback extends uvm_callback; ... endclass
- Define callback methods in user-defined callback class
- In this example pre_drive() and post_drive() are the callback methods.
virtual task pre_drive; endtask virtual task post_drive; endtask
Complete user-defined class code
class driver_callback extends uvm_callback; `uvm_object_utils(driver_callback) function new(string name = "driver_callback"); super.new(name); endfunction virtual task pre_drive; endtask virtual task post_drive; endtask endclass
In order to use callbacks defined,
- Callback class has to be registered with the object/component where callbacks are going to be used.
- Callback class can be registered by using macro `uvm_register_cb
`uvm_register_cb(driver,driver_callback)
In order to call the callback methods,
- Need to place method call’s (callback hook) to methods defined in user-defined callback class (pre_drive() and post_drive())
- Callback methods can be called by using macro `uvm_do_callbacks
`uvm_do_callbacks(driver,driver_callback,pre_drive()); `uvm_do_callbacks(driver,driver_callback,post_drive());
Complete driver code
class driver extends uvm_component; `uvm_component_utils(driver) `uvm_register_cb(driver,driver_callback) function new(string name, uvm_component parent); super.new(name,parent); endfunction task run_phase(uvm_phase phase); `uvm_do_callbacks(driver,driver_callback,pre_drive()); drive_pkt(); `uvm_do_callbacks(driver,driver_callback,post_drive()); endtask task drive_pkt(); `uvm_info("DRIVER","Inside drive_pkt method",UVM_LOW); endtask endclass
Implementing Callback Method
We have looked into, how to define the callback methods (In user-defined callback class) and placing hook to callback methods (In driver class using `uvm_do_callbacks macro)
Here will see how to add logic to callback methods.
- Need to extend the user-defined callback class and write one more callback class callback_1
class user_callback extends driver_callback; ... endclass
- Implement the methods with logic in it (this example we are adding only display’s)
task pre_drive; `uvm_info("USER_CALLBACK","Inside pre_drive method",UVM_LOW); endtask task post_drive; `uvm_info("USER_CALLBACK","Inside post_drive method",UVM_LOW); endtask
Complete callback class code
class user_callback extends driver_callback; `uvm_object_utils(user_callback) function new(string name = "user_callback"); super.new(name); endfunction task pre_drive; `uvm_info("USER_CALLBACK","Inside pre_drive method",UVM_LOW); endtask task post_drive; `uvm_info("USER_CALLBACK","Inside post_drive method",UVM_LOW); endtask endclass
Using Callback
In the testcase where callbacks need to be applied,
- Declare and create an object of callback class in which methods are implemented (callback_1).
user_callback callback_1; callback_1 = user_callback::type_id::create("callback_1", this);
- In order to execute the callback method, register the callback object to the driver using the ‘add’ method
uvm_callbacks#(driver,driver_callback)::add(env.driv,callback_1);
Complete testcase code
class user_callback_test extends basic_test; user_callback callback_1; `uvm_component_utils(user_callback_test) function new(string name = "user_callback_test", uvm_component parent=null); super.new(name,parent); endfunction function void build_phase(uvm_phase phase); super.build_phase(phase); callback_1 = user_callback::type_id::create("callback_1", this); uvm_callbacks#(driver,driver_callback)::add(env.driv,callback_1); endfunction endclass
callback_test is the test with callbacks added, and basic_test is without callbacks.
Simulator Output:
UVM_INFO @ 0: reporter [RNTST] Running test basic_test... UVM_INFO driver.sv(23) @ 0: uvm_test_top.env.driv [DRIVER] Inside drive_pkt method
callback_test simulator output (With Callback)
UVM_INFO @ 0: reporter [RNTST] Running test user_callback_test... UVM_INFO user_callback.sv(14) @ 0: reporter [USER_CALLBACK] Inside pre_drive method UVM_INFO driver.sv(23) @ 0: uvm_test_top.env.driv [DRIVER] Inside drive_pkt method UVM_INFO user_callback.sv(18) @ 0: reporter [USER_CALLBACK] Inside post_drive method
With the above result, we could see that displays added in callback methods are getting printed in callback_test.
The addition of logic to the callback methods will give more control on stimulus driving.
In the next example will see an example of how driving stimulus can be controlled using callbacks.
Callback Class and Macros
uvm_callback class
user-defined callback classes can be written by extending the uvm_callback class.
In it, the user defines one or more virtual methods.
These virtual methods are referred to as callback methods, these are empty methods with users have the option of overriding them.
class CB extends uvm_callback; ... endclass
uvm_register_cb
`uvm_register_cb(T,CB)
This macro is used to register the Callback (CB) with the Object(T).
Where,
CB => user defined callback class.
T => Object in which CB is used.
w.r.t above example:
CB => driver_callback class
T => driver class
uvm_do_callbacks
`uvm_do_callbacks(T,CB,METHOD)
This macro calls the callback methods defined in the user-defined callback class.
CB => user defined callback class.
T => Object in which CB is used.
METHOD => callback method to be called
w.r.t above example:
CB => driver_callback class
T => driver class
METHOD => pre_drive and post_drive
add method
uvm_callbacks#(T, CB)::add(t,cb);
Registers the callback object with the object in which callback is used.
CB => user defined callback class type.
T => Object type in which CB is used.
cb => callback class object
t => object in which callback is used
w.r.t above example:
CB => driver_callback class
T => driver class
cb => callback_1
t => driver class (differs if multiple objects of same type present)
❮ Previous Next ❯