2015-02-04 4 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

Мой коллега предложил это решение, подобное тому, что предложил Дейв.

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, потому что вы отметили его. –

 Смежные вопросы

  • Нет связанных вопросов^_^