1

this topic has a similar question like mine. But they don't figured out any solution.

I have defined a class with subclasses. The subclass contains a vector, which width should be different in the array.

array[0] class with subclasses and vector width 32

array[1] class with subclasses and vector width 64

array[2] class with subclasses and vector width 128

and so on.

The definition of the class is the same, only the size of the vector differs.

Example

Class-definition:

package classes;

    class subsubclass#(int width);
          logic  [width:0]                  data3;      
    endclass

    class subclass#(int width); 
          subsubclass #(width)              data2 = new;
          logic                             auto2;
    endclass 

    class my_class#(int width);
          subclass #(width)                 data1 = new;
          logic                             auto1;      
    endclass

endpackage

Testbench:

my_class#(32) my_array [0:5];

initial begin
        int x;
        for (int x=0; x<6; x++) begin
           my_array[x] = new;       
        end
end

In this situation i am creating an array of classes with same width. How can i change this? I tried various things, but i can't figure out if there is a solution.

for e.g.   
    my_array[0].subclass.subsubclass.data3 
    and 
    my_array[1].subclass.subsubclass.data3

should differ. But how? And yes in need it with an array because of using it later in many for loops.

update#1 @dave_59

simplified Class-definition:

virtual class base;
    pure virtual function logic [511:0] get_data();
    pure virtual function int getwidth();
endclass

 class my_class#(int width) extends base;
    logic                                   auto;
    logic  [width:0]                        data; 
    virtual function logic [511:0] get_data();
              return data;
    endfunction
    virtual function int getwidth(); 
             return width; 
    endfunction
endclass

base  my_array [0:4];

Testbench:

    initial begin
           my_array[0] = my_class#(16)::new;     
           my_array[1] = my_class#(8)::new;     
           my_array[2] = my_class#(64)::new;     
           my_array[3] = my_class#(128)::new;     
           my_array[4] = my_class#(256)::new;
    end

I tried different definitions: test0, test1 and test2. I got an error that "my_array" is an unkown type. Any idea how to fix it? :)

my_array[0] test0; // or
my_array    test1; // or
my_array[0].get_data() test2;

update#2 @dave_59

    package classes;

    class subsubclass#(int width);
       logic  [width-1:0]                  data3 = '1;      
    endclass

    class subclass#(int width); 
       subsubclass #(width)              data2 = new;
       logic                             auto2;
    endclass 

       virtual               class base;
          pure virtual function logic [511:0] get_data();
       pure virtual function int get_width();
    endclass

    class my_class#(int width) extends base;
       logic                 auto;
       subclass#(width)          data1 = new;

       virtual               function logic [511:0] get_data();
          return data1.data2.data3;
       endfunction
       virtual               function int get_width(); 
          return width; 
       endfunction
    endclass

    endpackage : classes

Testbench

       module top;

       import classes::*;
       base  my_array [0:4];

        initial begin
               my_array[0] = my_class#(16)::new;     
               my_array[1] = my_class#(8)::new;     
               my_array[2] = my_class#(64)::new;     
               my_array[3] = my_class#(128)::new;     
               my_array[4] = my_class#(256)::new;
           foreach(my_array[i]) $display("i: %0d, width:%0d, data3:%0h",
                         i, my_array[i].get_width(), my_array[i].get_data());
        end

my_array[0].data1.auto2 = 1;

    endmodule : top

How can i set for example a "1" for auto? I tried

my_array[0].data1.auto2 = 1;

It would be nice because i need to do some looped assignments.

I can't expand the subclasses in modelsim.

I got this error

near "[": syntax error, unexpected '[', expecting IDENTIFIER or TYPE_IDENTIFIER

update#3

class package simplified

package classes;    
    class subclass#(int width); 

    logic  [width-1:0]                  data2 = '1; 

    endclass 

    virtual class base;

        logic                   auto2;
        logic                   auto;
        pure virtual function logic [511:0] get_data();
        pure virtual function int get_width();

    endclass

    class my_class#(int width) extends base;

       subclass#(width)          data1 = new;

       virtual               function logic [511:0] get_data();
          return data1.data2;
       endfunction
       virtual               function int get_width(); 
          return width; 
       endfunction
    endclass
endpackage : classes

Testbench

module top;
  import classes::*;  
  base  my_array [0:4];

        initial begin
               my_array[0] = my_class#(2)::new;     
               my_array[1] = my_class#(4)::new;     
               my_array[2] = my_class#(8)::new;     
               my_array[3] = my_class#(16)::new;     
               my_array[4] = my_class#(32)::new;
        end


        genvar x;
        int temp [4:0] = {3500, 600, 200, 10, 3};

        generate  

            for (x=0; x<5; x++) begin 

                assign my_array[x].data1.data2 = temp[x];

            end
        endgenerate
endmodule : top

The assignment for every data2 is just an example, but it should visualize what i am looking for. My target is to have an array of the same class but with a different data width. Later i want to access for assignments via for loops (see above). Now i can expand the hierarchy but still can't access it like "my_array[x]. ..." (screenshot of modelsim). Is there any way to access the parameterized "data" and set assignments?

