UVM入门与进阶学习笔记3——phase机制

传统硬件设计模型在仿真开始前已完成例化和连接;而SV软件部分,类的例化需要在仿真开始后完成。虽然类的例化通过调用构建函数new()实现,但仅通过new()函数无法解决一个重要问题——验证环境层次化时需要保证例化的先后关系,以及在确立各个组件均完成例化后的连接。且如果需要实现高级功能,如顶层到底层的配置时,也无法在底层组件例化之前提前完成配置逻辑

因此UVM引入phase机制,通过该机制可以清晰地将UVM仿真的阶段层次化。不单单是对各个phase的先后顺序处于同一phase中的层次化组件之间的phase也有先后关系
在这里插入图片描述
只有run_phasetask,可消耗时间,用来给dut发送激励。具体的运行过程:一般只用run_phase就行,不必细分(不用main_phase)。0时刻之前编译与连接;0时刻执行build_phase, connect_phase, run_phase入口(run_test(“test_name”));0时刻之后run_phase执行完,到fianl_phase结束。

对UVM组件,主要关心各个phase执行的先后顺序。在定义了各个phase虚方法后,UVM环境会按照phase的顺序分别调用这些方法。
在这里插入图片描述

module common_phase_order;
import uvm_pkg::*;
`include "uvm_macros.svh"
 
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);
    `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_simulation_phase(uvm_phase phase);
    `uvm_info("start_of_simulation_phase", "", UVM_LOW)
endfunction
task run_phase(uvm_phase phase); //注意是task
    `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;
subcomp c1, c2;
`uvm_component_utils(topcomp)
function new(string name, uvm_component parent);
    super.new(name, parent);
endfunction
function void build_phase(uvm_phase phase);
    `uvm_info("build_phase", "", UVM_LOW)
    c1 = subcomp::type_id::create("c1", this);
    c2 = subcomp::type_id::create("c2", this);
endfunction
endclass
 
class test1 extends uvm_test;
topcomp t1;
`uvm_component_utils(test1)
function new(string name, uvm_component parent);
    super.new(name, parent);
endfunction
function void build_phase(uvm_phase phase);
    t1 = topcomp::type_id::create("t1", this);
endfunction
endclass
输出结果
UVM_INFO @ 0: uvm_test_top.t1 [build_phase]  //notice
UVM_INFO @ 0: uvm_test_top.t1.c1 [build_phase]
UVM_INFO @ 0: uvm_test_top.t1.c2 [build_phase]
UVM_INFO @ 0: uvm_test_top.t1.c1 [connect_phase]
UVM_INFO @ 0: uvm_test_top.t1.c2 [connect_phase]
UVM_INFO @ 0: uvm_test_top.t1 [connect_phase]
UVM_INFO @ 0: uvm_test_top.t1.c1 [end_of_elaboration_phase]
UVM_INFO @ 0: uvm_test_top.t1.c2 [end_of_elaboration_phase]
UVM_INFO @ 0: uvm_test_top.t1 [end_of_elaboration_phase]
UVM_INFO @ 0: uvm_test_top.t1.c1 [start_of_simulation_phase]
UVM_INFO @ 0: uvm_test_top.t1.c2 [start_of_simulation_phase]
UVM_INFO @ 0: uvm_test_top.t1 [start_of_simulation_phase]
UVM_INFO @ 0: uvm_test_top.t1.c1 [run_phase]
UVM_INFO @ 0: uvm_test_top.t1.c2 [run_phase]
UVM_INFO @ 0: uvm_test_top.t1 [run_phase]
UVM_INFO @ 0: uvm_test_top.t1.c1 [extract_phase]
UVM_INFO @ 0: uvm_test_top.t1.c2 [extract_phase]
UVM_INFO @ 0: uvm_test_top.t1 [extract_phase]
UVM_INFO @ 0: uvm_test_top.t1.c1 [check_phase]
UVM_INFO @ 0: uvm_test_top.t1.c2 [check_phase]
UVM_INFO @ 0: uvm_test_top.t1 [check_phase]
UVM_INFO @ 0: uvm_test_top.t1.c1 [report_phase]
UVM_INFO @ 0: uvm_test_top.t1.c2 [report_phase]
UVM_INFO @ 0: uvm_test_top.t1 [report_phase]
UVM_INFO @ 0: uvm_test_top.t1 [final_phase] //notice
UVM_INFO @ 0: uvm_test_top.t1.c1 [final_phase]
UVM_INFO @ 0: uvm_test_top.t1.c2 [final_phase]
  • 上面9个phase对一个测试环境的生命周期是有固定的先后执行顺序,同时对同一个phase中的组件,也会按层次顺序自顶向下或自底向上执行。
  • build phase的执行顺序是自顶向下,符合验证结构建设的逻辑。因为只有先例化高层组件,才会创建空间容纳低层组件
  • 只有uvm_component及继承于uvm_component的子类,才会按phase机制将上面9个phase先后执行完毕。
  • 常用的phase包括build、connect、run和report,分别完成组件的建立、连接、运行和报告。这些phase在uvm_component中通过_phase的后缀完成虚方法的定义。
  • 只有run_phase是可耗时的任务,该方法可完成一些等待、激励、采样的任务;其他phase对应的方法都是函数,必须立即返回(0耗时)。
  • run_phase中用户若要完成测试,通常需组织下面的激励序列:上电、复位、寄存器配置、发送主要测试内容、等待DUT完成测试

12个分支phase——用户发送激励的一种简单方式是在run_phase中完成上面所有激励;另一种方式,如果可以将上面的几种典型的序列分到不同的区间,让对应的激励按区搁置的话,也能让测试更有层次。因此run_phase又可以分为12个phase:

  1. pre_reset_phase
  2. reset_phase
  3. post_reset_phase
  4. pre_configure_phase
  5. configure_phase
  6. post_configure_phase
  7. pre_main_phase
  8. main_phase
  9. post_main_phase
  10. pre_shutdown_phase
  11. shutdown_phase
  12. post_shutdown_phase

实际上run_phase任务和12个分支phase是并行的,12个phase也是按先后顺序执行的,即在start_of_simulation_phase任务执行后,run_phasereset_phase开始执行,而在shutdown_phase执行后需等待run_phase执行完才可进入extract_phase

为避免不必要的干扰,用户可选择run_phase或12个分支phase中的若干来完成激励,但不要将它们混合起来使用,这样容易导致执行关系的不明确。

  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值