![87e7ab6f8c90edd1b536027d7a7b40f8.png](https://img-blog.csdnimg.cn/img_convert/87e7ab6f8c90edd1b536027d7a7b40f8.png)
SystemVerilog提供了除了Verilog-1995中固定大小数组之外多种类型的数组。
声明并初始化固定大小的数组
int lo_hi[0:15]; // 16 ints [0]..[15]
int c_style[16]; // 16 ints [0]..[15]
我们还可以声明固定大小的多个维度的数组
bit [7:0] b_unpacked[3]; // Unpacked
这是一类unpacked数组,使用下述方式存储
![650da5b0d45049473a7cc3e9b896f89d.png](https://img-blog.csdnimg.cn/img_convert/650da5b0d45049473a7cc3e9b896f89d.png)
字符数组
可以使用’{}内的字符初始化数组。
int ascend[4] = ’{0,1,2,3}; // Initialize 4 elements
int decend[5];
int md[2][3] = ’{’{0,1,2}, ’{3,4,5}};
descend = ’{4,3,2,1,0}; // Set 5 elements
descend[0:2] = ’{5,6,7}; // Set first 3 elements
ascend = ’{4{8}}; // Four values of 8
基本数组操作 - for和foreach
操作数组的最常用方法是使用for或foreach循环。
initial begin
bit [31:0] src[5], dst[5];
for (int i=0; i<$size(src); i++)
src[i] = i;
foreach (dst[j])
dst[j] = src[j] * 2; // dst doubles src values
end
在上例中,变量i被声明为for循环中的本地变量。SystemVerilog函数中的$size函数返回数组的大小。 在foreach中,根据数组名称和索引自动逐步遍历数组中的所有元素。变量j也是foreach循环的本地变量。
多维的foreach语句语法不是 [i] [j],而是[i,j]。
initial begin
$display("Initial value:");
foreach (md[i,j]) // Yes, this is the right syntax
$display("md[%0d][%0d] = %0d", i, j, md[i][j]);
$display("New value:");
md = ‘{{9, 8, 7}, 3{5}}; // Replicate last 3 values
foreach (md[i,j]) // Yes, this is the right syntax
$display("md[%0d][%0d] = %0d", i, j, md[i][j]);
end
基本数组操作 - 复制和比较
我们可以不使用循环,而直接使用数组操作来比较和复制。比较的结果仅限于相等和不相等。 如下所示:
initial begin
bit [31:0] src[5] = ’{0,1,2,3,4},
dst[5] = ’{5,4,3,2,1};
// Aggregate compare the two arrays
if (src==dst)
$display("src == dst");
else
$display("src != dst");
// Aggregate copy all src values to dst
dst = src;
// Change just one element
src[0] = 5;
// Are all values equal (no!)
$display("src %s dst", (src == dst) ? "==" : "!=");
// Are last elements 1-4 equal (yes!)
$display("src[1:4] %s dst[1:4]",
(src[1:4] == dst[1:4]) ? "==" : "!=");
end
Packed数组
对于某些数据,例如一个32位寄存器。有时希望将其视为四个8位值,而在其他时候则视为一个单个无符号值。 SystemVerilog Packed数组被同时视为一个数组或者单个值。它使用连续空间存储,没有未使用的空间。
Packed 数组声明中需要指定数组大小。 变量bytes是一个包含四个字节的Packed数组
,存储在单个longword中
bit [3:0] [7:0] bytes; // 4 bytes packed into 32-bits
bytes = 32’hdead_beef;
$displayh(bytes,, // Show all 32-bits
bytes[3], // most significant byte "de"
bytes[3][7]); // most significant bit "1"
![d893ed9d082b789d8170e19977c9e8e9.png](https://img-blog.csdnimg.cn/img_convert/d893ed9d082b789d8170e19977c9e8e9.png)
packed数组和unpacked数组可以混合使用。例如希望声明一个可以作为bits、 bytes或者longbytes表示的数组:
bit [3:0] [7:0] barray [3]; // Packed: 3x32-bit
barray[0] = 32’h0123_4567;
barray[0][3] = 8’h01;
barray[0][1][6] = 1’b1;
![02b120fc9c69600b0a4135bbef2349ab.png](https://img-blog.csdnimg.cn/img_convert/02b120fc9c69600b0a4135bbef2349ab.png)
如何选择packed和 unpacked数组?
应该选择哪个 – packed或者 unpacked数组?
packed数组方便索引数据长度的转换。例如,你可能需要将内存数据索引bytes 改变为longbytes。 上面的数组barray可以处理这个要求。 只能packed固定大小的数组,动态数组、关联数组和队列无法被packed。