uvm_event运用场景:
- 当同步是想立即响应的。
- 当一些uvm_object想和uvm_component进行同步的时候(无法用TLM),或者是object和object之间进行同步。
和sv中的event的区别:
- SV中event是单纯一个类型(声明了就可以用),而UVM的uvm_event是一个类(需要相应的创建或拿到句柄)。
- uvm_event是通过从资源池获取共享的对象句柄,避免组件之间的相互依赖。
- event被->触发之后,会触发使用@等待该事件的对象;uvm_event通过trigger()来触发,会触发使用wait_trigger()等待的对象。如果要再次等待事件触发,event只需要再次用->来触发,而uvm_event需要先通过reset()方法重置初始状态,再使用trigger()来触发。
- event无法携带更多的信息,而uvm_event可以通过trigger(uvm_event data = null)的可选参数,将所要伴随触发的数据信息都写入到该触发事件中,而等待该事件的对象可以通过方法wait_trigger_data(output uvm_object data)来获取事件触发时写入的数据对象。这实际上是一个句柄的传递,传递的句柄类型是uvm_object,也就是说传递的对象句柄得是uvm_object类型的。那如何传递非uvm_object类型的对象呢,首先这个对象必须是uvm_object的子类或者子类的子类,然后才能将其句柄作为trigger()方法的参数,返回值是一个父类的uvm_object类型,然后wait_trigger ()的参数必须是uvm_object类型的,可以用一个uvm_object类型的tmp作为参数传递句柄,然后使用$cast赋值给目标类型句柄。
- UVM的uvm_event有相应定义的回调函数。(不同于randomize那种回调函数,这里的回调函数是需要添加的,如果不绑定是不会执行的),event触发时无法直接触发回调函数,而uvm_event可以通过add_callback(uvm_event_callback cb, bit append = 1)函数来添加回调函数。
- event无法直接获取等待它的进程数目,而uvm_event不但可以通过get_num_waiters()来获取等待它的进程数目。
- sv中的event不可以响应那种等待前就触发的事件,uvm_event可以利用wait_ptrigger()/wait_ptrigger_data来完成等待,这样不会因为事件在等待前触发而被阻塞。
e1=uvm_event_pool::get_global("e1");//如果在全局资源池中没有,则为它创建一个
e1=uvm_event_pool::get_global("e1");
e1.wait_trigger_data(data);
拓展:
uvm_barrier:
通常用来同步多个组件,解决了组件独立运行所需要的封闭性,通过设置一定的等待阈值,当有不少于阈值的进程在等待时,才会同时触发。