Sum() function behaviour in constraint

Hi,

can any one explain the constraint statement with sum().
i am not able to understand working of sum() call in below code.

module tb;
class cls;
 rand int unsigned d;
 rand int unsigned arr[10];
 
 constraint arr_c{
   foreach(arr[i]) { arr[i] inside {[1:10]};}
   foreach(arr[i]) { arr.sum() with (int'(item==arr[i])) == (arr[i]==d ? 2:1);}
 }
endclass
initial begin
cls obj = new;
  int sum1;
  repeat(5) begin
    void'(obj.randomize());
    sum1 = obj.arr.sum();
    $display("d = %d, arr = %p  sum = %d",obj.d,obj.arr,sum1);
    
  end
end
endmodule

Thanks,
Zalak

In reply to zalak patel:

Sometimes it helps to unroll the foreach loop and sum() reduction to get a better picture of what is inside it.

Unrolling the foreach:


   arr.sum() with (int'(item==arr[0])) == (arr[0]==d ? 2:1);
   arr.sum() with (int'(item==arr[1])) == (arr[1]==d ? 2:1);
   ...
   arr.sum() with (int'(item==arr[9])) == (arr[9]==d ? 2:1);

Unrolling the sum() on just the first line:

int'(arr[0]==arr[0]) + int'(arr[1]==arr[0]) + int'(arr[2]==arr[0]) ... + int'(arr[9]==arr[0]) 
   == (arr[0]==d ? 2:1);

The sum() is counting the number of times the value of arr[0] appears in the remainder of the array. And the constraint is that value can only appear once or twice depending on the value of d.

In reply to dave_59:

Hi Dave,

I see the following output from your code.
d = 6, arr = '{'h6, 'ha, 'h4, 'h7, 'h2, 'h6, 'h1, 'h3, 'h9, 'h8} sum = 56
d = 2, arr = '{'h9, 'h6, 'h2, 'h2, 'h3, 'ha, 'h7, 'h4, 'h5, 'h8} sum = 56
d = 6, arr = '{'h6, 'h3, 'h5, 'h9, 'h6, 'ha, 'h2, 'h8, 'h7, 'h4} sum = 60
d = 3, arr = '{'h2, 'h3, 'h3, 'h7, 'h9, 'h6, 'h5, 'ha, 'h1, 'h4} sum = 50
d = 9, arr = '{'h7, 'h8, 'h9, 'h9, 'h3, 'h1, 'h2, 'h4, 'ha, 'h6} sum = 59

What I don’t understand is that, we are not constraining the values of ‘d’, still the value of ‘d’ seems to co-relate with the array elements. Which part of the constraint takes care of that? Can you please elaborate.

In reply to imajeeth:

This has to do with the probability of picking a solution where arr[i]==d ? 2:1 is true. If you run more randomizations, or try a different tool, you get more varied results.

In reply to dave_59:

Hi Dave,

I ran more iterations and on a different simulator.

d = 3448731155, arr = '{10, 8, 7, 9, 1, 5, 6, 4, 3, 2} sum = 55

d = 10, arr = '{4, 7, 1, 9, 6, 2, 10, 10, 5, 8} sum = 62

d = 5, arr = '{7, 5, 6, 1, 2, 8, 3, 9, 5, 10} sum = 56

d = 7, arr = '{9, 1, 10, 5, 3, 4, 7, 6, 7, 8} sum = 60

d = 2709912681, arr = '{7, 6, 4, 2, 1, 10, 5, 3, 9, 8} sum = 55

d = 3329498380, arr = '{3, 8, 9, 4, 1, 5, 2, 6, 7, 10} sum = 55

d = 8, arr = '{5, 8, 8, 4, 1, 7, 6, 9, 10, 3} sum = 61

d = 3791730389, arr = '{10, 8, 3, 5, 9, 2, 6, 4, 1, 7} sum = 55

d = 8, arr = '{8, 3, 5, 8, 1, 10, 4, 6, 9, 7} sum = 61

d = 4, arr = '{9, 4, 6, 1, 2, 10, 7, 5, 4, 3} sum = 51

d = 8, arr = '{4, 8, 8, 2, 10, 7, 6, 9, 3, 1} sum = 58

d = 7, arr = '{9, 7, 2, 4, 7, 3, 8, 10, 5, 1} sum = 56

d = 184511901, arr = '{10, 7, 4, 8, 2, 5, 3, 6, 9, 1} sum = 55

d = 6, arr = '{9, 4, 6, 3, 1, 7, 8, 5, 10, 6} sum = 59

d = 4280891571, arr = '{4, 3, 9, 1, 6, 7, 2, 8, 5, 10} sum = 55

d = 5, arr = '{9, 6, 5, 3, 4, 2, 1, 5, 7, 10} sum = 52

d = 7, arr = '{2, 3, 7, 9, 5, 4, 6, 10, 1, 7} sum = 54

d = 2648681502, arr = '{6, 5, 8, 2, 9, 4, 7, 3, 10, 1} sum = 55

d = 6, arr = '{6, 5, 4, 9, 3, 7, 2, 6, 8, 10} sum = 60

d = 2, arr = '{2, 8, 6, 7, 1, 2, 3, 10, 9, 5} sum = 53

d = 8, arr = '{8, 4, 9, 5, 8, 1, 7, 10, 3, 2} sum = 57

d = 779515184, arr = '{5, 9, 10, 3, 1, 4, 2, 8, 6, 7} sum = 55

d = 9, arr = '{8, 9, 6, 4, 3, 10, 7, 9, 5, 2} sum = 63

d = 3115883629, arr = '{7, 10, 6, 4, 5, 2, 8, 3, 9, 1} sum = 55

d = 1330958981, arr = '{3, 5, 1, 10, 4, 2, 9, 6, 7, 8} sum = 55

d = 2467735596, arr = '{1, 8, 10, 5, 7, 2, 9, 3, 4, 6} sum = 55

d = 9, arr = '{2, 4, 5, 3, 9, 9, 10, 7, 8, 6} sum = 63

d = 473926402, arr = '{3, 10, 9, 6, 8, 4, 2, 5, 7, 1} sum = 55

d = 2874044966, arr = '{10, 9, 8, 6, 5, 2, 4, 7, 3, 1} sum = 55

d = 2324438489, arr = '{9, 10, 3, 5, 4, 7, 2, 1, 6, 8} sum = 55

d = 10, arr = '{2, 4, 7, 10, 9, 3, 10, 6, 1, 8} sum = 60

d = 126692788, arr = '{3, 4, 7, 1, 5, 6, 8, 2, 10, 9} sum = 55

d = 4065882940, arr = '{3, 5, 1, 10, 2, 9, 6, 7, 4, 8} sum = 55

d = 8, arr = '{5, 7, 3, 6, 4, 1, 2, 9, 8, 8} sum = 53

d = 1, arr = '{5, 8, 4, 6, 2, 3, 10, 9, 1, 1} sum = 49

d = 3332065966, arr = '{10, 6, 5, 4, 2, 1, 9, 8, 7, 3} sum = 55

d = 1950928199, arr = '{7, 10, 6, 1, 9, 8, 5, 4, 2, 3} sum = 55

d = 8, arr = '{2, 7, 5, 6, 8, 10, 3, 1, 8, 9} sum = 59

d = 3, arr = '{3, 4, 6, 10, 2, 1, 3, 5, 9, 8} sum = 51

d = 5, arr = '{9, 6, 2, 8, 1, 10, 3, 5, 4, 5} sum = 53

d = 6, arr = '{9, 6, 8, 4, 10, 2, 3, 1, 5, 6} sum = 54

d = 4, arr = '{6, 7, 2, 1, 4, 9, 4, 5, 3, 8} sum = 49

d = 8, arr = '{6, 8, 5, 4, 3, 7, 9, 2, 10, 8} sum = 62

d = 6, arr = '{1, 6, 2, 3, 10, 6, 9, 4, 8, 7} sum = 56

d = 905989676, arr = '{5, 6, 3, 10, 8, 4, 1, 9, 7, 2} sum = 55

d = 10, arr = '{1, 6, 3, 10, 7, 9, 10, 2, 5, 8} sum = 61

d = 1655851845, arr = '{1, 4, 7, 5, 6, 10, 9, 8, 3, 2} sum = 55

d = 1, arr = '{6, 1, 10, 3, 2, 5, 7, 8, 1, 9} sum = 52

d = 4, arr = '{5, 7, 6, 8, 2, 1, 4, 4, 3, 9} sum = 49

d = 2374300102, arr = '{8, 4, 1, 2, 7, 10, 3, 5, 6, 9} sum = 55

d = 5, arr = '{5, 6, 9, 1, 3, 4, 10, 5, 2, 8} sum = 53

d = 10, arr = '{4, 1, 8, 7, 5, 9, 2, 3, 10, 10} sum = 59

d = 3209517074, arr = '{7, 3, 2, 9, 1, 6, 4, 10, 5, 8} sum = 55

d = 2, arr = '{4, 1, 6, 5, 9, 3, 2, 10, 2, 8} sum = 50

d = 4, arr = '{4, 8, 9, 1, 5, 7, 10, 6, 3, 4} sum = 57

d = 548290078, arr = '{3, 2, 1, 9, 10, 5, 6, 7, 4, 8} sum = 55

d = 8, arr = '{1, 8, 6, 7, 9, 10, 5, 4, 3, 8} sum = 61

d = 5, arr = '{5, 3, 4, 1, 10, 6, 9, 7, 2, 5} sum = 52

d = 1717079317, arr = '{5, 7, 3, 2, 4, 6, 1, 8, 10, 9} sum = 55

d = 1312438862, arr = '{5, 10, 8, 3, 9, 2, 1, 6, 4, 7} sum = 55

d = 6, arr = '{9, 2, 6, 7, 6, 4, 10, 8, 3, 5} sum = 60

d = 127296639, arr = '{9, 4, 2, 10, 7, 8, 6, 1, 3, 5} sum = 55

d = 1, arr = '{4, 7, 2, 9, 5, 10, 3, 6, 1, 1} sum = 48

d = 1237903860, arr = '{3, 7, 10, 2, 4, 6, 5, 9, 1, 8} sum = 55

d = 3010218235, arr = '{6, 9, 3, 1, 8, 2, 10, 5, 7, 4} sum = 55

d = 2, arr = '{7, 5, 2, 8, 2, 4, 10, 1, 3, 6} sum = 48

d = 10, arr = '{4, 7, 10, 2, 9, 1, 10, 8, 5, 3} sum = 59

d = 2347759551, arr = '{8, 10, 7, 6, 1, 5, 2, 9, 4, 3} sum = 55

d = 3135333307, arr = '{3, 10, 2, 6, 1, 7, 8, 5, 9, 4} sum = 55

d = 4, arr = '{4, 5, 7, 1, 6, 3, 9, 10, 4, 2} sum = 51

d = 7, arr = '{1, 7, 9, 6, 7, 2, 4, 5, 8, 10} sum = 59

d = 3529179464, arr = '{9, 4, 8, 6, 1, 7, 10, 3, 5, 2} sum = 55

d = 4065687826, arr = '{4, 6, 8, 1, 9, 10, 5, 7, 2, 3} sum = 55

d = 2232218145, arr = '{1, 7, 10, 2, 5, 8, 4, 9, 6, 3} sum = 55

d = 7, arr = '{2, 1, 8, 10, 9, 7, 3, 4, 7, 6} sum = 57

d = 1254977361, arr = '{7, 10, 2, 6, 9, 3, 4, 1, 8, 5} sum = 55

d = 8, arr = '{10, 8, 1, 5, 9, 4, 2, 6, 8, 3} sum = 56

d = 3654859172, arr = '{4, 3, 9, 1, 2, 8, 6, 7, 5, 10} sum = 55

d = 9, arr = '{9, 5, 9, 10, 6, 2, 1, 3, 7, 8} sum = 60

d = 2, arr = '{10, 5, 4, 2, 2, 7, 6, 8, 9, 1} sum = 54

d = 10, arr = '{8, 10, 3, 5, 4, 1, 9, 10, 6, 2} sum = 58

d = 3757398698, arr = '{8, 7, 2, 10, 1, 5, 9, 3, 4, 6} sum = 55

d = 4, arr = '{9, 3, 10, 2, 7, 4, 5, 4, 1, 6} sum = 51

d = 3, arr = '{1, 5, 10, 8, 9, 6, 3, 4, 2, 3} sum = 51

d = 1259208169, arr = '{7, 10, 5, 1, 8, 2, 3, 9, 6, 4} sum = 55

d = 542627384, arr = '{5, 2, 7, 10, 9, 4, 8, 1, 3, 6} sum = 55

d = 2, arr = '{4, 1, 5, 3, 6, 7, 2, 8, 10, 2} sum = 48

d = 2491603756, arr = '{4, 3, 8, 6, 1, 9, 5, 2, 10, 7} sum = 55

d = 64254222, arr = '{3, 10, 2, 5, 1, 8, 6, 9, 4, 7} sum = 55

d = 7, arr = '{4, 3, 9, 2, 6, 10, 7, 8, 5, 7} sum = 61

d = 200049790, arr = '{4, 9, 7, 6, 8, 1, 2, 5, 3, 10} sum = 55

d = 2700441529, arr = '{2, 4, 3, 6, 1, 9, 5, 7, 8, 10} sum = 55

d = 10, arr = '{10, 1, 3, 10, 9, 2, 5, 8, 6, 4} sum = 58

d = 9, arr = '{7, 8, 6, 9, 5, 4, 3, 9, 2, 10} sum = 63

d = 82148929, arr = '{2, 10, 9, 6, 5, 4, 3, 1, 7, 8} sum = 55

d = 1345155058, arr = '{7, 1, 9, 5, 4, 8, 10, 2, 6, 3} sum = 55

d = 713321669, arr = '{3, 5, 4, 10, 8, 7, 1, 6, 2, 9} sum = 55

d = 7, arr = '{3, 7, 6, 10, 5, 7, 4, 9, 2, 1} sum = 54

d = 1097467810, arr = '{10, 5, 1, 2, 9, 7, 4, 8, 3, 6} sum = 55

d = 1813324735, arr = '{6, 9, 8, 4, 10, 3, 5, 7, 2, 1} sum = 55

As you see, the occurrence of a single digit value for ‘d’ is much higher. We either get a value of ‘d’ <=10 or a very large value. Why is there no values between 11 through 9999. I’m suprised there is not even a single occurrence of those values. Don’t you think 100 transactions is a good enough sample size?

In reply to imajeeth:

The largest unsigned integer is 4,294,967,295. The probability of seeing a number between 11 and 9999 would be

(9999-11+1)/(4294967295-12)= 0.00000232574

So you would have to run over 1M transactions to have a 1% probability of seeing a number between 11-9999.