phase机制
一、前言
- SV的验证环境构建中,我们可以发现,传统的硬件设计模型在仿真开始前,已经完成例化和连接了;而SV的软件部分对象例化则需要在仿真开始后执行。
- 虽然对象例化通过调用构造函数new()来实现,但是单单通过new()函数无法解决一个重要问题,那就是验证环境在实现层次化时,无法保证例化的先后关系,以及各个组件在例化后的连接。
- 此外如果需要实现高级功能,例如在顶层到底层的配置时,SV也无法在底层组件例化之前完成对底层的配置逻辑。
- 因此UVM在验证环境构建时,引入了phase机制,通过该机制我们可以很清晰地将UVM仿真阶段层次化。
- 这里的层次化,不单单是各个phase的先后执行顺序,而且处于同一phase中的层次化组件之间的phase也有先后关系。
二、执行机制
- 如果暂时抛开phase的机制剖析,对于UVM组件的开发者而言,它们主要关心各个phase执行的先后顺序。
- 在定义了各个phase虚方法后,UVM环境会按照phase的顺序分别调用这些方法。
![在这里插入图片描述](https://img-blog.csdnimg.cn/1923512d56d8474f95ff1b2251b340a7.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5pWw5a2XSUPlsI_nmb3nmoTml6XluLjkv67ngrw=,size_13,color_FFFFFF,t_70,g_se,x_16)
- 九个phase对应九种方法,这九种方法只有component具备
- 上面的九个phase对于一个测试环境的声明周期而言,是有固定的先后执行顺序的;同时对于同一个phase中的组件,执行也会按照层次的顺序或者自顶向下、或者自底向上来执行。
- 对于build phase,执行顺序按照自顶向下,这符合验证结构建设的逻辑。因为只有先例化高层组件,才会创建空间来容纳底层组件。
- 只有uvm_component及其继承于uvm_component的子类,才会按照phase机制将上面的九个phase先后执行完毕。
- 常用的phase包括build、connect、run和report,它们分别完成了组件的建立、连接、运行和报告。这些phase在uvm_component中通过_phase的后缀完成了虚方法的定义,比如build_phase()可以定义一些组件例化和配置的任务。
- 在所有phase中,只有run_phase方法是一个可以耗时的任务,这意味着该方法可以完成一些等待、激励、采样的任务。对于其它phase对应的方法都是函数,必须立即返回(0耗时)。
- 在run_phase中,用户如果要完成测试,通常需要组织下面的激励序列:
- 上电
- 复位
- 寄存器配置
- 发送主要测试内容
- 等待DUT完成测试
三、 phase例子
package phase_order_pkg;
import uvm_pkg::*;
`include "uvm_macros.svh"
class comp2 extends uvm_component;
`uvm_component_utils(comp2)
function new(string name = "comp2", uvm_component parent = null);
super.new(name, parent);
`uvm_info("CREATE", $sformatf("unit type [%s] created", name), UVM_LOW)
endfunction
function void build_phase(uvm_phase phase);
super.build_phase(phase);
`uvm_info("BUILD", "comp2 build phase entered", UVM_LOW)
`uvm_info("BUILD", "comp2 build phase exited", UVM_LOW)
endfunction
function void connect_phase(uvm_phase phase);
super.connect_phase(phase);
`uvm_info("CONNECT", "comp2 connect phase entered", UVM_LOW)
`uvm_info("CONNECT", "comp2 connect phase exited", UVM_LOW)
endfunction
task run_phase(uvm_phase phase);
super.run_phase(phase);
`uvm_info("RUN", "comp2 run phase entered", UVM_LOW)
`uvm_info("RUN", "comp2 run phase entered", UVM_LOW)
endtask
function void report_phase(uvm_phase phase);
super.report_phase(phase);
`uvm_info("REPORT", "comp2 report phase entered&#