Array constraint. Each row total should be 100, with each element less than 80. I want to understand how to do this using only sum method of array

class fs_array;
  rand bit [7:0] array1[3][4];
  int i,j;
  rand int n;
// ************************* incorrect output *******************************************
  constraint array_c   {     
    foreach  (array1[i]) {
      array1[i].sum(item) with ((int'(item) < 80) ? item : 0) == 100; // Trying : each row total is 100 (with each element value less than 80)
      }
  }     
// ****************************************************************************************

//  180     23    189     77  
//
//  229     41     59     98  
//
//   41    173    237     59  

  function void display();
    foreach (array1[i]) begin
      foreach (array1[i][j]) begin
        $write("  %d  ",array1[i][j]);
      end
      $display("\n");
    end
  endfunction
  
endclass

module fixedsize_array_randomization;
  fs_array pkt;

  initial begin
    pkt = new();
    pkt.randomize();
    pkt.display();   
  end
  
endmodule 
// *******Gives expected output ****** only difference from above constraint is "(int'(item) < 26"  ********************
  constraint array_c   {     
    foreach  (array1[i]) {
      array1[i].sum(item) with ((int'(item) < 26) ? item : 0) == 100; // Trying : each row total is 100 (with each element value less than 26)
      }
  }     
// ****************************************************************************************

//   25     25     25     25  
//
//   25     25     25     25  
//
//   25     25     25     25  

In reply to vickydhudashia:

What you need is some thing like below


class fs_array;
  rand bit [7:0] array1[3][4];
  int i,j;
  rand int n;
// ************************* incorrect output *******************************************
  constraint array_c   {     
    foreach  (array1[i]) {
      array1[i].sum(item) with ((int'(item)))== 100; // Gives sum of 100, pardon bracket error  if any
      }
  }     

  function void display();
    foreach (array1[i]) begin
      foreach (array1[i][j]) begin
        $write("  %d  ",array1[i][j]);
      end
      $display("\n");
    end
  endfunction
 
endclass
 
module fixedsize_array_randomization;
  fs_array pkt;
 
  initial begin
    pkt = new();
    pkt.randomize();
    pkt.display();   
  end
 
endmodule 


In reply to sa5691:

Hey sa5691, sorry for not being clear on my requirement.
I need each element’s value to be less than 80 and sum of row to be 100.

I can do this seperatly and get correct result. But I want to specify this using sum method of array.


constraint array_c   {     
    foreach  (array1[i]) {       // for each row
      foreach (array1[,j]) {     // for each column in 1 row // meaning element
        array1[i][j] < 80;  // value of that element less than 80
      }
      array1[i].sum(item) with (int'(item)) == 100; // each row total is 100
      }
  }  

In reply to vickydhudashia:

  constraint array_c   {     
    foreach  (array1[i]) 
      array1[i].sum(item) with ((item < 80) ? item : 101) == 100; 
  }

You first try was very close. Your cast int’(item) < 80 is unnecessary because the width of the conditional expression does not propagate to the result of the conditional operator ?:— it’s just true or false. The result width is the maximum width of the second(true) or third(false) operand. Since the false operand is plain decimal number, its width is at least 32 bits, so the result will be at least 32 bits

That third operand needs to be a value greater than 100 so that item < 80 must always be true.

In reply to dave_59:

That’s a nice trick for the False Operand .

So if I need to constraint elements within a range ( along with the sum ) ,
Would the following be permissible too ? ::


constraint array_c   {     
    foreach  (array1[i]) 
      array1[i].sum(item) with ( ( item inside { [ Low : High ] , Specific value1 , Specific value2 , ...  } ) ? item : 101) == 100; 
  }

The basic logic being that inside returns 1’b0 / 1’b1 .

In reply to ABD_91:
Hey ABD_91, Yes your guess is correct


  constraint array1_row {
       foreach (array1[i]) {
         array1[i].sum(item) with ((item inside {[0:7], [93:100], 90, 10}) ? item : 101) == 100;
       }          
  }

//    3     90      5      2  
//
//   95      5      0      0  
//
//    1      0     93      6  
//
//   93      5      0      2  


In reply to dave_59:

Thanks Dave. Now I understand

  1. simple sum of elements in a row

array1[i].sum with (int'(item)) == 100;

  1. sum of row with restriction on element selection

array1[i].sum with ((item inside {[0:7], [78:83], 90, 10}) ? item : 101) == 100;

and 3) sum with repetition of some specific elements


array1[i].sum with (int'(item)) == 100;
array1[i].sum with ((item == 10) ? 1 : 0) == 2;

In reply to vickydhudashia:

All these are all nice tricks, however it would be so much better for readability and debuggability to write these out as separate constraints.

In reply to dave_59:

Hi Dave, Could you please help me understand why the third operand should be 101. Why cant it be 0
“That third operand needs to be a value greater than 100 so that item < 80 must always be true.” How will that work?

In reply to Atresh:

Because adding 0 to the sum would prevent the final sum from being 100.