UVM工厂机制
Posted yuandonghua
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UVM工厂机制相关的知识,希望对你有一定的参考价值。
1、UVM工厂机制作用
在面向对象编程中,工厂机制用来解决类型很多,用户不想知道类型的名字就构造实例的功能。在UVM中,工厂机制其实并不是实现这个功能,应为在使用工厂的时候还是需要使用类型名字。UVM的工厂模式的作用,我认为有以下几点:
(1)、方便component类型生成树形结构
(2)、为object类型和component类型提供override功能
(3)、提供了对象的copy和clone方法
1)、方便component类型生成树形结构
uvm_component也是基层自uvm_object,但是uvm_component的一些特性uvm_object没有0。一是在new的时候指定parent来形成一种树形结构(UVM的树形节点都是component组成的);二是component的phase自动执行。在build_phase中,例化uvm_component对象需要提供一个parent对象来类例化一个component对象(这也是为什么build_phase是top to down的执行顺序),使用工厂机制的话,用户不用关心层次,只把parent的句柄传给factory即可,factory中处理树的构件和例化过程。(这并不是factory威力最大的地方,使用普通的函数也可以实现。)
2)、为object类型和component类型提供override功能
在编写用例的时候通常需要多种激励,也就是需要不同的squence,为了实现不同的用例发送不同的激励,在VMM中是在tc中继承xaction实现一个新的xaction_new,然后把原型传给generator,这样generator就可以根据tc中定义的xaction_new来产生数据包,在UVM中就是使用工厂机制实现了这个功能。方式是在factory中管理了2张表,分别是m_inst_override_quenes和m_type_overrides,overrride信息放在这两个表中,在create的时候查表,看有没有被overrride如果override了就例化override的类型,否则例化原理的类型。
3)、提供了对象的copy和clone方法
2、UVM工厂机制使用
UVM工厂机制的使用要分为3个步骤,其中第二个步骤是可选的:
(1)、注册(register)
UVM的注册是通过宏来实现,且object和component的宏不一样(原因是component注册的时候需要构建树形结构)
object类 `uvm_object_utils(T) `uvm_object_param_utils(T) // 用于参数类的注册,注册的类的Tname=“<unkown” component类 `uvm_component_utils(T) —— driver、monitor、agent、scb、rm、TestCase等 `uvm_component_param_utils(T) // 用于参数类的注册,注册的类的Tname=“<unkown”
`uvm_object_utils(T)示例:
`uvm_component_utils(T)示例:
`uvm_component_param_utils(T)示例:(注册类型带parameter,注册后Tname是默认值“<unknow>”)
(2)、重载(override)
重载的函数分为4种,可以分为两类,set_type是替换原来的所以例化,set_inst则是只替换特定层次下的例化。
// 统一替换
set_type_override_by_type(my_driver::get_type(),new_driver::get_type())。
set_type_override_by_name(“my_driver”,”new_driver”)。
// 只替换指定层次下的类
set_inst_override_by_type(my_driver::get_type(),new_driver::get_type(), “env.agent.drv”)。
set_inst_override_by_name(“my_driver”,”new_driver”,”env.agent.drv”)。
如果是commonet组件,比如说Testcase,可以直接调用uvm_component里面提供的function进行override,但是要注意其输入参数的顺序有的跟uvm_factory会不一样。比如说
由于一般都是在tc下面进行override,且tc是component所以可以只用uvm_component继承过来的set_inset_override_by_type等函数,而不需要是使用uvm_factory的set_inst_override_by_type等函数(如果使用uvm_factory的函数还要先获取一个uvm_factory的对象:uvm_factory::get()获取,这是单例模式)
(3)、例化(create)
使用了工厂模式就必须使用工厂的例化方式,不能使用new的例化方式,否则工厂机制的特性都不能实现。
m_driver = my_driver::type_id::create("my_driver", this);
3、UVM工厂机制实现方式
工厂机制的使用其实就是工厂机制的实现过程,这个部分通过分析内部的实现机制,来理解UVM如何实现工厂机制,还是分为注册、重载、例化三部分来分析。
(1)、注册
UVM的注册是通过宏来实现,以object的注册为例。object的注册有`uvm_object_utils(T)宏,这个宏内部其实还包裹了其他的宏
将uvm_object_utils(T)展开的如下:
其中起到注册功能的是`m_uvm_object_registry_internal(T,T)这个宏,其他的宏的作用是添加到一下函数。下面分析一下`m_uvm_object_registry_internal(T,T)这个宏:
这个宏的第一句就是关键:
typedef uvm_object_registry #(T,`"s`") type_id
这个语句就是往注册类中添加了一个类型成员type_id,加入注册的类是my_driver那么type_id对应的是uvm_object_registry #(my_driver, "my_driver")类,有了这个类就可以调用这个类的静态成员函数比如create()函数,这也是为什么我们例化的语句为my_driver::type_id::create("my_driver",this)的原因。
到这里,我们知道注册的主要作用是往注册类中添加了一个type_id类型成员。
(2)覆盖
的set_inst_override_by_type()是将替换信息放到uvm_factory类的m_inst_override_queues表成员里面。类似的,set_type_override_by_type()是将替换信号放到uvm_factory类的m_type_overrides表成员里面。
这两表中的信息在调用create的时候会查看。
(3)、例化
首先来看下使用create()函数时的调用过程:
调用过程可以看到,通过调用uvm_object_register的create()函数最终会委托给uvm_factory的create相关函数,在掉用uvm_factory的create函数的时候就会查uvm_factory中的m_inst_override_queues和m_type_overrides这两个表,来确定返回实例的类型。查表产生实例的过程如下:
如果类型被override了就返回override的类型成员,如果没有就返回原来类型的成员。
4、Factory支持的命令行参数
+uvm_set_inst_override=<req_type>,<override_type>,<full_inst_pa th> 例如:+uvm_set_inst_override=“my_monitor,new_monitor,uvm_test_top.env.o_agt.mon”
+uvm_set_type_override=<req_type>,<override_type>,<replace> 例如:+uvm_set_type_override=“my_monitor,new_monitor”
5、就factory是否配置正确
(1)通过uvm_top.print_topology()
Testcase的拓扑结构能够通过uvm_top.print_topology()打印出来。通过检查打印出来的log可以检查当前环境中的组件或transaction是否为重载的对象,以判断重载是否正确。uvm_top是uvm_root的一个全局实例,由UVM自动产生的。
比如:
在Testcase中执行uvm_top.print_topology()之后
(2)通过factory.print()
上面的方法会打印出整体环境的树形结构,没有进行factory重载的组件也会被打印出来,log信息繁杂,不利于组件重载的检查。如果只关注factory重载信息,可以使用factory.print()来打印factory的重载信息,以检查重载是否正确。
另外factory.print()可以带参数0,1,2,默认是1。
factory.print(0) : 只打印发生替换的类
factory.print(1)(默认):所有用户自定义并且注册了的类将被打印
factory.print(2) :UVM自身的和用户自定位并注册了的类将被打印
以上是关于UVM工厂机制的主要内容,如果未能解决你的问题,请参考以下文章