0

I've modified a code block written by dave_59 in this answer to create a pathological case that illustrates my question:

virtual class base;
  ???
endclass
class my_class#(int width) extends base;
      typedef bit [width-1:0] vec_t; 
      virtual function vec_t get_zeros();
          vec_t x = '0;
          return x;
      endfunction
endclass
base  my_array [1:3];
initial begin
           my_array[1] = my_class#(1)::new;     
           my_array[2] = my_class#(2)::new;     
           my_array[3] = my_class#(3)::new;         
           ...

Is there a way to do the above in a loop? Something like this is what I want, although it doesn't work because SV requires class parameters to be statically defined:

    for (int i=1; i<=3; i++)
        my_array[i] = my_class#(i)::new;

I would think a generate block would work, but I'm having trouble figuring out syntax that compiles. I'm also not sure what needs to be in the base class (or if I even need a base class). If I do need a base class, I'm also not clear how it should handle the get_zeros function since that function's return type depends on the parameter.

Craig
  • 855
  • 1
  • 9
  • 14

1 Answers1

1

You should be able to use generate blocks as in the following example:

virtual class base;
   virtual function void  print_wdt();
   endfunction // print_wdt
endclass // base

      
class my_class#(int width) extends base;
   typedef bit [width-1:0] vec_t;
   virtual function void  print_wdt();
      $display("width: %0d", $bits(vec_t));
   endfunction // print_wdt
endclass // my_class


program a;
   base x[*];

   // genblock
   for(genvar i = 1; i < 4; i++) begin
      // need 'initial'
      initial x[i] = my_class#(i)::new();
   end
   
   initial begin
     #1 foreach(x[i]) begin
        x[i].print_wdt;
     end
   end
endprogram // a
Serge
  • 11,616
  • 3
  • 18
  • 28
  • Thank you for the very quick response! Would you be able to update your answer to support the "get_zeros" function I show in my question? Since that function is based on a type that depends on the parameter, I'm not sure how the base class should handle it. – Craig Apr 24 '23 at 17:14
  • @Craig you have not provided full picture of inheritance for this function. So, there is just not enough info for updating. You can replace the *print_wdt* with whatever function you need. – Serge Apr 24 '23 at 18:19
  • I created the base class because it seemed like that was the only way to get the array declared, i.e. `base x[*]`. I don't want inheritance otherwise. When you call x[i].get_zeros, it calls the base class function first because that's the type that X is declared as. But because the return value of get_zeros depends on the parameter, it's not clear that a base class equivalent can be declared. I have since talked to others who think this approach isn't how Verilog was intended to be used, so I'm going to drop it and accept your answer. If you have additional thoughts, though, I'm all ears. – Craig Apr 24 '23 at 18:47
  • 1
    This question is about instantiating a parameterized class. But, for returning parametrized vectors you can use open arrays and ref args in this case: `virtual function void result(ref bit [] res); res = vec; ...` – Serge Apr 24 '23 at 21:11
  • Use `output` arguments not `ref`. Much less restrictive. – dave_59 Apr 25 '23 at 21:25