In reply to sharatk:
To say that a function call creates an implicit solve y before x constraint is slightly misleading (see this description of the solve before construct).
The constraint solver works in solution spaces. A solution space is the collection of all possible values sets for the random values that satisfy the active constraints. You can think of the constraint solver as building the solution space first, then randomly choosing one set of values for the random variables.
Calling a user function breaks the solution space in half—one for the input, and one for the output of the function. The input solution space gets built and values picked before building the output space. This means that any constraints involving the function output have no effect on the input space, and could result in constraint failure. For example
class A
rand int x,y;
function int f(int a);
return a;
endfunction
constraint c1 { x == f(y); }
constraint c2 { x inside {[1:20]}; }
constraint c3 { y inside {[10:30]}; }
endclass
The constraint solver can choose any value between 10 to 30 for y, but the fact that x is constrained between 1 to 20 has no effect on the choice for y. So if 21 gets chosen for y, the solver will fail because constraint c2 cannot be satisfied.