SV组件实现篇之八:监测器的采样(下)

 

SV组件实现篇之八:监测器的采样(下)...



monitor的采样功能

在介绍完了clocking块的三种属性之后,verifier梅就准备利用这一特性来实现slave monitor的数据采样。由于slave的输入输出端数据协议简单,因此,我们准备将采集到的数据都存入到一个统一的数据格式中:



接下来,我们引入作为连接stimulator与monitor的interface,slv_ini_if和slv_rsp_if:



从上面定义的两个接口来看,verifier梅利用了clocking块的采样特性,在其中分别声明了用来采样的clocking和信号列表。同时,它们各自提供了一个开放的方法和FIFO(用队列来实现),用来存储采集到的数据。

再来看看两个monitor,即slv_ini_mon和slv_rsp_mon是如何定义的:





上述两个monitor提供的方法相同,均为:

  • run:让monitor运转起来,保持时刻监视和采样数据。
  • mon_trans:每次收集一个有效数据。
  • put_trans:将有效数据通过虚接口vif存入接口中的FIFO。


再来看看两个monitor提供的成员变量,分别是自己对应的虚接口和一个只有声明,并没有在构建函数中例化的句柄trans。

这里的mon_trans在采集完有效的一次数据写入后,通过clocking块准确地将采样到的数据先先入到“临时创建”的对象中,该对象的句柄为trans,进而通过break退出方法。接下来,将trans的值(新创建对象的句柄)写入到接口的FIFO中,如此往复。

这里,读者需要注意的是,通过每次触发有效的数据写入事件,来创建新的对象trans = new(),进而将有效数据写入到trans指向的新对象中,再到随后通过vif.put_trans(trans)将每次句柄的值写入接口的FIFO中,这整个过程当中,两个monitor都在不断地创建对象,那么在每次更改trans值(从旧对象指向了新的对象),之前对象是否还存在呢?毕竟,读者可能疑惑,trans毕竟不再指向旧对象了。

答案是,之前创建的对象仍然存在,因为FIFO中每个元素仍然在引用之前创建的每一个对象,根据SV空间自动回收机制的用法,只有我们再销毁了FIFO即这个队列之后,那么之前创建的对象由于环境中再没有其它句柄的引用,这样所有之前创建的对象才会被回收。例如,我们可以通过队列的delete()删除整个队列,进而销毁其元素指向的对象。



从上面这个上意图来看,随着有效数据采样发生e1 -> e2 -> e3 -> e4 -> ...,每次都会创建新的对象,而且trans也会指向最想的对象,同时之前创建的所有对象的句柄都存入vif.mon_fifo中。注意,这里存入的是对象的句柄,而不是对象本身。以后,其它的组件例如checker,也可以通过接口内FIFO的句柄元素来索引到它们分别指向的对象。

上面的这个数据打包写入的方式,是将interface内定义的队列作为数据缓存中间站,而后,一旦checker创建好以后,也可以将interface的指针传递给checker,进而为checker提供get_trans()的方法。这样,checker即可以从各个interface中得到采集到的数据。

实际上,采样好的数据应该缓存到什么地方,选择有很多,除了可以存放到interface中,也可以考虑存放到monitor或者checker内部,而后通过monitor与checker之间的直接对话来实现。这也就是下一节我们会引出的,组件之间的主要对话方式,或者进程之间同步的方法

最后,我们再来看看,上面定义的interface和monitor在顶层testbench的例化:



至此,monitor通过clocking块做数据采样并且打包写入缓存的方式接介绍完了。目前,我们暂时可以将数据缓存至接口内的缓存,而在我们下一节学习了《组件间的通信》之后,我们就可以用进程间通信的三种类型来做更灵活的尝试了。

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


    关注 路科验证


微信扫一扫关注公众号

0 个评论

要回复文章请先登录注册