路科验证的个人空间 https://blog.eetop.cn/1561828 [收藏] [复制] [分享] [RSS]

空间首页 动态 记录 日志 相册 主题 分享 留言板 个人资料

日志

UVM通信篇之七(终):同步通信元件(下)

已有 2074 次阅读| 2018-1-28 13:49 |个人分类:验证系统思想|系统分类:芯片设计

uvm_callback应用

除了UVM提供新的类方便组件之间的同步之外,另外一种同步方式回调函数(callback)也方便了类的封装复用。读者们可以试想一下,在通常情况下,如果得到了一个封闭的包,其中的类如果有些成员方法需要修改,或者需要扩展新的方法时,应该怎么做呢?如果这个包是外来的,那么它的维护方首先不建议我们去修改这个类的本身。如果我们通过类的继承来实现这一要求,又无法进一步在该包的环境中用新的子类替换原来的父类。那么,UVM的覆盖机制(override)就可以帮到忙。除了覆盖机制,还有callback也可以为用户提供可以自定义的处理方法。这就使得,如果用户不需要添加新的方法,而是想延展之前的方法,那么就不需要通过继承类的方式,而只需要通过在后期自定义callback方法来实现。


在之前《核心基类》中我们已经谈过,uvm_object本身就提供了丰富的callback方法供用户们自己定义:

  • copy()和do_copy()

  • print()和do_print()

  • compare()和do_compare()

  • pack()和do_pack()

  • unpack()和do_unpack()

  • record()和do_record()


默认情况下,这些回调函数do_xxx是定义为空的,所以譬如用户执行了copy()函数,那么它会在执行末尾再执行do_copy()函数。所以,do_copy()就是copy()的回调函数。通过在copy()的执行尾端,来勾住(hook)下一个callback函数do_copy()。如果用户自定义了这些回调函数,那么就可以执行扩展后的方法。


那么,这种普通的回调函数定义就足够了,为什么还要专门定义一个uvm_callback类呢?可以说,通过这个新添加的类,使得回调都有了顺序和继承性。关于顺序和继承性的实现,又是通过两个相关的类uvm_callback_iter和uvm_callbacks #(T, CB)来实现的。接下来,我们依然给出一个实例来说明在uvm_callback的帮助下,回调函数可以玩出什么新的花样。



输出结果:

UVM_INFO @ 0: reporter [RNTST] Running test test1...

UVM_INFO @ 0: uvm_test_top.env.c1 [RUN] proceeding data 100

UVM_INFO @ 0: reporter [CB] cb1 executed with data 200

UVM_INFO @ 0: reporter [CB] cb2 executed with data 300


如果读者已经理解了回调函数本身的“钩子”属性,那么从上面这个例子可以看到,uvm_callback类使得钩子属性变得更加容易控制和继承。在这里例子中,有下面一些需要读者注意的地方:

  • callback可以通过继承的方式来满足用户更多的定制,例如上面的c2继承于cb1。

  • 为了保证调用callback的组件类型T与callback类型CB保持匹配,建议用户在T中声明T与CB的匹配,该声明可以通过宏`uvm_register_cb(T, CB)来实现。用户养成了注册的习惯之后,如果以后一旦调用的T与CB不匹配,那么在检查完匹配注册表之后系统会打印warning信息,提示用户调用的潜在问题。

  • uvm_callback实现了回调函数执行的层次性,因此在实现方面,不再是在T的方法中直接呼叫某一个回调方法,而是通过宏`uvm_do_callbacks(T, CB, METHOD)来实现。该宏最直观的作用在于会循环执行已经与该对象结对的uvm_callback中的方法。此外,还有一个宏`uvm_do_callbacks_exit_on(T, CB, METHOD, VAL)可以进一步控制执行回调函数的层次,简单来讲,回调函数会一直执行,直到返回值与给入的VAL值相同就立刻返回,这一点使得回调方法执行顺序上面有了更多的选择。

  • 有了`uvm_do_callbacks宏还不够,需要注意的是,在执行回调方法时,依赖的是已经例化的uvm_callback对象。所以,最后一步,需要例化uvm_callback对象,上面的例子中分别例化了cb1和cb2。最后,通过“结对子”的方式,通过uvm_callbacks #(T, CB)的静态方法add()来添加成对的uvm_object对象和uvm_callback对象。


从这个例子可以看到,uvm_callback的灵活性不但在于可以利用继承性的优点,实现用户的自定义内容,还在于回调函数不再固定依赖于某一些固定的程序,而是通过对象(uvm_object)和对象(uvm_callback)的绑定实现了精细化的回调函数指定。从最后的执行顺序来看,也证明了通过uvm_callbacks #(T, CB)::add()方法的简便性。


到这里,我们本章《UVM通信篇》已经就TLM通信模式、TLM1和TLM2的通信应用和组件之间的同步方式给出了详细的说明,希望读者可以利用这些便捷的类构建UVM环境中的快车道。


我们下一章将进入UVM环境中的车流中,看一看首当其冲的车流sequence是如何流向于整个交通环境中,而作为顶层的交通指挥,又有哪些好的手段可以实现交通的便利,请大家继续关注《UVM序列篇》。


谢谢你对路科验证的关注,也欢迎你分享和转发真正的技术价值,你的支持是我们保持前行的动力。


点赞

评论 (0 个评论)

facelist

您需要登录后才可以评论 登录 | 注册

  • 关注TA
  • 加好友
  • 联系TA
  • 0

    周排名
  • 0

    月排名
  • 0

    总排名
  • 0

    关注
  • 253

    粉丝
  • 25

    好友
  • 33

    获赞
  • 45

    评论
  • 访问数
关闭

站长推荐 上一条 /1 下一条

小黑屋| 关于我们| 联系我们| 在线咨询| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-3-29 03:42 , Processed in 0.014516 second(s), 12 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
返回顶部