上次更新完《IC验证"UVM验证平台"组成》后本打算不再更新…但有人反映要继续更新…继续连载…小编考虑到一个好的连续剧不能没有结尾,所以后期会持续更新ic验证的UVM相关内容…
今天更新一个最简单的验证平台,只有driver的验证平台…
driver是验证平台最基本的组件,是整个验证平台数据流的源泉。本节以一个简单的DUT为例,说明一个只有driver的UVM验 证平台是如何搭建的。
最简单的验证平台,假设有如下的DUT定义:
这个DUT的功能非常简单,通过rxd接收数据,再通过txd发送出去。其中rx_dv是接收的数据有效指示,tx_en是发送的数据有 效指示。这里所有例子都是基于这个DUT。
UVM中的driver应该如何搭建?
UVM是一个库,在这个库中,几乎所有的东西都是使用类(class)来实现的。driver、 monitor、reference model、scoreboard等组成部分都是类。类是像SystemVerilog这些面向对象编程语言中最伟大的发明之一,是面 向对象的精髓所在。类有函数(function),另外还可以有任务(task),通过这些函数和任务可以完成driver的输出激励功能,完 成monitor的监测功能,完成参考模型的计算功能,完成scoreboard的比较功能。类中可以有成员变量,这些成员变量可以控制类 的行为,如控制driver的行为等。当要实现一个功能时,首先应该想到的是从UVM的某个类派生出一个新的类,在这个新的类中 实现所期望的功能。所以,使用UVM的第一条原则是:验证平台中所有的组件应该派生自UVM中的类。
UVM验证平台中的driver应该派生自uvm_driver,一个简单的driver如下例所示:
这个driver的功能非常简单,只是向rxd上发送256个随机数据,并将rx_dv信号置为高电平。当数据发送完毕后,将rx_dv信号 置为低电平。
上述代码中还出现了uvm_info宏。这个宏的功能与Verilog中display语句的功能类似,但是它比display语句更加强大。它有三个参数:
第一个参数是字符串,用于把打印的信息归类;
第二个参数也是字符串,是具体需要打印的信息;
第三个参数则是冗余级别。
在验证平台中,某些信息是非常关键的,这样的信息可以设置为UVM_LOW,而有些信息可有可无,就可以设置为 UVM_HIGH,介于两者之间的就是UVM_MEDIUM。UVM默认只显示UVM_MEDIUM或者UVM_LOW的信息,uvm_info宏打印的结果如下:
UVM_INFO my_driver.sv (20 )@48500000
:drv[my_driver]data is drived
在uvm_info宏打印的结果中有如下几项:
1.UVM_INFO关键字:表明这是一个uvm_info宏打印的结果。除了uvm_info宏外,还有uvm_error宏、uvm_warning宏,后文中 将会介绍。
2.my_driver.sv(20):指明此条打印信息的来源,其中括号里的数字表示原始的uvm_info打印语句在my_driver.sv中的行号。
3.48500000:表明此条信息的打印时间。
4.drv:这是driver在UVM树中的路径索引。UVM采用树形结构,对于树中任何一个结点,都有一个与其相应的字符串类型的 路径索引。路径索引可以通过get_full_name函数来获取,把下列代码加入任何UVM树的结点中就可以得知当前结点的路径索引:
$display(“the full name of current component is: %s”, get_full_name());
[my_driver]:方括号中显示的信息即调用uvm_info宏时传递的第一个参数。
data is drived:表明宏最终打印的信息。
可见,uvm_info宏非常强大,它包含了打印信息的物理文件来源、逻辑结点信息(在UVM树中的路径索引)、打印时间、对信息的分类组织及打印的信息。读者在搭建验证平台时应该尽量使用uvm_info宏取代display语句。
定义my_driver后需要将其实例化。这里需要注意类的定义与类的实例化的区别。所谓类的定义,就是用编辑器写下:
classs A;
…
endclass
而所谓类的实例化指的是通过new创造出A的一个实例。如:
A a_inst;
a_inst = new();
类的定义类似于在纸上写下一纸条文,然后把这些条文通知给SystemVerilog的仿真器:验证平台可能会用到这样的一个类, 请做好准备工作。而类的实例化在于通过new()来通知SystemVerilog的仿真器:请创建一个A的实例。仿真器接到new的指令 后,就会在内存中划分一块空间,在划分前,会首先检查是否已经预先定义过这个类,在已经定义过的情况下,按照定义中所指 定的“条文”分配空间,并且把这块空间的指针返回给a_inst,之后就可以通过a_inst来查看类中的各个成员变量,调用成员函数/任 务等。对大部分的类来说,如果只定义而不实例化,是没有任何意义的 [3];而如果不定义就直接实例化,仿真器将会报错。
对my_driver实例化并且最终搭建的验证平台如下:
第2行把uvm_macros.svh文件通过include语句包含进来。这是UVM中的一个文件,里面包含了众多的宏定义,只需要包含一 次。
第4行通过import语句将整个uvm_pkg导入验证平台中。只有导入了这个库,编译器在编译my_driver.sv文件时才会认识其中的 uvm_driver等类名。
第24和25行定义一个my_driver的实例并将其实例化。注意这里调用new函数时,其传入的名字参数为drv,前文介绍uvm_info 宏的打印信息时出现的代表路径索引的drv就是在这里传入的参数drv。另外传入的parent参数为null,在真正的验证平台中,这个 参数一般不是null,这里暂且使用null。
第26行显式地调用my_driver的main_phase。在main_phase的声明中,有一个uvm_phase类型的参数phase,在真正的验证平台 中,这个参数是不需要用户理会的。本节的验证平台还算不上一个完整的UVM验证平台,所以暂且传入null。
第27行调用finish函数结束整个仿真,这是一个Verilog中提供的函数。
运行这个例子,可以看到“data is drived”被输出了256次。
通知:
本章更新后将持续更新更新…
如:
加入factory机制
加入objection机制
加入virtual inteRFace
加入transaction
加入env
加入monitor
封装成agent
加入reference model
加入scoreboard
加入field_automation机制…
如果有任何疑问请在下方评论…