Item.index usage in constraints

I would like to see the first 3 elements of cnum to be set to 1 and rest to be 0. There is no real purpose here, I am just playing around with item.index usage. Another thing that I tried was item.index%2 and come up with alternate 1s and 0s. Constraint does not seem to be working for cnum, but, anum and bnum work just fine.

module test();
 
class temp;
  rand bit anum[16];
  rand bit bnum[16];
  rand bit cnum[16];
  
  constraint e {
    bnum.sum() with (int'(item==0))==5;
    anum.sum with (int'(item))==5;
    cnum.sum with (int'(item.index<3?1:0))==3;
  }
endclass
  
initial
begin
      temp t = new();
      t.randomize();
      $display("%p\n %p\n %p", t.bnum, t.anum, t.cnum);
      $finish;
end
 
endmodule

'{'h1, 'h1, 'h0, 'h0, 'h0, 'h1, 'h0, 'h0, 'h1, 'h1, 'h1, 'h1, 'h1, 'h1, 'h1, 'h1}
'{'h1, 'h1, 'h0, 'h0, 'h1, 'h0, 'h0, 'h0, 'h0, 'h0, 'h0, 'h0, 'h1, 'h0, 'h1, 'h0}
'{'h0, 'h0, 'h1, 'h0, 'h1, 'h0, 'h1, 'h1, 'h0, 'h1, 'h1, 'h0, 'h1, 'h1, 'h1, 'h1} <<<— this is not right

In reply to kernalmode1:

The problem with your constraint on cnum is that there is no constraint on any element. The expression
cnum.sum with (int’(item.index<3?1:0))
has a constant value 3. It would easier to do what you want using
and
reduction.

cnum.and with (item.index<3?item:!item));

BTW, always test the result of calling randomize().

In reply to dave_59:

Hi Dave,

.and reduction and also .product reduction worked perfectly for these cases.

cnum.product with (int'(item.index%2?item:!item))==1;

'{'h0, 'h1, 'h0, 'h1, 'h0, 'h1, 'h0, 'h1, 'h0, 'h1, 'h0, 'h1, 'h0, 'h1, 'h0, 'h1}

But I fail to understand why .sum would not work. Here is my understanding on what was supposed to happen with .sum

As long as array index %2 is non-zero, generate 1 else generate 0 qualified by adding the values so that they evaluate to 8, which is size/2.

This works when I try to print the value after randomization.

$display("\n %d", t.cnum.sum with (int'(item.index%2?item:0)));

csum =           8

What am I missing here in its usage in constraints as opposed to its usage in regular code?
Does it work the same way in both?

In reply to kernalmode1:

item.index is not a random variable, it is an iterator that goes from 0…15.

cnum.sum with (int'(item.index%2?item:0)

is equivalent to

int'(0%2 ? csum[0] : 0) + int'(1%2 ? csum[1] : 0) + int'(2%2 ? csum[2] : 0) + ... +int'(15%2 ? csum[15] : 0)

which reduces to the following constraint

int'(csum[1]) + int'(csum[3]) + int'(csum[5]) + ...int'(csum[15])) = 8

That leaves csum[0], csum[2], csum[4], … csum[14] unconstrained.

In reply to dave_59:

It does not even do this -

int'(csum[1]) + int'(csum[3]) + int'(csum[5]) + ...int'(csum[15])) = 8

for some reason. I did expect atleast the odd indices to be 1. But here is one solution of randomization using this contsraint

cnum.sum with (int'(item.index%2?item:!item))==8;
'{'h0, 'h1, 'h0, 'h1, 'h1, 'h0, 'h1, 'h0, 'h1, 'h0, 'h0, 'h0, 'h1, 'h1, 'h0, 'h1}

In reply to kernalmode1:

Okay, I stuck at it and completed the second constraint also. This fixed it and using .sum reduction, I got what I was looking for

cnum.sum with (int'(item.index%2==1?item:0))==8;
cnum.sum with (int'(item.index%2==0?item:0))==0;

'{'h0, 'h1, 'h0, 'h1, 'h0, 'h1, 'h0, 'h1, 'h0, 'h1, 'h0, 'h1, 'h0, 'h1, 'h0, 'h1}

Thanks Dave!