目录
6. phase机制
- SV不能做到的:虽然通过new函数例化对象,在验证env实现层次化时无法保证例化的先后关系,以及各个组件在例化后的连接;顶层到底层的配置时无法在底层组件例化之前完成对底层的配置逻辑
- 作用:将uvm仿真阶段层次化,有先后。不仅是各个phase的先后执行顺序,同一phase中的层次化组件之间的phase也有先后关系
- 9个phase对应9个方法,只有component具备这9个,主要用build,connect,run,report。运行顺序自上到下
class subcomp extends uvm_component;
`uvm_component_utils (subcomp)
function new (string name, uvm_component parent);
super.new(name, parent);
endfunction
function void build_phase (uvm_phase phase);//传递当前的phase进来
`uvm_info("build_phase", "", UVM_LOW)
endfunction
function void connect_phase (uvm_phase phase);
`uvm_info("connect_phase", "", UVM_LOW)
endfunction
function void end_of_elaboration_phase (uvm_phase phase);
`uvm_info("end_of_elaboration_phase", "", UVM_LOW)
endfunction
function void start_of_elaboration_phase (uvm_phase phase);
`uvm_info("start_of_elaboration_phase", "", UVM_LOW)
endfunction
task run_phase (uvm_phase phase);
`uvm_info("run_phase", "", UVM_LOW)
endtask
function void extract_phase (uvm_phase phase);
`uvm_info("extract_phase", "", UVM_LOW)
endfunction
function void check_phase (uvm_phase phase);
`uvm_info("check_phase", "", UVM_LOW)
endfunction
function void report_phase (uvm_phase phase);
`uvm_info("report_phase", "", UVM_LOW)
endfunction
function void final_phase (uvm_phase phase);
`uvm_info("final_phase", "", UVM_LOW)
endfunction
endclass
class topcomp extends subcomp;//继承9个phase后
subcomp c1, c2;
......
function void build_phase (uvm_phase phase);
`uvm_info("build_phase", "", UVM_LOW)
c1 = subcomp::type_id::create("c1", this);//利用工厂例化c1和c2
c2 = subcomp::type_id::create("c2", this);//this是parent的参数
endfunction
endclass
class test1 extends uvm_test;
topcomp t1;
......
function void build_phase (uvm_phase phase);
t1 = topcomp::type_id::create("t1", this);
endfunction
endclass
build自顶向下,connect自底向上,如表格所示
- 只有uvm_component及其继承子类才会按照phase机制将这9个phase先后执行完毕
- 只有run_phase是task,可以完成一些等待、激励、采样的需要耗时的任务。
- run_phase测试需要组织的激励序列:上电,复位,寄存器配置,发送主要测试内容,等待dut完成测试
- run_phase有12个细分的phase,不建议用,这12个和run_phase是并行的,12个执行完也得等run_phase执行完才会执行下一个phase
UVM编译和运行的顺序
- 0时刻前先编译
- 0时刻启动always和initial块,从顶层module的initial调用run_test(),执行全局phase,完成前4个phase
- 开始仿真后执行run_phase和12个分支phase(fork_join)
- 仿真结束后执行剩余4个phase
- root→test→env→components
- 仿真开始时建立验证环境的方式
-
通过uvm_pkg提供的全局函数run_test(),选择性地指定要运行哪一个uvm_test,test都继承于uvm_test
-
若没有参数传递给run_test(),仿真时可以指定仿真时调用的uvm_test
+UVM_TESTNAME=<test_name>
-
- 上述方式都必须在顶层调用全局函数run_test(),这个函数从uvm_root创建了一个UVM世界
看看源代码
task run_test (string test_name="");
uvm_root top;
uvm_coreservice_t cs;
cs=uvm_coreservice_t::get();//拿到coreservice,全局唯一的实例
top=cs.get_root();//通过coreservice拿到顶层
top.run_test(test_name);//调用顶层的run_test()
endtask
uvm_top的职责
- 作为隐形的uvm世界顶层,任何其他组件实例都在它之下,通过创建组件时指定parent来构成层次
- parent为null,它将作为uvm_top的子组件
- 控制所有组件的phase顺序
- 通过层次名称索引组件实例
- 通过uvm_top全局配置报告的繁简度verbosity
- 全局报告设备。在组件内外部都可以访问uvm报告设备
通过uvm_top调用run_test(test_name),做了如下初始化:
- 得到正取的test_name
- 初始化objection机制
- 创建uvm_test_top实例
- 调用phase控制方法,安排所有组件的phase方法执行顺序
- 等待所有phase结束,关闭phase控制进程
- 报告总结,结束仿真
UVM仿真结束
- 只有一种结束机制:利用objection挂起机制,控制仿真结束
- uvm_objection类提供了一种供所有component和sequence共享的计数器,参与到objection机制中的参与组建可以独立的各自挂起raise_objection,防止run_phase退出。所有组件drop_objection后,计数器才为0,run_phase才可以退出
- 也就是运行时至少要有1个挂起objection
raise_objection (uvm_object obj =null, string description="", int count=1)
drop_objection (uvm_object obj =null, string description="", int count=1)
set_drain_time (uvm_object obj =null, time drain)//设置退出时间
- 建议:
- 对于component(),可以在run_phase()中使用phase.raise_objection()/phase.drop_objection()控制run_phase的退出
- 为description字符串参数提供说明
- 使用默认count值
- uvm_top或uvm_test_top尽可能少用set_drain_time()
class test1 extends uvm_test;
...
task run_phase (uvm_phase phase);
phase.raise_objection(this);//一进来就先举手。当前组件在当前phase
`uvm_info("run_phase", "entered", UVM_LOW)
#1us;
`uvm_info("run_phase", "exited", UVM_LOW)
phase.drop_objection(this);//执行完就手放下
endtask
endclass
举手前如果加上#1ps;那也不会继续执行下面的语句,因为看不到objection举手会马上跳出run_phase
- 习惯在sequence中挂起,sequence没有run_phase(),有body(),在body首尾举手和落下。