UVM Primer - UVM基础 - Factory模式

在Factory模式中,我们希望传递一个参数到方法里然后就得到了我们指定的对象。

virtual class animal;
   protected int age=-1;
   protected string name;

   function new(int a, string n);
      age = a;
      name = n;
   endfunction : new

   function int get_age();
      return age;
   endfunction : get_age

   function string get_name();
      return name;
   endfunction : get_name

   pure virtual function void make_sound();

endclass : animal


class lion extends animal;

   bit              thorn_in_paw = 0;

   function new(int age, string n);
      super.new(age, n);
   endfunction : new

   function void make_sound();
      $display ("The lion, %s, says Roar", get_name());
   endfunction : make_sound
   
endclass : lion


class chicken extends animal;

   function new(int age, string n);
      super.new(age, n);
   endfunction : new

   function void make_sound();
      $display ("The Chicken, %s, says BECAWW", get_name());
   endfunction : make_sound


endclass : chicken

class animal_factory;
//静态方法:我们可以在验证平台中任意使用。 //make_animal方法里有两个chicken和lion变量。我们会用这两个来调用构造函数来得到正确的动物类型 static
function animal make_animal(string species, int age, string name); //返回animal变量的函数 chicken chicken; lion lion; case (species) "lion" : begin lion = new(age, name); return lion; //由于函数的返回值是animal,所以返回 lion对象和chicken对象都是可以的 end "chicken" : begin chicken = new(age, name); return chicken; //由于函数的返回值是animal,所以返回 lion对象和chicken对象都是可以的 end default : $fatal (1, {"No such animal: ", species}); endcase // case (species) endfunction : make_animal endclass : animal_factory class animal_cage #(type T=animal); static T cage[$]; static function void cage_animal(T l); cage.push_back(l); endfunction : cage_animal static function void list_animals(); $display("Animals in cage:"); foreach (cage[i]) $display(cage[i].get_name()); endfunction : list_animals endclass : animal_cage module top; initial begin animal animal_h; lion lion_h; chicken chicken_h; bit cast_ok;
//我们在Factory中调用make_animal()来生成一个15岁的木莎法。Factory 用多态来创建了一个狮子并保存在animal_h里。 animal_h
= animal_factory::make_animal("lion", 15, "Mustafa");
//首先我们用animal_h变量调用make_sound()。这个是可以的,因为make_sound()是个虚函数。仿真器会调用lion类的方法,因为animal_h中保存的是狮子对象 animal_h.make_sound(); //要访问lion类独有的数据成员,我们需要把动物成员转换成狮子成员。这个叫做 "casting" cast_ok
= $cast(lion_h, animal_h); if ( ! cast_ok) $fatal(1, "Failed to cast animal_h to lion_h"); if (lion_h.thorn_in_paw) $display("He looks angry!"); animal_cage#(lion)::cage_animal(lion_h);
//系统调用$cast指示仿真器把第二个参数的类型animal类的animal_h转换为第一个参数的类型(lion类的 lion_h),同时进行拷贝。不过这个只在目标类是被转换类的子类时有效。就是说你不能把lion转换成chicken
if (!$cast(lion_h, animal_factory::make_animal("lion", 2, "Simba"))) $fatal(1, "Failed to cast animal from factory to lion_h"); animal_cage#(lion)::cage_animal(lion_h); if(!$cast(chicken_h ,animal_factory::make_animal("chicken", 1, "Clucker"))) $fatal(1, "Failed to cast animal factory result to chicken_h"); animal_cage #(chicken)::cage_animal(chicken_h); if(!$cast(chicken_h, animal_factory::make_animal("chicken", 1, "Boomer"))) $fatal(1, "Failed to cast animal factory result to chicken_h"); animal_cage #(chicken)::cage_animal(chicken_h); $display("-- Lions --"); animal_cage #(lion)::list_animals(); $display("-- Chickens --"); animal_cage #(chicken)::list_animals(); end endmodule : top

 

posted on 2020-02-26 16:38  yiyedada  阅读(205)  评论(0编辑  收藏  举报

导航