Contact / Report an issue

SystemVerilog Array Slice

what is array slice?


Slice is a selection of one or more contiguous elements of an array, whereas part select is a selection of one or more contiguous bits of an element.

what is the difference between an array slice and part select?


As mentioned above part select operates on bits of an element, whereas slice operates on elements of an array. Part select and Slice is explained below.

array part select


SystemVerilog uses the term part select to refer to a selection of one or more contiguous bits of a single dimension packed array.

bit [31:0] data;
bit [07:0] byte[4];

byte[0] = data[07:0];
byte[1] = data[15:8];
byte[2] = data[23:16];
byte[3] = data[31:24];


The above example refers to copying 32-bit data to a byte array. this is done with the part selection of data variables.

program array_slice;
  bit [31:0] data;
  byte       byte_data[4];

  initial begin
    std::randomize(data);
    
    $display("Value of data is %h",data);
    
    $display("Before the assignment,");
    foreach(byte_data[i])
      $display("\t byte_data[%0d] = %h",i,byte_data[i]);   
    
    byte_data[0] = data[07:0];
    byte_data[1] = data[15:8];
    byte_data[2] = data[23:16];
    byte_data[3] = data[31:24]; 
    
    $display("After the array part select,");
    foreach(byte_data[i])
      $display("\t byte_data[%0d] = %h",i,byte_data[i]);   
  end
endprogram 

 Simulator Output: 

Values of data is 05e23536
Before the assignement,
byte_data[0] = 00
byte_data[1] = 00
byte_data[2] = 00
byte_data[3] = 00
After the array part select,
byte_data[0] = 36
byte_data[1] = 35
byte_data[2] = e2
byte_data[3] = 05
Execute the above code on 

array slice


SystemVerilog uses the term slice to refer to a selection of one or more contiguous elements of an array.

  bit [31:0] packet_type_A [7:0]; //array of 8 elements of width 32bit
  bit [31:0] packet_type_B [1:0]; //array of 2 elements of width 32bit

  packet_type_B = packet_type_A[5:4]; //assigning 2 elements of array packet_type_A  to packet_type_B


program array_slice;
  bit [31:0] packet_type_A [7:0];
  bit [31:0] packet_type_B [1:0];

  initial begin
    std::randomize(packet_type_A);
    
    $display("Value of packet_type_A are %p",packet_type_A);
    
    $display("Before the array part select,");
    $display("\tValues of packet_type_B are %p",packet_type_B);
    
    packet_type_B = packet_type_A[5:4];
    
    $display("After the array part select,");
    $display("\tValues of packet_type_B are %p",packet_type_B);   
  end
endprogram 

 Simulator Output: 

Before the array part select,
Values of packet_type_B are '{'h0, 'h0}
After the array part select,
Values of packet_type_B are '{'hbe7fe77d, 'h30aa33e2}

Execute the above code on 


array part select in system Verilog

How to write generic logic for bit selection?


Using +: and -: Notation part selection generic logic can be written.

+: Notation


byte = data[j +: k];

j  -> bit start position
k -> Number of bits up from j'th position

 +: example: 

byte = data[0 +: 8];

0 -> Starting point
8 -> 8 elements up from 0 , so end point is 7.

byte = data[7:0];

The above 32-bit data copying to byte array can be re-written with + notation as below.

foreach(byte[i]) byte[i] = data[8*i +: 8];

Above code can be expanded as below,

byte[0] = data[8*0 +: 8]; //data[7:0]
byte[i] = data[8*1 +: 8]; //data[15:8]
byte[i] = data[8*2 +: 8]; //data[23:16]
byte[i] = data[8*3 +: 8]; //data[31:24]

program array_slice;
  bit [31:0] data;
  byte       byte_data[4];

  initial begin
    std::randomize(data);
    
    $display("Value of data is %h",data);
    
    $display("Before the assignement,");
    foreach(byte_data[i])
      $display("\t byte_data[%0d] = %h",i,byte_data[i]);   
    
    foreach(byte_data[i]) byte_data[i] = data[8*i +: 8];
    
    $display("After the array part select,");
    foreach(byte_data[i])
      $display("\t byte_data[%0d] = %h",i,byte_data[i]);   
  end
endprogram 

 Simulator Output: 
Value of data is 05e23536
Before the assignement,
byte_data[0] = 00
byte_data[1] = 00
byte_data[2] = 00
byte_data[3] = 00
After the array part select,
byte_data[0] = 36
byte_data[1] = 35
byte_data[2] = e2
byte_data[i3] = 05
Execute the above code on 

-: Notation


byte = data[j -: k];

j  -> bit start position
k -> Number of bits down from the j'th position

 -: example: 

byte = data[7 -: 8];

7 -> Starting point
8 -> 8 elements down from 7 , so end point is 0.

byte = data[7:0];

The above 32-bit data copying to byte array can be re-written with + notation as below.

foreach(byte[i]) byte[i] = data[(8*(i+1))-1 -: 8];

Above code can be expanded as below,

byte[0] = data[(8*1)-1 -: 8]; //data[7  -: 8] => data[7:0]
byte[i] = data[(8*2)-1 -: 8]; //data[14 -: 8] => data[15:8]
byte[i] = data[(8*3)-1 -: 8]; //data[23 -: 8] => data[23:16]
byte[i] = data[(8*4)-1 -: 8]; //data[31 -: 8] => data[31:24]

program array_slice;
  bit [31:0] data;
  byte       byte_data[4];

  initial begin
    std::randomize(data);
    
    $display("Value of data is %h",data);
    
    $display("Before the assignement,");
    foreach(byte_data[i])
      $display("\t byte_data[%0d] = %h",i,byte_data[i]);   
    
    foreach(byte_data[i]) byte_data[i] = data[(8*(i+1))-1 -: 8];
    
    $display("After the array part select,");
    foreach(byte_data[i])
      $display("\t byte_data[%0d] = %h",i,byte_data[i]);   
  end
endprogram 

 Simulator Output: 
Value of data is 05e23536
Before the assignement,
 byte_data[0] = 00
 byte_data[1] = 00
 byte_data[2] = 00
 byte_data[3] = 00
After the array part select,
 byte_data[0] = 36
 byte_data[1] = 35
 byte_data[2] = e2
 byte_data[i3] = 05
Execute the above code on 

Rule:

The size of the part select or slice must be constant, but the position can be variable.

As per the rule 'byte = data[j +: k]'; or 'byte = data[j -: k];', k must be always constant.

in the above examples k=8.