《UVM白皮书》关于env的介绍
前文在driver中使用`uvm_component_utils()宏加入factory机制时,【学习记录丨UVM】1.2驱动器driver(2)—— 引入factory、objection机制和interface-CSDN博客有提到在top_tb中使用一个run_test()语句就能替换掉左侧原来的实例化和main_phase的显式调用。如下图。
但是这里有一个问题,run_test只能进行一个实例化。
验证平台往往还有monitor,scoreboard等其他组件,那这些组件的实例化要在哪里进行呢?
怎么办呢?
dengdengdengdeng噔噔噔噔~,我们可以引入一个容器!
在这个容器里实例化driver,monitor等组件,然后run_test()时把这个容器class作为传递的参数。
在UVM中,这个容器类被称为uvm_env。
一、一个简单的env结构:
class my_env extends uvm_env;//env派生自uvm_env
my_driver drv;//实例化my_driver,即把my_driver装到env这个容器里
function new(string name="my_env",uvm_component parent);
super.new(name,parent);
endfuncion
virtual function void build_phase(uvm_phase phase);//实例化driver
super.build_phase(phase);
drv = my_driver::type_id::create("drv",this);//factory机制带来的实例化方式,
//只有使用这个实例化方式后续才能使用factory机制中强大的重载功能!!!
endfunction
`uvm_component_utils(my_env)
endclass
需要注意,在验证平台中实例化组件时都应该使用type_name::type_id::create的方式。
前文介绍interface的时候也见到了build_phase。
- build_phase是UVM_phase机制中的一个,在new函数之后main_phase之前执行
- build_phase 主要用来通过config_db机制的set,get来传递一些数据,以及实例化成员变量等。
- 它是一个function phase函数phase,是不消耗仿真时间的,总是在仿真时间0执行;而其他main/ run_phase是task phase,是任务phase,需要消耗时间。
二、UVM的树形结构
1. 上边举例中的树形结构
回顾一下上边my_env中的new函数
function new(string name="my_env",uvm_component parent);
super.new(name,parent);
endfuncion
new函数有两个参数,第一个是实例的名字,第二个是parent。
现在driver在env中实例化,所以my_driver的父节点(parent)就是my_env。
通过parent的形式,UVM建立起了树形的组织结构。
上边的示例只有env和driver,my_env是树根,而my_driver是它的枝叶。
- 在UVM中,不管是哪个组件实例,树根的名字是固定的,叫做uvm_test_top;
- 枝叶从属关系是在build_phase中以type_name::type_id::create实例化方式手动实现的;
- UVM树形结构中,每个节点都必须派生自uvm_component;
2. 树形结构中的build_phase执行顺序
上边我们注意到,env和driver都有build_phase,那么要按照什么顺序执行呢?
在UVM的树形结构中,build_phase的执行顺序 遵照从树根到树叶的顺序。
即先执行my_env的 build_phase,再执行my_driver的build_phase。当把整棵树的build_phase都执行完毕后,再执行后边的phase。
三、验证平台层次结构变化对top_tb的影响
1. config_db.set的第2个参数-路径索引
my_driver在容器类my_env中进行了实例化,那么top_tb中的config_db的set函数的第2个参数(路径索引)就需要改变了。
class my_env extends uvm_env
…
drv = my_driver::type_id::create("my_drv", this);
…
endclass
**********************************************************************
module top_tb;
…
initial begin
uvm_config_db#(virtual my_if)::set(null, "uvm_test_top.my_drv", "vif", inpu t_if);
end
endmodule
set函数的第2个参数由原来的uvm_test_top改为了uvm_test_top.my_drv。
原来验证平台中只有driver,那它在uvm树形结构中自然是树根uvm_test_top;但是现在env是树根uvm_test_top,而my_drv是env的build_phase实例化driver时传递的名字,所以现在路径索引就是uvm_test_top.my_drv了。
2.run_test()的参数
run_test()的参数由原来的my_driver变成了my_env。
initial begin
run_test("my_env");
end
这也是本文开头说的引入容器类env的应用。自然之后我们会在容器类env中加入其他component组件。