SV中用来做线程间同步方法分别是semaphore、event和mailbox。然而在UVM中,同步的不再只局限于同一个对象中的各个线程,而是还有各个组件之间的同步
问题。一旦发生同步的要求发生在各个组件之间,这就要求组件之间通过某种可以同步的方法来实现。而考虑到UVM各个组件的封闭性原则,我们并不推荐通过层次索引的形式在组件中来索引公共的event或者semaphore。UVM为了解决封闭性的问题,定义了如下的类来满足组件之间的同步:
- uvm_event,uvm_event_pool和uvm_event_callback
- uvm_barrier, uvm_barrier_pool
一、uvm_event用法
- 不同的组件可以共享同一个uvm_event,这不是通过跨层次传递uvm_event对象句柄来实现共享的,因为这并不符合组件环境封闭的原则。这种共享同一个uvm_event对象是通过uvm_event_pool这一全局资源池来实现的。
- 这个资源池类是uvm_object_string_pool #(T)的子类,它可以生成和获取通过字符串来索引的uvm_event对象。T 替换成uvm_event类型。
- 通过全局资源池对象(唯一的),在环境中任何一个地方的组件都可以从资源池中获取共同的对象,这就避免了组件之间的互相依赖。
class edata extends uvm_object; //--创建trigger()触发时传递的数据信息
int data;
`uvm_component_utils(edata)
function new(string name = "edata");
super.new(name);
endfuncation
endclass
calss ecb extends uvm_event_callback; //--创建add_callback()添加的回调函数
function new(string name = "ecb");
super.new(name);
endfuncation
function bit pre_trigger(uvm_event e,uvm_object data=null);
`uvm_info("EPRETRIG",$sformatf("before trigger event %s",e.get_name()),UVM_LOW)
return 0;
endfunction
function void post_trigger(uvm_event e,uvm_object data=null);
`uvm_info("EPRETRIG",$sformatf("after trigger event %s",e.get_name()),UVM_LOW)
endfunction
endclass
class comp1 extends uvm_component; //组件comp1
uvm_event e1;
function new(string name ,uvm_component parent);
super.new(name,parent);
endfuncation
//**1.声明事件变量(句柄)**
function void build_phase(uvm_phase phase);
super.build_phase(phase);
e1 = uvm_event_pool::get_global("e1"); //**2.在资源池中创建一个共享事件e1,并赋值给本地事件e1** 静态调用不用创建。
endfunction
task run_phase(uvm_phase phase);
edata d = new(); //实例化数据包
ecb cb =