Array.sum does not give expected output. Is this simulator issue?

Hello All,

I am trying to use simple array.sum method but somehow I am not getting output as expected. Is this simply simulator issue ?

also, i was trying to use .sum method for inline constraint. Does it give similar output as class based .sum() method?

It should be the same but somehow my outputs are not as expected, so getting confused.



module size_sum();

class dynamic_array;
  rand bit [7:0] array[ ];
   
  constraint size_c   { array.size() inside {[4:10]}; }
  constraint array_c  { array.sum() == 'd45;}
  constraint array_ec { foreach(array[i]) array[i] > 1;}
   
  function void display();
    $display("array size is = %0d",array.size());
    $display("array = %p",array);
  endfunction
endclass
 

  dynamic_array pkt;
  bit [1:0]buflen[];

  initial begin
    pkt = new();
    pkt.randomize();
    pkt.display();  
    assert(std::randomize(buflen) with {buflen.size()==7; buflen.sum()>0; buflen.sum()< 4;});
    $display("buflen size id %0d buflen =%0p",buflen.size(), buflen); // buflen: does this give similar output as constraint array_c  { array.sum() == 'd45;}
  end

endmodule : size_sum


Output

array size is = 5
array = '{'hf2, 'h25, 'h2d, 'hd4, ‘h15}
buflen size id 7 buflen =’{'h3, 'h3, 'h3, 'h3, 'h2, 'h2, 'h2}

In reply to edaboy:

The issue is that width of each element of buflen is 2-bits
So the sum will be calculated using 2-bit precision .

'h3 + 'h3 + 'h3 + 'h3 + 'h2 + 'h2 + 'h2 == 'h12 == 'd18

So if you see the lower 2 bits of 'd18 i.e 'b100_10 are 'b10

which is based on your constraint of sum inside { [1:3] }

You need to change constraint to ::


assert(std::randomize(buflen) with {buflen.size()==7 ;
        buflen.sum() with ( int'( item ) )  inside { [1:3] } ; });

This calculates sum using 32-bit precision

The Same Issue exists with array_c . The actual sum is 'd557 and not 'd45 .

 The  lower  8 - bits of  'd557  gives  'd45 . 

Change the constraint to ::


  constraint array_c  {  array.sum() with ( int'( item ) )  == 'd45 ; }
  

Thanks for the explanation, i see that is working too.

How about if I simply declare variables as integer ?


module size_sum();

class dynamic_array;
  rand bit [7:0] array[ ];
   
  constraint size_c   { array.size() inside {[4:10]}; }
  constraint array_c  {  array.sum() with ( int'( item ) )  == 'd45 ; }
  constraint array_ec { foreach(array[i]) array[i] > 1;}
   
  function void display();
    $display("array size is = %0d",array.size());
    $display("array = %p",array);
  endfunction
endclass
 

  dynamic_array pkt;
  bit [1:0]buflen[];
  int unsigned bufint[]; // int variable declaration

  initial begin
    pkt = new();
    pkt.randomize();
    pkt.display();  

    assert(std::randomize(buflen) with {buflen.size()==7 ;
        buflen.sum() with ( int'( item ) )  inside { [1:3] } ; });

    assert(std::randomize(bufint) with {bufint.size()==7; 
       bufint.sum() with (int'(item)) < 10;}); // .sum() for int variable.

    $display("buflen size id %0d buflen =%0p",buflen.size(), buflen);
    $display("bufint size id %0d bufint =%0p",bufint.size(), bufint);
  end

endmodule : size_sum


array size is = 5
array = '{'h3, 'h4, 'hc, 'he, ‘hc}
buflen size id 7 buflen =’{'h0, 'h0, 'h2, 'h1, 'h0, 'h0, ‘h0}
bufint size id 7 bufint =’{'he053a795, 'h2cd77a2e, 'ha8b386b8, 'h501258b6, 'h23e51217, 'hbe4a63e1, 'hc7110db7}

In reply to edaboy:

This too results in an overflow although the sum is calculated using 32-bits .

Now as your element width is 32-bit , change the precision to a Number greater than it


bufint.sum() with ( 34'(item)) < 10 ;

Now sum is calculated using 34-bit precision of each element .

An alternative is ensuring that the higher bits of individual elements are 0 ::


bufint[31:10] == 0 ; //  As  the  sum  is  less than  10  the  higher  bits  would be 0 

In reply to edaboy:

You may want to look at Verilog Basics for SystemVerilog Constrained Random Verification.