文章目录
一、Callback机制的作用
- Callback机制在UVM验证平台,最大用处就是为了
提高验证平台的可重用性
; - 在不创建复杂的OOP层次结构前提下,针对组件中的某些行为,在其之前后之后,内置一些函数,
增加或者修改UVM组件的操作,增加新的功能,从而实现一个环境多个用例
; - 还可以通过Callback机制
构建异常的测试用例
;
二、回调函数callback的使用步骤:
- 在UVM组件中内嵌callback函数或任务;
- 声明一个UVM callback空壳类;
- 从UVM callback空壳类中扩展UVM callback类;
- 在验证环境中创建并登记UVM callback实例。
三、代码code应用实例
3.1.声明一个UVM callback空壳类
1).通常都声明在同一个组件文件中;
2).所有的方法都声明为virtual,函数体为空;
class driver_callback extends uvm_callback;
`uvm_object_utils(driver_callback)
function new (string name = "driver_callback");
super.new(name);
endfunction
virtual task pre_send (driver drv, transaction tr);endtask //声明为virtual,利用多态性, 函数体是空的
virtual task post_send (driver drv, transaction tr);endtask //声明为virtual,利用多态性, 函数体是空的
endclass
3.2.在组件中的主操作函数或任务之前或者之后嵌入Callback函数
1). 使用宏`uvm_register_cb在组件中登记UVM_callback;
2).使用宏`uvm_do_callbacks在组件中行为之前后之后嵌入callback函数或者任务;(如下例中的pre_send( )和post_send( )函数)
typedef class driver_callback; //类的预定义,以便后续提前使用未定义的driver类
class driver extends uvm_driver#(transaction); //**1. 在底层组建中嵌入Callback函数**
`uvm_register_cb(driver, driver_callback); //在组件中登记UVM_callback
...
virtual task run_phase(uvm_phase phase);
forever begin
seq_item_port.get_next_item(req); //申请数据发送
`uvm_do_callbacks(driver,driver_callback,pre_send(this,req)); //在数据处理前,使用宏`uvm_do_callbacks嵌入Callback函数或者任务
send(req); //数据处理
`uvm_do_callbacks(driver,driver_callback,post_send(this,req)); //在数据处理后,使用宏`uvm_do_callbacks嵌入Callback函数或者任务
seq_item_port.item_done(); //数据发送完毕
end
endtask
endclass
3.3.编写Callback函数具体实现方法(如:错误注入)
1).第二步的回调方法为空方法,什么操作也没有;
2).通过继承,覆盖上面定义的回调类中的回调方法:
class driver_error_callback extends driver_callback; //继承Callback空壳类,实现函数方法的覆盖
`uvm_object_utils(driver_error_callback)
function new(string name="driver_error_callback");
super.new(name);
endfunction
virtual task pre_send(driver drv, transaction tr);
drv.req.payload.delete(); //简单示例,在主函数操作前注入错误
endtask
virtual task post_send(driver drv, transaction tr);
`uvm_info("DRIVER_ERROR_CALLBACK","Inside post_drive method",UVM_LOW); //简单示例,在主函数操作之后,打印
endtask
endclass
3.4.在测试案例中创建并登记callback的实例(对象)
1)、在测试用例中创建并例化callback对象;
2)、调用uvm_callbacks #(T, CB) :: add(t,cb)将callback对象添加到test;
class driver_err_test extends test_base; //在测试用例中创建对象并登记
`uvm_component_utils(driver_err_test)
function new(string name = "driver_err_test", uvm_component parent=null);
super.new(name,parent);
endfunction
…………
driver_error_callback drv_err_cb; //声明句柄
function void build_phase(uvm_phase phase);
super.build_phase(phase);
drv_err_cb = driver_error_callback_callback::type_id::create("callback_1", this); //创建Callback实例
uvm_callbacks #(driver,driver_callback)::add(env.agt.drv, drv_err_cb); //调用add()方法将回调类添加到test
uvm_callbacks #(driver,driver_callback)::display(); //显示并打印登记信息用于调式
endfunction
endclass
对于uvm_callbacks#(T, CB)::add(t,cb)方法,其几个参数的含义如下:
-
T:表示回调类所在的组件名,即实现Callback机制的组件名,回调类与组件类在同一组件文件中;
-
CB:表示空壳回调类的类名;
-
t:表示回调类所在的组件的实例名,也就是组件的对象名;
-
cb:表示回调类的实例名,也就是对象名;
四、Callback调试方法
- 在编译时,添加选项+UVM_CB_TRACE_ON即可; callbackhan函数一般成对出现。