37

如何在 Verilog 中声明和使用一维和二维字节数组?

例如。如何做类似的事情

byte a_2D[3][3];
byte a_1D[3];

// using 1D
for (int i=0; i< 3; i++)
{
    a_1D[i] = (byte)i;
}

// using 2D
for (int i=0; i< 3; i++)
{
    for (int j=0; j< 3; j++)
    {
        a_2D[i][j] = (byte)i*j;
    }
}
4

3 回答 3

58

Verilog 以位为单位思考,因此reg [7:0] a[0:3]会给您一个 4x8 位数组(=4x1 字节数组)。您可以使用a[0]. 第二个字节的第三位是a[1][2].

对于二维字节数组,首先检查您的模拟器/编译器。旧版本(我相信 '01 之前)将不支持此功能。然后reg [7:0] a [0:3] [0:3]会给你一个二维字节数组。a[2][0][7]例如,可以访问单个位。

reg [7:0] a [0:3];
reg [7:0] b [0:3] [0:3];

reg [7:0] c;
reg d;

initial begin

   for (int i=0; i<=3; i++) begin
      a[i] = i[7:0];
   end

   c = a[0];
   d = a[1][2]; 


   // using 2D
   for (int i=0; i<=3; i++)
      for (int j=0; j<=3; j++)
          b[i][j] = i*j;  // watch this if you're building hardware

end
于 2010-06-10T08:55:17.227 回答
12

除了 Marty 的优秀答案之外,SystemVerilog 规范还提供了byte数据类型。下面声明一个 4x8 位变量(4 个字节),为每个字节分配一个值,然后显示所有值:

module tb;

byte b [4];

initial begin
    foreach (b[i]) b[i] = 1 << i;
    foreach (b[i]) $display("Address = %0d, Data = %b", i, b[i]);
    $finish;
end

endmodule

这打印出来:

Address = 0, Data = 00000001
Address = 1, Data = 00000010
Address = 2, Data = 00000100
Address = 3, Data = 00001000

这在概念上类似于 Marty 的reg [7:0] a [0:3];. 但是,byte它是 2 状态数据类型(0 和 1),而是reg4 状态 (01xz)。使用byte还需要您的工具链(模拟器、合成器等)支持此 SystemVerilog 语法。还要注意更紧凑的foreach (b[i])循环语法。

SystemVerilog 规范支持多种多维数组类型。LRM 可以比我更好地解释它们;请参阅IEEE Std 1800-2005第 5 章。

于 2010-06-10T13:25:19.160 回答
5

实际上很简单,就像 C 编程一样,您只需要在声明时传递右侧的数组索引。但是,是的,对于 4 个元素,语法将类似于 [0:3]。

reg a[0:3]; 

这将创建一个 1D 的单个位数组。类似地,可以像这样创建二维数组:

reg [0:3][0:2];

现在在 C 中假设您创建了一个 int 的 2D 数组,那么它将在内部创建一个 32 位的 2D 数组。但不幸的是,Verilog 是一种 HDL,因此它以位而不是一堆位来思考(尽管 Verilog 中有 int 数据类型),它可以允许您创建任意数量的位来存储在数组元素中(这不是在 C 的情况下,您不能在 C 中的 2D 数组的每个元素中存储 5 位)。因此,要创建一个 2D 数组,其中每个元素都可以保存 5 位值,您应该这样写:

reg [0:4] a [0:3][0:2];
于 2014-12-09T03:23:18.583 回答