I got this error: Field/method name (data1) not in 'my_array'

update#4 (edit: question/problem fixed)

class package simplified

    package classes;    
class subclass#(int width); 

logic  [width-1:0]                  data2; 

endclass 

virtual class base;


    logic                   auto2;
    logic                   auto;
    pure virtual function logic [511:0] get_data();
    pure virtual function int get_width();
    pure virtual task  set_data(int i);

endclass

class my_class#(int width) extends base;

   subclass#(width)          data1 = new;

   virtual               function logic [511:0] get_data();
      return data1.data2;
   endfunction

   virtual               function int get_width(); 
      return width; 
   endfunction

  virtual task set_data(int i); 
        data1.data2 = i;
  endtask


endclass
    endpackage : classes

Testbench

 module top;
      import classes::*;  
      base  my_array [0:4];

            initial begin
                   my_array[0] = my_class#(2)::new;     
                   my_array[1] = my_class#(4)::new;     
                   my_array[2] = my_class#(8)::new;     
                   my_array[3] = my_class#(16)::new;     
                   my_array[4] = my_class#(32)::new;

                   my_array[0].set_data(2);
                   my_array[1].set_data(4);
                   my_array[2].set_data(6);
                   my_array[3].set_data(8);
                   my_array[4].set_data(10);
            end

       /*   
            genvar x;
            int temp [4:0] = {3500, 600, 200, 10, 3};

             generate  

                for (x=0; x<5; x++) begin 

                    assign my_array[x].data1.data2 = temp[x];

                end
            endgenerate
 */
    endmodule : top

I have updated my (simplified) example with a task to set the data in data2. Inside the inital begin block are the calls of the task for whole array. I don't get any error messages but the problem is, that the data is not set. After the compilation and simulation the values of data2 are still zero. Suggestions? Edit: Mistake was using "logic" instead of "integer" at the class task.

1 Answer 1

3

You need to create a common base class variable that can store handles to the different class specializations with different width parameters. Then you need to have a pure virtual method in the base class that returns a common type for accessing data3, perhaps the maximum size of width expected. You can do this with the top level class

virtual class base;
  pure virtual function logic [63:0] get_data3();
  pure virtual function int getwidth();
endclass
class my_class#(int width) extends base;
      subclass #(width)                 data1 = new;
      logic                             auto1;   
      virtual function logic [63:0] get_data3();
          return data1.data2.data3;
      endfunction
      virtual function int getwidth(); return width; endfunction
endclass
base  my_array [0:5];
initial begin
           my_array[0] = my_class#(32)::new;     
           my_array[1] = my_class#(32)::new;     
           my_array[2] = my_class#(8)::new;     
           my_array[3] = my_class#(8)::new;     
           my_array[4] = my_class#(8)::new;     
           ...

Now you can refer to my_array[0].get_data3() and my_array[4].get_data3() and the data3 value will be right justified. There is a lot of other ways you could return the data, like a dynamic stream of bits or bytes.

Instead of extending the top level class, you could also just create a base class for the subsubclass. Then you dont have to parameterize my_class and subclass, unless of course those classes need the width.

Here is a complete, self-contained example

package classes;

class subsubclass#(int width);
   logic  [width-1:0]                  data3 = '1;      
endclass

class subclass#(int width); 
   subsubclass #(width)              data2 = new;
   logic                             auto2;
endclass 

   virtual               class base;
      pure virtual function logic [511:0] get_data();
   pure virtual function int get_width();
endclass

class my_class#(int width) extends base;
   logic                 auto;
   subclass#(width)          data1 = new;

   virtual               function logic [511:0] get_data();
      return data1.data2.data3;
   endfunction
   virtual               function int get_width(); 
      return width; 
   endfunction
endclass

endpackage : classes

   module top;

   import classes::*;
   base  my_array [0:4];

    initial begin
           my_array[0] = my_class#(16)::new;     
           my_array[1] = my_class#(8)::new;     
           my_array[2] = my_class#(64)::new;     
           my_array[3] = my_class#(128)::new;     
           my_array[4] = my_class#(256)::new;
       foreach(my_array[i]) $display("i: %0d, width:%0d, data3:%0h",
                     i, my_array[i].get_width(), my_array[i].get_data());
    end
endmodule : top
Sign up to request clarification or add additional context in comments.

12 Comments

Thank you for the quick response. I got an error Class 'my_class' is parameterized. Parameterized nested classes currently not supported. Should be there a "endclass" before or after "base my_array [0:5];"?
If fixed the example. I had duplicated class my_class lines.
Ok i already figured the typo out, thanks. I've updated my example in my first message, but i got a "unkown type" error (see above). Suggestions?
It always helps to provide a complete, self-contained example.
Ok thank you. I have updated my first post. How can i set up e.g. the logic auto2 as "1" of my_array[0]? Like this: my_array[0].data1.auto2 = 1 (see above);
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.