System Verilog: Dynamic Arrays

System Verilog: Dynamic Arrays

`Dynamic array` is one of the aggregate data types in system verilog. It is an unpacked array whose size can be set or changed at run time.

In verilog, dimension of the array can be set during declaration and it cannot be changed during run time. But in most of our verification scenarios, array dimensions need to be changed during runtime like packet length or size of the read or write data variations in runtime etc. In these scenarios, the only option if using verilog is to declare an array with maximum possible size.

These limitations has been overcome in system verilog by the introduction of dynamic array. Dynamic arrays support all variable data types as element types,including arrays.

Dynamic array initialization and resizing The constructor `new[]` is used to initialize dynamic arrays. Other built-in method for dynamic array operations are `size()` and `delete()`.The `size()` method returns the size of the array and `delete()` clears all the elements yielding an empty array. The default size of an uninitialized dynamic array is 0.

module dynamic_array_check1;

//Declaration int darrA [], darrB []; logic [7:0] data[];

initial begin

//Default size of an uninitialized dynamic array is 0. $display($time,"--------- Default size of an uninitialized dynamic array is 0---------"); $display($time,"darrA_size=%0d ,darrB_size=%0d ,data_size=%0d ",darrA.size() ,darrB.size() ,data.size() );

//Setting the array sizes #10 darrA = new[10]; //Set the array size to 10 for darrA #10 darrB = new[20]; //Set the array size to 20 for darrB #1 data = new[2]; // Set the array size to 2 for data $display($time,"--------- Set array size using new[] constructor---------"); $display($time,"darrA_size=%0d ,darrB_size=%0d ,data_size=%0d ",darrA.size() ,darrB.size() ,data.size() ); end

endmodule /* Loading snapshot worklib.dynamic_array_check1:sv .................... Done ncsim> source /opt/cadence/incisive_11.10.011/tools/inca/files/ncsimrc ncsim> run 0--------- Default size of an uninitialized dynamic array is 0--------- 0darrA_size=0 ,darrB_size=0 ,data_size=0 21--------- Set array size using new[] constructor--------- 21darrA_size=10 ,darrB_size=20 ,data_size=2 ncsim: *W,RNQUIE: Simulation is complete. ncsim> exit */

The size argument need not match the size of the initialization array. When the initialization size is greater, it is truncated to match the size argument; If it is smaller, the initialized array is appended with the default values to attain the specified size. Resizing can be done by preserving the previous values. The following code shows setting and resetting size of dynamic array, resize by preserving previous values, and delete method usage.

module dynamic_array_check2;

//Declaration int darrA [], darrB []; logic [7:0] data[]; integer mem[2][];

initial begin #5 darrA = new[4]; //Set the array size to 4 for darrA #5 darrB = new[3]; //Set the array size to 3 for darrB #5 data = new[2]; // Set the array size to 2 for data

$display(" --------- Setting array sizes ---------"); $display($time,"darrA_size=%0d ,darrB_size=%0d ,data_size=%0d ",darrA.size() ,darrB.size() ,data.size() );

#2 darrA = '{20, 30, 40, 50, 60}; //Size set was 4, but assigning 5 elements #2 darrB = '{60, 70}; //Size was 3, but assigned only 2 elements. #2 data = '{8'b00110011, 8'b11110000,8'b10101010}; ////Size was 2, but added 3 elements.

$display(" --------- Add greater/less elements than array sizes -Resize happens ---------"); $display($time,"darrA_size=%0d ,darrB_size=%0d ,data_size=%0d ",darrA.size() ,darrB.size() ,data.size() ); $display($time,"darrA[0]=%0d ,darrB[0]=%d, darrA[1]=%d ,darrB[1]=%d ",darrA[0],darrB[0],darrA[1],darrB[1] );

//Resizing darrA to 2 by copying darrB values. #10 darrA = new[2] (darrB); $display($time,"darrA_size=%0d ,darrB_size=%0d ,data_size=%0d ",darrA.size() ,darrB.size() ,data.size() ); $display($time,"darrA[0]=%0d ,darrB[0]=%0d, darrA[1]=%0d ,darrB[1]=%0d ",darrA[0],darrB[0],darrA[1],darrB[1] );

