文章目录

  • 一、源代码中是什么?
    • uvm_event_base类
      • 类的介绍:
      • 类的方法:
    • uvm_event类
      • 类的介绍:
      • 类的方法:
    • uvm_event_callback类:
      • 类的介绍:
      • 类的方法:
  • 二、uvm_event用法是怎么样?
    • 为什么要有uvm_event?
    • uvm_event 类比 event多的几个重要特性
    • 具体代码例子讲解uvm_event的使用
    • 什么情况下会使用uvm_event?
  • 三、致谢

一、源代码中是什么?

uvm_event.svh (361行)中实现了uvm_event机制,实现了两个类:uvm_event_base和uvm_event。
uvm_event_callback.svh中实现了uvm_event_callback类;

uvm_event_base类

类的介绍:

uvm_event_base直接扩展自uvm_object,相当于在SystemVerilog event基础上包了层uvm的外衣。除了sv event支持的属性外,uvm_event_base还能保存waiter的数目且支持callback。

类的方法:

uvm_event_base中实现的主要方法有:

uvm_event类

类的介绍:

uvm_event派生自uvm_event_base,其中实现的方法有:

类的方法:

uvm_event_callback.svh

uvm_event_callback类:

类的介绍:

uvm_event_callback直接从uvm_object扩展而来,是个参数化的虚类,该类用于uvm_event的callback

该类中,实现了两个function:pre_trigger和post_trigger,使用该类时需重载这两个函数。
pre_trigger中默认返回0,如果如要在触发时间之前做判断,可以重载pre_trigger函数使其返回1,这样就不再触发event且不执行post_trigger。
post_traigger在触发uvm_event之后自动执行,默认返回0,用户可重载该callback函数实现自定义功能。

回调是使用等待事件的进程的替代方法。 当回调附加到事件时,每次触发事件时都会调用该回调对象的回调函数。

类的方法:

new: 创建一个新的回调对象。
pre_trigger :在触发相关事件之前调用此回调。
post_trigger: 触发关联事件后调用此回调。

二、uvm_event用法是怎么样?

为什么要有uvm_event?

uvm_event等类是同步通信元件;

《芯片验证漫游指南》8.5 节介绍了 SV 用来做线程同步的几种元件,分别是 semaphore、event 和 mailbox。然而在 UVM 中,需要同步线程不再只局限于在同一个对象中,还需要解决不同组件之间的线程同步问题。一旦线程同步要求发生在不同组件,就要求组件之间通过某种方法来实现同步。考虑到 UVM 组件的封闭性原则,我们并不推荐通过层次索引的形式在组件中来索引公共的event 或 semaphore。 UVM 为了解决封闭性的问题,定义了如下的类来满足组件之间的同步要求:

uvm_event, uvm_event_pool 和 tvm_event_ calback
uvm_barrier, uym_ barrier_pool

这两组类分别用于服务两个组件之间的同步和多个组件之间的同步。此外,回调函数作为一种实现基类复用的手段,在 UVM 中也被进一步封装为一个类uvm_callback,它不但具备普通回调函数可以在函数执行前后调用的特点,还增加了丰富的特性来完成层次化调用,uvm_callback 类作为我们对函数调用的同步手段来了解。下面我们给出实例来讲解这三组类的特性和用法。

uvm_event 类比 event多的几个重要特性

  • event 被->触发之后,触发使用@等待该事件的对象;uvm_event通过 trigger()来触发,触发使用 wait_trigger()等待该事件的对象。要再次等待事件触发, event 只需再次用->触发,而uvm_event 需要先通过 rese()方法重置初始状态,再使用 trigger()来触发。
  • event无法携带更多的信息,而 uvm_event 可以通过 trigger(T data = null)的可选参数,将伴随触发的数据对象都写入到该触发事件中,而等待该事件的对象可以通过方法wait_ triger_ data(output T data)来获取事件触发时写入的数据对象。
  • event 触发时无法直接触发回调函数,而 uvm_ event 可以通过 add_callback(uvm_event_callback cb, bit append = 1)函数来添加回调函数。
    event 无法直接获取等待它的进程数目,而 uvm_event 可以通过 get_num_waiters()来获取等符它的进程数目。

不同组件可以共享同一个 uvm_event,这不需要通过跨层次传递 uvm_event 对象句柄来实现共享,因为这不符合组件环境封闭的原则,该其享方式是通过uvm _even_poot这一全局资源池来实现的。这个资源池类是 uvm_object_string pool #(T)的子类,它可以生成和获取通过字符串来索引的uvm_event对象。通过全局资源池(唯一的),环境中的任何组件都可以从资源池获取共享的对象句柄,这就避免了组作之间的互相依赖。

具体代码例子讲解uvm_event的使用

接下来我们就结合uvm_event、 uvm_event_pool 和 uvm_event_callback 来讲解一个典型用例。

