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

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

日志

UVM序列篇之七:sequence的层次化(上)

已有 2535 次阅读| 2018-2-4 14:28 |个人分类:验证系统思想|系统分类:芯片设计

伴随着对sequence/item发送方式的了解,读者们也需要从之前4位初出茅庐的verifier梅、尤、娄和董他们的角度来看看,如何完成验证的水平复用和垂直复用。就水平复用而言,在MCDF的各个子模块的验证语境中,它指的是如何利用已有的资源,完成高效的激励场景创建;而就垂直复用来看,它指的是在集成MCDF子系统验证结构中,可以完成结构的复用和激励场景的复用两个方面,而在之前《UVM结构篇》中我们已经介绍了结构的复用,因此,这里的垂直复用主要关注于激励场景的复用。所以,无论是水平复用还是垂直复用,激励场景的复用很大程度上取决于如何设计sequence,使得底层的sequence实现合理的粒度,帮助完成水平复用,而进一步依托于低层的激励场景,最终可以实现底层到高层的垂直复用。


因此,我们本节也就MCDF的实际验证场景出发,引申出下面的几个概念完善sequence的层次化:

  • hierarchical sequence

  • virtual sequence

  • layering sequence


通过对这三个与sequence层次化有关的概念的解读和实际场景的分析,我们希望读者在读了本文之后,可以就不同的sequence场景复用设计出适合自己验证场景的sequence结构。而这三者之间,在一些特定情况下,也会实现有机组合,最终为整体的验证复用提供良好的支持。


Hierarchical Sequence

在验证MCDF中的寄存器模块时,verifier将SV的验证环境进化到了UVM环境之后,有了下面的这样一幅验证框图。有了验证结构,就进入了构建验证场景的环节,在这里面,关于测试寄存器模块的场景,可以将其拆解为:

  • 设置时钟和复位

  • 测试通道1的控制寄存器和只读寄存器

  • 测试通道2的控制寄存器和只读寄存器

  • 测试通道3的控制寄存器和只读寄存器


也许读者对此会有不同的测试环节,然而无论怎么设计,这其中的理念都脱离不开对于底层测试sequence的合理设计。而上面的场景拆解下的sequence需要挂载的都是reg_master_agent中的sequencer。这里我们给出一段代码用来表示底层sequence的设计和顶层hierarchical sequence对这些底层sequence的结构化使用。



在sequence与driver之间传送item时,对于item应该包含的数据内容在之前的《sequence和item》一节中就介绍过,而在上面的这段简单例码,对于item类bus_trans的定义也包含了几个简单的域cmd、addr和data。在后续的clk_rst_seq和reg_test_seq这两个底层的sequence在例化和传送item时,就通过随机化bus_trans中的域来实现不同的命令和数据内容。通过这些不同数据内容的item,最终可以实现不同的测试目的。在上面的top_seq中,它就通过对clk_rst_seq和reg_test_seq这两个element sequence进行组合和随机化赋值,最终实现了上面提到的一个完整的测试场景,即先打开调整时钟和完成复位,其后对寄存器模块中的所有寄存器完成读写测试。


所以,如果将clk_rst_seq和reg_test_seq作为底层的sequence,或者称之为element sequence,那么top_seq作为一个更高层的协调sequence,它本身也会容纳更多的sequence,对它们进行协调和随机限制,通过将这些element sequence进行有机的调度,最终完成一个期望的测试场景。那么,这里的top_seq我们就可以称之为hierarchical sequence,它内部可以包含多个sequence和item,而通过层层的嵌套,最终完成测试序列的合理切分。对于verifier而言,有了粒度合适的element sequence,他们就更容易在这些设计好的“轮子”上面,实现验证的加速过程。而在本文一开始提到的水平复用,就非常依赖于hierarchical sequence的实现。


在这里读者需要注意的是,如何区别于接下来讲到的virtual sequence,毕竟它们两者之间的共同点就是对于各个sequence的协调,而它们的不同则在于,hierarhical sequence主要面对的对象是同一个sequencer,即hierarchical sequence本身也会挂载到sequencer上面,而对于virtual sequence而言,它内部的sequence可以允许面向不同的sequencer种类,这一点我们也将在接下来详细讨论。


Virtual Sequence

