Monday, July 27, 2020

Race Conditions in Verilog

Hi Everyone !!!!,

In this article we are going to see the race conditions in verilog,

Race Condition:
  When two or more expressions are executed at the same time step, and if the order of the execution is nondeterministic, then the race condition occurs.

Method 1:
    module race;
        wire p;
        reg q;
        assign p=q;
        initial begin
        q=1;
        #1 q=0;  
        #display(p);
        end
    endmodule

Because the execution of expression evaluation and net update events may be intermingled, race conditions are possible.
Whenever "
The simulator is correct in displaying either a 1 or a 0. The assignment of 0 to q enables an update event for p. The simulator may either continue and execute the $display task or execute the update for p, followed by the $display task.
Method 2:
  module race2;
   bit clk;
   reg[3:0] a;
   always #5 clk=~clk;
   always @( posedge clk) 
     a=1;
   always @ ( posedge clk)
     a=5;
   initial begin 
     #1000 $finish;
   end
 endmodule

Race Condition occurs when same register is written in both the blocks. Here you are seeing that one block is updating value of "a" while another also. Now which always block should go first. This is nondeterministic in IEEE standard.

Method 3:
   module race2;
   bit clk;
   reg[3:0] a;
   bit b;
   always #5 clk=~clk;
   always @( posedge clk) 
     a=1;
   always @ ( posedge clk)
     b=a;
   initial begin 
     #1000 $finish;
   end
 endmodule

Race Condition occurs when evaluation and assignment of same variable with the same clk edge.

How to Prevent Race Condition:
  • Using Non Blocking Statements
  • Using Program Block
  • Using Clocking Block
  • DUT and TB must be operated on different edges of same clk pulses
Note:
Brief explanation about Program Block and Clocking Block  will see on further upcoming Blogs.

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 Sure You Put Your Feet In The Right Place, Then Stand Firm"
                                                                                       -Abraham Lincoln



Saturday, July 25, 2020

How to Randomize a Non Random Variable in System Verilog

Hi Everyone!!!!

Today we are going to see the concepts of "How to randomize a Non random Variable "

 System verilog supports multiple methods to generate random data. By using any of these we can randomize a variable.

System Verilog randomization methods
  • $urandom() and $random
  • $urandom_range()
  • std::randomize()
  • randomize()                                                                                                                      
By Using $urandom() and random()       
  •         This function returns a new 32 bit random number.
  •          $random generates signed number.
  •          $urandom generates unsigned number.      
By using $urandom_range()
  •           The $urandom_range() function returns an unsigned integer within a specified range. 
  •           The function shall return an unsigned integer in the range of maxval ... minval.
    Example 1:
    val = $urandom_range(7,0);
    If minval is omitted, the function shall return a value in the range of maxval ... 0.
    Here it will produce  (7..0)
    Example 2:
    val = $urandom_range(7);
    If maxval is less than minval, the arguments are automatically reversed so that the first argument
    is larger than the second argument.
    Example 3:
    val = $urandom_range(0,7);
    All of the three previous examples produce a value in the range of 0 to 7, inclusive.

By Using std::randomize()
     Variables can be randomized by using std::randomize. It can allowed the inline constraint using "with" clause.
       We can also use as below,
  •           std::randomize(variable)
  •           std::randomize(variable) with {constraints;};
By Using randomize() 
    The randomize() method can be used to temporarily control the set of random and state variables within a class instance or object. 
     When the randomize() method is called with no arguments, it randomize only rand/randc variables.
     When randomize() is called with arguments, those arguments only will be randomized irrespective of rand/randc declaration.
Example:

    class non_random;
        rand byte x, y;   //random variables
        byte v, w;           //state variables
    endclass
    module TB;
        initial begin
            non_random a = new();
            a.randomize();         // Here random variables(x,y) only will be randomized and v,w won't randomize since it is a state variable
           a.randomize( x );     // Here X alone will be randomized others will be treated as state variable even we declare a variable as rand/randc
           a.randomize( v, w ); // Here v,w are randomized and other variable will be treated as state variable
           a.randomize( w, x ); // Here w,x are randomized 
        end
   endmodule

This mechanism controls the set of active random variables which is conceptually equivalent to making a set of calls to the rand_mode() method to disable or enable.


