|HOME |ABOUT |ARTICLES |ACK |FEEDBACK |TOC |LINKS |BLOG |JOBS |


Tutorials



ARRAY RANDOMIZATION


Most application require to randomize elememts of array.Arrays are used to model payload,port connections etc.
SystemVerilog has Fixed Arrays,Dynamic arrays,queues and Associative arrays.
If an array is constrained by both size constraints and iterative constraints for constraining every element of array. The size constraints are solved first, and the iterative constraints next. In the example,size_c is solved first before element_c. As constraint element_c canot be solved without knowing the size. So there is implicit ordering while solveing this type of constraints.
This is the only approach for applying constraints to individual elements of arrays, with this approach,performance is degraded. If  Payload.size() = 1000, then 1000 constraints are created by foreach. it takes much time for the solver to solve all the constraints. Another simple approach is using a task to randomize each element. This approach is 5X times faster than foreach.


EXAMPLE:
class Eth_pkt_82;
  rand byte Payload[] ;
  constraint size_c { Payload.size() inside {[46:1500]}; }
  task randomize_foreach;
    foreach ( Payload[ i ] ) 
    Payload[ i ] = 50 + $urandom % 50;// try with randomize( Payload[i]) with .....
  endtask
endclass

program iterative;
  Eth_pkt_82 obj;
  initial
  begin
    obj = new();
    for(int i=0;i< 10000;i++)
    begin
      void'(obj.randomize());
        obj.randomize_foreach();
    end
  end
endprogram


In applications where some constraints are dependent on the array elements, the following may help. call the randomization function in constraints, define proper variable ordering.

EXAMPLE:
   class Eth_pkt;
       rand byte Payload[] ;
       rand byte size;
       bit dummy = 1;
      
       constraint dummy_c { dummy == randomize_size();}
       constraint size_c { size inside {[10:100]};}
       constraint order_c1 {solve size before dummy;}
       constraint order_c2 {solve dummy before Payload;}
      
       function bit randomize_size();
           Payload = new[size];
           randomize_size = 1;
           return randomize_size;
       endfunction
      
   endclass
  
   program iterative_88;
       Eth_pkt obj;
      
      initial
      begin
         obj = new();
         void'(obj.randomize());
         for(int i=0;i< 10;i++)
            begin
            void'(obj.randomize());
            $display(" Eth_pkt.size : %d  :: Payload.size() : %d ",obj.size,obj.Payload.size());
            for(int j=0;j<obj.Payload.size();j++)
            $write("%4d _",obj.Payload[j]);
            $display("");
         end
      end
   endprogram


In the above example, constraint order_c1 {solve size before dummy;} makes sure that size is randomized before function ranomize_size() is called.


If constraints are dependent on the sum of the elements of the dynamic array. The interesting elements are the new random variables which are created by current randomization call. If you are not using any techinique to get the right size after randomization sum() returns the sum of all the array elements .

EXAMPLE:
class dynamic_array_89;
   rand byte size;
   rand byte data[];
   constraint size_c { data.size() == size; size >= 0; }
   constraint sum_c  { data.sum()  < 1000;}
endclass


Do manually in a function and use it or just use { data.sum() with (item.index < size) 1000;}There is one more bug in the above code.The sum() method  returns a single value of the same type as the array element type.So the sum returns only 8 bits in this case.So a.sum() is allways less than 255 which is less than 1000 and allways the constraint is satisfied which is not what is expected.


EXAMPLE:
program summ;
   dynamic_array obj = new();
   integer sum;

   initial
   begin
      sum =0;
      void'(obj.randomize());
      for(int i=0;i< obj.size ;i++)
         sum= sum+obj.data[i];
      $display(" Sum is %d ",sum);
   end
endprogram
 

