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,

Friday, August 7, 2020

TYPEDEF Class in System Verilog

Hi Everyone !!!

    Today We are going to see the concepts of typedef class in System Verilog.

    A typedef used to provide a forward declaration of the class. In some use case, the class needs to be instantiated/used before the class declaration. For this kind of situation, typedef  is used.

Syntax :

typedef class class_name;

Typedef Examples:

Without typedef

 In the below example. There are two classes class1 and class2. class2 is instantiated class1 and class1 is instantiated class2. Both the classes need the handle of each other. As execution will happen in sequential order. So it leads to compilation error.

//class-1
class class1;
  class2 c;    //using class2 handle before declaring it.
endclass
 
//class-2
class class2;
  class1 c;
endclass
  
module  tb;
  initial begin
    class1 c1;
    class2 c2;
    $display("Inside typedef_class");
  end
endmodule
OUTPUT:
Error-[SE] Syntax error
Following verilog source has syntax error :
token 'class2' should be a valid type. Please declare it virtual if it
is an Interface.
"test1.sv", 6: token is ';'
class2 c;

With typedef

 When compiler sees typedef class it will know the definition of the class will found on later. The compilation error of the above example can be avoided by using typedef


typedef class class2; //Indication to the compiler class2 might be used before declaration
//class-1
class class1;
  class2 c;    // compiler knows declaration may come later.
endclass
 
//class-2
class class2;
  class1 c;
endclass
  
module tb;
  initial begin
    class1 c1;
    class2 c2;
    $display("Inside typedef_class");
  end
endmodule
OUTPUT:
Inside typedef_class
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  

"Doing Nothing for others is the undoing of ourselves".
                                                                                             - Horace Mann

                                          



Sunday, August 2, 2020

How to Randomize a Real Variable?

Hi Everyone !!!,
    In This session we are going to see how to Randomize a Real variable.
  Using randomize() method we can able to randomize only integral data-type variables only(bit,logic,reg,wire,integer,enum, packed struct). 
    Here I show the two ways to randomize variable of type real.

Example 1:
In below mentioned code I am trying to randomize real data types,It leads to compilation error. LRM won't support real and string data_types for Randomization.

class rand_rdata;
  rand real rdata;
endclass
module TB;
  rand_rdata r;
  initial begin
    r=new();
    r.randomize();
    repeat(5) begin
      $display(" REAL DATA %0d ",r.rdata);
    end
  end
endmodule

OUTPUT:
TimeScale is 1 ns / 1 ns

Error-[IRRVD] Illegal rand variable type
testbench.sv, 16
"rdata"
The rand variable 'rdata' must be an integral type, an enum type, a packed
struct, or of type 'bit'.
Change the type of the random variable 'rdata' to an integral, bit, packed
struct, or enum type or remove the 'rand' qualifier.

1 error

$bitstoreal converts the bit value to a real number. By using this system function real values can be generated.  Real value randomization Logic's are explained in Example 2&3.

Example 2:
class rand_real;
  rand bit [63:0] data;
  real rdata;
  function void post_randomize();
    this.rdata = $bitstoreal(data);  // This is the trick here. (Randomized data value is converted to Real value by using system function)
  endfunction
endclass

module top();
  rand_real R;
  initial begin
    R = new();
    repeat (4) begin
      if (R.randomize()) begin
        $display ("R.data=%0d, R.rdata=%e", R.data, R.rdata);
      end
      else begin
      $error ("Randomization Failed");
      end
    end
  end
endmodule

OUTPUT:
R.data=11603960314292000697, R.rdata=-1.560983e-149
R.data=5297240865832474715, R.rdata=1.397281e+46
R.data=17254093185709081402, R.rdata=-7.145857e+228
R.data=12279536430588681223, R.rdata=-2.239116e-104
V C S S i m u l a t i o n R e p o r t

Example 3:
class rand_real;
  rand integer i, j;
  real rdata;
  function void post_randomize();
    this.rdata = $bitstoreal({i, j}); //This is the trick here (Randomized i,j converted to equivalent real here)
  endfunction
endclass

module TB();
  rand_real R;
  initial begin
    R = new(); 
    repeat (5) begin
      if (R.randomize()) begin
        $display ("R.i=%0d, R.j=%0d, R.real_data=%e", R.i, R.j, R.rdata);
      end
      else begin
      $error ("Randomization Failed");
      end
    end
  end
endmodule

OUTPUT:
R.i=-384116807, R.j=-1593209748, R.real_data=-2.006518e+198
R.i=1637914715, R.j=1233360000, R.real_data=1.866503e+162
R.i=397247290, R.j=-277685674, R.real_data=1.263399e-194
R.i=-407577593, R.j=-1435914926, R.real_data=-3.717586e+191
R.i=-1298805792, R.j=-1452694196, R.real_data=-5.174229e-65
V C S S i m u l a t i o n R e p o r t


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  


"Be a lifelong student. The more you learn, the more you earn and the more self-confidence you will have" - Brain Tracy


`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 ...