(2)UVM基础之核心基类和组件家族

核心基类

UVM世界中的类最初都是从一个uvm_void根类(root class)继承来的,而实际上这个类并没有成员变量和方法。
uvm_void只是一个虚类(virtual class)。在继承于uvm_void的子类中,有两个类,一个为uvm_object类,另外一个为uvm_port_base类。
在UVM世界的类库地图中除过事务接口(transaction interface)类继承于uvm_port_base其它所有的类都是从uvm_object类一步步继承而来的。
在这里插入图片描述

从uvm_object提供的方法和相关的宏操作来看,它的核心方法主要提供与数据操作的相关服务:Copy、Clone、Compare、Print、Pack/Unpack

copy和clone的区别:在UVM的数据操作中,需要对copy和clone加以区分。前者默认已经创建好了对象,只需要对数据进行拷贝;后者则会自动创建对象并对source object进行数据拷贝,再返回target object句柄。无论是copy或者clone,都需要对数据进行复制。

uvm_component与uvm_object

uvm_component派生自uvm_object,uvm_object是UVM中最基本的类,几乎所有的类都继承自uvm_object。uvm_component有两大特性是uvm_object所没有的,一是通过在new的时候指定parent参数来形成一种树形的组织结构,二是有phase的自动执行特点。
在这里插入图片描述
从uvm_object派生出了两个分支,所有的UVM树的结点都是由uvm_component组成的,只有基于uvm_component派生的类才可能成为UVM树的结点;最左边分支的类或者直接派生自uvm_object的类,是不可能以结点的形式出现在UVM树上的

常用派生自uvm_object的类

  1. uvm_sequence_item:定义的所有的transaction要从uvm_sequence_item派生。transaction就是封装了一定信息的一个类,虽然UVM中有一个uvm_transaction类,但是在UVM中,不能从uvm transaction派生一个transaction,而要从uvm_sequence_item派生。事实上,uvm_sequence_item是从uvm_transaction派生而来的,因此uvm_sequence_item相比uvm_transaction添加了很多实用的成员变量和函数/任务,从uvm_sequence_item直接派生,就可以使用这些新增加的成员变量和函数/任务。

  2. uvm_sequence:所有的sequence要从uvm_sequence派生一个。sequence就是sequence_item的组合。sequence直接与sequencer打交道,当driver向sequencer索要数据时,sequencer会检查是否有sequence要发送数据。当发现有sequence item待发送时,会把此sequence_item交给driver。

  3. config:所有的config一般直接从uvm_object派生。config的主要功能就是规范验证平台的行为方式。如规定driver在读取总线时地址信号要持续几个时钟,片选信号从什么时候开始有效等。注意config与config_db的区别。 config其实指的是把所有的参数放在一个object中,然后通过config_db的方式设置给所有需要这些参数的component。

除了上面几种类是派生自uvm_object外,还有下面几种:

  1. uvm_reg_item:它派生自uvm_sequence_item。 uvm_reg_map、uvm_mem、uvm_reg_field、uvm_reg、uvm_reg_file、uvm_reg_block等与寄存器相关的众多的类都是派生自uvm_object,它们都是用于register_model。

  2. uvm_phase:它派生自uvm_object,其主要作用为控制uvm_component的行为方式,使得uvm_component平滑地在各个不同的phase之间依次运转。