Using y.sum with (item + 32'b0) will result in a 32 bit proper sum.

EXAMPLE:
class dynamic_array;
   rand integer size;
   rand reg [7:0] data[];
   constraint sum_c  { data.sum() == data[0];}
   constraint size_c { data.size() == size; size >1000 ;size < 2000; }

endclass

program summ;
   dynamic_array obj = new();
   integer sum;
   initial
   repeat(10)
      begin
      sum =0;
      void'(obj.randomize());
      for(int i=0;i< obj.size ;i++)
      begin
         sum= sum+obj.data[i];
      end
      $display(" Sum is %d obj.sum() %d",obj.data[0],obj.data.sum());
   end
endprogram


Randomization donot create the objects. So when a array of objects is randomized, all the objects are pointing to null and randomization can not be done on null objets.new() has to be called to creat objects then only randomize can be done on it.So creat array of objects before calling the randomize.

EXAMPLE:
  class cls;
    rand integer Var;
  endclass
  
  class arr_obj;
     rand cls objcls [0:2];
  endclass
  
  program arr_obj_p_91;
     arr_obj obj = new() ;
     int i;
     initial
     begin
        if(obj.randomize())
        begin
           $display(" Randomization is done ");
           for(i=0;i<3;i++)
             if(obj.objcls[i] == null )
                $display( " obj.objcls == null ");
             else
                $display(" obj.objcls.Var : %d ", obj.objcls[i].Var );
        end
        else
        $display(" Randomization failed ");
     end
  endprogram
RESULTS:

  #  Randomization is done
  #  obj.objcls == null
  #  obj.objcls == null
  #  obj.objcls == null

  


In the following, objects are created during the creation of arr_obj. This can also be done in pre_randomize. When dynamic arrays of objects are created, similar approach has to be taken and size of the dynamic array has to be decided before the new() is called, which makes no sense using the dynamic array of objects.


EXAMPLE:
   class cls;
      rand integer Var; 
   endclass
  
   class arr_obj; 
      rand cls objcls [0:2];
  
      function new();
         foreach(objcls[i])
         objcls[i]=new();
      endfunction
      
   endclass
  
   program arr_obj_p_91;
       arr_obj obj = new() ;
       int i;
       initial
           begin
           if(obj.randomize())
           begin
               $display(" Randomization is done ");
               for(i=0;i<3;i++)
                  if(obj.objcls[i] == null )
                     $display( " obj.objcls == null ");
                  else
                     $display(" obj.objcls.Var : %d ", obj.objcls[i].Var );
           end 
           else
              $display(" Randomization failed ");
       end
   endprogram
RESULTS:

  Randomization is done
  obj.objcls.Var :   733126180
  obj.objcls.Var :  -119008195
  obj.objcls.Var :   342785185





To create queue of objects,first length of the queue has to be randomized.Then number of objects equal to length of queue.Delete the old elements in the queue.Then push each object new objects in to the queue.Lastly randomize each object.

EXAMPLE:
   class cls;
      rand integer Var;
   endclass
  
   class q_cls;
      rand cls obj[$];
      rand bit [2:0] length;
 
      function void pre_randomize();
         length = $urandom % 20 ;    // Compute the length of queue.
         obj     = {} ;               // Delet all the elements in the queue or .delet can be used
         repeat(length)
         begin
            cls obj_loc;
            obj_loc = new();           // Creat new object.      
            obj.Push_back(obj_loc) ;   // insert it into queue.
         end
      endfunction
    endclass
 
   program q_obj_p_93;
   q_cls obj = new();
  
   initial
   begin
      if(obj.randomize())
      begin
         $display( "Randomization done");
         $write( " Length of q : %0d :::",obj.length);
         for(int i ;i< obj.length;i++)
         begin
             cls obj_temp;
             obj_temp = obj.obj.Pop_front();
             $write(" : %0d : ",obj_temp.Var);
         end
      end
      else
         $display( "Randomization failed");
   end
   endprogram
RESULT:

Randomization done
 Length of q : 6 ::: : 1474208060 :  : -1098913923 :  : 816460770 :  : 41501707 :  : -1179418145 :  : -212817600 :



Some application like linked list needs to generate an array of random values which are unique. foreach provides the solution,but the simples and the best solution is assign all the elements in arrat with its index and use shuffel inside a task.shuffle() randomizes the order of the elements in the array.Constraint solver is not used hear,so the preformance is better.


EXAMPLE:
    class List;
       integer Pointer[5] ;
  
       task randomize_unique;
          foreach ( Pointer[ i ] ) 
             Pointer[ i ] = i;
          Pointer.shuffle();
       endtask
    endclass
    
    program Unique_rand_94;
     List obj;
    
    initial
    begin
       obj = new();
       obj.randomize_unique();
       for(int i=0;i< 5;i++)
       begin
          $display(" Pointer[%0d] = %d ",i,obj.Pointer[i]);
       end
    end
    endprogram
RESULT:


 Pointer[0] =           2
 Pointer[1] =           1
 Pointer[2] =           3
 Pointer[3] =           0
 Pointer[4] =           4


Using foreach in global constraints in the following way wont work currently. as the . operator(dot) is not supported in foreach in LRM currently.

EXAMPLE:
class parent;
   rand byte a[0:9];
endclass

class child_96;
   rand parent P;
   rand byte a[0:9];
   constraint Not_supported { foreach(P.a[i]) P.a[i] == a[i];}
endclass

The correct way to write the above constraint is
constraint Supported { foreach(a[i]) a[i] == P.a[i];}


Index
Constrained Random Verification
Verilog Crv
Systemverilog Crv
Randomizing Objects
Random Variables
Randomization Methods
Checker
Constraint Block
Inline Constraint
Global Constraint
Constraint Mode
External Constraints
Randomization Controlability
Static Constraint
Constraint Expression
Variable Ordering
Constraint Solver Speed
Randcase
Randsequence
Random Stability
Array Randomization
Constraint Guards
Titbits

Report a Bug or Comment on This section - Your input is what keeps Testbench.in improving with time!





<< PREVIOUS PAGE

TOP

NEXT PAGE >>

copyright © 2007-2017 :: all rights reserved www.testbench.in::Disclaimer