- SV中线程同步:semaphore、event、mailbox
- uvm中的同步是不同组件之间的线程同步问题,要求组件之间实现同步
uvm_event与uvm_event_pool
- event被→触发后会触发使用@等待该事件的对象,如果要再次触发,还是需要用→来触发;无法携带更多的信息;无法直接触发回调函数;无法直接获取等待他的进程数目
- uvm_event,可以实现上面所有的无法:通过trigger()来触发,会触发使用wait_trigger()等待该事件的对象,再次触发需要先通过reset()方法重置初始状态再用trigger触发;可以通过trigger(T data=null)的可选参数将伴随触发的数据对象都写入到该触发事件中,等待该事件的对象可以通过wait_trigger_data(output T data)来获取事件触发时写入的数据对象;通过add_callback(uvm_event_callback cb, bit append=1)函数来添加回调函数;get_num_waiters()
- 不同组件可以共享同一个uvm_event,这个共享方式是通过uvm_event_pool这一全局资源池来实现(uvm_object_string_pool #(T)的子类,可以生成和获取通过字符串来索引的uvm_event对象)
- 环境中的任何组件都可以从资源池获取共享的对象句柄,避免组件之间相互依赖
class edata extends uvm_object;
class ecb extends uvm_event_callback;
function bit pre_trigger(uvm_event e, uvm_object data=null);
`uvm_info("", $sformatf(), UVM_LOW)
function void post_trigger(uvm_event e, uvm_object data=null);
class comp1 extends uvm_component;
function void build_phase(...);
e1=uvm_event_pool::get_global("e1");
class comp2 extends uvm_component;
function void build(...);
e1=uvm_event_pool::get_global("e1");
e1.wait_trigger_data(tmp);
class env1 extends uvm_env;
- 无论多少个组件,只要寻求同一个名称的uvm_event,就可以共享这个uvm_event对象(通过pool::get_global)
- 需要传递数据就定义扩展于uvm_object的数据子类,通过uvm_event::trigger(T data=null)来传递数据对象
- 等待的组件通过uvm_event::wait_trigger_data(output T data)获取该对象
- 如果无法确定在等待事件之前,uvm_event是否已经被trigger,可以通过方法wait_ptrigger()和wait_ptrigger_data()来完成等待。这样即使event被trigger,等待方法仍可继续执行
- 使用场景:偶然触发的数据传输,且需要立即响应
- 使用场景:uvm_object和uvm_component对象之间要发生同步
- 使用场景:sequence与sequence之间,sequence与driver之间进行同步
- 注意:TLM传输必须是在component之间完成,不能在component和object之间
uvm_barrier与uvm_barrier_pool
- 作用:对多个组件进行同步协调
- 定义了新的类uvm_barrier_pool来全局管理这些uvm_barrier对象(同event_pool,也是基于通用参数类uvm_object_string_pool定义的)

typedef uvm_object_string_pool
typedef uvm_object_string_pool
- uvm_barrier可以设置等待阈值threshold,当有不少于threshold的进程在等待该对象时才会触发该事件,同时激活所有正在等待的进程
class comp1 extends uvm_component;
`uvm_component_utils(comp1)
function void build_phase(uvm_phase phase);
b1=uvm_barrier_pool::get_global("b1");
task run_phase(uvm_phase phase);
class comp2 extends uvm_component;
`uvm_component_utils(comp2)
function void build_phase(uvm_phase phase);
b1=uvm_barrier_pool::get_global("b1");
task run_phase(uvm_phase phase);
class env1 extends uvm_env;
`uvm_component_utils(env1)
function void build_phase(uvm_phase phase);
super.build_phase(phase);
c1=comp1::type_id::create("c1", this);
c2=comp2::type_id::create("c2", this);
b1=uvm_barrier_pool::get_global("b1");
task tun_phase(uvm_phase phase);
`uvm_info("BSYNC", $sformatf("", b1.get_threshold(), $time), UVM_LOW)

uvm_event_callback
- 作用:延展之前的方法;也是一种同步方式
- uvm_object提供的callback方法,默认情况do_是空的
- copy() do_copy()
- print() do_print()
- compare() do_compare()
- pack() do_pack()
- unpack() do_unpack()
- record() do_record()
- 如果执行了uvm_object()::copy(),那么在函数执行末尾会自动执行uvm_object::do_copy()
- uvm通过uvm_callback_iter类和uvm_callbacks #(T, CB)类实现函数毁掉的顺序和继承性
class edata extends uvm_object;
class cb1 extends uvm_callback;
virtual function void do_trans(edata d);
function void do_trans(edata d);
class comp1 extends uvm_component;
`uvm_register_cb(comp1, cb1)
task run_phase(uvm_phase phase);
`uvm_do_callbacks(comp1, cb1, do_trans(d))
class env1 extends uvm_env;
`uvm_component_utils(env1)
function new(string name, uvm_component parent);
function void build_phase(uvm_phase phase);
super.build_phase(phase);
c1=comp1::type_id::create("c1", this);
uvm_callbacks #(comp1)::add(c1, m_cb1);
- uvm_callback建立了回调函数执行的层次性,通过宏`uvm_do_callbacks(T, CB, METHOD)循环执行与该对象结对的uvm_callback类的方法
- `uvm_do_callbacks_exit_on(T, CB,METHOD, VAL)可以进一步控制执行回调函数的层次,回调函数会保持执行直到返回值与VAL相同才会返回