Sunday, August 9, 2020

Array Slicing in System Verilog

 Hi Everyone !!! 

   In this blog we are going to see concepts of Array Slicing.

   In System Verilog, by using part select we can select one part of an array elements and assigned to another array.

   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] array1;
bit [07:0] array2[4];
 
array2[0] = array1[07:0];
array2[1] = array1[15:8];
array2[2] = array1[23:16];
array2[3] = array1[31:24];
The above example refers to copying 32-bit array1 to array2. this is done with the part selection of array1 variables.
program array_slice_TB;
  bit [31:0] array1;
  byte  array2[4];
 
  initial begin
    std::randomize(array1);
     
    $display("Value of array1 is %h",array1);
    $display("Before Part select");
    foreach(array2[i])
      $display("\t array2[%0d] = %h",i,array2[i]);  
    array2[0] = array1[07:0];
    array2[1] = array1[15:8];
    array2[2] = array1[23:16];
    array3[3] = array1[31:24];
     
    $display("After the array part select,");
    foreach(array2[i])
      $display("\t array2[%0d] = %h",i,array2[i]);  
  end
endprogram

Simulator Output

Values of array1 is 05e23536
 Before Part select
array2[0] = 00 
array2[1] = 00 
array2[2] = 00 
array2[3] = 00
 After the array part select, 
array2[0] = 36 
array2[1] = 35
array2[2] = e2 
array2[3] = 05

array slice
SystemVerilog uses the term slice to refer to a selection of one or more contiguous elements of an array.
  bit [31:0] array1 [7:0]//array of 8 elements of width 32bit
  bit [31:0] array2 [1:0]//array of 2 elements of width 32bit
   array2 = array1[5:4]//assigning 2 elements of array array1  to array2
program array_slice;
  bit [31:0] array1 [7:0];
  bit [31:0] array2 [1:0];
 
  initial begin
    std::randomize(array1);
     
    $display("Value of array1 are %p",array1);
     
    $display("Before the array part select,");
    $display("\tValues of array2 are %p",array2);
     
    array2 = array1[5:4];
     
    $display("After the array part select,");
    $display("\tValues of array2 are %p",array2);  
  end
endprogram

Simulator Output

Value of array1 are '{'h2b5c2c6e, 'h815f8d74, 'hcf578554, 'h7bb6d188, 'hfad5c89b, 'h401079a, 'hcf21010, 'h471cef5f} 
Before the array part select,
Values of array2 are '{'h0, 'h0}
After the array part select,
Values of array2 are '{'hcf578554, 'h7bb6d188}
HOW TO WRITE GENERIC LOGIC FOR BIT SELECTION?
Using +: and -: Notation part selection generic logic can be written.

+: NOTATION

array2 array1 [j +: k];
j -> bit start position
k -> Number of bits up from j’th position 

+: example:
array2 = array1 [j +: k];
0 -> Starting point
8 -> 8 elements up from 0 , so end point is 7.
array2 = array1 [7:0];

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

foreach(array1[i]) array2[i] = array1[8*i +: 8];
Above code can be expanded as below,
array2[0] = array1[8*0 +: 8]//array1[7:0]
array2[1] = array1[8*1 +: 8]//array1[15:8]
array2[2] = array1[8*2 +: 8]//array1[23:16]
array2[3] = array1[8*3 +: 8]//array1[31:24]
program array_slice;
  bit [31:0] array1;
  byte       array2[4];
 
  initial begin
    std::randomize(array1);
     
    $display("Value of array1 is %h",array1);
     
    $display("Before the assignement,");
    foreach(array2[i])
      $display("\t array2[%0d] = %h",i,array2[i]);  
     
    foreach(array2[i]) array2[i] = array1[8*i +: 8];
     
    $display("After the array part select,");
    foreach(array2[i])
      $display("\t array2[%0d] = %h",i,array2[i]);  
  end
endprogram

Simulator Output

Value of array1 is 05e23536
Before the assignement,
array2[0] = 00
array2[1] = 00
array2[2] = 00
array2[3] = 00
After the array part select,
array2[0] = 36
array2[1] = 35
array2[2] = e2
array2[2] = 05
Array slicing Example for ( -:)
program array_slice;
  bit [31:0] array1;
  byte       array2[4];
 
  initial begin
    std::randomize(array1);
    $display("Value of array1 is %h",array1);
     for( int i=3;i>=0;i--) begin
         array2[i]=array1[8*(i+1)-1-:8];
        $display("\t array2 %p [%0d]",array2,i);  
        end
  end
endprogram

Simulator Output

Value of array1 is 2b5c2c6e
array2 '{0, 0, 0, 43} [3]
array2 '{0, 0, 92, 43} [2]
array2 '{0, 44, 92, 43} [1]
array2 '{110, 44, 92, 43} [0]

The above code is written by using (+:) notation also.
Array slicing Example for ( +:)
program array_slice;
  bit [31:0] array1;
  byte       array2[4];
 
  initial begin
    std::randomize(array1);
    $display("Value of array1 is %h",array1);
     forint i=0;i<=3;i++) begin
         array2[i]=array1[(8*i)+:8];
        $display("\t array2 %p [%0d]",array2,i);  
        end
  end
endprogram

Simulator Output

Value of array1 is 2b5c2c6e
array2 '{110, 0, 0, 0} [0]
array2 '{110, 44, 0, 0} [1]
array2 '{110, 44, 92, 0} [2]
array2 '{110, 44, 92, 43} [3]

Rule:
The size of the part select or slice must be constant, but the position can be variable.
As per the rule ‘array2 = array1[j +: k]’; or ‘array2 = array1[j -: k];’, k must be always constant.
in the above examples k=8.

Hope this logic's will be useful to everyone !!!
Giving feedback is more precious than writing an article!!! 😊😊😊😊😊
Always welcome both positive and negative feedback's !!!
Feel free to post any queries related SV and UVM  

“No one can make you feel inferior without your consent.”      ― Eleanor Roosevelt,

1 comment:

  1. Thank you very much for the useful information about the notation for bit selection.

    ReplyDelete

`define Macro usage in System Verilog

 Hi Everyone !!! In this blog we are going to see the usage of `define macro in System Verilog. A text macro substitution facility has been ...