System verilog randomization: inconsistency in LRM?

In constraint section LRM says: Pg 438
Functions(Inside the constraint) shall be called before constraints are solved, and their return values shall be treated as state variables.

It also says:
Random variables used as function arguments shall establish an implicit variable ordering or priority. Constraints that include only variables with higher priority are solved before other, lower priority constraints. Random variables solved as part of a higher priority set of constraints become state variables to the remaining set of constraints.

From the first sentence it seems to say if I have something like.
class B;
rand int x, y;
constraint C { x <= F(y); }
constraint D { y inside { 2, 4, 8 } ; }
endclass
It will evaluate F(y) with unrandomized value of y which is 0. But second statement contradicts it?
Someone please help me thro this confusion.

In reply to sharatk:

Functions aren’t called before all constraints are solved, but before the relevant constraints are solved.

In your case, the function creates an implicit solve y before x. This means constraint D will be solved first to yield a value of y. Afterwards, F will be called with the value of y obtained from the previous step. Then, constraint C will be solved to yield x.

In reply to Tudor Timi:

For a simple case like say countones, you are correct and I validated it. But when I go ahead and wrote much complicated constraint, It totally failed. I had to work around creating temporary array and using inbuilt “sum” function.
It could be a quirk of cadence Simulator, but I had no other way of validating it.

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.

In reply to dave_59:

Some tools work back in this case and choose a different value for y, such that the randomize doesn’t fail.

In reply to dave_59:

Thank you Dave. Your insights are great as usual.
I worked on an example which going by your description should have worked. It was a little complicated as main class has other class as members and randomization fails.
I had to code a hack to proceed.
If you would like to see the example, please let me know where I can send it to you? You can probably check it in Modelsim (I only have IUS, which is not too great with constraints)

In reply to Tudor Timi:

That works in some cases, but you could not rely on it. Also, some people depend on this behavior to limit the scope of overriding soft constraints

In reply to dave_59:

Hi Dave ,

Could you please elaborate on " this behavior to limit the scope of overriding soft constraints "

In reply to Etrx91:
I think soft constraints add unnecessary complexity, and there is usually a better way to write your constraints. So I’n not about to provide an example.