phase机制简介
phase机制主要目的是使UVM的运行仿真层次化,让各种例化先后次序正确。UVM的phase机制主要有9个,外加12个动态phase。除了run_phase是task,要消耗仿真时间,其余都是function。build_phase和final_phase是自顶向下运行,其余都是自底向上运行。run_phase和12个动态phase是并行运行的,有这12个动态phase主要是进一步将run_phase中的事务划分到不同的phase中进行,简化代码。注意,run_phase和12个动态phase最好不要同时使用。
*从运行上看,9个phase顺序执行,不同组件的同一个phase全部执行完之后才能进入下一个phase,此外,不同组件中同一个phase执行也有顺序,build_phase自顶向下,connect_phase自底向上等。
phase机制执行顺序(扩展)
无论是自上而下还是自下而上,都只适用于UVM树中有直系关系的component,对于同一层次,具有兄弟关系的component,例如agent中的driver和monitor,它们是谁先被例化的呢?实际上,无论是在自上而下的build_phase还是自下而上的connect_phase,其执行顺序都与代码顺序无关,而是严格按照实例化时指定名字的字典序(abcdefg....),如aaa先例化,ddd再例化。
除了兄弟关系的component(driver和monitor),还有叔侄关系的component(scoreboard和driver),UVM采用的是深度优先原则,举个例子:agent例化时名字为"agt",而scoreboard为"scb",那么agt的build_phase先执行,执行完毕后接下来执行的是agt中的driver,monitor以及sequencer的build_phase。全部执行完毕之后再执行scoreboard的build_phase。
phase中domain概念
Domain是用来组织不同组件的,实现独立运行的。默认情况下,UVM的9个phase属于common_domain,12个小phase属于uvm_domain。如果我们有两个driver类,默认情况下,两个driver类中的复位phase和mainphase必须同时执行,但是我们可以设置两个driver属于不同的domain,这样两个driver就是独立运行的了,相当于处于不同的时钟域。
run_phase和mian_phase之间的关系
run_phase和main_phase都是task phase,是并行运行的。如果想执行一些耗费时间的代码,就要在此phase下的任意一个component中至少提起一次objection。值得一提的是,如果12个动态phase有objection提起,那么run_phase根本不需要raise_objection就可以自动执行。反过来则不行。
phase的跳转
在main_phase执行过程中,突然遇到reset信号被置起,可以使用jump()实现从main_phase到reset_phase的跳转:phase.jump(uvm_reset_phase::get())。
当然不是所有的phase都可以作为jump的参数。比如从main_phase跳转到build_phase就会报错,因为"No non-zero delays are allowed before run test",所以不能跳转到function phase,此外,run_time_phase也不能跳转到run_phase,因为run_phase不是run_time_phase的先驱phase或者后继phase,它们是并行运行的。