1. callback机制的必要性
在UVM验证平台中,callback机制的最大用途就是提高验证平台的可重用性。如果把两个项目不同的地方使用callback函数来做,而把相同的地方写成一个完整的env,这样重用时,只要改变相关的callback函数env可完全的重用。
除了提高可重用性外,callback机制还用于构建异常的测试用例。
2.callback机制的使用
对于一个VIP开发者,预留一个callback函数/任务时需要做以下几步:
- 定义一个A类
- 声明一个A_pool类
- 在预留callback函数/任务接口的类中调用uvm_register_cb宏
- 在要调用callback函数/任务接口的函数/任务中使用uvm_do_callbacks宏
1.A类要从uvm_callback派生,另外还需要定义一个pre_tran的任务,此任务的类型一定要是virtual的,因为从A派生的类需要重载这个任务
class A extends uvm_callback;
virtual task pre_tran(my_driver dev, ref my_transaction tr);
endtask
endclass
2.声明一个A_pool类,还要指明这个池子将会被哪个类使用
typedef uvm_callbacks#(my_driver, A) A_pool;
在my_driver中做如下声明
typedef class A;
class my_driver extends uvm_driver#(my_traction);
...
`uvm_component_utils(my_driver)
`uvm_register_cb(my_driver, A)
...
endclass
task my_driver::main_phase(uvm_phase phase);
...
while(1) begin
seq_item_port.get_next_item(req);
`uvm_do_callbacks(my_driver, A, pre_tran(this, req))
driver_one_pkt(req);
seq_item_port.item_done();
end
endtask
对VIP的使用者,需要做以下几步:
- 从A派生一个类,在这个类中定义好pre_tran
- 在测试用例的connect_phase中将从A派生的类实例化
class my_callback extends A;
virtual task pre_tran(my_driver drv, ref my_transaction tr);
`uvm_info("my_callback", "this is pre_tran task", UVM_MEDIUM)
endtask
`uvm_object_utils(my_callback)
endclass
function void my_case0::connect_phase(uvm_phase phase);
my_callback my_cb;
super.connect_phase(phase);
my_cb = my_callback::type_id::create("my_cb");
A_poll::add(env.i_agt.drt, my_cb);
endfunction
3. 子类继承父类的callback机制
- 使用uvm_set_super_type宏,将子类和父类关联在一起,第一个参数是子类,第二个参数是父类
- 在main_phase中调用uvm_do_callbacks宏时,第一个参数是my_driver不是子类,即调用方式和在父类一样
class new_driver extends my_driver;
`uvm_component_utils(new_driver)
`uvm_set_super_type(new_driver, my_driver)
...
endclass
task new_driver::main_phase(uvm_phase phase);
...
while(1) begin
seq_item_port.get_next_item(req);
`uvm_info("new_driver", "this is new driver", UVM_MEDIUM)
`uvm_do_callbacks(my_driver, A, pre_tran(this, req))
drive_one_pkt(req);
seq_item_port.item_done();
end
endtask