本系列将采用3段式结构,
1. 对于设计模式概述:visitor 模式
2. 对应到UVM 源码中如何体现
3. 其他
以下正文:
一,visitor模式
表示一个作用于某对象结构(uvm_component)的各元素操作(build_phase/connect_phase等定义的虚操作)。它使你可以再不改变各元素的类(uvm_component)的前提下定义作用于这些元素的新操作(用户自定义实现对于xxx_pahse的具体操作实现)。
在visitor实例(例如uvm_build_phase)中,提供了对访问对象(uvm_component)的的某一方面(build_phase)的访问或操作。
二,UVM中的visitor模式
UVM中的pahse机制并非传统意义上的visitor模式,单纯的访问者模式无法实现UVM phase提供的强大功能,个人理解UVM在实现phase机制时进行了如下方面的扩展:
1. 传统访问者模式强调对单一对象(uvm_component)的不同方面(xxx_phase)的访问,在UVM的实现中,通过为component指定父类的方式,将所有的component组织成树状结构,从而可以从任意节点/对象(uvm_componet)开始对整棵树进行遍历,UVM中使用了两种top_down,与buttom_up两种遍历方式。
2.传统访问那种模式会在visitor(uvm_xxx_phase)中实现对对象的具体操作,这也要求对象中的元素要保持稳定,而在UVM中,visitor(uvm_xxx_phase)采用了代理模式,在visitor的访问操作中,调用了对象的实际操作(用户实现的uvm_component的xxx_phase),是的对象的元素可以改变,因为操作元素的实现也在是由对象实现,对象当然知道自己所有元素。
三,UVM 顶层遍历流程:
首先在get_common_domain中建立visitor(uvm_xxx_phase)列表,call flow如下
uvm_root::run_test -> uvm_phase::m_run_phases -> uvm_domain get_common_domain -> domain.add 通过domain.add 将各uvm_xxx_phase 组织起来,形成下图左侧主线结构。
而后在uvm_phase::m_run_phases 中,通过mailbox m_phase_hopper 实现对各build的顺次执行,以build_phase为例
在uvm_phase::m_run_phases中首先将取出build_phase而后调用:
(A)phase.execute_phase -> (B)m_imp.traverse(top,this,UVM_PHASE_EXECUTING) -> (C)ph.execute(comp, phase) ->(D)exec_func(comp,phase) -> (E)comp.build_phase(phase)
其中,B: 将调用uvm_top_down中实现的traverse,实现component树自上而下的遍历。
C: uvm_top_down 的execute 函数最终将调用虚函数exec_func 有各具体子类实现,此处为uvm_build_phase实现
D: uvm_build_phase 实现的exec_func 如前面所说,此处作为代理,最终将调用componet自己的build_phase 进行实际操作
到此为止,实现了对component 树的遍历,与用户自定义phase函数的top_down的调用执行。