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
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) ;
}
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
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 ?