天气: 晴朗
心情: 平静
一个完整的UVM验证平台应该具有一些基本功能:产生并驱动激励,与DUV行为一致的理想参考模型reference_model(golden_model),监测并收集DUV和reference_mode的输入/输出信号,比较并判断DUV和reference_mode的输出是否一致且符合预期结果,等。这些基本的功能由相应的组件来完成。那么,这些组件之间是如何可靠、高效的完成验证工作的?或者说,UVM方法学中有哪些特有的机制可以保证验证平台自动的、可靠的并且高效率的完成验证工作呢?这篇内容将对一些常见的UVM机制进行一些简单的总结。
常见的UVM机制:
1.field_automation机制
对field_automation最直观的感受是,他可以自动实现copy、compare、print等三个函数。当使用uvm_field系列相关宏注册之后,可以直接调用以上三个函数,而无需自己定义。这极大的简化了验证平台的搭建,尤其是简化了driver和monitor,提高了效率。
2.config_db机制
config_db机制在UVM验证平台中主要用于参数传递。它们通常都是成对出现的,set函数是寄信,而get函数是收信。函数格式如下:
uvm_config_db# (Type)::set(this,"inst_path","field",value); //将value寄送给
“field(字段)”
uvm_config_db# (Type)::get(this,"","field",field)
//field将接收参数的传递
结果得到:field = value;
所谓“字段”,是变量名包含的内容。在set和get函数中为第三个参数,字段在set和get中必须保持一致,才能保证参数的正确传递。例如要将参数值10,传递给int类型的变量data,则:
uvm_config_db# (int)::set(this,"env.i_agt.drv","dat",10);
//将10寄送给env组件中的成员变量“data”
uvm_config_db#
(int)::get(this,"","dat",data) //字段“dat”保持一致,成员变量data将接收参数的传递
结果得到:data = 10;
3.objection机制
UVM中通过objection机制来控制验证平台的关闭,需要在drop_objection之前先raise_objection。验证在进入到某一phase时,UVM会收集此phase提出的所有objection,并且实时监测所有objection是否已经被撤销了,当发现所有都已经撤销后,那么就会关闭此phase,开始进入下一个phase。当所有的phase都执行完毕后,就会调用$finish来将整个验证平台关掉。如果UVM发现此phase没有提起任何objection,那么将会直接跳转到下一个phase中。
UVM的设计哲学就是全部由sequence来控制激励生成,因此一般情况下只在sequence中控制objection。另外还需注意的是,raise_objection语句必须在main_phase中第一个消耗仿真时间的语句之前。
4.factory机制
factory机制的优势在于其具有重载功能。重载并不是factory机制的发明,只是factory机制的重载与这些重载都不一样。要想使用factory机制的重载功能,必须满足以下要求:
1) 无论是重载的类(parrot)还是被重载的类(bird),都要在定义时注册到factory机制中。
2)
被重载的类(bird)在实例化时,要使用factory机制的方式进行实例化,而不能使用传统的new的方式。
3)
最重要的是,重载的类(parrot)要与被重载的类(bird)有派生关系。重载的类必须派生自被重载的类,被重载的类必须是重载类的父类。
4)
component与object之间互相不能重载。虽然uvm_component是派生自uvm_object,但是这两者根本不能重载。因为,从两者的new参数的函数就可以看出来,二者互相重载时,多出来的一个parent参数会使factory机制无所适从。
当然,factory机制的实现被集成在了一个宏中:uvm_component_utils。这个宏最主要的任务是,将字符串登记在UVM内部的一张表中,这张表是factory功能实现的基础。只要在定义一个新的类时使用这个宏,就相当于把这个类注册到了这张表中。这样,factory机制可以实现:根据一个字符串自动创建一个类的实例,并且调用其中的函数(function)和任务(task),这个类的main_phase就会被自动调用。
5.callback机制
在UVM验证平台中,callback机制最大的用处就是提高验证平台的可重用性。很多情况下,验证人员期望在一个项目中开发的验证平台能够用于另外一个项目。但是,通常来说,完全的重用是比较难实现的,两个不同的项目之间或多或少会有一些差异。如果把两个项目不同的地方使用callback函数来做,而把相同的地方写成一个完整的env,这样重用时,只要改变相关的callback函数,env可完全的重用。
除了提高可重用性外,callback机制还用于构建异常的测试用例,VMM用户会非常熟悉这一点。只是在UVM中,构建异常的测试用例有很多种方式,如factory机制重载,而callback机制只是其中的一种。
6.phase机制
在不同的时间做不同的事情,这就是UVM中phase的设计哲学。但是仅仅划分成phase是不够的,phase的自动执行功能才极大方便了用户。当new语句执行完成后,后边的connect语句肯定就会自动执行。现引入phase概念,将前面的new的部分包裹进build_phase里面,把后边的connect语句包裹进connect_phase里边,很自然的,当build_phase执行结束后就应该自动执行connect_phase。
phase的引入在很大程度上解决了因代码顺序杂乱可能会引起的问题。遵循UVM的代码顺序划分原则(如build_phase做例化工作,connect_phase做连接工作等),可以在很大程度上减少验证平台开发者的工作量,使其从一段杂乱的工作中解脱出来。
UVM中的phase按照其是否消耗仿真时间($time打印出的时间)的特性,可以分成两大类:一类是function_phase,如产生build_phase、connect_phase等,这些phase都不消耗仿真时间,通过函数来实现;另一类是task_phase,如run_phase等,他们消耗仿真时间,通过任务来实现。给DUT施加激励、监测DUT的输出都是在这些phase中完成的。
所有的phase按照以下顺序自上而下自动执行:
build_pase
connect_phase
end_of_elaboration_phase
start_of_simulation_phase
*run_pase*
extract_phase
check_phase
report_phase
final_phase
其中,*run_phase*按照以下顺序自上而下执行:
pre_reset_phase
reset_phase
post_reset_phase
pre_configure_phase
configure_phase
post_configure_phase
pre_main_phase
main_phase
post_main_phase
pre_shutdown_phase
shutdown_phase
post_shutdown_phase
7.sequence机制
sequence机制用于产生激励,它是UVM中最重要的机制之一。sequence机制有两大组成部分:sequence和sequencer。在整个验证平台中sequence处于一个比较特殊的位置。sequence不属于验证平台的任何一部分,但是它与sequencer之间有着密切的关系。只有在sequencer的帮助下,sequence产生的transaction才能最终送给driver;同样,sequencer只有在sequence出现的情况下才能体现出其价值,如果没有sequence,sequencer几乎没有任何作用。除此之外,sequence与sequencer还有显著的区别。从本质上说,sequencer是一个uvm_component,而sequence是一个uvm_object。与my_transaction一样,sequence也有其生命周期。它的生命周期比my_transaction要更长一点,其内部的transaction全部发送完毕后,它的生命周期也就结束了。
8.通信机制TLM1.0
UVM中,通常使用TLM(Transaction Level
Modeling)实现component之间transaction级别的通信。TLM现在已经发展到TLM2.0,是对TLM1.0的扩展。但是TLM1.0足以满足大多数完整的验证平台的通信要求,所以主要学习TLM1.0。关于TLM1.0通信机制,后续将会详细介绍。