Callback in uvm_sequence
Table of Contents
Callback hooks can be placed in uvm_sequnence. Different flavors of the sequence can be obtained by implementing custom callback methods.
In the previous example’s we have seen callback implementation in uvm_driver. In this section will see how to implement the callback in uvm_sequence.
Callback implementation in uvm_sequence
Callback implementation steps for uvm_sequence are the same as in uvm_driver. Before going through this section, it is required to refer to the UVM callback example.
Below are the testbench components.
Let’s implement the callback in uvm_sequence to modify the sequence_item before sending it to the driver.
Steps involved are,
- Write callback class
- Register the callback class
- Place the callback hook
- Implement the callback method
- Create and register the callback object
Write Callback class
- Callback class is written by extending the uvm_callback
class mem_callback extends uvm_callback; ... endclass
- Adding a virtual callback method
class mem_callback extends uvm_callback; virtual task update_pkt(ref mem_seq_item pkt); endtask endclass
- Complete callback class code
class mem_callback extends uvm_callback; `uvm_object_utils(mem_callback) function new(string name = "mem_callback"); super.new(name); endfunction virtual task update_pkt(ref mem_seq_item pkt); endtask endclass
Register the callback class
- The callback class needs to be registered with the component. As the sequence is dynamic, the callback will be registered to a sequencer
`uvm_register_cb(mem_sequencer,mem_callback)
- Complete sequencer code
class mem_sequencer extends uvm_sequencer#(mem_seq_item); `uvm_component_utils(mem_sequencer) `uvm_register_cb(mem_sequencer,mem_callback) //--------------------------------------- //constructor //--------------------------------------- function new(string name, uvm_component parent); super.new(name,parent); endfunction endclass
Place the callback hook
- Callback hook is a call to callback method, and in this example, it is required to be placed in the sequence
`uvm_do_obj_callbacks(mem_sequencer,mem_callback,p_sequencer,update_pkt(req));
- Complete sequence code
class mem_sequence extends uvm_sequence#(mem_seq_item); `uvm_object_utils(mem_sequence) //--------------------------------------- //Constructor //--------------------------------------- function new(string name = "mem_sequence"); super.new(name); endfunction `uvm_declare_p_sequencer(mem_sequencer) //--------------------------------------- // create, randomize and send the item to driver //--------------------------------------- virtual task body(); req = mem_seq_item::type_id::create("req"); wait_for_grant(); req.randomize(); `uvm_do_obj_callbacks(mem_sequencer,mem_callback,p_sequencer,update_pkt(req)); send_request(req); wait_for_item_done(); endtask endclass
Implement the callback method
The callback will be implemented in the extended callback class.
- Write user_callback class by extending mem_callback
class user_callback extends mem_callback; `uvm_object_utils(user_callback) function new(string name = "user_callback"); super.new(name); endfunction endclass
- Implement the update_pkt callback method
- the update_pkt method is implemented to invert the value of the address.
class user_callback extends mem_callback; `uvm_object_utils(user_callback) function new(string name = "user_callback"); super.new(name); endfunction task update_pkt(ref mem_seq_item pkt); `uvm_info("USER_CALLBACK","[update_pkt] before packet modification",UVM_LOW); pkt.print(); pkt.addr = ~pkt.addr; `uvm_info("USER_CALLBACK","[update_pkt] after packet modification",UVM_LOW); pkt.print(); endtask endclass
Create and register the callback object
- Declare and create the callback
user_callback callback_1; callback_1 = user_callback::type_id::create("callback_1", this);
- Register the callback object with the component in which callback class is registered
uvm_callbacks#(mem_sequencer,mem_callback)::add(env.mem_agnt.sequencer,callback_1);
- Complete user_callback_test code
class user_callback_test extends mem_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); endfunction function void end_of_elaboration(); uvm_callbacks#(mem_sequencer,mem_callback)::add(env.mem_agnt.sequencer,callback_1); endfunction : end_of_elaboration endclass
Simulator Output: (mem_test)
UVM_INFO mem_driver.sv(38) @ 0: uvm_test_top.env.mem_agnt.driver [mem_driver] Recived Drive packet ---------------------------------- Name Type Size Value ---------------------------------- req mem_seq_item - @575 addr integral 4 'hb wr_en integral 1 'h0 rd_en integral 1 'h1 wdata integral 8 'h3f ---------------------------------- UVM_INFO /apps/vcsmx/etc/uvm-1.2/src/base/uvm_objection.svh(1270) @ 50: reporter [TEST_DONE] 'run' phase is ready to proceed to the 'extract' phase UVM_INFO /apps/vcsmx/etc/uvm-1.2/src/base/uvm_report_server.svh(847) @ 50: reporter [UVM/REPORT/SERVER]
Simulator Output: (user_callback_test)
UVM_INFO user_callback.sv(14) @ 0: reporter [USER_CALLBACK] [update_pkt] before packet modification ---------------------------------- Name Type Size Value ---------------------------------- req mem_seq_item - @577 addr integral 4 'hb wr_en integral 1 'h0 rd_en integral 1 'h1 wdata integral 8 'h3f ---------------------------------- UVM_INFO user_callback.sv(17) @ 0: reporter [USER_CALLBACK] [update_pkt] after packet modification ---------------------------------- Name Type Size Value ---------------------------------- req mem_seq_item - @577 addr integral 4 'h4 wr_en integral 1 'h0 rd_en integral 1 'h1 wdata integral 8 'h3f ---------------------------------- UVM_INFO mem_driver.sv(38) @ 0: uvm_test_top.env.mem_agnt.driver [mem_driver] Recived Drive packet ---------------------------------- Name Type Size Value ---------------------------------- req mem_seq_item - @577 addr integral 4 'h4 wr_en integral 1 'h0 rd_en integral 1 'h1 wdata integral 8 'h3f ---------------------------------- UVM_INFO /apps/vcsmx/etc/uvm-1.2/src/base/uvm_objection.svh(1270) @ 50: reporter [TEST_DONE] 'run' phase is ready to proceed to the 'extract' phase
Result Analysis
From the above simulation result, we can make out that,
user_callback_test is enabling the implemented callback methods.
Note:
In Compile & Run Options Provide,
+UVM_TESTNAME=mem_test to execute mem_test
+UVM_TESTNAME=user_callback_test to execute user_callback_test
❮ Previous Next ❯