[CU]factory机制4-factory机制重载的前提,方式,复杂重载,常用重载(factory机制重载)

1. factory机制重载的前提

(1) 无论是重载的类(extended class)还是被重载的类(base class),都要在定义时注册到factory机制中.

(2) 被重载的类(base class)在实例化时,需要使用factory机制式的实例化方式,而不是传统的new方式.

(3) 重载的类与被重载的类有派生关系. 重载的类必须派生自被重载的类,被重载的类必须是重载类的父类.

(4) component与object之间互相不能重载(二者new函数的参数也不同).

注1:重载语句一定要放在例化之前,注意build_phase中重载语句与例化语句的先后顺序;

2. factory机制重载的方式

2.1. 代码中重载

2.1.1 使用uvm_component内的重载函数

(1) set_type_override_by_type

1 function void uvm_component::set_type_override_by_type (uvm_object_wrapper original_type,
2                                                         uvm_object_wrapper override_type,
3                                                         bit    replace=1);
4   uvm_coreservice_t cs = uvm_coreservice_t::get();                                                     
5   uvm_factory factory=cs.get_factory();
6    factory.set_type_override_by_type(original_type, override_type, replace);
7 endfunction 
 1 //示例
 2 class my_component extends uvm_component;
 3     my_driver driver;
 4     ...
 5     virtual function void build_phase(uvm_phase phase);
 6         super.build_phase(phase);
 7         driver=new("driver",this); //new函数实例方式不能实现覆盖;
 8         ...
 9     endfunction
10 
11 endclass
12 
13 class my_component extends uvm_component;
14     my_driver driver;
15     ...
16     virtual function void build_phase(uvm_phase phase);
17         super.build_phase(phase);
18         driver=my_driver::type_id::create("driver",this);
19         ...
20     endfunction
21 
22 endclass
23 
24 class new_driver extends my_driver;
25     ...//add more functionality here;
26 endclass
27 
28 //test.sv or env.sv
29 virtual function void build_phase(uvm_phase phase);
30     super.build_phase(phase);
31     set_type_override_by_type(my_driver::get_type(), new_driver::get_type());
32 endfunction

(2) set_type_override

1 function void uvm_component::set_type_override (string original_type_name,
2                                                 string override_type_name,
3                                                 bit    replace=1);
4    uvm_coreservice_t cs = uvm_coreservice_t::get();                                                     
5    uvm_factory factory=cs.get_factory();
6    factory.set_type_override_by_name(original_type_name,override_type_name, replace);
7 endfunction 

(3) set_inst_override_by_type

 1 function void uvm_component::set_inst_override_by_type (string relative_inst_path,  
 2                                                         uvm_object_wrapper original_type,
 3                                                         uvm_object_wrapper override_type);
 4   string full_inst_path;
 5   uvm_coreservice_t cs = uvm_coreservice_t::get();                                                     
 6   uvm_factory factory=cs.get_factory();
 7 
 8   if (relative_inst_path == "")
 9     full_inst_path = get_full_name();
10   else
11     full_inst_path = {get_full_name(), ".", relative_inst_path};
12 
13   factory.set_inst_override_by_type(original_type, override_type, full_inst_path);
14 
15 endfunction

注1:注意transaction的层次路径;

 1 //示例
 2 class test_da_3_inst extends test_base;
 3     //utils and constructor not shown;
 4     virtual function void build_phase(uvm_phase phase);
 5         super.build_phase(phase);
 6         //set_inst_override("env.i_agent*.seqr.*","transaction","packet_da_3");
 7         set_inst_override_by_type("env.i_agent*.seqr.*",transaction::get_type(),packet_da_3::get_type());
 8     endfunction
 9 
10 endclass

(4) set_inst_override

 1 function void  uvm_component::set_inst_override (string relative_inst_path,  
 2                                                  string original_type_name,
 3                                                  string override_type_name);
 4   string full_inst_path;
 5   uvm_coreservice_t cs = uvm_coreservice_t::get();                                                     
 6   uvm_factory factory=cs.get_factory();
 7 
 8   if (relative_inst_path == "")
 9     full_inst_path = get_full_name();
10   else
11     full_inst_path = {get_full_name(), ".", relative_inst_path};
12 
13   factory.set_inst_override_by_name(
14                             original_type_name,
15                             override_type_name,
16                             full_inst_path);
17 endfunction 

2.1.2 使用uvm_factory类的重载函数

(1) set_type_override_by_type(uvm_object_wrapper orignial_type, uvm_object_wrapper override_type, bit replace=1)

(2) set_type_override_by_name (string original_type_name, string override_type_name, bit replace=1)

(3) set_inst_override_by_type(uvm_object_wrapper original_type, uvm_object_wrapper override_type, string full_inst_path)

(4) set_inst_override_by_name(string original_type_name, string override_type_name, string full_inst_path)

注1:系统中存在uvm_factory类型的全局变量factory,可以在initial语句中使用如下方式调用:

1 //示例
2 initial begin
3     factory.set_type_override_by_type(bird::get_type(),parrot::get_type());
4 end

2.1.3 使用uvm_component_registry#(T,Tname)/uvm_object_registry#(T,Tname)的set_type_override函数

 1 class uvm_object_registry #(type T=uvm_object, string Tname="<unknown>")
 2                                         extends uvm_object_wrapper;
 3   ...
 4   static function void set_type_override (uvm_object_wrapper override_type,
 5                                           bit replace=1);
 6     uvm_coreservice_t cs = uvm_coreservice_t::get();
 7     uvm_factory factory=cs.get_factory();
 8     factory.set_type_override_by_type(get(),override_type,replace);
 9   endfunction