//Resizing darrB to 5 by preserving previous values. #10 darrB = new[4] (darrB); $display(," --------- Resizing by preserving previous values ---------"); $display($time,"darrB_size=%0d",darrB.size()); $display($time,"darrB[0]=%0d ,darrB[1]=%0d, darrB[2]=%0d ,darrB[3]=%0d, ",darrB[0],darrB[1],darrB[2],darrB[3] );

#10 darrB.delete(); $display(" --------- Delete entire array using delete built-in method ---------"); $display($time,"darrB_size=%0d",darrB.size());

end

endmodule Loading snapshot worklib.dynamic_array_check2:sv .................... Done ncsim> source /opt/cadence/incisive_11.10.011/tools/inca/files/ncsimrc ncsim> run --------- Setting array sizes --------- 15darrA_size=4 ,darrB_size=3 ,data_size=2 --------- Add greater/less elements than array sizes -Resize happens --------- 21darrA_size=5 ,darrB_size=2 ,data_size=3 21darrA[0]=20 ,darrB[0]= 60, darrA[1]= 30 ,darrB[1]= 70 31darrA_size=2 ,darrB_size=2 ,data_size=3 31darrA[0]=60 ,darrB[0]=60, darrA[1]=70 ,darrB[1]=70 --------- Resizing by preserving previous values --------- 41darrB_size=4 41darrB[0]=60 ,darrB[1]=70, darrB[2]=0 ,darrB[3]=0,
--------- Delete entire array using delete built-in method --------- 51darrB_size=0 ncsim: *W,RNQUIE: Simulation is complete. ncsim> exit

Dynamic array assignments If the target of the assignment is a queue or dynamic array, resizing will be done to have the same number of elements as the source expression. But if a dynamic array is assigned to a fixed-size array, the size of the source will not be determined until run time. Run-time error will occur, if the size is different from fixed-size array.

module dynamic_array_check3;

//Declaration int darrA [], darrB []; int farr1[3], farr2[5];

initial begin farr1 = {100,200,300}; farr2 = {500,600,700,800,900};

//Assigning fixed size array to uninitialized dynamic arrays. #2 darrA = farr1; #2 darrB = farr2;

$display($time,"darrA_size=%0d ,darrB_size=%0d ",darrA.size() ,darrB.size()); $display($time,"darrA[0]=%0d ,darrA[1]=%0d, darrA[2]=%0d",darrA[0],darrA[1],darrA[2]);

//Swapping fixed size array assignments uninitialized dynamic arrays. #2 darrA = farr2; #2 darrB = farr1; $display($time,"darrA_size=%0d ,darrB_size=%0d ",darrA.size() ,darrB.size()); $display($time,"darrA[0]=%0d ,darrA[1]=%0d, darrA[2]=%0d",darrA[0],darrA[1],darrA[2]);

darrA.delete(); darrB.delete();

#10 darrA = new[3] (farr1); $display($time,"darrA_size=%0d ,darrB_size=%0d ",darrA.size() ,darrB.size()); $display($time,"darrA[0]=%0d ,darrA[1]=%0d, darrA[2]=%0d",darrA[0],darrA[1],darrA[2]);

end

endmodule

Loading snapshot worklib.dynamic_array_check3:sv .................... Done ncsim> source /opt/cadence/incisive_11.10.011/tools/inca/files/ncsimrc ncsim> run 4darrA_size=3 ,darrB_size=5 4darrA[0]=100 ,darrA[1]=200, darrA[2]=300 8darrA_size=5 ,darrB_size=3 8darrA[0]=500 ,darrA[1]=600, darrA[2]=700 18darrA_size=3 ,darrB_size=0 18darrA[0]=100 ,darrA[1]=200, darrA[2]=300 ncsim: *W,RNQUIE: Simulation is complete. ncsim> exit

Arrays as arguments to subroutines If dynamic array is used as formal argument, it can accept dynamic array, queue, or fixed-size array of a compatible type as actual argument.

In the below example, formal argument of mytask is a dynamic array of int,

task mytask( int darr []);

so the actual argument can be of dynamic array, queue, or fixed-size array. int darr1[] = new[10]; int farr[5];

mytask(darr1); mytask(farr);

But if fixed array is used as formal and dynamic array is used as actual argument, then dynamic array should be of compatible type and has to be initialized to the same size as fixed array used as formal argument of subroutine.

Here, formal argument of mytask is a fixed size array of 10 int elements.

task mytask( int farr[9:1]);

actual argument in dynamic array would be int darr[] = new[10];