Constraint question :: sum() with ( item.index .. )

I have following code ::


 class main;
  
  rand bit       b1num[16];
  rand bit [3:0] b4num[16];
 
 
  constraint SUM {
                  
                     b1num.sum with ( int'( ( item.index % 2 ) ? item : !item ) ) == 8 ; 
                     b4num.sum with ( int'( ( item.index % 2 ) ? item : !item ) ) == 8 ; 
                
                  }
endclass
 
 main m ;

initial begin
      m = new();
     
     if ( m.randomize() )
      begin     
       $display(" b1 is  %p", m.b1num); 
       $display(" b4 is  %p", m.b4num);
      end
end



I see following output ::

b1 is '{1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1} // Sum of odd indexes from 1 , 3 to 15 is 6 ; Sum of even indexes from 0 , 2 to 14 is 6
b4 is '{5, 0, 11, 0, 3, 3, 0, 0, 2, 0, 8, 1, 2, 2, 9, 1} // Sum of odd indexes from 1 , 3 to 15 is 7 ; Sum of even indexes from 0 , 2 to 14 is 40

Need help to understand how are the constraint evaluated ?

In int’( ( item.index % 2 ) ? item : !item ) ,
LHS ( item.index % 2 ) is True i.e 1 when index is odd that index 1 , 3 , 5 to 15
[Q1] So when LHS is true isn’t the constraint same as :: int’( b1[1] ) + int’( b1[3] ) + int’( b1[5] ) + … + int’( b1[15] ) == 8

[Q2] Also how does !item contribute to constraint ?
When index is 0 , 2 , 4… 14 what is the Constraint used ?

[Q3] Instead of writing ( item.index % 2 ) in condition can I write ( ( item.index[0] == 1 ) ) . ?

In reply to TC_2017:

The answers to Q1 and Q2 are tied together. The constraint is the same as

 int'( b1[1] ) + int'( !b1[2] ) + int'( b1[3] ) + int'( !b1[4] ) +... + int'( b1[15] ) == 8 

I think you meant to use0 instead of !item if you are only concerned about the sum of odd indexes. Also remember the result of !item is always a 1-bit value regardless of the size of item.

My response to Q3 is “try it”.

In reply to dave_59:

For [3] I did try but across simulators ( Not EDA playground but the ones used at work ) , 2 of them gave compilation issues whereas Questa didn’t .

I understand that we don’t discuss simulator issues here , so I asked in terms of syntax is it correct ?

I believe this works fine ::


rand bit [15:0] addr ;
constraint EVEN { addr[0] == 0 ; } // Even addresses only 

In reply to TC_2017:

From one of the simulators on EDAPlayground i’m getting “not yet implemented” which means it recognizes the syntax as being legal, but not implemented…yet.

In reply to dave_59:

Hi Dave ,

I was trying the above Sample Code using data type as ‘bit signed’ .
I see unexpected results with following code ::


class temp;
  rand bit signed [2:0] b4num[16];
 
  constraint e { 
                      b4num.sum with ( int'( ( item.index % 2 ) ? item : !item ) ) == 8 ; 
                       
               }   
endclass
 
 temp t ; 

 initial begin
       t = new();
        repeat(5)
          if ( t.randomize() )
          begin
        $display(" b4 is  %p", t.b4num);
        $display(" b4 Even sum is  %0d", t.b4num.sum() with (  int'( ( item.index % 2 ) ? 0 : !item ) )); 
        $display(" b4 Odd sum is  %0d",  t.b4num.sum() with (  int'( ( item.index % 2 ) ? item : 0 ) )); 
      end 
 end 


The Output for the code is ::
**
b4 is '{1, 1, 3, -3, -2, 0, -3, 1, -4, 0, -1, 0, 2, 1, -2, 0}
b4 Even sum is 0
b4 Odd sum is 0
b4 is '{-3, 2, 1, 2, -2, 0, -2, 1, -1, 0, 1, 3, -3, 0, 1, 0}
b4 Even sum is 0
b4 Odd sum is 8
b4 is '{2, 1, 1, 0, 2, 2, -2, -4, -4, 0, 1, 0, 2, 1, 2, 0}
b4 Even sum is 0
b4 Odd sum is 0**

Only 2nd Output meets my expectations

I am not sure how 1st and 3rd Output satisfy the sum() Constraint to be 8

In reply to Have_A_Doubt:

If the $display statement equations reflect your expectations, those two expressions need to be in your constraints. If you display your current constraint expression, you will see it is meeting your constraint. (note that !item is going to be 0 or 1 for any zero or non-zero value of item)

In reply to dave_59:

The last 2 display statements I added for debugging purposes .

My understanding is ( !item ) would be 1 ONLY if the element is 0
( !item ) would be 0 if the element is positive or negative

With 2nd OP ::

b4 is '{-3, 2, 1, 2, -2, 0, -2, 1, -1, 0, 1, 3, -3, 0, 1, 0}

Sum of Elements at odd index ( Based on constraint logic ) would be ::

2 + 2 + 0 + 1 + 0 + 3 + 0 i.e 8

Sum of Elements at even index ( via !item ) would be :

!(-3) + !(1) + !(-2) + !(-2) + !(-1) + !1 + !(-3) + !1 i.e

 0 +   0  +    0  +   0   + 0     + 0  +    0  + 0  i.e 0   

So 2nd Output matches my expectations ( Effective sum is 8 )

For 1st OP however ::

b4 is '{1, 1, 3, -3, -2, 0, -3, 1, -4, 0, -1, 0, 2, 1, -2, 0}

Sum of Elements at odd index ( Based on constraint logic ) would be ::

1 + -3 + 0 + 1 +  0 + 0 + 1 + 0 i.e 0 ( Same as 2nd debug display for 1st OP ) 

Sum of Elements at even index ( via !item ) would be :

!1 + !3 + !(-2) + !(-3) + !(-4) + !(-1) + !2 + !(-2) i.e
0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 i.e 0

( Same as 3rd debug display for 1st OP )

So effective sum is 0 ( 32’sb000 + 32’sb000 ) whereas I had constrained it to 8 ( 32’sb1000 ).

Still unable to understand the Output

In reply to Have_A_Doubt:

The problem is !item is a 1-bit unsigned value, and the result of the conditional operator is unsigned. When you cast it to int, it gets zero extended. Try outputting the result as

foreach (t.b4num[i]) $write("%0d ", int'(i%2 ? t.b4num[i]:!t.b4num[i]));