I came across a bit counting algorithm called Brian Kernighan algorithm and decided to use it in system verilog constraints as follows:
class A;
rand bit[7:0] numb;
function int hamWeight(bit[7:0] n);
int count=0;
while(n)begin
n = n & (n-1);
count++;
end
return count;
endfunction : hamWeight
constraint c_numb{
hamWeight(numb) == 1;
}
endclass
When I try the above code, it worked the first time. But as I try to run several seeds, there are few seeds that were failing with a randomization error. The warning that I get is “The randaomize method call failed. These variables contribute to a set of conflicting constraints”.
Since I have only one constraint, I’m not sure where to look at and how there is a conflict. Did I do something wrong fundamentally? If so can you tell me how to fix this?
Thanks
P.S : I know that there are other ways to get random 1 hot numbers, but I was just trying this out as an exercise.
In SV, function calls inside a constraint impose an implicit variable ordering (See: Verification Course Blog | VeriLog Courses | CVC). So in your case a random value of “numb” is chosen FIRST and then your constraint is solved - imagine with “numb = 0” you could get a failure.
@Srini - Oh. I get it. So is there a workaround for this? Is there a way we can solve the constraint first?
@mayurkubavat - That seems to be working. Thanks. However, having a function is better in case we want to generalize the number of 1’s in a number (for example if we need a number with 2 hot bits instead of 1).
That’s correct! But the problem here is, as Srini explained, function call inside constraint will force dependent variables to be solved first and this can generate conflicting conditions.
There won’t be parallelism if functions are used in constraint… So, that restricts the use i guess.
Can you explain how is the system function call different from the user defined function call? Because in some ways, all I was trying to do is implement the behavior of $countones in the class isn’t it?
In reply to szy0014:
The constraint solver recognizes certain builtin SystemVerilog functions as mathematical expressions and expands them into the constraint equations. It cannot do that with user defined functions. (well, the LRM does not currently define a way to do that)