将“type”参数传递给函数

时间:2015-02-04 23:02:49

标签: oop verilog system-verilog uvm

是否可以将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

2 个答案:

答案 0 :(得分: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

此代码的其余部分与原始示例中的代码大致相同。我刚刚通过添加typedef来注册这些类,这会导致object_registry中的静态变量和方法出现。

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详细解释了这个工厂模式代码的更多信息。

答案 1 :(得分:0)

我的一位同事建议这种解决方案类似于戴夫的建议。

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