UVM进程的同步之uvm_event

在SV中,可以使用event来实现进程之间的同步,在UVM中也与专门的类来实现进程之间的同步:
uvm_event#(typeT=uvm_object)。
uvm_event相比于event最大的优势是可以实现不同组件之间的同步。比如组件A,B要实现同步,如果使用SV的方法,必须在组件B中将组件A中的事件event赋值给组件B中的event,B.event=A.event。但是这样做出现了跨组件之间的变量连接,大大降低了组件之间相互的独立性,降低了环境的复用性。出现了uvm_event#(typeT=uvm_object) 这个同步事件

uvm_event#(type T=uvm_object)除了增加环境的独立性,复用性之外,还可以增加callback操作,这在SV event是不肯能实现的

同时uvm_event#(type T=uvm_object)在触发的同时,还可以传递数据,这个这在SV event是不肯能实现的

当然uvm_event#(typeT=uvm_object)本质上依旧是event的重重封装,只是更加方便用户的使用和环境的搭建。

在SV中 event是这么进行同步的

->event @event/wait(event.triggered)

在UVM中

uvm_event.trigger(), uvm_event.wait_trigger()/uvm_event.wait_ptrigger()

uvm_event.trigger(data), uvm_event.wait_trigger_data(data)/uvm_event.wait_ptrigger_data(data)

其中wait_ptrigger_*就是与SV中wait(event.triggered)一样,为了解决同一个delta_cycle的竞争冒险

上面说到,在调用uvm_event.trigger的时候,会调用callback方法,pre_trigger和post_trigger。这两个callback方法在uvm_event_callback方法中实现的(需要用户重载这个virtual uvm_event_callback类),注意在重载pre_trigger的时候不要修改默认的返回值0,否则将不会执行后续真正的trigger和post_trigger,这个与randomize相似。

在UVM中有一个叫uvm_event_pool的资源池(single模式),所有的uvm_event均在这里面实现管理与同步

uvm_event ev1=uvm_event_pool::get_global(“ev1”)//创建名字叫ev1的uvm_event。整个UVM环境均可以访问。

如果在另一个地方也调用:
uvm_event ev1=uvm_event_pool::get_global(“ev1”)。这个时候并不会再创建uvm_event,因为此时uvm_event_pool这个资源池中已经存在了名字叫ev1的事件,所有直接赋值。这样就实现了事件的同步

UVM进程的同步之uvm_event