2015-02-04 40 views
4

是否可以將type參數傳遞給函數,以便create_eclass*函數只能通過將類類型參數傳遞給函數來寫入一次?將「type」參數傳遞給函數

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 

回答

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 
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,詳細解釋了這個工廠模式代碼的更多內容。

+0

是的。我只將UVM連接放入,因爲您已將其標記。 –