TRICKY EXAMPLES
 1)        module example;
             bit[31:0] data1;
             bit[63:0] data2;
             bit[31:0] data3;
             bit[31:0] data4;
             bit[31:0] data5;
             bit[31:0] data6;
             bit[31:0] number;
             initial begin
             repeat(10) begin
                       data1=$urandom();  //It will produce 32 bit unsigned number
                       data2={$urandom(),$urandom()};    // It will produce 64 bit unsigned number
                       data3=$random; //It will produce 32 bit signed number
                       data3=$unsigned($random); //It will produce a 32 bit unsigned number
                       data4=$urandom_range(50,30); //It will produce 50 to 30 ranges of values
                       data5=$urandom_range(30); // It will produce 0 to 30 values only
                       data6=$urandom%10 //It will produce 0 to 9 number only
                       number = $urandom & 15; // 4-bit  unsigned random number will be produced. Generally $urandom produce 32 bit number and doing "AND" operation of 15 we will generate random 4 bit number. This is one Trick.
            end
            end
           endmodule
        
 2) 
        module example2;
            bit[7:0] data;
            initial begin
            repeat(4) begin
               std::randomize(data)with{data<4}; //It randomize and produce value less than 4 values only
            end
            end
         endmodule

Note:

The seed is an optional argument that determines the sequence of random numbers generated. The seed can be any integral expression. $urandom(int seed), $random( int seed). For particular seed the same value will be generated whenever we trigger the simulation.


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   

"A truly strong person does not need the approval of others any more than a lion needs the approval
of sheep." --Vernon Howard



Thursday, July 23, 2020

Blocking and Non Blocking in Verilog

Hi Everyone !!!,

In this session we are going to the concepts and tricky codes about Blocking and Non Blocking in Verilog, 
Blocking Statement:
    Blocking statement executed sequentially. It blocks the next statement execution until the current statement completion.
    Blocking statement is a one step process. Which means Evaluate the RHS of the expression and update the LHS in same time step.
    Blocking statements are executed in active region.Blocking statement always suffer from Race condition since two process (Evaluation&assignment)  happens in same time step.
      Blocking statements can be used in always,initial and assign statements.
    Syntax:
          value= <timing control><expression?
       
         Here value is data type that is valid for procedural assignment statement
                is the assignment operator
         timing control- can either be delay control (#6) or en event control (eg: @posedge clk)
      eg: data=0; 
            a= #4 1;
Non Blocking Statement:  
        Non Blocking statement executed parallel. It allows you to schedule a assignment without blocking the procedural flow. It doesn't block the next statement until the current statement completion.
          Non Blocking statement occurred in active region and LHS assignment will happen in Non Blocking Assignment (NBA) region.  
        Non Blocking is a two step process:
                * Evaluate the RHS expression at the beginning of time step .
                * LHS assignment will be happened at the end of time step.
         Non Blocking statements can be used in always,initial. It can't be used in assign statement.
           
 Syntax:
          value<= <timing control><expression?
       
         Here value is data type that is valid for procedural assignment statement
                <=  is the assignment operator
         timing control- can either be delay control (#6) or en event control (eg: @posedge clk)
      eg: data<=0; 
            a<= #4 1;

Note:
       For combinational logic blocking and sequential logic non blocking assignments are preferred.
       

TRICKY PROGRAMS!!!!!!!

1)            module example1;
                    reg a=0,b=1;
                    initial begin
                       a<=b;
                       b<=a;
                        $monitor("a=%0d,b=%0d",a,b)
                     end
                endmodule
output:
    a=1,b=0
                     
Working logic:
            Evaluation of RHS will happens in first time step(active region)
            Assignment happens in at the end of time step(non blocking region). So values gets swapped.
            For swapping two variable without using third variable non blocking assignment will be used.

2)          module example2;
                  reg a,b,c,d,e,f;
                  //**Blocking Assignments
                  initial begin
                      a= #10 1;  //Here simulator assigns 1 for a at time of 10
                      b= # 2 0;  // B gets assigned at simulation time of 12
                      c= #4   1; // C gets assigned at simulation time of 16
                   end
                 //** Non Blocking Assignments
                   initial begin
                       d<= #10; //Here simulator assigns 1 for a at time of 10
                       e<=#2 0; // e gets assigned at simulation time of 2
                       f<=#4 1; // f gets assigned at simulation time of 4
                    end
                   initial begin
                        $monitor($time,"a=%b b=%b c=%b d=%b e=%b f=%b",a,b,c,d,e,f);
                   end
                 endmodule

3)     When you schedule multiple non-blocking assignments to occur in same variable in a particular time slot, the simulator cannot guarantee the order in which it processes the assignments. the final value of the variable is indeterminate.

                 module example3;
                    reg a=1;
                    initial begin
                       a<=#4 0;
                       a<=#4 1;
                        $monitor("a=%0d,b=%0d",a,b)
                     end
                endmodule
