Count function in constraint

I am not getting the output for this code while using function in constraint. Is it the correct way to use?
Code:

module test();

class Packet;
bit [2:0] length;
rand bit [2:0] A ;
constraint c1 { length == count_ones(A); }
endclass

function int count_ones ( bit [2:0] w );
$display("Inside function W: %0b",w);
for( count_ones = 0; w != 0; w = w >> 1 )
begin
$display("Inside for loop W: %0b",w);
count_ones += 1;
$display("Count: %0d",count_ones);
end
endfunction

Packet p;

initial begin
  p = new();// Create a packet
repeat(10)
begin  
	if(p.randomize())
	$display("length=%d A=%b ",p.length,p.A);
end

end

endmodule

Output:

=======================================================

Solver failed when solving following set of constraints

bit[2:0] length = 3’h0;
integer fv_1 /count_ones(A)/ = 1;

constraint c1 // (from this) (constraint_mode = ON) (file.sv:11)
{
(length == fv_1 /count_ones(A)/);
}

=======================================================

In reply to Huzefa Halolwala:

Hi,

Please make length as rand variable. If you dont want it to be rand variable, put that functionality in a task and do the assignment.

In reply to Huzefa Halolwala:
You have to be very careful when calling a user defined function in a constraint. A function call breaks the constraint set in half. The inputs to the function are solved first before calling the function. Then the result of the function call is used as a state variable to solve the rest of the constraints involving that result.

In your example, you have A as an input to a function, and there are no constraints on A. The return value from count_ones could be between 0 and 3. You did not declare length as a rand variable, so it is also a state variable whose initial value is 0. So if the return value of count_ones was not 0, you will get a constraint failure.

There is a built-in function, $countones, that can be used and will avoid this problem

constraint c1 { length == $countones(A); }

In reply to dave_59:


class Packet;
rand bit [2:0] length;
rand bit [2:0] A ;

function int count_ones ( bit [2:0] w );
for( count_ones = 0; w != 0; w = w >> 1 )
begin
count_ones += w & 1'b1;
end
endfunction
constraint c1 { length == count_ones(A);
		solve A before length; }
endclass


I have modified the above program to this and it is working properly.

Thank you dave and Anudeeep

In reply to Huzefa Halolwala:
There is no need for
solve A before length
because the function call implies this.

In reply to dave_59:

Thank You for the comment Dave

In reply to dave_59:

Hi Dave ,

For the following Snippet



`ifdef B
rand bit [7:0] length ; 
`endif

rand bit [7:0] Var ;

`ifdef B // "B"uilt in function
constraint One {  length  == $count_ones(Var) ; }  // Both are random
`else
constraint One {   $count_ones(Var) == 4 ; }  // Number of Ones are Fixed
`endif


Irrespective of whether +define+B is used or not I end up getting a constraint Failure .

I went through the LRM but they haven’t mentioned anything regarding Built-In Functions inside Constraints .

I am confused whether its a Simulator limitation ( Even on the New ones ) or is it illegal to write them

Regards,
AGIS

In reply to Etrx91:

This is an open issue in the LRM. But many simulators implement things long before they wind up in the LRM. Who knows when will ever see another LRM version.