- Fixed Arrays or Fixed-Sized Arrays (sometimes known as static arrays) whose size cannot be changed once declared.
- Dynamic arrays which can be resized run time.
Example 1 : Declaring and using SystemVerilog fixed-sized arrays
int data[0:15]; // 16 ints [0]..[15] int address[16]; // 16 ints [0]..[15]
address[15] = 1; // Set last array element
You can create multidimensional fixed-size arrays by specifying the dimensions after the variable name. This makes an unpacked array; we will take a look for packed arrays later. The following example creates several two-dimensional arrays of integers, 8 entries by 4, and sets the last entry to 1.
Example 2 : Declaring and using multidimensional fixed-sized array
int array2 [0:7][0:3]; // Verbose declaration int array3 [8][4]; // Compact declaration array2[7][3] = 1; // Set last array element
SystemVerilog stores each element on a longword (32-bit) boundary. So a byte, shortint, and int are all stored in a single longword, while a longint is stored in two longwords. (Simulators frequently store four-state types such as logic and integer in two or more longwords.)
Example 3 : SystemVerilog Unpacked Array Declaration
bit [7:0] unpacked_array[3]; // Unpacked array
Unpacked array declared above is stored as shown below
You can initialize an array using an array literal that is an apostrophe and curly braces. Using this array literal you can set some or all elements at once. Also its easy to replicate values by putting a count before the curly braces. Below we have shown example to initialize the systemverilog fixed arrays
Example 4 : Initialize SystemVerilog Array
int ascend[4] = ’{0,1,2,3}; // Initialize 4 elements int decend[5]; int array[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
Basic Array Operations
The most common way to manipulate an array is with a for or foreach loop. In below example the variable "i" is declared local to the for loop. To get the size of array we can use system function $size that returns the size of array. For foreach loop statement, you specify the array name and an index in square brackets and Systemverilog automatically steps through all the elements of the array. The index variable is local to the loop.
Example 5 : Access the arrays using for and foreach loops
// SystemVerilog For and Foreach loop to access arrays module array_loops; initial begin bit [31:0] src[5], dst[5]; for (int i=0; i<$size(src); i++) begin src[i] = i; $display("src[%0d] = %0d", i, src[i]); end foreach (dst[j]) begin dst[j] = src[j] * 2; // dst doubles src values $display("dst[%0d] = %0d", j, dst[j]); end end endmodule
Simulation Results:
src[0] = 0
src[1] = 1
src[2] = 2
src[3] = 3
src[4] = 4
dst[0] = 0
dst[1] = 2
dst[2] = 4
dst[3] = 6
dst[4] = 8
Now in below example note that for SystemVerilog multidimensional arrays the syntax is not as you might expected. Instead of listing each subscript in separate square brackets – [i][j] – they are combined with a comma – [i,j].
Example 6: SystemVerilog Accessing Multidimensional Arrays using Foreach loop
// SystemVerilog For and Foreach loop to access arrays module array_loops; int md[2][3]; 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}, {default: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 endmodule
Simulation Results:
Initial value:
md[0][0] = 0
md[0][1] = 0
md[0][2] = 0
md[1][0] = 0
md[1][1] = 0
md[1][2] = 0
New value:
md[0][0] = 9
md[0][1] = 8
md[0][2] = 7
md[1][0] = 5
md[1][1] = 5
md[1][2] = 5
Packed arrays :
1 | bit [3:0] [7:0] bytes; // 4 bytes packed into 32-bits |
Packed Array Layout
You can mix packed and unpacked dimensions. You may want to make an array that represents a memory that can be accessed as bits, bytes, or long words. In Example 2-14, barray is an unpacked array of three packed elements.
Declaration of mixed packed and unpacked arrays
1 | bit [3:0] [7:0] barray [3]; // Packed: 3x32-bit |
The variable bytes is a packed array of four bytes, which are stored in a single longword. barray is an array of three of these elements.
With a single subscript, you get a longword of data, barray[2]. With two subscripts, you get a byte of data, barray[0][3]. With three subscripts, you can access a single bit, barray[0][1][6]. Note that because one dimension is specified after the name, barray[3], that dimension is unpacked, so you always need to use at least one subscript.
Choosing Between Packed and Unpacked Array
Which should you choose — packed or unpacked array?
A packed array is handy if you need to convert to and from scalars. For example, you might need to reference a memory as a byte or as a longword. The above array barray can handle this requirement. Only fixed-size arrays can be packed, not dynamic arrays, associative arrays, or queues.
If you need to wait for a change in an array, you have to use a packed array. Perhaps your testbench might need to wake up when a memory changes value, so you want to use the @ operator. But this is only legal with scalar values and packed arrays. Using the earlier examples, you can block on the variable lw, and barray[0], but not the entire array barray unless you expand it: @(barray[0] or barray[1] or barray[2]).
Previous : Net Type
Next : Dynamic Arrays