output:
    Here "a" value is indeterminate.

4)       If the simulator executes two procedural bloks concurrently and the procedural block contains non blocking assignment operators with same time delay so the final value is indeterminate.
                module example4;
                    reg a;
                    initial  a<=#4 0;
                    initial  a<=#4 1;
                    initial begin
                        $monitor("a=%0d,b=%0d",a,b)
                     end
                endmodule
output:
    Here "a" value is indeterminate.

5)        When multiple Non Blocking assignments with timing controls are made to same variable. the assignments can be made without cancelling previous non blocking assignments.

               module example5;
                    reg a=0;
                    reg[2:0] i;
                    initial begin
                        for(i=0;i<=5;i++) begin
                            a<=#(i*10)i[0];
                        end
                    end
                endmodule

Output:
        @time 0   a=0;
        @time 10 a=1;
        @time 20 a=0;
        @time 30 a=1;
        @time 40 a=0;
        @time 50 a=1;

Hope this logics 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   

"You have power over your mind-not outside events.
  Realize this, and you will find strength"





Wednesday, July 22, 2020

How to Swap a two variable with and without using temporary variable in System Verilog

Hi Everyone !!!!,
                  In this session we are going to see the methods of swapping a two variables with and without using temporary variables in System Verilog.

Method 1:
                  By using non blocking statement.
                                  
                                      module TB;
                                           int a=10,b=15;
                                           initial begin 
                                              a<=b;
                                              b<=a;
                                               $monitor(" Values of a=%0d b=%0d",a,b);
                                           end
output:
                         Values of a=15 b=10

Note:
      Non blocking statements executes parallelly  and assign the values at the end of current time step. We will see brief info about blocking and non blocking in further blogs.

Method 2:
                  By using xor operators.

                                        module TB;
                                           int a=10,b=15;
                                           initial begin 
                                              a=a^b;  // a=(1010)^(1111)->0101
                                              b=a^b; //b=(0101)^(1111)=1010->10
                                              a=a^b; //a=(0101)^(1010)=1111->15
                                              $display(" Values of a=%0d b=%0d",a,b);
                                        end
output:
                         Values of a=15 b=10 

Method 3:

                       By using addition and subtraction operators. But it won't support for signed numbers.

                                        module TB;
                                           int a=10,b=15;
                                           initial begin 
                                              a=a+b;  // a=25
                                              b=a-b;   //b=25-15->10
                                              a=a-b;   //a=25-10->15
                                              $display(" Values of a=%0d b=%0d",a,b);
                                        end
output:
                         Values of a=15 b=10 

Method 4:
                       By using  multiplication and division operators.

                                        module TB;
                                           int a=10,b=15;
                                           initial begin 
                                              a=a*b;  // a=150
                                              b=a/b;  //b=150/15->10
                                              a=a/b;  //a=150/10->15
                                              $display(" Values of a=%0d b=%0d",a,b);
                                        end
output:
                         Values of a=15 b=10 

Method 5:

                    By using temporary variable.
                                
                                       module TB;
                                           int a=10,b=15, temp;
                                           initial begin 
                                              temp=a;
                                                    a=b;
                                                    b=temp;
                                              $display(" Values of a=%0d b=%0d",a,b);
                                        end
output:
                                  Values of a=15 b=10 


Hope this logics 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   

"The world breaks everyone, and afterward, Some are strong at the broken places." 
                                                                                                         
                                                                                        -Ernest Hemingway 

Data Hiding and Encapsulation in System Verilog

Hi Everyone !!!,
    In this section we are going to see concepts of Data Hiding&Encapsulation in System Verilog.
  
    We may use the Base Classes or Base Class library provided by third party sources. We have seen how to access the Class properties and methods. For example "Class Members" in system verilog can be accessed using the class handles. By Default Class members are Public in nature  which means class members can be accessed directly from outside of that class. 
     Data hiding is the process of hiding or making visible of properties  in particular places of the class by using local and protected keywords is known as data hiding.
     For safety purpose or preventing corruption of logic's in base classes system verilog supports two qualifiers .
        Two Qualifiers
      * Local                    * Protected 
Local Qualifier:
       By declaring properties as local. We can't access the outside of the class.

      Example:
        1)                  class  data_hide;
                                local int x;  //** here integer x is declared as "local"
                             endclass
                             module TB;
                                   data_hide  d;
                                   initial begin
                                          d=new();
                                          d.x=10;  //** here we are accessing local qualifier variable in outside of the class which is not possible it leads to compilation error.
                                   end
                             endclass

