[CU]factory机制1-factory机制的功能,本质,使用与调试,原理的反思

1.factory机制的功能

(1) factory机制的典型功能是创建类的实例重载.

2.factory机制的本质

(1) factory的本质:重载new函数;

(2) uvm_object/uvm_component的派生类在采用factory机制实例化时,会通过factory机制在内部表格中查找是否有相关的重载记录;如果查到有重载记录,会使用新的类型代替旧的类型;

3.factory机制的使用

(1) 在定义一个类时,需要使用uvm_component_utils/uvm_object_utils等宏进行类的注册,才能使用factory机制的功能;

(2) factory机制仅适用于uvm_object及其派生类和uvm_component及其派生类;

[CU]factory机制2-factory机制之用于类注册的宏(factory机制-注册) - __见贤思齐 - 博客园 (cnblogs.com)

[CU]factory机制3-factory机制创建实例(create_object/component_by_type/name)(factory机制-例化) - __见贤思齐 - 博客园 (cnblogs.com)

[CU]factory机制4-factory机制重载的前提,方式,复杂重载,常用重载(factory机制重载) - __见贤思齐 - 博客园 (cnblogs.com)

4.factory机制的调试

(1) uvm_component.print_override_info

1 function void  uvm_component::print_override_info (string requested_type_name, 
2                                                    string name="");
3   uvm_coreservice_t cs = uvm_coreservice_t::get();                                                     
4   uvm_factory factory=cs.get_factory();
5   factory.debug_create_by_name(requested_type_name, get_full_name(), name);
6 endfunction

注1:print_override_info实质上调用的是uvm_factory的debug_create_by_name;

注2:print_override_info的参数对应的应该是原始的类型,而不是新的类型;

注3:在connect_phase,使用被重载类的句柄调用该函数,如:

 1 //my_case0.sv
 2 function void my_case0::build_phase(uvm_phase phase);
 3     ***
 4     set_inst_override_by_type("evn.o_agt.mon",my_monitor::get_type(),new_monitor::get_type());
 5     ***
 6 endfunction
 7 
 8 function void my_case0::connect_phase(uvm_phase phase);
 9     super.connect_phase(phase);
10     env.o_agt.mon.print_override_info("my_monitor");
11     ***
12 endfunction

(2) uvm_factory.print()

注1:该函数只有一个参数,其取值可能为0,1或2;

注2:当其参数为0时,仅仅打印被重载的实例和类型;

注3:当其参数为1时,打印参数为0时的信息,以及用户创建的并注册到factory的所有类的名称;

注4:当其参数为2时,打印参数为1时的信息,以及系统创建的并注册到factory的所有类的名称;

注5:uvm_factory::print()应该放置在override语句后面;

(3) uvm_top.print_topology();

注1:该函数没有参数;

注2:该函数显示整颗UVM树的拓扑结构,而UVM树在build_phase执行完成后才完全建立完成,因此该函数需要置于build_phase后的其他phase调用;

注3:该函数通常会置于所有测试用例的基类base_test中;

5.factory机制原理的反思

为什么在factory机制中引入uvm_object_registry #(type T=uvm_object, string Tname=”<unknown>”)以及uvm_component_registry #(type T=uvm_component, string Tname=”<unknown>”)?

(1) factory机制的核心是联合数组-m_type_names,其索引是string类型的,其存储的内容是uvm_object_wrapper类型的;

