UVM factory的实际应用

factory其实是对多态的一个扩展。

例子一:

class bird extends uvm_object;
   virtual function void hungry();
      $display("I am a bird, I am hungry");
   endfunction
   function void hungry2();
      $display("I am a bird, I am hungry2");
   endfunction

   `uvm_object_utils(bird)
   function new(string name = "bird");
      super.new(name);
   endfunction 
endclass
class parrot extends bird;
virtual function void hungry();
      $display("I am a parrot, I am hungry");
   endfunction
   function void hungry2();
      $display("I am a parrot, I am hungry2");
   endfunction

   `uvm_object_utils(parrot)
   function new(string name = "parrot");
      super.new(name);
   endfunction 
endclass
class big_parrot extends parrot;
   virtual function void hungry();
      $display("I am a big_parrot, I am hungry");
   endfunction
   function void hungry2();
      $display("I am a big_parrot, I am hungry2");
   endfunction

   `uvm_object_utils(big_parrot)
   function new(string name = "big_parrot");
      super.new(name);
   endfunction 
endclass

set_type_override_by_type的基本用法(一)

class my_case0 extends base_test;

   function new(string name = "my_case0", uvm_component parent = null);
      super.new(name,parent);
   endfunction 
   extern virtual function void build_phase(uvm_phase phase); 
   extern virtual function void print_hungry(bird b_ptr); 
   `uvm_component_utils(my_case0)
endclass

function void my_case0::print_hungry(bird b_ptr);
   b_ptr.hungry();
   b_ptr.hungry2();
endfunction

function void my_case0::build_phase(uvm_phase phase);
   bird bird_inst;
   parrot parrot_inst;
   super.build_phase(phase);
   
   set_type_override_by_type(bird::get_type(), parrot::get_type());
   
   bird_inst = bird::type_id::create("bird_inst");
   parrot_inst = parrot::type_id::create("parrot_inst");
   print_hungry(bird_inst);
   print_hungry(parrot_inst);
endfunction

仿真结果

  • 有关类作为函数参数的相关知识(print_hungry)可以参考:https://www.cnblogs.com/xuqing125/p/15934714.html
  • my_case0其实是从uvm_component中扩展来的,所以可以直接在my_case0里面调用set_type_override_by_type。
  • set_type_override_by_type (uvm_object_wrapper original_type,                                                      uvm_object_wrapper override_type,                                                      bit replace=1)三个参数的类型:第一个和第二个是uvm_object_registry #(bird,"bird")和uvm_object_registry #(parrot,"parrot"),第三个参数replace只会应用在bird多次override的场景下。
  • override语句将会把所有的bird类型替换成parrot类型。内部语法相当于是bird = parrot

set_type_override_by_type的基本用法(二)
修改上述case.

   set_type_override_by_type(bird::get_type(), parrot::get_type());
   set_type_override_by_type(parrot::get_type(), big_parrot::get_type());
   
   bird_inst = bird::type_id::create("bird_inst");
   parrot_inst = parrot::type_id::create("parrot_inst");
   print_hungry(bird_inst);
   print_hungry(parrot_inst);

  • 联想source code,m_type_overrides[]中有两条override的记录,分别是override.original_type = uvm_object_registry #(bird,"bird") override.override_type = uvm_object_registry #(parrot,"parrot") 和override.original_type = uvm_object_registry #(parrot,"parrot") override.override_type = uvm_object_registry #(big_parrot,"big_parrot")
  • bird::type_id::create("bird_inst"),传入的是bird的wrapper,所以find_override_by_type会foreach(m_type_overrides[]),bird->parrot->big_parrot的递归调用find_override_by_type()
  • 所以所有的bird和parrot都会被big_parrot替代。其内部语法的实现bird = big_parrot;parrot = big_parrot

set_type_override_by_type的基本用法(三)
修改上述case

class big_parrot extends bird;
   virtual function void hungry();
      $display("I am a big_parrot, I am hungry");
   endfunction
   function void hungry2();
      $display("I am a big_parrot, I am hungry2");
   endfunction

   `uvm_object_utils(big_parrot)
   function new(string name = "big_parrot");
      super.new(name);
   endfunction 
endclass

   set_type_override_by_type(bird::get_type(), parrot::get_type());
   set_type_override_by_type(bird::get_type(), big_parrot::get_type());
   
   bird_inst = bird::type_id::create("bird_inst");
   parrot_inst = parrot::type_id::create("parrot_inst");
   print_hungry(bird_inst);
   print_hungry(parrot_inst);

仿真结果

  • set_type_override_by_type的第三个参数replace默认为1.
  • 当bird被多次override的时候,replace=1的时候,会把前一次的m_override_types的内容用后一次的刷新。当replace=0的时候,会直接忽略掉这次的override。
set_type_override_by_type(bird::get_type(), parrot::get_type());
set_type_override_by_type(bird::get_type(), big_parrot::get_type(),0);

仿真结果

需要注意的一点是replace的参数仅仅只会在bird第二次以上override的时候才会有作用,如果是第一次override,replace=1/0都没有作用。

//set_type_override_by_type(bird::get_type(), parrot::get_type());
set_type_override_by_type(bird::get_type(), big_parrot::get_type(),0/1);
I am a big_parrot, I am hungry
I am a bird, I am hungry2
I am a parrot, I am hungry
I am a bird, I am hungry2
posted on 2022-04-02 10:50  猪肉白菜_125  阅读(172)  评论(0编辑  收藏  举报