Hi,
I have used the example in the link https://verificationguide.com/uvm/uvm-callback-in-uvm-sequence/
and tried to implement the same but using a virtual sequencer.
I have created a axi_mm_callback class extending from uvm_callback class. Another class axi_user_callback class extends from axi_mm_callback class that implements a task wherein the addr value is 'h101010.
But when I call this axi_user_callback class from my test, only the parent class is executed and I can see the message “ENTERED AXI_MM_CALLBACK” in the sim.log. The callback is registered with the virtual seqeuncer that ultimately starts the actual sequencer. The task update_pkt in the axi_user_callback class is never executed.
I don’t understand what is missing.
Any help would be much appreciated.
Thank you.
----------------------CODE----------------------------
class axi_mm_callback extends uvm_callback;
`uvm_object_utils(axi_mm_callback)
function new(string name = "axi_mm_callback");
super.new(name);
`uvm_info(get_full_name(),$psprintf("ENTERED AXI_MM_CALLBACK\n"),UVM_DEBUG);
endfunction
virtual task update_pkt(ref axi_mm_uvc_pkg::axi_mm_transaction pkt);
endtask
endclass
---------------------------------------------------------
class axi_user_callback extends axi_mm_callback;
`uvm_object_utils(axi_user_callback)
function new(string name = "axi_user_callback");
super.new(name);
endfunction
task update_pkt(ref axi_mm_uvc_pkg::axi_mm_transaction pkt);
`uvm_info("USER_CALLBACK","[update_pkt] before packet modification",UVM_HIGH);
pkt.print();
pkt.awaddr = 'h10101010;
`uvm_info("USER_CALLBACK","[update_pkt] after packet modification",UVM_HIGH);
pkt.print();
endtask
endclass
// Class: axi_mm_virtual_sequencer
//------------------------------------------------------------------------------
class axi_mm_virtual_sequencer extends uvm_sequencer#(axi_mm_uvc_pkg::axi_mm_transaction);
`uvm_component_utils(axi_mm_virtual_sequencer)
`uvm_register_cb(axi_mm_virtual_sequencer,axi_mm_callback)
//the test from where I call the uvm_callbacks in the end of elaboration phase
function axi4_mem_intf_error_inject_callback_test::new(string name = "", uvm_component parent = null);
super.new(name, parent);
endfunction : new
//------------------------------------------------------------------------------
// function : build_phase
// creating object for all the sequences
//------------------------------------------------------------------------------
function void axi4_mem_intf_error_inject_callback_test::build_phase(uvm_phase phase);
super.build_phase(phase);
callback_1 = axi_user_callback::type_id::create("callback_1", this);
axi_seq= axi4_mem_intf_error_inject_callback_seq::type_id::create("axi_seq",this);
endfunction : build_phase
function void axi4_mem_intf_error_inject_callback_test::end_of_elaboration();
uvm_callbacks#(axi_mm_uvc_pkg::axi_mm_sequencer,axi_mm_callback)::add(intr_top_env.mm_env.axi_mm_uvc_h.seqr.callback_1);
endfunction : end_of_elaboration
//------------------------------------------------------------------------------
// task : run_phase
// randomizing each sequences with some value
// then starting the sequences inside respective sequencer with .start method
//------------------------------------------------------------------------------
task axi4_mem_intf_error_inject_callback_test::run_phase (uvm_phase phase);
phase.raise_objection(this);
axi_seq= axi4_mem_intf_error_inject_callback_seq::type_id::create("axi_seq");
initial_bringup_seq= axi4_mem_intf_initial_bringup_sequence::type_id::create("initial_bringup_seq");
`uvm_info( get_type_name(), "Starting AXI Write Read sequence...", UVM_DEBUG)
initial_bringup_seq.start(intr_top_env.vseqr);
create_axi_lite_reg_traffic('h424,'h00800010,'h1,axi_mm_enum_defines_pkg::AXI4_MM_VIP_INITIATOR_EN);
create_axi_lite_reg_traffic('h72C,'h00800010,'h1,axi_mm_enum_defines_pkg::AXI4_MM_VIP_RESPONDER_EN);
axi_seq.start(intr_top_env.vseqr);
phase.drop_objection(this);
phase.phase_done.set_drain_time (this, 100);
endtask : run_phase
The seqeunce where the uvm_do_callbacks macro is used
function axi_mm_write_seq::new(string name = "axi_mm_write_seq");
super.new(name);
`uvm_info(get_full_name(),$sformatf("\n Sequence Info : NAME=%0s", get_full_name()),UVM_DEBUG)
endfunction : new
//------------------------------------------------------------------------------
// task: body
//
//------------------------------------------------------------------------------
task axi_mm_write_seq::body();
axi_mm_uvc_pkg::axi_mm_transaction axi_wr_trans;
axi_mm_uvc_pkg::axi_mm_transaction rsp_item;
axi_wr_trans = axi_mm_uvc_pkg::axi_mm_transaction::type_id::create("axi_wr_trans");
port_cfg = p_sequencer.get_config();
axi_wr_trans.set_config(port_cfg);
`uvm_info(get_full_name(),$psprintf("debug axi_mm DATA WIDTH %0d \n",axi_wr_trans.data_width),UVM_DEBUG);
repeat(NUM_LOOP) begin
start_item(axi_wr_trans);
axi_wr_trans.ruser_enable = 0;
axi_wr_trans.aruser_enable = 0;
axi_wr_trans.randomize() with {read_or_write_direction == axi_mm_enum_defines_pkg::AXI4_TRANS_WRITE;
awaddr == addr;
awid == awid_mm;
awlen == burst_len;
};
`uvm_do_obj_callbacks(axi_mm_uvc_pkg::axi_mm_sequencer,axi_mm_callback,p_sequencer,update_pkt(axi_wr_trans));
`uvm_info(get_full_name(),$psprintf("axi_mm_WRITE_INIT_transaction object \n %s \n",axi_wr_trans.sprint()),UVM_DEBUG);
finish_item(axi_wr_trans);
get_response(rsp_item);
end
endtask : body