当前位置: 代码迷 >> 综合 >> UVM之uvm_callback详解
  详细解决方案

UVM之uvm_callback详解

热度:38   发布时间:2024-02-02 11:52:18.0

在DV中,我们可以使用factory,override机制来实现方法的重载,继而修改现有类的方法和属性。想象一下下面的一个应用场景,driver从sequencer拿到transaction,需要根据一些条件进行一些特殊处理才可以驱动到interface上,而现有的环境没有做这方面的处理。这个时候我们可以重载这个类,修改这个方法(用户的角度),但是TB开发人员(有时候不是用户),比如VIP开发的时候,开发人员可能无法穷经所有的情况,或者锁着项目的迭代,出现了一些新的特性,在TB中使用回调函数变成了一种可选项,这里我们介绍一下uvm_callback是怎么使用的,以及内部的机理是什么。

回调函数基本的3个步骤,

(1)注册

(2)添加

(3)调用

class mycb extends uvm_callback;virtual function void do_processing();endfunction
endclass
class my_comp extends uvm_component;`uvm_register_cb(my_comp,mycb);task run_phase(uvm_phase phase);`uvm_do_callacks(my_comp,mycb,do_processing());endtask
enclass

在上述代码中,`uvm_register_cb(my_comp,mycb)起到的是注册是作用。

define uvm_register_cb(T,CB) \
static local bit m_rigister_cb_``CB=uvm_callbacks#(T,CB)::m_register_pair(`"T`",`"CB`");

展开这个`uvm_register_cb(my_comp,mycb)

m_register_cb_mycb=uvm_callbacks#(my_comp,mycb)::m_register_pair("my_comp","mycb");

首先先明确一下继承关系

uvm_callbacks_base   //基类
uvm_typed_callback#(T)//子类
uvm_callbacks#(T,CB)   //子子类

m_register_pair方法做了下面几件工作

(1)创建父类uvm_typed_callback#(my_comp),创建父父类uvm_callbacks_base,创建本身uvm_callbacks#(my_comp,mycb)(2)创建uvm_callbacks#(my_comp,uvm_callback),uvm_typed_callback#(my_comp)句柄指向uvm_callbacks#(my_comp,uvm_callback)这个对象。
(3)typeid_map[uvm_typeid#(comp)]=uvm_callbacks#(my_comp,uvm_callback)type_map[uvm_callbacks_base]=uvm_typeid#(my_comp)
(4) uvm_callbacks#(my_comp,uvm_callback).m_this_type.push_back(uvm_callbacks#(my_comp,mycb))
(5)uvm_callbacks#(my_comp,mycb).m_regoster=1  //标志注册完成
//说明:
变量m_this_type是队列     uvm_callbacks_base m_this_type[$]

上述完成了注册类型的任务

下一步就是添加:添加的是句柄

class my_env extends uvm_env;my_comp   comp_inst;mycb      cb_inst;virtual function build_phase(uvm_phase phase);super.build_hase(phase);comp_inst=my_comp::type_id::create("comp_inst",this);cb_inst=  mycb::tyep_id::create("cb_inst");uvm_callbacks#(my_comp)::add(comp_inst,cb_inst);endfunction
endclass

add 方法做了下面几件事情

(1)判断 参数uvm_callback CB 这个参数时候为null,是的话报错退出
(2)uvm_callbacks#(my_comp,uvm_callback).check_registration(comp_inst,cb_inst);(2-1) cb_inst必须是uvm_callback的子类或者本身句柄(2-2) comp_inst必须是my_comp的子类或者本身句柄
(3)uvm_pool#(uvm_object,uvm_queue#(uvm_callback)) m_pool[comp_inst].push_back(cb_inst)

总结下来就是uvm_callbacks#(my_comp)::add的作用是向全局的pool中存放comp_inst 以及cb_inst整个pair

最后一个步骤是调用

`uvm_do_callbacks#(my_comp,mycb,do_processing());

这样就会去调用mycb::do_processing()的方法。

  相关解决方案