SystemVerilog:使用变量创建压缩数组

时间:2015-12-23 14:37:21

标签: arrays task system-verilog

我想创建一个在SystemVerilog中执行以下操作的任务:

  1. 接收3个输入参数和1个输出参数。
  2. 随机化数据并将数据分配给位变量(输出参数)。

    1. task rand_wr_data(input int size, int data_range_hi, int data_range_lo, output bit [31:0] data);
    2.     bit unsigned [(size - 1):0] rand_data_bits;
    3.     bit unsigned [(data_range_hi - data_range_lo):0] wr_data_bits;
    4.    
    5.     int unsigned rand_data = $urandom();
    6.     wr_data_bits = rand_data;
    7.     data = wr_data_bits << (data_range_lo + 1);
    8. endtask: rand_data
    
  3. 上面的代码会给我一个错误,因为第2行和第3行的非常量表达式错误,因此我在声明数组的范围时使用常量。我尝试过以下但无济于事。

        [parameter | localparam | const] int data_size = size;
    

    因此,我有几个问题如下:

    1. 有没有办法使用我的代码中的变量创建一个打包数组?
    2. 还有其他办法可以做我想做的事吗?
    3. 我可以接收可变大小的数组作为任务参数,而不是必须声明其大小的数组吗?
    4. 在我的代码的第6行中,我想将一个unsigned int分配给一个32位数组,但之后我会收到不同的结果。我怎么能做到这一点?
    5. 谢谢。

1 个答案:

答案 0 :(得分:3)

参考错误:非常量表达。所有压缩变量大小必须在编译时中定义。但是在这里,您提供的运行时大小不是可行的。从此以后就出错了。

可能有一些有用且不那么有用的解决方法如下:

声明sizedata_range_hidata_range_lo作为参数。由于参数编译/详细时间期间被评估,因此这将起作用。但是您无法在运行时直接更改这些参数。

task rand_wr_data ( output bit [31:0] data);
  parameter int size=8, data_range_hi=8,data_range_lo=0;
  bit unsigned [(size - 1):0] rand_data_bits;

作为替代方案和有效方式,请参阅SystemVerilog LRM 1800-2012第13.8节:

  

参数化子程序允许用户一般性地指定或定义实现。当使用该子例程时,可以提供完全定义其行为的参数。这样只允许一个定义 编写维护而不是多个子例程,具有不同的数组大小,数据类型和可变宽度。

以下段落:

  

实现参数化子程序的方法是在参数化类中使用静态方法(见8.10和8.25)。

     

可以将该类声明为虚拟,以便阻止对象构建并强制执行方法的严格静态用法

您可以在其中创建参数化的virtual类和static任务。使用范围解析运算符::)和参数覆盖来调用此任务。可以按如下方式完成:

virtual class wrapper #(parameter int size=8, int data_range_hi=8, int data_range_lo=0);
 static task rand_wr_data(output bit [31:0] data);
 bit unsigned [(size - 1):0] rand_data_bits;
 // ...
 // ...
 endtask
endclass
// ...
// in some module/class, call task
wrapper #(16,8,0)::rand_wr_data (a);
// ...

将类声明为virtual可确保不能为该类创建任何对象。 LRM第13.8节中给出的示例也可能有用。

一个工作示例是在EDAPlayground here

提出您的问题

  

有没有办法使用我的代码中的变量创建一个打包数组?

是的,如上所述。

  

还有其他办法可以做我想做的事吗?

可能还有其他方法,例如define指令可以由用户在运行时设置,但它们在整个模拟中保持不变。

  

我可以接收可变大小的数组作为任务参数而不是必须声明其大小的数组吗?

是的,如上所述。

  

在我的代码的第6行中,我想将一个unsigned int分配给一个32位数组,但之后会收到不同的结果。我怎么能做到这一点?

位是默认值unsigned,因此无需声明bit unsigned,只需bit即可;但那不是问题。此处的问题似乎wr_data_bits定义为bit unsigned [(data_range_hi - data_range_lo):0] wr_data_bits;,而rand_data定义为int unsigned rand_data。两者的大小可能变化

如果您将31作为(data_range_hi - data_range_lo)传递,则值将匹配。给定的示例代码链接显示相等的值。

wr_data_bits = 5e23536 rand_data = 5e23536

我试过谷歌搜索但没有找到太多信息。有关更多信息,请参阅this链接。