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];

4 comments on “System Verilog: Dynamic Arrays

  1. Pingback: System Verilog: Associative Arrays | VLSI Pro

    1. Sini Balakrishnan Post author

      Hi Harshita
      I don’t think you can delete a particular element from a dynamic array, like the way we do in associative array. Delete method clears all the elements yielding an empty array.
      Thanks
      Sini

      Reply
  2. Lokesh

    Hi Sini,

    Can we specify ranges while allocating memory to the dynamic array?

    int memory[];
    memory=new[5:1];

    something like the above?

    Reply

Leave a Reply to Lokesh Cancel reply

Your email address will not be published. Required fields are marked *