Callback add method
Table of Contents
Add method implementation
static function void add( T obj, uvm_callback cb, uvm_apprepend ordering = UVM_APPEND )
- Registers the callback object with the object in which callback is used
- It is allowed to register multiple callbacks derived from the same callback
- If ordering is UVM_APPEND (default), the callback will be executed after previously added callbacks, else the callback will be executed ahead of previously added callbacks
Using add method
The previous example shows the usage of the add method.
In order to execute the callback method, the Callback object needs to be registered to the object/component.
uvm_callbacks#(T, CB)::add(t,cb);
Multiple add for the same method
To the single callback hook, it is possible to have call to multiple flavors of the same method.
i.e if the same method is implemented in multiple extended classes, then it is possible to register all the methods to the same callback hook.
On calling of `uvm_do_callbacks
macro all the callback methods executed in the order which methods are registered.
Example for Multiple flavors of the same method
Let’s consider the previous example and implement multiple flavors of the same method.
In the previous example, pre_drive()
and post_drive()
are callback methods and implemented them in user_callback class.
Now lets implement callback methods in user_callback_1 and user_callback_2 classes by extending driver_callback class.
user_callback_1
Below is user_callback_1 class implemented with displays USER_CALLBACK-1
class user_callback_1 extends driver_callback; `uvm_object_utils(user_callback_1) function new(string name = "user_callback_1"); super.new(name); endfunction task pre_drive; `uvm_info("USER_CALLBACK-1","Inside pre_drive method",UVM_LOW); endtask task post_drive; `uvm_info("USER_CALLBACK-1","Inside post_drive method",UVM_LOW); endtask endclass
user_callback_2
Below is user_callback_2 class implemented with displays USER_CALLBACK-2
class user_callback_2 extends driver_callback; `uvm_object_utils(user_callback_2) function new(string name = "user_callback_2"); super.new(name); endfunction task pre_drive; `uvm_info("USER_CALLBACK-2","Inside pre_drive method",UVM_LOW); endtask task post_drive; `uvm_info("USER_CALLBACK-2","Inside post_drive method",UVM_LOW); endtask endclass
Testcase
In the below test case’s user_callback_1 and user_callback_2 are registered using the add method.
user_callback_test
user_callback_1 is registered first and then user_callback_2.
class user_callback_test extends basic_test; user_callback_1 callback_1; user_callback_2 callback_2; `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_1::type_id::create("callback_1", this); callback_2 = user_callback_2::type_id::create("callback_2", this); uvm_callbacks#(driver,driver_callback)::add(env.driv,callback_1); uvm_callbacks#(driver,driver_callback)::add(env.driv,callback_2); endfunction endclass
user_callback_2_test
Lets write one more testcase user_callback_2_test, with user_callback_2 is registered first and then user_callback_1.
class user_callback_2_test extends basic_test; user_callback_1 callback_1; user_callback_2 callback_2; `uvm_component_utils(user_callback_2_test) function new(string name = "user_callback_2_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_1::type_id::create("callback_1", this); callback_2 = user_callback_2::type_id::create("callback_2", this); uvm_callbacks#(driver,driver_callback)::add(env.driv,callback_2); uvm_callbacks#(driver,driver_callback)::add(env.driv,callback_1); endfunction endclass
Simulator Output: (user_callback_test)
UVM_INFO @ 0: reporter [RNTST] Running test user_callback_test... UVM_INFO user_callback.sv(18) @ 0: reporter [USER_CALLBACK-1] Inside pre_drive method UVM_INFO user_callback.sv(39) @ 0: reporter [USER_CALLBACK-2] Inside pre_drive method UVM_INFO slave_driver.sv(23) @ 0: uvm_test_top.env.driver [DRIVER] Inside drive_pkt method UVM_INFO user_callback.sv(22) @ 0: reporter [USER_CALLBACK-1] Inside post_drive method UVM_INFO user_callback.sv(43) @ 0: reporter [USER_CALLBACK-2] Inside post_drive method
Simulator Output: (user_callback_2_test)
UVM_INFO @ 0: reporter [RNTST] Running test user_callback_2_test... UVM_INFO user_callback.sv(39) @ 0: reporter [USER_CALLBACK-2] Inside pre_drive method UVM_INFO user_callback.sv(18) @ 0: reporter [USER_CALLBACK-1] Inside pre_drive method UVM_INFO slave_driver.sv(23) @ 0: uvm_test_top.env.driver [DRIVER] Inside drive_pkt method UVM_INFO user_callback.sv(43) @ 0: reporter [USER_CALLBACK-2] Inside post_drive method UVM_INFO user_callback.sv(22) @ 0: reporter [USER_CALLBACK-1] Inside post_drive method
Form the above simulator output we could see the order of execution of callback methods,
In user_callback_test user_callback_1 method executed first and then user_callback_2 method.
In user_callback_2_test user_callback_2 method executed first and then user_callback_1 method.
❮ Previous Next ❯