10   ...
11 endclass
 1 class uvm_component_registry #(type T=uvm_component, string Tname="<unknown>")
 2                                            extends uvm_object_wrapper;
 3   ...
 4   static function void set_type_override (uvm_object_wrapper override_type,
 5                                           bit replace=1);
 6     uvm_coreservice_t cs = uvm_coreservice_t::get();
 7     uvm_factory factory=cs.get_factory();                                          
 8     factory.set_type_override_by_type(get(),override_type,replace);
 9   endfunction
10   ...
11 endclas
 1 //示例
 2 class user_agent_base extends uvm_agent;
 3     `uvm_component_utils(user_agent_base)
 4     ...
 5 endclass
 6 
 7 class user_agent extends user_agent_base;
 8     `uvm_component_utils(user_agent)
 9     ...
10 endclass
11 
12 class user_env extends uvm_env;
13     `uvm_component_utils(user_env)
14     user_agent_base agent_base;
15     ...
16     function void build_phase(uvm_phase phase);
17         super.build_phase(.phase(phase));
18         agent_base=user_agent_base::type_id::create("agent_base",this);
19     endfunction
20     ...    
21 endclass
22 
23 class user_test extends uvm_test;
24     `uvm_component_utils(user_test)
25     ...
26 
27     function void build_phase(uvm_phase phase);
28         user_agent_base::type_id::set_type_override(user_agent::get_type());
29         super.build_phase(.phase(phase));
30     endfunction
31 
32 endclass

2.2. 命令行中重载

注1:使用时,不要随意引入空格;

1 <sim cmd> +uvm_set_inst_override=<req_type>,<override_type>,<full_inst_path>
2 <sim cmd> +uvm_set_type_override=<req_type>,<override_type>[,<replace>]

3.factory机制之复杂重载

3.1 连续重载

 1 //示例
 2 class parrot extends bird;
 3 class big_parrot extends parrot;
 4 
 5 function void my_case0::build_phase(uvm_phase phase);
 6     bird   bird_inst;
 7     parrot parrot_inst;
 8     super.build_phase(phase);
 9 
10     set_type_override_by_type(bird::get_type(), parrot::get_type());
11     set_type_override_by_type(parrot::get_type(), big_parrot::get_type());
12 
13     bird_inst=bird::type_id::create("bird_inst");       //big_parrot
14     parrot_inst=parrot::type_id::create("parrot_inst"); //big_parrot
15 endfunction

3.2 替换重载

(1)在有多个重载时,最终重载的类要与最初被重载的类有派生关系. 最终重载的类必须派生自最初被重载的类, 最初被重载的类必须是最终重载类的父类.

 1 //示例
 2 class parrot extends bird;
 3 class sparrow extends bird;
 4 
 5 //example1:
 6 function void my_case0::build_phase(uvm_phase phase);
 7     bird   bird_inst;
 8     parrot parrot_inst;
 9     super.build_phase(phase);
10 
11     set_type_override_by_type(bird::get_type(),parrot::get_type());
12     set_type_override_by_type(bird::get_type(),sparrow::get_type());
13 
14     bird_inst=bird::type_id::create("bird_inst");   //sparrow
15     parrot_inst=parrot::type_id::create("parrot_inst");  //parrot
16 endfunction
17 
18 
19 //example2:
20 function void my_case0::build_phase(uvm_phase phase);
21     bird   bird_inst;
22     parrot parrot_inst;
23     super.build_phase(phase);
24 
25     set_type_override_by_type(bird::get_type(),parrot::get_type());
26     set_type_override_by_type(parrot::get_type(),sparrow::get_type());
27 
28     bird_inst=bird::type_id::create("bird_inst");   //sparrow
29 endfunction

4.factory机制之常用重载

4.1. 重载transaction

 

1 function void my_case0::build_phase(uvm_phase phase);
2 
3     super.build_phase(phase);
4     factory.set_type_override_by_type(my_transaction::get_type(),crc_err_tr::get_type());
5     uvm_config_db#(uvm_object_wrapper)::set(this,"env.i_agt.sqr.main_phase","default_sequence",normal_sequence::type_id::get());
6 
7 endfunction

4.2. 重载sequence

 

 1 class case_sequence extends uvm_sequence #(my_transaction);
 2     ...
 3     virtual task body();
 4         normal_sequence nseq;
 5         repeat(10) begin
 6             `uvm_do(nseq)
 7         end
 8     endtask
 9     ...
10 endclass
11 
12 function void my_case0::build_phase(uvm_phase phase);
13         super.build_phase(phase);
14         factory.set_type_override_by_type(normal_sequence::get_type(), abnormal_sequence::get_type());
15         uvm_config_db#(uvm_object_wrapper)::set(thi,"env.i_agt.sqr.main_phase","default_sequence",case_sequence::type_id::get());
16 
17 endfunction

4.3. 重载component

scoreboard与参考模型等都可以重载;尤其对于参考模型而言,处理异常的激励源是比较耗时的事情; 可能对于一个DUT来说,其80%的代码都是用于处理异常情况,作为模拟DUT的参考模型来说,更是如此;

(1) 如果将所有的异常情况都用一个参考模型实现,那这个参考模型的代码量将会非常大;

(2) 如果将参考模型分散为数十个参考模型,每一个处理一种异常情况,当建立相应异常的测试用例时,将正常的参考模型由它替换掉;这样,可使代码清晰,并增加了可读性;

 

 

 

 

 

 

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

导航