class edata extends uvm_object;
int data;`uvm_object_utils(edata)…
endclassclass ecb extends uvm_event_callback;`uvm_object_utils(ecb)…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;endfunctionfunction void post_trigger(uvm_event e, uvm_object data = null);`uvm_info("EPOSTRIG", $sformatf("after trigger event %s", e.get_name()),
UVM_LOW)endfunction
endclassclass comp1 extends uvm_component;uvm_event e1`uvm_component_utils(comp1)function void build phase(uvm_phase phase);super.build_phase(phase);e1= uvm_event_pool::get_global("e1");endfunctiontask run_phase(uvm_phase phase);edata d = new();ecb cb = new() ;d.data = 100;#10ns;e1.add_callback(cb);e1.trigger(d);`uvm_info("ETRIG", $sformatf("trigger sync event at %t ps", %time), UVM_LOW)endtask
endclassclass comp2 extends uvm_component;uvm_event e1;`uvm_component_utils(comp2)...function void build_phase(uvm_phase phase);super.build_phase(phase);e1 = uvm_event_pool::get_global("e1");endfunctiontask run_phase(uvm_phase phase);uvm_object tmp;edata      d;`uvm_info("ESYNC", $sformatf("wait sync event at %t ps", $time), UVM_LOW)e1.wait_trigger_data(tmp);void'($cast(d, tmp));`uvm_info("ESYNC", $sformatf("get data %0d after sync at %t ps", d.data, $time), uvm_low)endtask
endclassclass env1 extends uvm_env;comp1 c1;comp2 c2;`uvm_component_utils(env)...
endclass

输出结果为:

UVM_INFO @ 0: reporter [RNTST] Running test test1.。
UVM_INFO @ 0: uvm_test_top.env.c2 [ESYNC] wait sync event at 0 ps
UVM_INFO @ 10000: reporter [EPRETRIG] before trigger event e1
UVM_INFO @ 10000: reporter [EPOSTRIG] after trigger event e1
UVM_INFO @ 10000:uvm_test_top.env.c1 [ETRIG] trigger sync event at 10000 ps
UVM_INFO @ 10000:uvm_test_top.env.c2 [ESYNC] get data 100 after sync at
10000 ps

在上面的例子中,组件 c1 和 c2 之间完成了从 c1 到 c2 的同步,且在同步过程中通过uvm_event e1传递了数据 edata,还调用了回调函数类 ecb 的 pre_trigger()和 post_trigger()方法。关于这个用例,有几点需要读者注意:

  • 无论有多少个组件,只要它们寻求同一个名称的 uym_event,就可以共享该 uvm_event对象。例如,上面的 c1 和 c2 通过 uvm_event_pool::get_global(“e1”)来获取同一个名称的 uym_event 对象,即便该对象不存在,uvm_event_pool资源池也会在第一次调用get_global()函数时创建这样一个对象以供使用。
  • 如果要传递数据,用户可以定义扩展于uvm_object的数据子类,并通过uvm_event:trigger(T data = null)来传递数据对象。而在等待 uvm_event 一侧的组件,则需要通过uvm_event:wait_trigger_data(output T data)来获取该对象。
  • 用户也可以扩展 uvm_event_callback 类,定义 uvm_event 被 trigger 前后的调用方法pre_trigger()和 post_trigger()。pre_trigger()需要有返回值,如果返回值为 1,则表示uvm_event 不会被trigger,也不会再执行 post trigger()方法;如果返回值为 0,则会继续 trigger 该事件对象。
  • 如果用户无法确定在等待事件之前,uvm_event 是否已经被 trigger,那么用户还可以通过方法 wait_ptrigger()和 wait _ptrigger_data()来完成等待。这样即便在调用事件等待方法之前该事件已经被触发,等待方法仍然不会被阻塞并且可以继续执行结束。

什么情况下会使用uvm_event?

那么在日常应用中,什么情况下会使用 uvm_event 呢?第 12 章提到,组件之间的常规数据流向是通过 TLM 通信方法实现的,比如 sequencer 与 driver 之间,或者 monitor 与 scoreboard之间。然而有些时候,数据传输是偶然触发的,并且需要立即响应,这个时候 uvm_event 就是得力的助手了uvm_event 同时也解决了一个重要问题,那就是在一些 uvm object 和uvm_component 对象之间如果要发生同步,但是无法通过 TLM 完成数据传输,因为 TLM传输必须是在组件(component)和组件之间进行的。然而,要在 sequence 与 sequence 之间进行同步,或 sequence 与 driver 之间进行同步,可以借助 uvm_event 来实现。


三、致谢

本文部分参考CSDN博主「MangoPapa」的文章,特此致谢!(https://blog.csdn.net/weixin_40357487/article/details/111103107)
本文部分转载自《芯片验证漫游指南》第12章的内容,特此致谢!

【UVM源码】uvm_event相关推荐

  1. UVM源码分析之factory机制详解

    前言 作者在学习了一段时间的UVM factory源码之后写下此文,旨在记录自己的学习成果,毕竟好记性不如烂笔头嘛,当然如果能帮助到对这部分有疑惑的同仁就更好了.作者是在笔记本电脑上的windows环 ...

  2. 【UVM源码学习】uvm_comparer

      uvm_comparer是个基类,提供了对象object比较的策略,比较结果(比较次数.成功与否)保存在comparer object中.uvm_object::compare及uvm_objec ...

  3. 【UVM源码学习】uvm_spell_chkr

      uvm_spell_chkr,基类,用于uvm相关字符串拼写检查.该类中主要实现了两个方法:check和levenshtein_distance.   check.若待检查的字符串s已存在于字符串 ...

  4. 【UVM源码学习】uvm_resource_db

      使用uvm_resource_base或uvm_resource来set/get resource时,往往需要多行code才能实现,uvm_resource_db则提供了一组接口,用一行代码实现r ...

  5. UVM factory机制源码探微

    文章目录 1. UVM factory机制的使用 2. class 在factory 中的注册过程 2.1. `uvm_component_utils() 2.1.1. m_uvm_component ...

  6. UVM config_db机制源码探微

    文章目录 1. uvm_config_db 基础 1.1. 简单set 1.2. 多重set 2. uvm_resource 2.1. uvm_resource_base 2.2. uvm_resou ...

  7. Jetson Agx Xavier USB驱动裁剪+can时钟修改+内核源码编译流程(jetpack4.6.1)

    自己做了一块Xavier载板,硬件裁剪了一些功能,导致官方镜像usb无法使用,我使用的是jetpack4.6.1(R32.7.1),所以进行驱动修改,重新编译内核. 一.虚拟机环境 在Windows下 ...

  8. 查看Hotspot源码,查看java各个版本源码的网站,如何查看jdk源码

    java开发必知必会之看源码,而看源码的第一步则是找到源码

  9. 【Golang源码分析】Go Web常用程序包gorilla/mux的使用与源码简析

    目录[阅读时间:约10分钟] 一.概述 二.对比: gorilla/mux与net/http DefaultServeMux 三.简单使用 四.源码简析 1.NewRouter函数 2.HandleF ...

  10. liunx上mysql源码安装mysql,搞定linux上MySQL编程(一):linux上源码安装MySQL

    [版权声明:尊重原创,转载请保留出处:blog.csdn.net/shallnet,文章仅供学习交流,请勿用于商业用途] 1. 首先下载源码包: ftp://ftp.jaist.ac.jp/pub/m ...

