SystemVerilog:创建具有不同参数的类数组

时间:2015-06-24 21:08:10

标签: arrays polymorphism subclass system-verilog

this topic has a similar question like mine.但他们没有找到任何解决方案。

我已经定义了一个带有子类的类。子类包含一个向量,该数组的宽度应该不同。

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

等等。

类的定义是相同的,只有向量的大小不同。

实施例

类定义:

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

测试平台:

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

在这种情况下,我正在创建一个宽度相同的类数组。我怎么能改变这个?我尝试了各种各样的东西,但我无法弄清楚是否有解决方案。

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

应该有所不同。但是怎么样? 是的,需要它与数组,因为稍后在许多for循环中使用它。

更新#1 @ dave_59

简化的类定义:

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];

测试平台:

    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

我尝试了不同的定义:test0,test1和test2。我收到了一个错误&#34; my_array&#34;是一种未知的类型。知道怎么解决吗? :)

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

更新#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

测试平台

       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

我如何设置例如&#34; 1&#34;对于汽车? 我试过了

my_array[0].data1.auto2 = 1;

这很好,因为我需要做一些循环任务。

我无法在modelsim中扩展子类。

我收到了这个错误

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

更新#3

类包简化

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

测试平台

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

每个data2的分配只是一个例子,但它应该可视化我正在寻找的东西。我的目标是拥有一个相同类但具有不同数据宽度的数组。后来我想通过for循环访问作业(见上文)。现在我可以扩展层次结构,但仍然无法像#34; my_array [x]那样访问它。 ...&#34; (screenshot of modelsim)。有没有办法访问参数化的&#34;数据&#34;并设置作业?

我收到此错误:字段/方法名称(data1)不在&#39; my_array&#39;

更新#4(编辑:问题/问题已解决)

类包简化

    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

测试平台

 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

我更新了我的(简化)示例,其中包含在data2中设置数据的任务。初始开始块内部是整个数组的任务调用。我没有收到任何错误消息,但问题是,数据未设置。在编译和模拟之后,data2的值仍为零。建议? 编辑:错误是使用&#34;逻辑&#34;而不是&#34;整数&#34;在课堂上的任务。

1 个答案:

答案 0 :(得分:1)

您需要创建一个公共基类变量,该变量可以将句柄存储到具有不同宽度参数的不同类专精。然后,您需要在基类中使用纯虚方法,该方法返回用于访问data3的公共类型,可能是预期的最大宽度。您可以使用顶级课程

来完成此操作
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;     
           ...

现在您可以参考my_array[0].get_data3()my_array[4].get_data3(),并且data3值将是正确的。还有很多其他方法可以返回数据,比如动态的位或字节流。

您也可以只创建子类的基类,而不是扩展顶级类。然后你不必参数化my_class和子类,除非这些类当然需要宽度。

这是一个完整的,自包含的示例

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