常用派生自uvm_component的类

  1. uvm_driver:所有的driver都要派生自uvm_driver。driver的功能主要就是向sequencer索要sequence_item(transaction),并且将sequence_item里的信息驱动到DUT的端口上,这相当于完成了从transaction级别到DUT能够接受的端口级别信息的转换。

  2. uvm_monitor:所有的monitor都要派生自uvm_monitor。monitor做的事情与driver相反,driver向DUT的pin上发送数据,而monitor则是从DUT的pin上接收数据,并且把接收到的数据转换成transaction级别的sequence_item,再把转换后的数据发送给scoreboard,供其比较。

  3. uvm_sequencer:所有的sequencer都要派生自uvm_sequencer。sequencer的功能就是组织管理sequence,当driver要求数据时,它就把sequence生成的sequence_item转发给driver。

  4. uvm_scoreboard:一般的scoreboard都要派生自uvm_scoreboard。scoreboard的功能就是比较reference model和monitor分别发送来的数据,根据比较结果判断DUT是否正确工作。

  5. reference model:UVM中并没有针对reference model定义一个类。所以通常来说,reference model都是直接派生自uvm component。reference model的作用就是模仿DUT,完成与DUT相同的功能。DUT是用Verilog写成的时序电路,而reference model则可以直接使用SystemVerilog高级语言的特性,同时还可以通过DPI等接口调用其他语言来完成与DUT相同的功能。

  6. uvm_agent:所有的agent要派生自uvm_agent。与前面几个比起来,uvm_agent的作用并不是那么明显。它只是把driver和monitor封装在一起,根据参数值来决定是只实例化monitor还是要同时实例化driver和monitor。 agent的使用主要是从可重用性的角度来考虑的。如果在做验证平台时不考虑可重用性,那么agent其实是可有可无的。

  7. uvm_env:所有的env(environment的缩写)要派生自uvm_env。env将验证平台上用到的固定不变的component都封装在一起。 这样,当要运行不同的测试用例时,只要在测试用例中实例化此env即可。

  8. uvm_test:所有的测试用例要派生自uvm_test或其派生类 ,不同的测试用例之间差异很大,所以 从uvm_test派生出来的类各不相同。任何一个派生出的测试用例中,都要实例化env, 只有这样,当测试用例在运行的时候,才能把数据正常地发给DUT,并正常地接收DUT的数据。

与uvm_object相关的宏

  1. uvm_object_utils:它用于把一个直接或间接派生自uvm_object的类注册到factory中。

  2. uvm_object param_utils:它用于把一个直接或间接派生自uvm_object的参数化的类注册到factory中。所谓参数化的类,是指类似于如下的类:

class A#(int WIDTH=32)extends uvm object;
  1. uvm_object_utils_begin:当需要使用field_automation机制时,需要使用此宏。如果使用了此宏,而又没有把任何字段使用uvm_field系列宏实现,是不会出现任何问题的。

  2. uvm_object_param_utils_begin:与uvm_object_utils_begin宏一样,只是它适用于参数化的且其中某些成员变量要使用field_automation机制实现的类。

与uvm_component相关的宏

类同uvm_object

uvm_component的限制

      uvm_component是从uvm_object派生来的。从理论上来说,uvm_component应该具有uvm_object的所有的行为特征。但是,由于uvm_component是作为UVM树的结点存在的,这一特性使得它失去了uwm_object的某些特征。
      在uvm_object中有clone函数,它用于分配一块内存空间,并把另一个实例复制到这块新的内存空间中。clone函数的使用方式如下:

class A extends uvm_object; 
...
endclass 

class my env extends uvm env; 
	virtual function void build phase(uvm phase phase); 
		A al; 
		A a2; 
		al=new("al"); 
		al.data=8'h9;
		$cast(a2, al. clone()); 
	endfunction 
endclass

上述的clone函数无法用于uvm_component中,因为一旦使用后,新clone出来的类,其parent参数无法指定。

      copy函数也是uvm_object的一个函数,在使用copy前,目标实例必须已经使用new函数分配好了内存空间,而使用clone函数时,目标实例可以只是一个空指针。 换言之,clone=new+copy。

虽然uvm_component无法使用clone函数,但是可以使用copy函数。因为在调用copy之前,目标实例已经完成了实例化,其parent参数已经指定了。

这篇笔记参考《UVM实战》、《芯片验证漫游指南》和某验证视频整理而成,仅作学习心得交流,如果涉及侵权烦请请告知,我将第一时间处理。

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

数字ic攻城狮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值