将 "type" 参数传递给函数

Passing "type" argument to functions

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

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

是的,您可以通过创建一个对象来完成此操作,该对象充当您要创建的类型的代理。这种代码模式在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

我有 a paper 详细解释了这个工厂模式代码。

我的一位同事提出的解决方案与 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