最新文章

  1. 调试技巧之 找准调试点
  2. 套路、逻辑与思辨(道理的论证)
  3. 动态代理的两种方式_动态代理是基于什么原理?
  4. 音视频技术开发周刊 | 150
  5. 移动Web应用程序开发HTML5篇
  6. react元素显隐控制
  7. 带孩子们做环球旅行的读后感_父母带孩子做心理咨询,需要注意哪些事项?
  8. silverlight计时器
  9. 阅读邮件回复邮件计算机操作题,《电子邮件》阅读练习题附答案
  10. 安卓期末作品小项目_学在澎雅 | 探索红叶李,闯关我最棒——杭州市澎雅小学二年级期末游园活动...
  11. lisp类似常青藤菜单_在autocad里面,我编写了很多lisp命令,我想新增一个菜单工具栏(如:文件(F),编辑(E),视图(V)......),然...
  12. idea代码格式化代码
  13. xbox 360手柄驱动程序_魔派PRO手柄常见问题解决方法一览
  14. 阿里P8大牛,熬夜半月肛出一份Docker文档,让你分分钟搞懂Docker
  15. VBA让Excel数据去重,数量相加
  16. 2019前端书籍推荐,前端PDF书籍,前端书籍下载
  17. 惠普HP LaserJet Pro M104a 打印机驱动
  18. 数据压缩实验5-JEPG解码
  19. 手机连接投影机的步骤_手机连接投影机的步骤(投影仪无线网连接步骤)
  20. 使用hanewin实现 win系统主机,vm虚拟机中linux系统和开发板三方共享文件夹

热门文章

  1. 生物信息学常见1000个软件的安装代码
  2. C语言贪吃蛇小游戏,贪吃蛇C语言代码实现大全
  3. maple的Linux安装步骤,[原创]CentOS6.0下安装Freeiris2/Asterisk全程指导教程
  4. 计算机多功能教室管理制度,多媒体教室管理制度
  5. xCheckRDCostMerge2NX2N函数流程
  6. VMware15pro安装Windows7虚拟机详细教程
  7. 计算机刷bios版本,技嘉bios升级工具(@BIOS)
  8. 计算机科学导论第12版答案,计算机科学导论第12章参考答案
  9. discuz开发经验discuz x3 怎么在帖子列表显示论坛板块图标
  10. AIDL的简单使用和注意事项