UVM callback example
Callback in uvm_driver
step1
实现空的callback class
class driver_cb extends uvm_callback;
extern virtual task <callback task/function>;
endclass
step 2
实现functional class
class my_driver extends uvm_driver;
typedef driver_cb cb_type;
typedef m_driver this_type;
`uvm_component_utils(my_driver)
`uvm_register_cb(this_type, cb_type)
// in functional task
//`uvm_do_callback(this_type, cb_type, cb_task(this, m_item));
task run_phase(uvm_phase phase);
`uvm_do_callback(this_type, cb_type, cb_task(this, m_item));
drive_pkt();
//`uvm_do_callbacks(driver,driver_callback,post_drive());
endtask
endclass
step3
实现具体 callback class 并且注入
class driver_cb_rready extends driver_cb;
// concept
endclass
class m_case/m_env extends uvm_test/uvm_env;
typedef uvm_callbacks#(m_driver, driver_cb) driver_cb_pool;
// build_phase
driver_cb_rready drv_cb_rrdy;
drv_cb_rrdy = driver_cb_rready::type_id::create("drv_cb_rrdy");
// connect_phase
driver_cb_pool::add(m_env.m_agt.m_drv, drv_cb_rrdy);
endclass
Callback in uvm_sequence
step1 实现空的callback class
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
step2 register the callback class to sequencer
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
step3 place the callback hook on the sequence
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
step4 实现具体 callback class 并且注入
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
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