在线咨询
eetop公众号 创芯大讲堂 创芯人才网
切换到宽版

EETOP 创芯网论坛 (原名:电子顶级开发网)

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
楼主: asic_wang

[原创] UVM/OVM中的factory---------个人总结

[复制链接]
 楼主| 发表于 2014-7-13 10:59:48 | 显示全部楼层
既然问题分析了,那就要找出对策了!
    问题在哪里?想一个问题:factory的override map里需要的最根本的信息是什么?没错,那就是类型而非一个具体对象!factory只想知道也只需要知道在我的override map里面有一个条目的含义是类型A需要不需要替换成A的子类,如果有,是A1还是A2还是其它.....我不像知道A里面是什么,有什么,做什么!
     很显然,我们想factory的override map里面注册的东西过于饱含信息量了!叫好比说,我在你家看到你的电视机我很喜欢,我也想去买一个,我其实只想让你告诉[注册]我电视机的型号[类型],但是你却给我这个电视机[对象]让我抱着它去商场里比对这个实物电视去买!不错,我这样是能买到这个牌子的电视机,但是这样做是不是最好的办法呢,显然不是的。
 楼主| 发表于 2014-7-13 11:16:09 | 显示全部楼层
本帖最后由 asic_wang 于 2014-7-13 11:36 编辑

但是systemverilog有一个关键字叫做type,如果我声明以下一条语句:
    type a_type;
    那么我希望能够这样来操作这个a_type变量:
     if(a_type == int)......
     if(a_type == uvm_component).....
     a_type = uvm_object; .......
    它就是type operator,也就是type操作符!
     我么可以使用诸如 var type(uvm_component)  my_component这样的声明语句,也可以使用如下负责的判断语句:

                                                                                                                                                                       
[size=9.000000pt]bit [size=9.000000pt][12:0] A_bus, B_bus;
[size=9.000000pt]parameter type [size=9.000000pt]bus_t = [size=9.000000pt]type[size=9.000000pt](A_bus);
                                       
[size=9.000000pt]case [size=9.000000pt]([size=9.000000pt]type[size=9.000000pt](bus_t))
[size=9.000000pt]type[size=9.000000pt]([size=9.000000pt]bit[size=9.000000pt][12:0]): addfixed_int #(bus_t) (A_bus,B_bus);


[size=9.000000pt]type[size=9.000000pt]([size=9.000000pt]real[size=9.000000pt]): add_float #([size=9.000000pt]type[size=9.000000pt](A_bus)) (A_bus,B_bus);[size=9.000000pt]          endcase                                
                       
               
       
     那就是我们的facotyr中的lookup函数必然会有这样的结构所表达的含义:
     case(type(lookup key))
          type(cpu_bus_driver): .......
          type(tcp_pkt):.......
          type(A):.......
          ........
     endcase
     注意,我指的是用这case语句结构表达的含义的本质,而不是说用case语句来表达!
 楼主| 发表于 2014-7-13 11:58:19 | 显示全部楼层
所以回到那两点问题上来,这两个问题的本质就是:
  (1)注册对象的全局性,换句话说有唯一性的需求;
  (2)信息的必要性,换句话说不要信息过量;
    所以,有一个最普通不过的方法来做就行了,怎么做呢?
  (1)tcp_pkt的“张三”对象你不希望我留着专用,那好,我给tcp_pkt变身一下,再定义一个新的类型叫做tcp_pkt_wrapper,而这个tcp_pkt_wrapper类型不会被任何的用户代码所用到,那么只要我生成一个tcp_pkt_wrapper的singleton不就行了,那么即不会影响用户使用tcp_pkt[你现在可以创建一个对象叫做“张三”等其它任何名字了],也满足唯一性的要求了!
  (2)那么透过tcp_pkt_wrapper能不能也把信息不要过量也一并满足了呢?这个wrapper再合适不过了,为什么?因为sv可以定义参数化的类类型,我把这些tcp_pkt,cpu_bus_driver,A等等作为模版参数传给tcp_pkt_wrapper,cpu_bus_driver_wrapper,A_wrapper.....岂不是很好!
          所以通过sv的type操作符,我们达到了不要信息过量的目的。

    整合上述两点,以tcp_pkt来说,我们只需要定义这样一个wrapper就达到目的了:
    class tcp_pkt_wrapper(type T=tcp_pkt);
    .......实现singleton......
    .......
    enclass
 楼主| 发表于 2014-7-13 14:02:19 | 显示全部楼层
3  UVM/OVM中的factory机制
    上诉的描述已经基本上把一些本质的东西都提及了,太过细节的东西没有必要在分析下去了;那我们就结合UVM中的factory来看看UVM的factory是如何实现的。
  (1)任何user defined 的class都是从uvm_object来
  (2)定义公共的wrapper类,uvm_obect_wrapper,此类的存在是为了提供一个基类,以便作为factory
          override map的lookup key和 lookup value;根本原因是因为每个参数化类都是一个不同的类型,
          如果没有一个公共基类,则无法用一个统一类型的句柄来作为override map的lookup key。
  (3)在(2)的基础上定了模版类 uvm_component_registry和uvm_object_registry,模版参数就是
          user defined的类。
  (4)每一个uvm_component_registry#(T)或uvm_object_registry#(T)都会有一个singleton用来作为user definded类型T的轻量级代理和factory的注册。
  (5)factory有多种override map,用来进行不同override方式的支持,如override by name、override by type、override inst、override type等。
  (6)当我们使用uvm_object_utils/uvm_component_utils的时候,这些宏的重要作用之一就是利用上述机制像uvm_factory中注册,定义变量type_id,定义函数get_type()等。
    看到这里,我最想说的是上述这些就是我对uvm class reference文档里下面这段话的理解,原文是:
”the uvm_object_wrapper provides an abstract interface for creating object and component proxies. Instances of these lightweight proxies, representing every uvm_object-based and uvm_component-based object available in the test environment, are requested with the uvm_factory. When the factory is called upon to create and object or component, it finds and delegates the request to the appropriate proxy.“
发表于 2014-7-14 13:39:49 | 显示全部楼层
override by name的机制很像是依赖查找
发表于 2014-7-14 16:35:33 | 显示全部楼层
为什么说 “cpu_agent.build()之后cpu_agent中的driver又会被重置为cpu_bus_driver而不是new_cpu_bus_driver;” 呢?
我记得是先override,然后再调用super.build_phase()呀。
发表于 2014-7-14 21:27:32 | 显示全部楼层
好帖子!下次讲讲如果是object,如何override
发表于 2014-7-15 08:00:54 | 显示全部楼层
下周五学习就讲这一篇吧,等我回来。
发表于 2014-7-15 17:44:23 | 显示全部楼层
仔细读了一遍,写的太好了。去粗取精,去伪存真,由表及里,由此及彼的典范!
 楼主| 发表于 2014-7-15 19:35:16 | 显示全部楼层
回复 19# yeewang
boss,评价太过了哈,
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

站长推荐 上一条 /3 下一条

小黑屋| 关于我们| 联系我们| 在线咨询| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-4-23 15:37 , Processed in 0.027462 second(s), 6 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
快速回复 返回顶部 返回列表