Regarding function in constraints

Hi All ,
Section 18.5.12 of the LRM discuses about function call in constraints . One of the key points is :

Functions shall be called before constraints are solved, and their return values shall be treated as state variables.

It then gives an example :


class B;
rand int x, y;
constraint C { x <= F(y); }
constraint D { y inside { 2, 4, 8 } ; }
endclass

So y gets solved / picked before x i.e there is an implicit solving order.

If I were to change constraint to :


class B;
 rand bit[3:0] y ,z ;
 rand bit[4:0] x ;
constraint C { x <= Func2(); }
function int Func2();
 y + z ;
endfunction
endclass

[Q1] In this casewould there still be an implicit solving/picking order ( although there are no input to the function ) ?

Section 13.2 of the LRM says :

“A nonvoid function can be used as an operand in an expression; the value of that operand is the value returned by the function.”

So another possible scenario is that Func2 ( or any function without input arguments in general ) relates to section 13.2 of the LRM rather then section 18.5.12.
This means that the constraint could be in-lined to :

constraint C { x <= int'( y + z ); }

Now there would be no implicit ordering between the 3 random variables .

[Q2] In case Func2() relates to section 13.2 of the LRM , are there any restrictions on what’s legal/illegal within the function ?
Section 18.5.12 has a list of restrictions for a function with input arguments called in a constraint . Eg : Static variable can’t be declared in such a function

In reply to MICRO_91:

User defined functions in constraints do not get in-lined. That is why all those rules about using function in constraints exist.

A function body that refers to variables outside the definition of the function body is a side-effect. The behavior is not defined.

In reply to dave_59:

Thanks Dave .

A function body that refers to variables outside the definition of the function body is a side-effect. The behavior is not defined.

On trying the code with a slight modification in the constraint : edaplayground

Two tools return the default value ( on 1st call to randomize() ) or the sum of the previous randomized values of y and z ( during latter calls )

3rd tool throws a compilation error since we access variables outside the function( which is along LRM )

So ideally a function called in constraint should have input arguments and the body of the function should only access the input arguments.
For functions with no input arguments , tools have different implementations. Hence such functions should be avoided.

In reply to dave_59:

Dave ,
A follow-up question. I was thinking of an example for the quote from Section 13.2 of the LRM :

“A nonvoid function can be used as an operand in an expression; the value of that operand is the value returned by the function.”

As you mentioned : “User defined functions in constraints do not get in-lined.”

So I was thinking of built-in functions eg: $countones


  rand bit[9:0] a;
  constraint ONES { $countones(a) == 4; }

In this case the return type of nonvoid function would be in-lined to the constraint , right ?


  constraint ONES { int'( a[9] + a[8] +  a[7] + a[6] + a[5] + a[4] +  a[3] + a[2] + a[1] + a[0] ) == 4; }

As a result there should be no implicit ordering for random variables using built-in functions.

In reply to MICRO_91:

You got it.