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

SystemVerilog: Creating packed arrays using variables

我想创建一个在 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
    

上面的代码将在第 2 行和第 3 行 非常量表达式错误 给我一个错误,因此我必须使用常量来声明数组的范围.我尝试了以下但无济于事。

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

因此,我有以下几点查询:

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

谢谢。

指的是错误:非常量表达式。所有压缩变量大小必须在编译时定义。但是这里您提供的 运行-time 大小不 可行 。从今以后的错误。

可能有一些有用和不太有用的解决方法,如下所示:

sizedata_range_hidata_range_lo 声明为参数。由于 参数 compile/elaboration 时间 期间被 评估,这应该有效。但是你不能在 运行-时间直接更改这些参数。

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 节:

A parameterized subroutine allows the user to generically specify or define an implementation. When using that subroutine one may provide the parameters that fully define its behavior. This allows for only one definition to be written and maintained instead of multiple subroutines with different array sizes, data types, and variable widths.

以及以下段落:

The way to implement parameterized subroutines is through the use of static methods in parameterized classes (see 8.10 and 8.25).

The class may be declared virtual in order to prevent object construction and enforce the strict static usage of the method.

您可以在其中创建参数化的 virtual class 和 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);
// ...

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

工作示例在 EDAPlayground here

回答您的问题:

Is there a way to create a packed array using variables like in my code?

是的,如上所述。

Is there another way to do what I would like to do above?

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

Can I receive variable size array as a task parameter instead of an array that has to have its size declared?

是的,如上所述。

In line 6 of my code, I would like to assign an unsigned int to a 32-bit array but I receive different result after that. How can I accomplish that?

位默认为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) 传递,则值将匹配。给定的示例代码 link 显示相等的值。

wr_data_bits = 5e23536 rand_data = 5e23536

我尝试用谷歌搜索但没有找到太多信息。有关详细信息,请参阅 this link.