(2) 在system verilog中,往任何数组或queue中存放内容,存放的通常是值,而不是一个类型;类是一个抽象的概念,不可能存放在一个数组里面;

  1 class uvm_object_registry #(type T=uvm_object, string Tname="<unknown>")
  2                                         extends uvm_object_wrapper;
  3   typedef uvm_object_registry #(T,Tname) this_type;
  4 
  5   // Function: create_object
  6   //
  7   // Creates an object of type ~T~ and returns it as a handle to a
  8   // <uvm_object>. This is an override of the method in <uvm_object_wrapper>.
  9   // It is called by the factory after determining the type of object to create.
 10   // You should not call this method directly. Call <create> instead.
 11 
 12   virtual function uvm_object create_object(string name="");
 13     T obj;
 14 `ifdef UVM_OBJECT_DO_NOT_NEED_CONSTRUCTOR
 15     obj = new();
 16     if (name!="")
 17       obj.set_name(name);
 18 `else
 19     if (name=="") obj = new();
 20     else obj = new(name);
 21 `endif
 22     return obj;
 23   endfunction
 24 
 25   const static string type_name = Tname;
 26 
 27   // Function: get_type_name
 28   //
 29   // Returns the value given by the string parameter, ~Tname~. This method
 30   // overrides the method in <uvm_object_wrapper>.
 31 
 32   virtual function string get_type_name();
 33     return type_name;
 34   endfunction
 35 
 36   local static this_type me = get();
 37 
 38   // Function: get
 39   //
 40   // Returns the singleton instance of this type. Type-based factory operation
 41   // depends on there being a single proxy instance for each registered type. 
 42 
 43   static function this_type get();
 44     if (me == null) begin
 45       uvm_coreservice_t cs = uvm_coreservice_t::get();                                                     
 46       uvm_factory factory=cs.get_factory();
 47       me = new;
 48       factory.register(me);
 49     end
 50     return me;
 51   endfunction
 52 
 53 
 54   // Function: create
 55   //
 56   // Returns an instance of the object type, ~T~, represented by this proxy,
 57   // subject to any factory overrides based on the context provided by the
 58   // ~parent~'s full name. The ~contxt~ argument, if supplied, supersedes the
 59   // ~parent~'s context. The new instance will have the given leaf ~name~,
 60   // if provided.
 61 
 62   static function T create (string name="", uvm_component parent=null,
 63                             string contxt="");
 64     uvm_object obj;
 65     uvm_coreservice_t cs = uvm_coreservice_t::get();                                                     
 66     uvm_factory factory=cs.get_factory();
 67   
 68     if (contxt == "" && parent != null)
 69       contxt = parent.get_full_name();
 70     obj = factory.create_object_by_type(get(),contxt,name);
 71     if (!$cast(create, obj)) begin
 72       string msg;
 73       msg = {"Factory did not return an object of type '",type_name,
 74         "'. A component of type '",obj == null ? "null" : obj.get_type_name(),
 75         "' was returned instead. Name=",name," Parent=",
 76         parent==null?"null":parent.get_type_name()," contxt=",contxt};
 77       uvm_report_fatal("FCTTYP", msg, UVM_NONE);
 78     end
 79   endfunction
 80 
 81 
 82   // Function: set_type_override
 83   //
 84   // Configures the factory to create an object of the type represented by
 85   // ~override_type~ whenever a request is made to create an object of the type
 86   // represented by this proxy, provided no instance override applies. The
 87   // original type, ~T~, is typically a super class of the override type. 
 88 
 89   static function void set_type_override (uvm_object_wrapper override_type,
 90                                           bit replace=1);
 91     uvm_coreservice_t cs = uvm_coreservice_t::get();
 92     uvm_factory factory=cs.get_factory();
 93     factory.set_type_override_by_type(get(),override_type,replace);
 94   endfunction
 95 
 96 
 97   // Function: set_inst_override
 98   //
 99   // Configures the factory to create an object of the type represented by
100   // ~override_type~ whenever a request is made to create an object of the type
101   // represented by this proxy, with matching instance paths. The original
102   // type, ~T~, is typically a super class of the override type.
103   //
104   // If ~parent~ is not specified, ~inst_path~ is interpreted as an absolute
105   // instance path, which enables instance overrides to be set from outside
106   // component classes. If ~parent~ is specified, ~inst_path~ is interpreted
107   // as being relative to the ~parent~'s hierarchical instance path, i.e.
108   // ~{parent.get_full_name(),".",inst_path}~ is the instance path that is
109   // registered with the override. The ~inst_path~ may contain wildcards for
110   // matching against multiple contexts.
111 
112   static function void set_inst_override(uvm_object_wrapper override_type,
113                                          string inst_path,
114                                          uvm_component parent=null);
115     string full_inst_path;
116     uvm_coreservice_t cs = uvm_coreservice_t::get();                                                     
117     uvm_factory factory=cs.get_factory();
118     
119     if (parent != null) begin
120       if (inst_path == "")
121         inst_path = parent.get_full_name();
122       else
123         inst_path = {parent.get_full_name(),".",inst_path};
124     end
125     factory.set_inst_override_by_type(get(),override_type,inst_path);
126   endfunction
127 
128 endclass
  1 class uvm_component_registry #(type T=uvm_component, string Tname="<unknown>")
  2                                            extends uvm_object_wrapper;
  3   typedef uvm_component_registry #(T,Tname) this_type;
  4 
  5 
  6   // Function: create_component
  7   //
  8   // Creates a component of type T having the provided ~name~ and ~parent~.
  9   // This is an override of the method in <uvm_object_wrapper>. It is
 10   // called by the factory after determining the type of object to create.
 11   // You should not call this method directly. Call <create> instead.
 12 
 13   virtual function uvm_component create_component (string name,
 14                                                    uvm_component parent);
 15     T obj;
 16     obj = new(name, parent);
 17     return obj;
 18   endfunction
 19 
 20 
 21   const static string type_name = Tname;
 22 
 23   // Function: get_type_name
 24   //
 25   // Returns the value given by the string parameter, ~Tname~. This method
 26   // overrides the method in <uvm_object_wrapper>.
 27 
 28   virtual function string get_type_name();
 29     return type_name;
 30   endfunction
 31 
 32   local static this_type me = get();
 33 
 34 
 35   // Function: get
 36   //
 37   // Returns the singleton instance of this type. Type-based factory operation
 38   // depends on there being a single proxy instance for each registered type. 
 39 
 40   static function this_type get();
 41     if (me == null) begin
 42         uvm_coreservice_t cs = uvm_coreservice_t::get();                                                     
 43         uvm_factory factory=cs.get_factory();
 44       me = new;
 45       factory.register(me);
 46     end
 47     return me;
 48   endfunction
 49 
 50 
 51   // Function: create
 52   //
 53   // Returns an instance of the component type, ~T~, represented by this proxy,
 54   // subject to any factory overrides based on the context provided by the
 55   // ~parent~'s full name. The ~contxt~ argument, if supplied, supersedes the
 56   // ~parent~'s context. The new instance will have the given leaf ~name~
 57   // and ~parent~.
 58 
 59   static function T create(string name, uvm_component parent, string contxt="");
 60     uvm_object obj;
 61     uvm_coreservice_t cs = uvm_coreservice_t::get();                                                     
 62     uvm_factory factory=cs.get_factory();
 63     if (contxt == "" && parent != null)
 64       contxt = parent.get_full_name();
 65     obj = factory.create_component_by_type(get(),contxt,name,parent);
 66     if (!$cast(create, obj)) begin
 67       string msg;
 68       msg = {"Factory did not return a component of type '",type_name,
 69         "'. A component of type '",obj == null ? "null" : obj.get_type_name(),
 70         "' was returned instead. Name=",name," Parent=",
 71         parent==null?"null":parent.get_type_name()," contxt=",contxt};
 72       uvm_report_fatal("FCTTYP", msg, UVM_NONE);
 73     end
 74   endfunction
 75 
 76 
 77   // Function: set_type_override
 78   //
 79   // Configures the factory to create an object of the type represented by
 80   // ~override_type~ whenever a request is made to create an object of the type,
 81   // ~T~, represented by this proxy, provided no instance override applies. The
 82   // original type, ~T~, is typically a super class of the override type. 
 83 
 84   static function void set_type_override (uvm_object_wrapper override_type,
 85                                           bit replace=1);
 86     uvm_coreservice_t cs = uvm_coreservice_t::get();
 87     uvm_factory factory=cs.get_factory();                                          
 88     factory.set_type_override_by_type(get(),override_type,replace);
 89   endfunction
 90 
 91 
 92   // Function: set_inst_override
 93   //
 94   // Configures the factory to create a component of the type represented by
 95   // ~override_type~ whenever a request is made to create an object of the type,
 96   // ~T~, represented by this proxy,  with matching instance paths. The original
 97   // type, ~T~, is typically a super class of the override type.
 98   //
 99   // If ~parent~ is not specified, ~inst_path~ is interpreted as an absolute
100   // instance path, which enables instance overrides to be set from outside
101   // component classes. If ~parent~ is specified, ~inst_path~ is interpreted
102   // as being relative to the ~parent~'s hierarchical instance path, i.e.
103   // ~{parent.get_full_name(),".",inst_path}~ is the instance path that is
104   // registered with the override. The ~inst_path~ may contain wildcards for
105   // matching against multiple contexts.
106 
107   static function void set_inst_override(uvm_object_wrapper override_type,
108                                          string inst_path,
109                                          uvm_component parent=null);
110     string full_inst_path;
111     uvm_coreservice_t cs = uvm_coreservice_t::get();                                                     
112     uvm_factory factory=cs.get_factory();
113     
114     if (parent != null) begin
115       if (inst_path == "")
116         inst_path = parent.get_full_name();
117       else
118         inst_path = {parent.get_full_name(),".",inst_path};
119     end
120     factory.set_inst_override_by_type(get(),override_type,inst_path);
121   endfunction
122 
123 endclass

 

 

 

 

 

 

 

 

 

posted on 2021-10-31 15:23  知北游。。  阅读(328)  评论(0编辑  收藏  举报

导航