2)                      class  data_hide;
                                local int x;  //** here integer x is declared as "local"
                                   task display();
                                      x=5;
                                      $display("Value %0d",x);  //it is allowed to use base class only
                                   endtask
                             endclass
                             module TB;
                                   data_hide  d;
                                   initial begin
                                          d=new();
                                          d.display();  
                                   end
                             endclass
     
Note : local qualifier properties are not allowed to access outside of the class and derived classes.

         3)               class parent;
                                  local int x;  //** here integer x is declared as "local"
                            endclass
                           class child extends parent;
                               x= 10;   /** here we are accessing  local qualifier variable in derived which is not possible it leads to compilation error.
                            endclass

Protected Qualifier:
       By declaring properties as protected. We can't access the outside of the class . Which is allowed to access in derived class and parent class only.

        Example:
        1)                  class  data_hide;
                                protected int x;  //** here integer x is declared as "protected"
                             endclass
                             module TB;
                                   data_hide  d;
                                   initial begin
                                          d=new();
                                          d.x=10;  //** here we are accessing protected qualifier variable  in outside of the class which is not possible it leads to compilation error.
                                   end
                             endclass 
        
       
      2)                   class parent;
                                  protected int x;  //** here integer x is declared as "protected"
                            endclass
                           class child extends parent;
                               x= 10;   /** protected variables are allowed to use derived class (child)only
                            endclass
                         

Note: We can declare function/tasks/variables as local or protected based on our use case.


Constant Class Properties:
               Sometimes in our Base Classes, We need some our class Properties to be read only & not allowed to change those Properties. This behavior can be achieved by using "const" keyword.
                Which means if the class property is declared with const keyword , it can not be modified or updated whole run time. It is two types.
                             *Global Constant
                              *Instance Constant

Global Constants:
                The value is assigned at the time of declaration with const qualifier. Then the same value is kept by that property. We are not allowed to change the property anywhere other than in the declaration till the run time. 
                   Example:
                                              class glob_const;
                                                 const int data=10;  //Global constants  ( global constants are allowed to assign to a non const variable and not allowed to override (allowed to declare static const int data also//
                                                 byte addr[];
                                                 function new(int size);
                                                     addr=new[size > data?data:size];
                                                 endfunction
                                            endclass
                                             module TB;
                                                 glob_const p;
                                                  initial begin
                                                      p=new(2);
                                                   end
                                               endmodule
                                              
                    2)
               
                                            class glob_const;
                                                 const int data=10;  //Global constants
                                                 byte addr[];
                                                 function new(int size);
                                                      data=15;  //Here I try to override global constant variable it leads to compilation error.
                                                     addr=new[size > data?data:size];
                                                 endfunction
                                            endclass
                                             module TB;
                                                 glob_const p;
                                                  initial begin
                                                      p=new(2);
                                                   end
                                               endmodule
                                           
Instance Constants:
                 For instance Constant properties, It has a two step process. First the property is declared inside the class with const keyword. Second the value to that property is assigned inside the constructor of that class. Here after , this initialized value is not allowed to be modify. 

Lets see an brief example 
                
                                                class inst_const;
                                                 const int data;  //Instance constants (not allowed to declare as static const int)
                                                 byte addr[];
                                                 function new();
                                                      data=$urandom%4096;  //one assignment in new-> its allowed in instance constant
                                                     addr=new[ data];
                                                 endfunction
                                            endclass
                                             module TB;
                                                 inst_const p;
                                                  initial begin
                                                      p=new();
                                                   end
                                               endmodule

Keypoints:
            Instance constants do not include an initial value in their declaration. This type of constants can be assigned a value at run time, but assignment can only done in the corresponding class constructor.
            Global constants are allowed to declare static because they same for all instances of the class.But instance constant can't be declared as static because it won't allow the assignment in constructor.


Hope this concepts 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  

"knowledge will give you the power,character will give you the respect so power and respect is the most demanded one in the world !!! Be a demanded one !!!!!!!"  






        


Tuesday, July 21, 2020

What is extern in system verilog and its purpose?

Hi Everyone !!!,
Today I am going to share the ideas about extern and its use case.

In System verilog, extern indicates that the body of the methods(task/function/constraint implementaion ) is to be found on outside of the class.
By using scope resolution operator also we can access the methods in outside of the class. Here the difference is if any method declared as extern it must be implemented in outside of the class other wise it will throw the compilation error. 

Coding Examples:
    
                    class methods;
                         rand int data1;
                         rand int data2;
                         constraint protocol1;  //**** implicit form--> it throws an warning message if we didn't implemnt the constraint in outside of the class****//
                         extern constraint protocol2; //*** explicit form--> we must implement the function otherwise it leads to compilation error
                  endclass
