4

是否可以将type参数传递给函数,以便create_eclass*函数只能通过将类类型参数传递给它来编写一次?

class bclass;

virtual function void print();
    $display("Base Class");
endfunction

endclass

class eclass1 extends bclass;

    function void print();
        $display("Extended Class1");
    endfunction

endclass

class eclass2 extends bclass;

    function void print();
        $display("Extended Class2");
    endfunction
endclass

program Test ;
    bclass q[$];

    function create_eclass1();
        bclass     b;
        eclass1    e;
        e=new();
        $cast(b,e);
        q.push_back(e);
    endfunction

    function create_eclass2();
        bclass     b;
        eclass2    e;
        e=new();
        $cast(b,e);
        q.push_back(e);
    endfunction

    initial
    begin
        create_eclass1();
        create_eclass2();
        foreach(q[i]) q[i].print();
    end
endprogram
4

2 回答 2

4

是的,您可以通过创建一个充当您要创建的类型的代理的对象来做到这一点。这种代码模式在 UVM 工厂中使用。

typedef bclass; // this would be uvm_object in the UVM

interface class object_wrapper; // like a virtual class except it only contains pure virtual methods
   pure virtual function bclass create;
endclass

class object_registry#(type T) implements object_wrapper;
   typedef object_registry#(T) this_type;
   local static this_type _singleton; // only one object for each class type
   local function new;
   endfunction
   static function object_wrapper get;
      if (_singleton == null) _singleton = new;
      return _singleton;
   endfunction // if
   virtual function T create;
      create = new;
   endfunction
endclass

此代码的其余部分与原始示例中的代码基本相同。我刚刚通过添加导致 object_registry 中的静态变量和方法存在的 typedef 注册了这些类。

class bclass;

   virtual function void print();
      $display("Base Class");
   endfunction

endclass

class eclass1 extends bclass;
   typedef object_registry#(eclass1) type_id;

   function void print();
      $display("Extended Class1");
   endfunction

endclass

class eclass2 extends bclass;
   typedef object_registry#(eclass2) type_id;
   function void print();
      $display("Extended Class2");
   endfunction
endclass

module Test ;
   bclass q[$];

   function void create_eclass(object_wrapper h);
      q.push_back(h.create());
   endfunction

   object_wrapper a1,a2;

   initial
     begin   
        create_eclass(eclass1::type_id::get() );
        create_eclass(eclass2::type_id::get() );
    // or another way - 
    a1 = eclass1::type_id::get();
    a2 = eclass2::type_id::get();
        create_eclass(a1 );
        create_eclass(a2 );
        create_eclass(a2 );
        create_eclass(a1 );

        foreach(q[i]) q[i].print();
     end
endmodule

我有一篇论文详细解释了这个工厂模式代码。

于 2015-02-05T06:34:36.857 回答
0

我的一位同事提出了类似于 Dave 建议的解决方案。

virtual class eclass_creator #( type T = bclass );
  static function T create(int k) ;
    create = new(k) ;
  endfunction
endclass

这允许创建一个作用域构造函数。

class bclass;
    int i;
    function new(int k);
        i=k;    
    endfunction
    virtual function void print();
        $display("Base Class %0d",i);
    endfunction
endclass

class eclass1 extends bclass;
    function new(int k);
        super.new(k);    
    endfunction
    function void print();
        $display("Extended Class1 %0d",i);
    endfunction
endclass

class eclass2 extends bclass;
    function new(int k);
        super.new(k);    
    endfunction
    function void print();
        $display("Extended Class2 %0d",i);
    endfunction
endclass

program Test ;
    bclass q[$];

    function void push(bclass inclass);
       q.push_back(inclass);
    endfunction

    initial
    begin
        push(eclass_creator #(eclass1)::create(5));
        push(eclass_creator #(eclass2)::create(10));
        foreach(q[i]) q[i].print();
    end
endprogram
于 2015-02-11T16:41:31.653 回答