伴随着底层模块的验证周期趋于尾声,在MCDF子系统验证环境集成的过程中,完成了前期的结构垂直复用,就需要考虑如何复用各个模块的element sequence和hierarchical sequence了。对于更上层的环境,可想而知的是,顶层的测试序列要协调的不再只是面向一个sequencer的sequence群,而是要面向多个sequencer的sequence群。那么面向不同sequencer的sequence群落在组织在以后,如何分别挂接到不同的sequencer上呢?在之前介绍的sequence,都是面向单一的sequencer,因此挂载也很简单,即通过uvm_sequence::start()来挂载root sequence,而在内部的child sequence则可以通过宏`uvm_do来实现。


面对上面的这个MCDF子环境验证结构框图,如果将各个模块环境的element sequence和hierarchical sequence都作为可以复用的sequence资源,那么就需要一个可以容纳各个sequence的容器来承载它们,同时,也需要一个合适的routing sequencer来组织不同结构中的sequencer,这样的sequence和sequencer分别称之为virtual sequencevirtual sequencer。就之前的sequence和sequencer而言,它们的差别在于:

  • virtual sequence可以承载不同目标sequencer的sequence群落。而组织协调这些sequence的方式则类似于高层次的hiearchical sequence。virtual sequence一般只会挂载到virtual sequencer上面。

  • virtual sequencer与普通的sequencer相比有着很大的不同,那就是它们只是起到了桥接其它sequencer的作用,即virtual sequencer是一个指示所有底层sequencer句柄的地方,它是一个中心化的路由器。同时virtual sequencer本身并不会传送数据对象例如item,因此,virtual sequencer不需要与任何的driver进行TLM连接。所以,UVM用户需要在顶层的connect阶段,做好virtual sequencer中各个悬空句柄与各个底层实体对象的一一对接,避免句柄的悬空。


接下来,我们将给出一段精简的代码,用来表示element sequence/hierarchical sequence与virtual sequence的关系,和底层sequencer与virtual sequencer的联系,同时也展现出virtual sequence与virtual sequencer的挂载方法。



从这里例子可以看到,对于virtual sequence mcdf_normal_seq而言,它可以承载各个子模块环境的原有sequence,而通过最后与其挂载的virtual sequencer mcdf_virtual_sequencer中的各个底层sequencer句柄,完成了实际的挂载。在这里读者需要区分的是,尽管在最后test1中,将virtual sequence挂载到了virtual sequencer上面,但是这种挂载的根本目的是为了提供给virtual sequence一个中心化的sequencer路由,而借助在virtual sequence中使用了宏`uvm_declare_p_sequencer,使得virtual sequence可以使用声明后的p_sequencer(类型为mcdf_virtual_sequencer),来进一步回溯到其内部的各个sequencer句柄。在这里,使用`uvm_declare_p_sequencer是较为方便的,因为这个宏在后台,可以新创建一个p_sequencer变量,而将m_sequencer的默认变量(uvm_sequencer_base类型)通过动态转换,变为类型为mcdf_virtual_sequencer类型的p_sequencer。只要声明的挂载sequencer类型正确,用户可以通过这个宏,完成方便的类型转换,因此才可以通过p_sequencer索引到在子类mcdf_virtual_sequencer中声明的各个sequencer的句柄变量。


读者可以从上面这个精简过的例码中了解到virtual sequence的协调作用,virtual sequencer的路由作用,以及在顶层中需要完成virtual sequencer同底层sequencer的连接,并且最终在test层中实现virtual sequence挂载到virtual sequencer上。这种中心化的协调方式,使得在顶层场景创建和控制方面更加得心应手,而且在后期的代码维护中,测试场景的可读性也得到了提高。


UVM初学者在一开始学习virtual sequence和virutal sequencer时容易出现编译和运行时句柄悬空的错误,还有一些概念上的偏差。在这里,路桑给出一些建议以供参考:

  • 需要区分virtual sequence同其它普通sequence(element sequence、hierarchical sequence)。

  • 需要区分virtual sequencer同其它底层负责传送数据对象的sequencer。

  • 在virtual sequence中记得使用宏`uvm_declare_p_sequencer来创建正确类型的p_sequencer变量方便后面的各个目标sequencer的索引。

  • 在顶层环境中记得创建virtual sequencer并且完成virtual sequencer中各个sequencer句柄从底层到顶层的跨层次连接。


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


点赞

评论 (0 个评论)

facelist

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

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

    周排名
  • 0

    月排名
  • 0

    总排名
  • 0

    关注
  • 253

    粉丝
  • 25

    好友
  • 33

    获赞
  • 45

    评论
  • 访问数
关闭

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

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

GMT+8, 2024-4-25 18:03 , Processed in 0.022567 second(s), 12 queries , Gzip On, Redis On.

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