UVM中的phase,按照其是否消耗仿真时间($time打印出的时间)的特性,可以分成两大类:一类是function phase,这些phase是通过函数实现;另外一类是task phase,这些phase是通过任务实现的。图1中,灰色背景所示的是task phase,其他白色背景为function phase。
在空间上,除了build_phase之外,所有不耗费仿真时间的phase(即function phase)都是自下而上执行的。类似run_phase、main_phase等task_phase也都是按照自下而上的顺序执行。但是与function phase自下而上执行不同的是,task phase是耗费时间的,所以它并不是等到“下面”的phase(如driver的run_phase)执行完才执行“上面”的phase(如agent的run_phase),而是将这些run_phase通过fork…join_none的形式全部启动。所以更准确的说法是自下而上的启动,同时在运行。
在时间上,所有的phase都会按照图1中的顺序自上而下自动执行。对于同一component来说,其12个run-time的phase(动态运行phase)是顺序执行的,但是它们也仅仅是顺序执行,并不是说前面一个phase执行完就立即执行后一个phase。以A component和B component中的main_phase和post_main_phase为例,如图2所示。
从图中可以看到对于A来说,main_phase在100时刻结束,其post_main_phase在200时刻执行。在100~200时刻,A处于等待B的状态,除了等待不做任何事情。B的post_main_phase在400时刻结束,之后处于等待A的状态。无论从A还是从B的角度看,都存在一段 等待时间。但是从整个验证平台的角度来看,各个task phase之间是没有任何空白的。整个验证平台必须所有的main_phase执行完毕,接下来执行post_main_phase;所有的post_main_phase执行完毕,接下来执行下一个phase,如pre_shutdown_phase。
上述的这种phase同步不仅适用于不同component的动态运行(run-time)phase之间,还适用于run_phase与run_phase之间。这两种同步都是不同component之间的相同phase之间的同步。除了这两种同步外,还存在一种run_phase与post_shutdown_phase之间的同步。这种同步的特殊之处在于,它是同一个component的不同类型phase(两类task phase,即run_phase与run-time phase)之间的同步,即同一个component的run_phase与其post_shutdown_phase全部完成才会进入下一个phase(extract_phase)。phase同步主要可以总结为图3的三种方式。