Constraint Failure

Hi ,

I am trying to achieve a Constraint that Elements with Indexes greater than 1 have Value equal to sum() of elements less than that Index .

Eg : A[4] == A[0]+A[1]+A[2]+A[3]

Here is my Code :: I try calling a Function in Constraint but it fails



class A  ;

rand int unsigned a[] ;

constraint DEPTH { a.size() == 10 ; }



constraint VALUES { 
                       foreach(a[i])
					   {
                          if ( i == 0 )
						  {
                              a[i] == 0 ;
                          
						  }
                          else if ( i == 1 )
						  {
                              a[i] == 1 ;
                          
						  }
                          else 
						  {
                              a[i] == SUM(a,i) ;
						  }

                       }
                  }


function int unsigned SUM ( input int unsigned AA[] , int unsigned Index ) ;


  foreach(AA[i])
  begin

     if ( i < Index )
	 begin

      SUM = SUM + AA[i] ;


	 end


  end


endfunction


endclass


A a1 ;


initial begin


a1 = new();

if ( a1.randomize() ) // Fails , But why ??
 begin

  $display("Success with %p",a1); 

 end

end




Have 2 Questions :

[1] Why does it Fail ?

[2] Any alternate way ??

Thanks

In reply to MICRO_91:

Your code has several problems

  • You are not allowed to refer to a random array as a whole variable in a constraint. You must have a constant select, or use an iterative constraint like foreach or array.sum that gets unrolled unto a constant select.
  • A user defined function call in a constraint breaks the solution space in half: first, the random variables used by the function inputs, and second, the set random variables assigned by the output. Once the set of input variables get solved, they become state variables. (they cannot change to solve constraints for the output)
  • You have a cyclic dependency on the inputs and outputs to your function. The solver does not look into your function to break the cycle.

You can fix this by using the built-in iterative sum() method.

constraint VALUES { 
                       foreach(a[i])
                          if ( i == 0 )
                              a[i] == 0 ;
                          else if ( i == 1 )
                              a[i] == 1 ;
                          else 
                              a[i] == a.sum() with (item.index<i ? item:0) ;
                   }

This gets unrolled into the following constraints

a[0] == 0;
a[1] == 1;
a[2] == a[0] + a[1] + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0;
a[3] == a[0] + a[1] + a[2] + 0 + 0 + 0 + 0 + 0 + 0 + 0;
...
a[9] == a[0] + a[1] + a[2] + a[3] + a[4] + a[5] + a[6] + a[7] + a[8] + 0;

In reply to MICRO_91:

[2] Any alternate way ??


class A  ;
 
rand int unsigned a[] ;
 
constraint DEPTH { a.size() == 10 ; }
 
 
 
constraint VALUES { 
                       
  foreach(a[i]) {
    if ( i == 0 )
       a[i] == 0 ;
    else if ( i == 1 )
	   a[i] == 1 ;
    else 
      a[i] == a.sum with (item.index<i? int'(item):0);    
	}
} 
 
endclass
 
 module test;
A a1 ;
 
 
initial begin
 
 
a1 = new();
 
if ( a1.randomize() ) // Fails , But why ??
 begin
 
  $display("Success with %p",a1); 
 
 end
 
end
                        
endmodule                         


In reply to dave_59:

Hi Dave ,

Thank you for your detailed answer , it was helpful . I have a few questions ::

(1) " You are not allowed to refer to a random array as a whole variable in a constraint. You must have a constant select, or use an iterative constraint like foreach or array.sum that gets unrolled unto a constant select "

I didn't get this part . Inside unique constraint I can constraint a whole unpacked array ( 1D as well as 2D  )

The above statement was again encountered below ::
I thought that circular dependency is the reason the code fails so I edited the code as


    a[i] == SUM(a[0:i-1]) ; // Changes in function too ( Only 1 Argument ) 
    

Since a is input to function in constraint , a will be solved first that is a.size() constraint . But I still get an error ::

 **ERROR :: Range must be bounded by constant expressions.**


With class methods ( which may or may not be used in constraints ) can't I pass variable index range as input to a dynamic array ? 

Thanks

In reply to verifeng2:

This doesn’t work on xcelium ( Not the one on eda , the paid one used at work ) ,
so I tried this ::



constraint VALUES { 
 
  foreach(a[i]) 
  {
    if ( i == 0 )
       a[i] == 0 ;
    else if ( i inside { 1 , 2 } )
	   a[i] == 1 ;
    else 
      a[i] == 2*a[i-1] ;    
   } 


Thanks ,

In reply to MICRO_91:

The Latter example works for me. You’ll have to take that up with your tool vendor.

In regard to your other questions, unique should be considered an iterative constraint. That is an oversight reported to the IEEE 1800 LRM committee.

The syntax a[0:i-1] is illegal syntax, in or outside a constraint.