UVM实战 卷I学习笔记5——UVM基础(2)UVM的树形结构

本文详细阐述了UVM组件中的parent参数在构建树形结构中的作用,包括为何需要指定parent,UVM树的根节点uvm_top的定位,以及层次结构相关的get_parent、get_child和get_children等关键函数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


UVM采用树形结构管理验证平台的各个部分。sequencer、driver、monitor、agent、model、scoreboard、env等都是树的一个结点。用树的形式来组织是因为作为一个验证平台,它必须能够掌握自己治下的所有“人口”,只有这样做才利于管理大家统一步伐做事情而不会漏掉谁。树形结构是实现这种管理的一种比较简单的方式。

uvm_component中的parent参数

UVM通过uvm_component实现树形结构。所有UVM树的结点本质上都是一个uvm_component。每个uvm_component都有一个特点:它们在new时需要指定一个类型为uvm_component、名字是parent的变量:function new(string name, uvm_component parent);

以下内容解释为何需要制定parent变量
一般在使用时parent通常都是this。假设A和B均派生自uvm_component,在A中实例化一个B:

class B extends uvm_component;
	...
endclass
class A extends uvm_component;
	B b_inst;
	virtual function void build_phase(uvm_phase phase);
		b_inst = new("b_inst", this);
	endfunction
endclass

在b_inst实例化时把this指针传递给了它,代表A是b_inst的parent。为什么要指定这么一个parent呢?一种常见的观点是,b_inst是A的成员变量,那么A就是b_inst的parent,无需再在调用new函数的时候指定,即b_inst在实例化时可以这样写:b_inst = new(“b_inst”); 但这样忽略了一点,b_inst是A的成员变量,那么在SV仿真器一级这种关系是确定的、可知的。假定有下面的类:

class C extends uvm_component;
	A a_inst;
	function void test();
	…
	a_inst.b_inst =;
	a_inst.d_inst =;
	…
	endfunction
endclass

可以在C类的test函数中使用a_inst.b_inst来得到B的值或给B赋值,但不能用a_inst.d_inst来给D赋值,因为D不存在于A里面。SV仿真器会检测这种成员变量的从属关系,只负责检查这些代码的合理性,不会主动发消息给代码,所以A根本就没有办法知道自己有B这个变量。

如果在test中想得到A中所有变量的指针应怎么办? 可能会说因为A是自己写出的,它只有一个变量且它的名字叫b_inst,所以可直接使用a_inst.b_inst。问题是假设要把整棵UVM树遍历一下,即要找到每个结点及结点的孩子的指针,那如何写呢?似乎根本就没有办法实现。

解决这个问题的方法是,当b_inst实例化时指定一个parent的变量,同时在每一个component内部维护一个数组m_children,当b_inst实例化时就把b_inst的指针加入到A的m_children数组中。只有这样才能让A知道b_inst是自己的变量,同时也才能让b_inst知道A是自己的父母。当b_inst有了自己的变量时,即在b_inst的m_children中加入变量的指针。

总而言之,在实例化变量时指定parent变量,可以形成一个树状结构从而起到建立层次的作用

UVM树的根

UVM中真正的树根是uvm_top,完整的UVM树如图所示:
在这里插入图片描述
uvm_top是一个全局变量,它是uvm_root的唯一实例,且uvm_root派生自uvm_component。uvm_test_top的parent是uvm_top,而uvm_top的parent则是null。

UVM为什么不以uvm_test派生的测试用例,即uvm_test_top作为树根?之前的例子中所有component在实例化时将this指针传递给parent参数,如my_env在base_test中实例化:env=my_env::type_id::create(“env”, this);假如不按上面写法而是将parent参数设为null,那么这个component的parent将会被系统设置为系统中唯一的uvm_root的实例uvm_top,如下图所示:
在这里插入图片描述
可见,uvm_root的存在可以保证整个验证平台中只有一棵树,所有结点都是uvm_top的子结点

在验证平台中,有时候需要得到uvm_top,由于uvm_top是一个全局变量,可直接使用uvm_top。除此之外, 还可以使用如下的方式得到它的指针:

uvm_root top;
top = uvm_root::get();

层次结构相关函数

UVM提供一系列的接口函数用于访问UVM树中的结点。这其中最主要的是以下几个:

get_parent函数:用于得到当前实例的parent
其函数原型为:extern virtual function uvm_component get_parent ();

与get_parent相对的是get_child函数:extern function uvm_component get_child (string name);

与get_parent不同,get_child需要一个string类型的参数name,表示此child实例在实例化时指定的名字。一个component只有一个parent,所以get_parent不需要指定参数;而可能有多个child,所以必须指定name参数。

可使用get_children函数得到所有的childextern function void get_children(ref uvm_component children[$]);

除了一次性得到所有的child外, 还可以使用get_first_child和get_next_child的组合依次得到所有的child

string name;
uvm_component child;
if(comp.get_first_child(name))
	do begin
		child = comp.get_child(name);
		child.print();
	end while(comp.get_next_child(name));

这两个函数的使用依赖于一个string类型的name。在这两个函数的原型中,name是作为ref类型传递的:

extern function int get_first_child (ref string name);
extern function int get_next_child (ref string name);

name只是用于get_first_child和get_next_child之间及不同次调用get_next_child时互相之间传递信息无需为name赋任何初始值,也没有必要在使用这两个函数过程中对其做任何赋值操作

get_num_children函数用于返回当前component所拥有的child的数量extern function int get_num_children ();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值