SystemVerilog TestBench

SystemVerilog TestBench Architecture

About TestBench

Testbench or Verification Environment is used to check the functional correctness of the Design Under Test (DUT) by generating and driving a predefined input sequence to a design, capturing the design output and comparing with-respect-to expected output.

Verification environment is a group of class’s performing specific operation. i.e, generating stimulus, driving, monitoring, etc. and those classes will be named based on the operation

TestBench Components

Name Type Description
transaction class Defines the pin level activity generated by agent (to drive to DUT through the driver) or the activity has to be observed by agent (Placeholder for the activity monitored by the monitor on DUT signals)
generator class Generates the stimulus (create and randomize the transaction class) and send it to Driver
driver class Receives the stimulus (transaction) from a generator and drives the packet level data inside the transaction into pin level (to DUT
monitor class Observes pin level activity on interface signals and converts into packet level which is sent to the components such as scoreboard
agent class An agent is a container class, which groups the class’s (generator, driver, and monitor) specific to an interface or protocol
scoreboard class Receives data items from monitors and compares them with expected values.
Expected values can be either golden reference values or generated from the reference model
environment class The environment is a container class for grouping higher level components like agent’s and scoreboard
test program The test is responsible for,

  • Configuring the testbench
  • Initiate the testbench components construction process
  • Initiate the stimulus driving
testbench_top class This is the topmost file, which connects the DUT and TestBench. It consists of DUT, Test and interface instances, the interface connects the DUT and TestBench

TestBench Hierarchy

SystemVerilog TestBench hierarchy
SystemVerilog TestBench hierarchy

TestBench Architecture

SystemVerilog Testbench
SystemVerilog Testbench

SystemVerilog TestBench Examples

SV Interview Questions

SystemVerilog Interview Questions

Below are the most frequently asked SystemVerilog Interview Questions,

  1. What is the difference between an initial and final block of the systemverilog?
  2. Explain the simulation phases of SystemVerilog verification?
  3. What is the Difference between SystemVerilog packed and unpacked array?
  4. What is “This ” keyword in the systemverilog?
  5. What is alias in SystemVerilog?
  6. randomized in the systemverilog test bench?
  7. in SystemVerilog which array type is preferred for memory declaration and why?
  8. How to avoid race round condition between DUT and test bench in SystemVerilog verification?
  9. What are the advantages of the systemverilog program block?
  10. What is the difference between logic and bit in SystemVerilog?
  11. What is the difference between datatype logic and wire?
  12. What is a virtual interface?
  13. What is an abstract class?
  14. What is the difference between $random and $urandom?
  15. What is the expect statements in assertions?
  16. What is DPI?
  17. What is the difference between == and === ?
  18. What are the system tasks?
  19. What is SystemVerilog assertion binding and advantages of it?
  20. What are parameterized classes?
  21. How to generate array without randomization?
  22. What is the difference between always_comb() and always@(*)?
  23. What is the difference between overriding and overloading?
  24. Explain the difference between deep copy and shallow copy?
  25. What is interface and advantages over the normal way?
  26. What is modport and explain the usage of it?
  27. What is a clocking block?
  28. What is the difference between the clocking block and modport?
  29. System Verilog Interview Questions, Below are the most frequently asked questions.
  30. What are the different types of verification approaches?
  31. What are the basic testbench components?
  32. What are the different layers of layered architecture?
  33. What is the difference between a $rose and @ (posedge)?
  34. What is the use of extern?
  35. What is scope randomization?
  36. What is the difference between blocking and non-blocking assignments?
  37. What are automatic variables?
  38. What is the scope of local and private variables?
  39. How to check if any bit of the expression is X or Z?
  40. What is the Difference between param and typedef?
  41. What is `timescale?
  42. Explain the difference between new( ) and new[ ] ?
  43. What is the difference between task and function in class and Module?
  44. Why always blocks are not allowed in the program block?
  45. Why forever is used instead of always in program block?
  46. What is SVA?
  47. Explain the difference between fork-join, fork-join_none, and fork- join_any?
  48. What is the difference between mailboxes and queues?
  49. What is casting?
  50. What is inheritance and polymorphism?
  51. What is callback?
  52. What is constraint solve-before?
  53. What is coverage and what are different types?
  54. What is the importance of coverage in SystemVerilog verification?
  55. When you will say that verification is completed?
  56. What are illegal bins? Is it good to use it and why?
  57. What is the advantage of seed in randomization?
  58. What is circular dependency?
  59. What is “super “?
  60. What is the input skew and output skew in the clocking block?
  61. What is a static variable?
  62. What is a package?
  63. What is the difference between bit [7:0] and byte?
  64. What is randomization and what can be
  65. What are the constraints? Is all constraints are bidirectional?
  66. What are in line constraints?
  67. What is the difference between rand and randc?
  68. Explain pass by value and pass by ref?
  69. What are the advantages of cross-coverage?
  70. What is the difference between associative and dynamic array?
  71. What is the type of SystemVerilog assertions?
  72. What is the difference between $display,$strobe,$ monitor?
  73. Can we write SystemVerilog assertions in class?
  74. What is an argument pass by value and pass by reference?

Related Links:

Multidimensional Dynamic Array

Multidimensional array

A multidimensional array is an array containing one or more arrays.

Multidimensional arrays can be of more than two levels deep. However, arrays more than three levels deep are hard to manage.

Number of indices required to access an array element differs on array dimension,

  • Two indices are required to access a two-dimensional array element
  • Three indices are required to access a three-dimensional array element

Multidimensional Dynamic array

SystemVerilog dynamic array can be,

  • regular array
  • irregular array

regular array

A regular array is a multidimensional array with member arrays of the same sizes.

for example,
2-D array with the number of columns same for all the rows

In below 3 x 2 array diagram,
All the 3 rows have 2 columns.

SystemVerilog regular array
SystemVerilog regular array

Irregular array

An irregular array is a multidimensional array with member arrays of different sizes.

for example,
2-D array with the number of columns different for the rows

In below array with 3 rows,
row 1, 2 and 3 have 2, 1 and 3 columns respectively.

SystemVerilog irregular array
SystemVerilog irregular array

2-Dimensional dynamic array example

Regular array

Below is a 3×2 2D dynamic array example.
In example shows the array declaration, creation, assignment and displaying the array elements.

SystemVerilog 2D Dynamic array
SystemVerilog 2D Dynamic array
program dynamic_array;
  
  //dynamic array declaration
  bit [7:0] d_array[][];
  
  initial begin
    //memory allocation
    d_array = new[3];
    
    foreach(d_array[i])
      d_array[i] = new[2];
    
    //assigning random value to elements
    foreach(d_array[i,j]) d_array[i][j] = $random;
    
    //displaying array elements
    foreach(d_array[i,j])   
      $display("\td_aaray[%0d,%0d] = %0d",i,j, d_array[i][j]);
  end

endprogram

Simulator Output

d_aaray[0,0] = 36
d_aaray[0,1] = 129
d_aaray[1,0] = 9
d_aaray[1,1] = 99
d_aaray[2,0] = 13
d_aaray[2,1] = 141

Click to execute on   

Irregular array

Below is a 2D irregular dynamic array example.
In example shows the array declaration, creation, assignment and displaying the array elements.

SystemVerilog 2d irregular array
SystemVerilog 2d irregular array
program dynamic_array;
  
  //dynamic array declaration
  bit [7:0] d_array[][];
  
  initial begin
    //memory allocation
    d_array = new[3];
    
    d_array[0] = new[2];
    d_array[1] = new[1];
    d_array[2] = new[4];
    
    //assigning random value to elements
    foreach(d_array[i,j]) d_array[i][j] = $random;
    
    //displaying array elements
    foreach(d_array[i,j])   
      $display("\td_aaray[%0d,%0d] = %0d",i,j, d_array[i][j]);
  end
endprogram

 Simulator Output 

d_aaray[0,0] = 36
d_aaray[0,1] = 129
d_aaray[1,0] = 9
d_aaray[2,0] = 99
d_aaray[2,1] = 13
d_aaray[2,2] = 141
d_aaray[2,3] = 101

Click to execute on   

3-Dimensional dynamic array example

Regular array

Below is a 2x2x4 3D dynamic array example.
In example shows the array declaration, creation, assignment and displaying the array elements.

SystemVerilog 3d dynamic array
SystemVerilog 3d dynamic array
program dynamic_array;
  
  //dynamic array declaration
  bit [7:0] d_array[][][];
  
  initial begin
    //memory allocation
    d_array = new[2];
    
    foreach(d_array[i]) begin //{
      d_array[i] = new[2];
      foreach(d_array[i,j]) begin //{
        d_array[i][j] = new[4];
      end //}
    end //}
    
    //assigning random value to elements
    foreach(d_array[i,j,k]) d_array[i][j][k] = $random;
    
    //displaying array elements
    foreach(d_array[i,j,k])   
      $display("\td_aaray[%0d,%0d,%0d] = %0d",i,j,k,d_array[i][j][k]);
  end

endprogram

Simulator Output

d_aaray[0,0,0] = 36
d_aaray[0,0,1] = 129
d_aaray[0,0,2] = 9
d_aaray[0,0,3] = 99
d_aaray[0,1,0] = 13
d_aaray[0,1,1] = 141
d_aaray[0,1,2] = 101
d_aaray[0,1,3] = 18
d_aaray[1,0,0] = 1
d_aaray[1,0,1] = 13
d_aaray[1,0,2] = 118
d_aaray[1,0,3] = 61
d_aaray[1,1,0] = 237
d_aaray[1,1,1] = 140
d_aaray[1,1,2] = 249
d_aaray[1,1,3] = 198

Click to execute on   

Irregular array

Below is a 3D irregular dynamic array example.
In example shows the array declaration, creation, assignment and displaying the array elements.

SystemVerilog 3D irregular array
SystemVerilog 3D irregular array
program dynamic_array;
  
  //dynamic array declaration
  bit [7:0] d_array[][][];
  
  initial begin
    //memory allocation
    d_array = new[2];
    
    d_array[0] = new[1];
    d_array[1] = new[2];
    
    d_array[0][0] = new[3];
    
    d_array[1][0] = new[2];
    d_array[1][1] = new[1];  
    
    //assigning random value to elements
    foreach(d_array[i,j,k]) d_array[i][j][k] = $random;
    
    //displaying array elements
    foreach(d_array[i,j,k])   
      $display("\td_aaray[%0d,%0d,%0d] = %0d",i,j,k,d_array[i][j][k]);
  end

endprogram

Simulator Output

d_aaray[0,0,0] = 36
d_aaray[0,0,1] = 129
d_aaray[0,0,2] = 9
d_aaray[1,0,0] = 99
d_aaray[1,0,1] = 13
d_aaray[1,1,0] = 141

Click to execute on   

SystemVerilog Dynamic Array Randomization

Dynamic Array Randomize

For a dynamic array, it is possible to randomize both array size and array elements.

randomize dynamic array size

In below example, dynamic array size will get randomized based on size constraint, and array elements will get random values.

  1. Declare array as rand
  2. Write constraint for array size, On randomization array size will get the random size
class dynamic_array;
  rand bit [3:0] array1[ ];
  rand bit [7:0] array2[ ];

  constraint a1_size_c { array1.size() inside {[4:10]}; }
  constraint a2_size_c { array2.size() inside {[4:10]}; }
  
  function void display();
    $display("array1 size is = %0d",array1.size());
    $display("array1 = %p",array1);
    $display("array2 size is = %0d",array2.size());
    $display("array2 = %p",array2);
  endfunction
endclass

program dynamic_array_randomization;
  dynamic_array pkt;

  initial begin
    pkt = new();
    pkt.randomize();
    pkt.display();   
  end
  
endprogram 

Simulator Output

array1 size is = 7
array1 = '{'h0, 'hf, 'he, 'h4, 'hf, 'h9, 'h8}
array2 size is = 10
array2 = '{'he, 'hab, 'hb0, 'h29, 'h57, 'h52, 'h26, 'h49, 'h34, 'h49}

Click to execute on   

array size based on another random variable

In the below example, the array size is constrained based on the value of another element.

  1. Declare array as rand
  2. On randomization, the array will get size based on the value of burst type
typedef enum {SINGLE,INCR,INCR4,WRAP4,INCR8,WRAP8} burst_t;

class dy_array;
  rand burst_t   burst_type;
  rand bit [7:0] data[ ];

  constraint data_s { 
    (burst_type == SINGLE)-> data.size() == 1;
    (burst_type == INCR)  -> data.size() == 1;
    (burst_type == INCR4) -> data.size() == 4;
    (burst_type == WRAP4) -> data.size() == 4;
    (burst_type == INCR8) -> data.size() == 8;
    (burst_type == WRAP8) -> data.size() == 8; }
  
  function void display();
    $display("burst_type = %s",burst_type.name());
    $display("data array size is = %0d",data.size());
    $display("data array = %p",data);
  endfunction
endclass

program dynamic_array_randomization;
  dy_array pkt;

  initial begin
    pkt = new();
    pkt.randomize();
    pkt.display();   
  end
endprogram 

Simulator Output

burst_type = WRAP4
data array size is = 4
data array = '{'h54, 'h88, 'h9b, 'h9a}

Click to execute on   

Generate unique elements in an array

In the below example.

  1. Constrain array with element value same as an index value
  2. In post randomization shuffle the array, so that array will not have an incremental values
class dynamic_array;
  rand bit [7:0] array[ ];
  
  constraint size_c  { array.size() inside {[4:10]}; }
  constraint array_c { foreach(array[i]) array[i] == i;}
  
  function void post_randomize();
    array.shuffle();  
  endfunction
  
  function void display();
    $display("array size is = %0d",array.size());
    $display("array = %p",array);
  endfunction
  
endclass

program dynamic_array_randomization;
  dynamic_array pkt;

  initial begin
    pkt = new();
    pkt.randomize();
    pkt.display();   
  end
endprogram 

Simulator Output

array size is = 7
array = '{'h3, 'h6, 'h2, 'h1, 'h4, 'h5, 'h0}

Click to execute on   

Sum method used in a dynamic array

In the below example, an array is randomized in such a way that the sum of all the elements equals to 45.

  1. Declare array with rand
  2. Constraint sum of an array using array method sum()
class dynamic_array;
  rand bit [7:0] array[ ];
  
  constraint size_c   { array.size() inside {[4:10]}; }
  constraint array_c  { array.sum() == 45;}
  constraint array_ec { foreach(array[i]) array[i] > 1;}
  
  function void display();
    $display("array size is = %0d",array.size());
    $display("array = %p",array);
  endfunction
endclass

program dynamic_array_randomization;
  dynamic_array pkt;

  initial begin
    pkt = new();
    pkt.randomize();
    pkt.display();   
  end
endprogram 

Simulator Output

array size is = 7
array = '{'h2, 'h15, 'h2, 'h2, 'h2, 'h2, 'he}

Click to execute on   

❮ Previous Next ❯

Systemverilog Array Randomization

SystemVerilog Randomize Array

Most of the array usage application needs randomization of an array. randomization is possible for array size as well as for array elements.

constrained randomization of array

  • It is possible to get the specific value on randomization, this can be achieved by writing/specifying the constraints.
  • During randomization, constraints of size are solved first, and then the elements constraints.

Array randomization is applicable to all the array types, The below section describes examples on array randomization and using array methods in constrained randomization.

Fixed Size Array Randomization

In a fixed size array, randomization is possible only for the array elements. as the size is fixed, it is not possible to change.

Generating random value for array elements.

In the below example, random values will be generated for array elements.

  1. Declare array as rand
  2. On randomization, the array will get random values
class fs_array;
  rand bit [3:0] array1[4];
  rand bit [7:0] array2[6];
  
  function void display();
    $display("array1 = %p",array1);
    $display("array2 = %p",array2);
  endfunction
endclass

program fixedsize_array_randomization;
  fs_array pkt;

  initial begin
    pkt = new();
    pkt.randomize();
    pkt.display();   
  end
  
endprogram 

Simulator Output

array1 = '{'he, 'h4, 'h4, 'h8} 
array2 = '{'h9b, 'h9a, 'h10, 'h5f, 'hde, 'h84}

Click to execute on   

Generate unique elements in an array

In the above example, we have seen randomization with random values. The below example shows the randomization with unique values by using the shuffle array method.

  1. Constrain array with element value same as an index value
  2. In post randomization shuffle the array, so that array will not have incremental value.
class fs_array;
  rand bit [7:0] array1[6];
  
  constraint array_c { foreach(array1[i]) array1[i] == i;}
  
  function void post_randomize();
    array1.shuffle();  
  endfunction
  
  function void display();
    $display("array1 = %p",array1);
  endfunction
  
endclass

program fixedsize_array_randomization;
  fs_array pkt;

  initial begin
    pkt = new();
    pkt.randomize();
    pkt.display();   
  end
endprogram 

Simulator Output

array1 = '{'h2, 'h1, 'h4, 'h0, 'h5, 'h3}

Click to execute on   

array sum constraint

In the below example, the array is randomized in such a way that the sum of all the elements equals 30.

  1. declare an array with rand.
  2. Constraint sum of an array using the array method sum().
class fs_array;
  rand bit [7:0] array1[6];
  
  constraint array_c { array1.sum() == 30;}
  
  function void display();
    $display("array1 = %p",array1);
  endfunction
  
endclass

program fixedsize_array_randomization;
  fs_array pkt;

  initial begin
    pkt = new();
    pkt.randomize();
    pkt.display();   
  end
endprogram 

Simulator Output

array1 = '{'h7, 'h0, 'h17, 'h0, 'h0, 'h0}

Click to execute on   

Array sum constraint with array elements

In the previous example, only the sum of array elements is considered, array elements can take any value. But in the below example array sum and also the value of each element is constrained.

  1. declare an array with rand
  2. Constraint sum of an array using the array method sum().
  3. Constraint array elements value.
class fs_array;
  rand bit [7:0] array1[6];
  
  constraint array_c { array1.sum() == 30;}
  constraint array_c_e { foreach(array1[i]) array1[i] > 2;}
  
  function void display();
    $display("array1 = %p",array1);
  endfunction
  
endclass

program fixedsize_array_randomization;
  fs_array pkt;

  initial begin
    pkt = new();
    pkt.randomize();
    pkt.display();   
  end
endprogram 

Simulator Output

array1 = '{'h7, 'h3, 'hb, 'h3, 'h3, 'h3}

Click to execute on   

Multidimensional

The below example shows the declaration and randomization of a multidimensional array with constraints.

cclass fs_array;
  rand bit [7:0] array1[3][4];
  
  constraint array_c { foreach(array1[i,j]) array1[i][j] == i*j;}
  
  function void display();
    $display("array1 = %p",array1);
  endfunction
  
endclass

program fixedsize_array_randomization;
  fs_array pkt;

  initial begin
    pkt = new();
    pkt.randomize();
    pkt.display();   
  end 
endprogram 

Simulator Output

array1 = '{'{'h0, 'h0, 'h0, 'h0}, '{'h0, 'h1, 'h2, 'h3}, '{'h0, 'h2, 'h4, 'h6}}

Click to execute on   

A multidimensional array with sum method

In below example sum of an array, elements is constrained.

cclass fs_array;
  rand bit [7:0] array1[3][4];
  
  constraint array_c { array1.sum() == 30;}
  
  function void display();
    $display("array1 = %p",array1);
  endfunction
  
endclass

program fixedsize_array_randomization;
  fs_array pkt;

  initial begin
    pkt = new();
    pkt.randomize();
    pkt.display();   
  end 
endprogram 

Simulator Output

array1 = '{'{'h0, 'h0, 'h16, 'h0}, '{'h0, 'h0, 'h0, 'h0}, '{'h0, 'h0, 'h8, 'h0}}

Click to execute on   

❮ Previous Next ❯

SystemVerilog Associative Array Randomization

Randomize Associative Array

As associative array stores entries in the sparse matrix, there is no meaning of randomizing array size. It is good to have randomization only for associative array elements.

There are no many use cases in randomizing associative array. Only to look array operations below example’s shows the possibility to randomize associative array size and elements.

randomize associative array size

In below example, associative array size will get randomized based on size constraint, and array elements will get random values

  1. Declare array with rand
  2. On randomization, the array will get random values
class assoc_array;
  rand bit [7:0] array[*];
  
  constraint size_c  { array.size() inside {[4:10]}; }
  
  function void display();
    $display("array size is = %0d",array.size());
    $display("array = %p",array);
  endfunction
endclass

program assoc_array_randomization;
  assoc_array pkt;

  initial begin
    pkt = new();
    pkt.randomize();
    pkt.display();   
  end
endprogram 

Simulator Output

array size is = 7
array = '{0x0:'h88, 0x1:'h9b, 0x2:'h9a, 0x3:'h10, 0x4:'h5f, 0x5:'hde, 0x6:'h84}

Click to execute on   

Generate random values in an array

Below example shows the associative array with the element type enum.

typedef enum {RED,GREEN,YELLOW} color_t;

class assoc_array;
  rand bit [7:0] colors[color_t];
  
  constraint colors_c { foreach(colors[ii]) colors[ii] > 4; }
  constraint colors_s { colors.num() == 3; }
  
  function void display();
    $display("colors array size is = %0d",colors.size());
    $display("colors array = %p",colors);
  endfunction
endclass

program assoc_array_randomization;
  assoc_array pkt;

  initial begin
    pkt = new();
    pkt.randomize();
    pkt.display();   
  end
endprogram

Simulator Output

colors array size is = 3
colors array = '{RED:'hab, GREEN:'h92, YELLOW:'hb}

Click to execute on   

❮ Previous Next ❯

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

Click to execute 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}

Click to execute 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

Click to execute 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

Click to execute 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.

❮ Previous Next ❯

Array Iterator index querying

SystemVerilog Array Iterator index querying

Methods discussed before works on an index or an element, but Array iterator index querying methods shall operate on both index and element.

Find array element with index example

Below example shows two types of conditions,

array_1.find with ( item == item.index );

returns the array element whose value is equal to the index value.

array_1.find(item) with ( item > item.index);

returns the array element whose value is greater than the index value.

module fixedsize_array;
  
  //declaration of array’s
  int array_1[6],array_2[6];
  int temp_qu[$],temp_cnt,temp_value;
  
  initial begin
    //array initialization
    array_1  = '{10,20,2,40,67,5};
    array_2  = '{80,4,2,40,67,5};
    
    //Type-1
    temp_qu = array_1.find with ( item == item.index );
    
    temp_cnt = temp_qu.size();
    $display("Index and Elments are same for %0d index's.",temp_cnt);
    
    for(int i=0;i<temp_cnt;i++) begin //{
      temp_value = temp_qu.pop_front();
      $display("\tsame for value %0d",temp_value);
    end //}
    
    //Type-2
    temp_qu = array_1.find(item) with ( item > item.index);
    
    temp_cnt = temp_qu.size();
    $display("Index and Elments conndition satisfied for %0d index's.",temp_cnt);
    
    for(int i=0;i<temp_cnt;i++) begin //{
      temp_value = temp_qu.pop_front();
      $display("\tfor value %0d",temp_value);
    end //}
           
  end
  
endmodule 

Simulator Output

Index and Elments are same for 2 index's.
 same for value 2
 same for value 5
Index and Elments conndition satisfied for 4 index's.
 for value 10
 for value 20
 for value 40
 for value 67

Click to execute on   

❮ Previous Next ❯

Array Reduction methods 2

Array reduction method XOR

On calling xor() method, logical xor (^) will be performed on all the array elements and returned.
Let’s consider an example of an array with 2, 3 and 4 elements.
sim
Before looking into examples, see to the Truth table for OR.

A B Y = A ^ B
0
0
0
0
1
1
1
0
1
1
1
0

1. Array with 2 elements.
Consider A=2 and B=3.
Y = A ^ B;

Binary Decimal
A
0010 2
B
0011 3
Y = A ^ B
0001 1

Consider A=2 and B=1.
Y = A ^ B;

Binary Decimal
A
0010 2
B
0001 1
Y = A ^ B
0011 3

2. Array with 3 elements.
Consider A=10, B=9, and C=8.

OR operation of 3 elements performed in 2 steps, In the first step A ^ B will be performed. In the second step result of the first step ^ C will be done. Considering X as the first step result.

X = A ^ B;
Y = X ^ C;

Binary Decimal
A
1010 10
B
1001 9
X = A ^ B
0011 3
C
1000
8
Y = X ^ C
1011
11

2. Array with 4 elements.
Consider A=3, B=5, C=7, and D=9.

Consider X and Y as intermediate results.
X = A ^ B;
Y = X ^ C;
Z = Y ^ D;

Binary Decimal
A
0011 3
B
0101 5
X = A ^ B
0110 6
C
0111
7
Y = X ^ C
0001
1
D
1001
9
Z = Y ^ D
1000
8

Complete code with above examples.

module fixedsize_array;
  
  //declaration of array’s
  int array_1[2];
  int array_2[2];
  int array_3[3];
  int array_4[4];
  
  int l_xor;
  
  initial begin
    //array initialization
    array_1  = '{2,3};
    array_2  = '{2,1};
    array_3  = '{10,9,8};
    array_4  = '{3,5,7,9};
    
    l_xor = array_1.xor();
    $display("Logical XOR of array_1 is \t%0d",l_xor);
    
    l_xor = array_2.xor();
    $display("Logical XOR of array_2 is \t%0d",l_xor);
    
    l_xor = array_3.xor();
    $display("Logical XOR of array_3 is \t%0d",l_xor);    

    l_xor = array_4.xor();
    $display("Logical XOR of array_4 is \t%0d",l_xor);    
  end
  
endmodule

Simulator Output

Logical XOR of array_1 is 1
Logical XOR of array_2 is 3
Logical XOR of array_3 is 11
Logical XOR of array_4 is 8

Click to execute on   

Array reduction methods SUM, PRODUCT using ‘with’ clause

Condition or expression specified within the with clause will be applied to all the array elements during array reduction methods.

array_1  = '{1,2,3,4};
array_1.sum with (item * 2);

the item indicates the array element.
each array element will be multiplied by 2 and then the sum method will be performed.

Intermediate array elements after multiplication with 2 is ‘{2,4,6,12};
sum method will be performed on new array elements. sum = 2+4+6+12;

Below is an example of sum and product methods using with clause.

module fixedsize_array;
  
  //declaration of array’s
  int array_1[4];
 
  int t_sum,t_product;
  
  initial begin
    //array initialization
    array_1  = '{1,2,3,4};

    t_sum = array_1.sum with (item * 2); 
    //t_sum = (1*2)+(2*2)+(3*2)+(4*2) = 2+4+6+8
    $display("Sum of array_1 is \t%0d",t_sum);

    t_product = array_1.product with (item + 2); 
    //t_product = (1+2)*(2+2)*(3+2)*(4+2) = 3*4*5*6
    $display("product of array_1 is \t%0d",t_product);
  end
  
endmodule 

Simulator Output

Sum of array_1 is 20
product of array_1 is 360

Click to execute on   

Array reduction methods AND, OR and XOR using ‘with’ clause

The operation of these methods is the same as the above example.

module fixedsize_array;
  
  //declaration of array’s
  int array_1[2];
  int array_2[2];
  int array_3[2];
  
  int b_and,b_or,l_xor;
  
  initial begin
    //array initialization
    array_1  = '{2,3};
    array_2  = '{2,1};
    array_3  = '{1,3};
    
    b_and = array_1.and with (item * 2);
    $display("Bit-wise AND of array_1 is \t%0d",b_and);
    
    b_or = array_2.or with (item + 3);
    $display("Bit-wise OR of array_2 is \t%0d",b_or);
    
    l_xor = array_3.xor with (item * 3);
    $display("Logical XOR of array_3 is \t%0d",l_xor);       
  end
  
endmodule

Simulator Output

Bit-wise AND of array_1 is 4
Bit-wise OR of array_2 is 5
Logical XOR of array_3 is 10

Click to execute on   

Array reduction methods on Dynamic and Associative arrays

Examples seen before are on fixed size array, below example is on a dynamic and associative array.

module dyn_asoc_array;
  
  //declaration of array’s
  int dyn_array[];
  int asoc_array[*];
 
  int t_sum,t_product;
  
  initial begin
    dyn_array = new[4];
    
    //array initialization
    dyn_array  = '{1,2,3,4};
    
    asoc_array[3] = 8;
    asoc_array[5] = 2;
    asoc_array[7] = 6;
    asoc_array[9] = 1;

    t_sum = dyn_array.sum(); //t_sum = 1+2+3+4
    $display("Sum of dyn_array is \t\t%0d",t_sum);

    t_product = dyn_array.product(); //t_product = 1*2*3*4
    $display("product of dyn_array is \t%0d",t_product);
    
    t_sum = asoc_array.sum(); //t_sum = 8+2+6+1
    $display("Sum of asoc_array is \t\t%0d",t_sum);

    t_product = asoc_array.product(); //t_product = 8*2*6*1
    $display("product of asoc_array is \t%0d",t_product);    
    
  end
  
endmodule 

Simulator Output

Sum of dyn_array is 10
product of dyn_array is 24
Sum of asoc_array is 17
product of asoc_array is 96

Click to execute on   

❮ Previous Next ❯

SystemVerilog Array Locator methods

Array locator methods

Array locator methods are useful for finding the index or elements of an array.

  • operate on any unpacked arrays and queues.
  • the return type of these methods is a queue.
  • with an expression, Array elements or indexes can be searched.

Built-in array locator methods can be classified as, element finder and index finder.

element finder methods:

Method Description
find() returns all the elements satisfying the given expression
find_first() returns the first element satisfying the given expression
find_last() returns the last element satisfying the given expression
min() returns the element with the minimum value or whose expression evaluates to a minimum
max() returns the element with the maximum value or whose expression evaluates to a maximum
unique() returns all elements with unique values or whose expression is unique

index finder methods:

Method Description
find_index() returns the indexes of all the elements satisfying the given expression
find_first_index() returns the index of the first element satisfying the given expression
find_last_index() returns the index of the last element satisfying the given expression
unique_index() returns the indexes of all elements with unique values or whose expression is unique

‘with’ clause is optional for min,max,unique and unique_index methods

Array Index Finder methods

Index finder method shall return single or multiple indexes which satisfies the condition.
The condition also shall be single or multiple conditions. multiple conditions can be written on using conditional expressions. example: &&, || etc.
Below example shows the return of single and multiple index return.

class packet;
  int a;
  int b;
  
  function void display();
    $display("\tValue of a = %0d",a);
    $display("\tValue of b = %0d",b);
  endfunction
endclass


module assoc_array;
  
  //declaration of array
  packet assoc_array[*];
  packet pkt;
  int    count,qu[$],tmp_var;
  
  initial begin
    
    pkt = new();
    pkt.a = 8;
    pkt.b = 3;
    assoc_array[2] = pkt;
    
    pkt = new();
    pkt.a = 0;
    pkt.b = 6;
    assoc_array[5] = pkt;
    
    pkt = new();
    pkt.a = 2;
    pkt.b = 6;
    assoc_array[6] = pkt;
        
    pkt = new();
    pkt.a = 1;
    pkt.b = 6;
    assoc_array[9] = pkt;
    //----------------------------------------------------------------------------
    //------- Find Index Method -------
    //----------------------------------------------------------------------------
    
    //Type-1: returning one matching index
    qu = assoc_array.find_index with (item.a == 'h2);
    count = qu.size();
    
    for(int i=0;i<count;i++) begin //{
      tmp_var = qu.pop_front();
      $display("Index of Asoc Array for a == 2 is %0d",tmp_var);
    end //}
    
    //Type-2: returning mutiple matching index
    qu = assoc_array.find_index with (item.b == 6);
    count = qu.size();
    
    for(int i=0;i<count;i++) begin //{
      tmp_var = qu.pop_front();
      $display("Index of Asoc Array for b == 6 is %0d",tmp_var);
    end //}
    
    //Type-3: with multiple conditions
    qu  = assoc_array.find_index with (item.a == 2 && item.b == 6);
    count = qu.size();
    
    for(int i=0;i<count;i++) begin //{
      tmp_var = qu.pop_front();
      $display("Index of Asoc Array for a == 2,  b == 6 is %0d",tmp_var);
    end //}
    
    //Type-4: with multiple conditions
    qu  = assoc_array.find_index with (item.a < 2 && item.b > 5);
    count = qu.size();
    
    for(int i=0;i<count;i++) begin //{
      tmp_var = qu.pop_front();
      $display("Index of Asoc Array for a < 2,  b > 5 is %0d",tmp_var);
    end //}
  end
endmodule

Simulator Output

Index of Asoc Array for a == 2 is 6
Index of Asoc Array for b == 6 is 5
Index of Asoc Array for b == 6 is 6
Index of Asoc Array for b == 6 is 9
Index of Asoc Array for a == 2, b == 6 is 6
Index of Asoc Array for a < 2, b > 5 is 5
Index of Asoc Array for a < 2, b > 5 is 9

Click to execute on   

Array Index Finder methods FIRST_MATCH and LAST_MATCH

class packet;
  int a;
  int b;
  
  function void display();
    $display("\tValue of a = %0d",a);
    $display("\tValue of b = %0d",b);
  endfunction
endclass


module assoc_array;
  
  //declaration of array
  packet assoc_array[*];
  packet pkt;
  int    cnt,qu[$],tmp_var;
  
  initial begin
    
    pkt = new();
    pkt.a = 3;
    pkt.b = 8;
    assoc_array[2] = pkt;
    
    pkt = new();
    pkt.a = 8;
    pkt.b = 3;
    assoc_array[5] = pkt;
    
    pkt = new();
    pkt.a = 2;
    pkt.b = 6;
    assoc_array[6] = pkt;
    
    pkt = new();
    pkt.a = 8;
    pkt.b = 3;
    assoc_array[8] = pkt;
    
    pkt = new();
    pkt.a = 8;
    pkt.b = 3;
    assoc_array[9] = pkt;
    
    //----------------------------------------------------------------------------
    //------- Find First/Last Index Method -------
    //----------------------------------------------------------------------------
    
    //Type-1: returning first matching index
    qu = assoc_array.find_first_index with (item.a == 8);
    cnt = qu.size();
    
    for(int i=0;i<cnt;i++) begin //{
      tmp_var = qu.pop_front();
      $display("First Index of Asoc Array for a == 8 is %0d",tmp_var);
    end //}
    
    //Type-2: returning first matching index
    qu = assoc_array.find_first_index with (item.a == 8 && item.b == 3);
    cnt = qu.size();
    
    for(int i=0;i<cnt;i++) begin //{
      tmp_var = qu.pop_front();
      $display("First Index of Asoc Array for a == 8,  b == 3 is %0d",tmp_var);
    end //}
    
    //Type-3: returning last matching index
    qu = assoc_array.find_last_index with (item.a == 8 &&  item.b == 3);
    cnt = qu.size();
    
    for(int i=0;i<cnt;i++) begin //{
      tmp_var = qu.pop_front();
      $display("Last Index of Asoc Array for a == 8,  b == 3 is %0d",tmp_var);
    end //}
    
  end
endmodule 

Simulator Output

First Index of Asoc Array for a == 8 is 5
First Index of Asoc Array for a == 8, b == 3 is 5
Last Index of Asoc Array for a == 8, b == 3 is 9

Click to execute on   

Array Element Finder methods

class packet;
  int a;
  int b;
  
  function void display();
    $display("\tValue of a = %0d",a);
    $display("\tValue of b = %0d",b);
  endfunction
endclass


module assoc_array;
  
  //declaration of array
  packet assoc_array[*];
  packet pkt,tmp_var,qu[$];
  int    cnt;
  
  initial begin
    
    pkt = new();
    pkt.a = 8;
    pkt.b = 3;
    assoc_array[2] = pkt;
    
    pkt = new();
    pkt.a = 0;
    pkt.b = 6;
    assoc_array[5] = pkt;
    
    pkt = new();
    pkt.a = 2;
    pkt.b = 6;
    assoc_array[6] = pkt;
        
    pkt = new();
    pkt.a = 1;
    pkt.b = 6;
    assoc_array[9] = pkt;
    
    //----------------------------------------------------------------------------
    //------- Find Element Method -------
    //----------------------------------------------------------------------------
    
    //Type-1: returning one matching element
    qu = assoc_array.find with (item.a == 'h2);
    cnt = qu.size();
    
    $display("Elements of Asoc Array for a == 2 are,");
    for(int i=0;i<cnt;i++) begin //{
      tmp_var = qu.pop_front();
      $display("Element No: %0d",i+1);
      tmp_var.display();
    end //}
    
    //Type-2: returning mutiple matching element
    qu = assoc_array.find with (item.b == 6);
    cnt = qu.size();
    
    $display("Elements of Asoc Array for b == 6 are,");
    for(int i=0;i<cnt;i++) begin //{
      tmp_var = qu.pop_front();
      $display("Element No: %0d",i+1);
      tmp_var.display();
    end //}
    
    //Type-3: with multiple conditions
    qu  = assoc_array.find with (item.a == 2 && item.b == 6);
    cnt = qu.size();
    
    $display("Elements of Asoc Array for a == 2,  b == 6,");
    for(int i=0;i<cnt;i++) begin //{
      tmp_var = qu.pop_front();
      $display("Element No: %0d",i+1);
      tmp_var.display();
    end //}
 
    //Type-4: with multiple conditions
    qu  = assoc_array.find with (item.a < 2 && item.b > 5);
    cnt = qu.size();
    
    $display("Elements of Asoc Array for a < 2,  b > 5,");
    for(int i=0;i<cnt;i++) begin //{
      tmp_var = qu.pop_front();
      $display("Element No: %0d",i+1);
      tmp_var.display();
    end //}
  end
endmodule 

Simulator Output

Elements of Asoc Array for a == 2 are,
Element No: 1
 Value of a = 2
 Value of b = 6
Elements of Asoc Array for b == 6 are,
Element No: 1
 Value of a = 0
 Value of b = 6
Element No: 2
 Value of a = 2
 Value of b = 6
Element No: 3
 Value of a = 1
 Value of b = 6
Elements of Asoc Array for a == 2, b == 6,
Element No: 1
 Value of a = 2
 Value of b = 6
Elements of Asoc Array for a < 2, b > 5,
Element No: 1
 Value of a = 0
 Value of b = 6
Element No: 2
 Value of a = 1
 Value of b = 6

Click to execute on   

Array Element Finder methods FIND_FIRST and FIND_LAST along ‘with’ clause

class packet;
  int a;
  int b;
  
  function void display();
    $display("\tValue of a = %0d",a);
    $display("\tValue of b = %0d",b);
  endfunction
endclass


module assoc_array;
  
  //declaration of array
  packet assoc_array[*];
  packet pkt,qu[$],tmp_var;
  int    cnt;
  
  initial begin
    
    pkt = new();
    pkt.a = 3;
    pkt.b = 8;
    assoc_array[2] = pkt;
    
    pkt = new();
    pkt.a = 8;
    pkt.b = 3;
    assoc_array[5] = pkt;
    
    pkt = new();
    pkt.a = 2;
    pkt.b = 6;
    assoc_array[6] = pkt;
    
    pkt = new();
    pkt.a = 8;
    pkt.b = 3;
    assoc_array[8] = pkt;
    
    pkt = new();
    pkt.a = 8;
    pkt.b = 3;
    assoc_array[9] = pkt;
    
    //----------------------------------------------------------------------------
    //------- Find First/Last element Method -------
    //----------------------------------------------------------------------------
    
    //Type-1: returning first matching element
    qu = assoc_array.find_first with (item.a == 8);
    cnt = qu.size();
    
    $display("First Element of Asoc Array for a == 8 are,");
    for(int i=0;i<cnt;i++) begin //{
      tmp_var = qu.pop_front();
      $display("Element No: %0d",i+1);
      tmp_var.display();
    end //}
    
    //Type-2: returning first matching element
    qu = assoc_array.find_first with (item.a == 8 && item.b == 3);
    cnt = qu.size();
    
    $display("First Element of Asoc Array for a == 8 , b == 3 are,");
    for(int i=0;i<cnt;i++) begin //{
      tmp_var = qu.pop_front();
      $display("Element No: %0d",i+1);
      tmp_var.display();
    end //}
    
    //Type-3: returning last matching element
    qu = assoc_array.find_last with (item.a == 8 &&  item.b == 3);
    cnt = qu.size();
    
    $display("Last Element of Asoc Array for a == 8 , b == 3 are,");
    for(int i=0;i<cnt;i++) begin //{
      tmp_var = qu.pop_front();
      $display("Element No: %0d",i+1);
      tmp_var.display();
    end //}    
  end
endmodule 

Simulator Output

First Element of Asoc Array for a == 8 are,
Element No: 1
 Value of a = 8
 Value of b = 3
First Element of Asoc Array for a == 8 , b == 3 are,
Element No: 1
 Value of a = 8
 Value of b = 3
Last Element of Asoc Array for a == 8 , b == 3 are,
Element No: 1
 Value of a = 8
 Value of b = 3

Click to execute on   

Array Element Finder methods min and max

module fixedsize_array;
  
  //declaration of array’s
  int array_1[4];
  int temp_value[$];
  
  initial begin
    //array initialization
    array_1  = '{80,20,3,40};
    
    temp_value = array_1.min(); 
    $display("Min value elenent of array_1 is \t%p",temp_value);

    temp_value = array_1.max(); 
    $display("Max value elenent of array_1 is \t%p",temp_value);       
  end
  
endmodule 

Simulator Output

Min value elenent of array_1 is '{3} 
Max value elenent of array_1 is '{80}

Click to execute on   

❮ Previous Next ❯