oopverilogsystem-veriloguvm

Passing "type" argument to functions


Is it possible to pass a type argument to function so that create_eclass* function can only be written once by passing class type argument to it ?

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

Solution

  • A colleague of mine suggested this solution similar to what Dave suggested.

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

    This allows to create a scoped constructor.

    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