//*** Before the method name class name should  be specified with scope resolution operator to specify which class the method corresponds to ***//
                  constraint methods::protocol1{data1 inside{-4,5,7};} // **if we didn't implement we will get the warning message as protocol1 is not defined***//
                  constraint methods::protocol2{data2 >=0;} //  ** if we didn't implement we will get the compilation error**//
                
                   module TB;
                         methods mth;
                         initial begin
                           mth=new();
                            repeat(5) begin
                             mth.randomize();
                           end
                         end
                   endmodule


Example 2:

              class methods;
                  bit[2:0] data;
                  bit[2:0] addr;
//Here the function is declared as extern. From this we can understand the computation method implementation contains outside of the class//
                  extern function void computation();
              endclass
              // Implentation of the function in done outside of the class
                   function void methods::computation();
                      $display(" %0d %0d",data,addr);
                   endfunction
          
                   module extern_method;
                          methods m;
                          initial begin
                             m=new();
                              m.addr=5;
                              m.data=4;
                              m.computation();
                          end
                  endmodule

Note:
    local/protected/virtual qualifiers are allowed in extern methods. For example in above program we can declare extern vitrual function void computation
    The number of arguements,arguments name and its type should  be matched with definition and implementation  of methods.
         

Hope this code 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

     "Share your knowledge. It is the way to achieve immortality"
                                                                                                  -Dalai Lama



Monday, July 20, 2020

Difference between rand and randc keyword in system verilog

Hi Everyone !
 In this section dealing about rand,randc keywords and usage.

Rand Method:
                  By using this method we we can generate a random number. Their values are uniformly distributed. So the generated number can be repeated.
                   Rand can be used in all constraint.
            Real time example for rand keyword:
                   Think of rolling dice or coin. For every roll there is a equal probability of getting new value of repeated current one. There is a chance of  equal probability  of every occurrence.

Randc Method: 
            Randc keyword are random-cyclic. The basic idea is that randc iterated over all the values in the range and no value is repeated within an iteration. Or in other words solver does not repeat a random value until every possible value generation.Once the all the iteration is finished, a new iteration is automatically generated. For efficient memory usage maximum 8 bit is used. 
            Some constraints not allowed to declare a variable as randc. Usually solver first solve the randc keyword. Randc keyword is not supported in Distribution and solve before constraint 
             Real time example of randc keyword:
                     Think of dealing cards from a deck: you deal out every card in the deck in random order, then shuffle the deck, and deal out the cards in a different order. Note that the cyclic pattern is for a single variable. 

    Example:
            class Practice;
               rand bit[2:0] data1;
               randc bit[2:0] data2;     
            endclass

             module TB;
                  Practice p;
                  initial begin
                   p=new();
                    repeat (5) begin
                           p.randomize();
                            $display(" Data1=%0d Data2=%0d",p.data1,p.data2);
                    end
                    end
                endmodule

Simulator output:
                      Data1=3    Data2=  4
                      Data1=.4   Data2=  3
                      Data1= 2   Data2=  0
                      Data1= 3   Data2=  6 
                      Data1= 1   Data2 = 7
                
Data1 is declared as rand so it may produce a repeated value.(3 value is repeated twice)
Data2 is declares as randc so it won't produce a repeated value until every cycle completion.


TRICKY Interview question:
 How to implement randc functionality without using randc keyword? or Generate a unique numbers without using unique keyword ?. Here I am generating unique random values upto 15. 

                

class unique_value;

  rand int data[];

  constraint c1{foreach (data[i]) data[i] inside {[0:15]};}

  constraint c2{ foreach(data[i])

                {foreach(data[j])

                {if(i!=j)

                data[i]!=data[j];}}}

 

 endclass

 

module test();

  unique_value uq;

  initial begin

    uq = new();

    uq.data=new[15];

    uq.randomize();

    $display("Array = %p",uq.data);

  end

endmodule

 

OUTPUT: -       # Array = '{0, 14, 7, 15, 5, 9, 1, 8, 11, 12, 6, 3, 4, 10, 13}


Hope this code 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

                                                              "Share your knowledge. It is the way to achieve immortality"
                                                                                                  -Dalai Lama

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