How to Make an array of extended class (a list of test)

Hi,

I am trying to make an array of objects (or a list of objects) that are all extended from a base class. Each object is a different test. All common come is in the base class and each test scenario is defined in its extended class. For example:


class CTest;
    string name; 
    virtual cpu_if zcpu; // l'interface CPU

    function new(string name, virtual cpu_if zcpu);
        this.name       = name;
        ...
    endfunction
    
    task processor_startup; // common to all tests

    endtask
    
endclass : CTest

class Test0001 extends CTest;

    function new(virtual cpu_if zcpu);
        super.new("Test0001", zcpu);
    endfunction

    task run();
    endtask
    
endclass
// There are similar test for 0002, 0003, etc.


Then to call a sequence of test, I have to create and run every test in sequence. For example:


  task run_all();
    Test0001 test0001;
    Test0002 test0002;
    Test0003 test0003;

    test0001 = new(zcpu);
    test0001.run();
    log_status(test0001);

    test0002 = new(zcpu);
    test0002.run();
    log_status(test0002);

    test0003 = new(zcpu);
    test0003.run();
    log_status(test0003);
  endtask  

It is pretty repetitive to create a class variable for each of the derived class type to be able to create the object and then call its run method. I’d rather use an array, or a list, something like (in pseudo-code, this won’t compile):


CTest array_of_test[3];
array_of_test[0] = (something to create class object of type Test0001)
array_of_test[1] = (something to create class object of type Test0002)
array_of_test[2] = (something to create class object of type Test0003)

 for i each element in the array 
   begin
     array_of_test[i].run();
     log_status(array_of_test[i]);
   end

Any other structure than an array would do (like a list, queue, etc.) My goal is to reduce the cut-and-paste associated with every new test. Is there a better way of doing this?

Thank you for any advice,
jf

In reply to jflarin:

SystemVerilog has syntax to do exactly this using the class scope operator.

array_of_test[0] = Test0001::new(cpu);
array_of_test[1] = Test0002::new(cpu);
array_of_test[2] = Test0003::new(cpu);

You will also need to make the run task a pure virtual method in your base class.

virtual class CTest;
    string name; 
    virtual cpu_if zcpu; // l'interface CPU
 
    function new(string name, virtual cpu_if zcpu);
        this.name       = name;
        ...
    endfunction
 
    task processor_startup; // common to all tests
 
    endtask
    pure virtual task run;
endclass : CTest

This virtual class CTest is not allowed to be constructed directly, and any extension to it must define a run task.

In reply to dave_59:

Hi Dave,

Thank you for your reply.

This looks like a solution. Sadly, it kills my simulator, which then becomes a tool issue, not a SystemVerilog issue, so not a valid subject for this forum. So I’ll work on the tool and report back as soon as possible.

Thanks again,

jf

In reply to jflarin:

Workaround

class Test0001 extends CTest;
 
    function new(virtual cpu_if zcpu);
        super.new("Test0001", zcpu);
    endfunction
    static function Test0001 create(virtual cpu_if zcpu);
       Test0001 r = new(zcpu)
       return r;
    endfunction

    task run();
    endtask
 
endclass


array_of_test[0] = Test0001::create(cpu);