目录
·所有派生自uvm_driver的类的new函数有两个参数:
一、代码常用缩写:
UVC=bus agent
adapter:寄存器桥接
arb=arbiter:仲裁器
ap=uvm_analysis_port
chnl=chnnel:信道(数据通道)
cfg=config:配置
db=database:
freq=frequnce:频率
reg=register:寄存器
env=environment:环境
rep=report :报告
req =request:请求
rsp=response:响应
registration :注册
override:覆盖
trans=transaction:事务
fmt=formatter:整形器
tb=testbench:测试平台
prio=priority:优先级
mst=master_agent:主代理
slv=slave_agent:从代理
sb=scoreboard:计分板(比较器)
sqr=sequencer:跟随器(关口)
seq=sequence:序列(马路)
virt=virtual:虚拟的
virt_sqr:虚拟跟随器:用于传递transactions
vif=virtual interface虚拟接口
TLM(transaction level model)事务级模型
transaction:事务(包含传输指令、数据整包、状态等)
宏:macro
UNDIR=unicdirection单向传输
BIDIR=bidirection双向传输
ecb=event_callback event回调函数(用于同步通信)
threshold 等待阈值
二、简单的UVM平台
验证平台四大部件:
driver:
激励的功能是由driver来实现。driver功能主要就是向sequencer索要sequence_item(transaction),把transaction级别的数据转变成DUT的端口级别,并驱动给DUT,
scoreboard记分板:
要能够根据DUT的输出来判断DUT的行为是否与预期相符合=checker
monitor:
验证平台要收集DUT的输出并把它们传递给scoreboard。monitor的行为与driver相反,用于收集DUT的端口数据,并将其转换成transaction交给后续的组件如reference model、scoreboard等处理。
reference model参考模型:
验证平台要能够给出预期结果。
使用UVM的第一条原则是:验证平台中所有的组件应该派生自UVM中的类。
driver、monitor、reference model、scoreboard等组成部分都是类。
类有函数(function),另外还可以有任务(task),有成员变量。
通过这些函数和任务可以完成driver的输出激励功能,完成monitor的监测功能,完成参考模型的计算功能,完成scoreboard的比较功能。成员变量可以控制类的行为,如控制driver的行为等。
·所有派生自uvm_driver的类的new函数有两个参数:
一个是string类型的name,
一个是uvm_component类型的parent。
这是uvm_component类的一大特征。
main_phase:
·driver所做的事情几乎都在main_phase中完成。UVM由phase来管理验证平台的运行,这些phase统一以xxxx_phase来命名,且都有一个类型为uvm_phase、名字为phase的参数。main_phase是uvm_driver中预先定义好的一个任务。因此几乎可以简单地认为,实现一个driver等于实现其main_phase。
uvm_info宏:
与Verilog中display语句的功能类似,更加强大。
有三个参数:
第一个参数是字符串,用于把打印的信息归类;
第二个参数也是字符串,是具体需要打印的信息;
第三个参数则是冗余级别。
某些信息是非常关键——设置为UVM_LOW(低过滤),
而有些信息可有可无——设置为UVM_HIGH(高过滤),
介于两者之间的就是——UVM_MEDIUM。
`uvm_info("my_driver", "data is drived", UVM_LOW)
工厂机制:
run_test:
传递给run_test一个字符串(如my_drive),创建字符串所代表类的一个实例,并且会自动调用my_driver的main_phase。
根据类名创建一个类的实例,这是uvm_component_utils宏所带来的效果:所有派生自uvm_component及其派生类的类都应该使用uvm_component_utils宏注册。。在UVM验证平台中,只要一个类使用uvm_component_utils注册且此类被实例化了,那么这个类的main_phase就会自动被调用。
objection机制:
raise_objection:挂起才运行
UVM中通过objection机制来控制验证平台的关闭。在每个phase中,UVM会检查是否有objection被提起(raise_objection),如果有,那么等待这个objection被撤销(drop_objection)后停止仿真;如果没有,则马上结束当前phase。
drop_objection:落下就是结束
是finish函数的替代者,只是在drop_objection语句之前必须先调用raise_objection语句,raise_objection和drop_objection总是成对出现。
raise_objection语句必须在main_phase中第一个消耗仿真时间的语句之前。
virtual interface:代码中的绝对路径已经消除
避免绝对路径的方法:宏或者interface
避免绝对路径的一个方法是使用宏。当路径修改时,只需要修改宏的定义即可。
避免绝对路径的另外一种方式是使用interface。
interface来连接验证平台与DUT的端口
模块中可以声明interface
类中只能声明virtual interface=vif
config_db机制:
在config_db机制中,分为set和get两步操作。
所谓set操作,理解成是“寄信”,
而get则相当于是“收信”。在top_tb中执行set操作
build_phase
当UVM启动后,会自动执行build_phase。build_phase在new函数之后main_phase之前执行。在build_phase中主要通过config_db的set和get操作来传递一些数据,以及实例化成员变量等。
build_phase执行顺序
在UVM的树形结构中,build_phase的执行遵照从树根到树叶的顺序,即先执行my_env的build_phase,再执行my_driver的build_phase。当把整棵树的build_phase都执行完毕后,再执行后面的phase。
uvm_fatal宏
是一个类似于uvm_info的宏,但是它只有两个参数,这两个参数与uvm_info宏
的前两个参数的意义完全一样。uvm_fatal的出现表示验证平台出现了重大问题而无法继续下去,必须停止仿真并做相应的检查。
平台各组件:
transaction:
一笔transaction就是一个包。每个包的大小至少是64byte。这个包中要包括源地址、目的地址、包的类型、整个包的CRC校验数据。
monitor:
验证平台要收集DUT的输出并把它们传递给scoreboard。monitor的行为与driver相对(driver向DUT的pin上发送数据,而monitor则是从DUT的pin上接收数据),用于收集DUT的端口数据,并将其转换成transaction交给后续的组件如reference model、scoreboard等处理。
uvm_monitor在整个仿真中是一直存在的,所以它是一个component。由于monitor需要时刻收集数据,永不停歇,所以在main_phase中使用while(1)循环来实现这一目的
uvm_env:
派生自uvm_component
将验证平台上用到的固定不变的component都封装在一起。
reference model:
作用就是模仿DUT,完成与DUT相同的功能。DUT是用Verilog写成的时序电路,而reference model则可以直接使用SystemVerilog高级语言的特性,同时还可以通过DPI等接口调用其他语言来完成与DUT相同的功能
my_model并不复杂,这其中令人感兴趣的是my_transaction的传递方式。my_model是从i_agt中得到my_transaction,并把my_transaction传递给my_scoreboard。
在UVM中,通常使用TLM(Transaction Level Modeling)实现component之间transaction级别的通信在UVM的transaction级别的通信中,数据的发送有多种方式,其中一种是使用uvm_analysis_port。
uvm_agent:
显。它只是把driver和monitor封装在一起,根据参数值来决定是只实例化monitor还是要同时实例化driver和monitor。agent的使用主要是从可重用性的角度来考虑的。与uvm_component相比,uvm_agent的最大改动在于引入了一个变量is_active:
scoreboard:
my_scoreboard要比较的数据一是来源于reference model,通过exp_port获取
二是来源于o_agt的monitor。后者通过 act_port获取。
在main_phase中通过fork建立起了两个进程:
一个进程处理exp_port的数据,当收到数据后,把数据放入 expect_queue中;
另一进程处理act_port的数据,这是DUT的输出数据,当收集到这些数据后,从expect_queue中弹出之前从 exp_port收到的数据,并调用my_transaction的my_compare函数。
加入field_automation机制
1、直接调用copy、compare、print
2、调用pack_bytes将tr中所有的字段变成byte流放入data_q
使用unpack_bytes函数将data_q中的byte流转换成tr中的各个字段
base_test
真正的测试用例都是基于base_test派生的一个类。
report_phase
也是UVM内建的一个phase,它在main_phase结束之后执行。在report_phase中根据UVM_ERROR的数量来打印不同的信息。一些日志分析工具可以根据打印的信息来判断DUT是否通过了某个测试用例的检查。