Array.sum method in constraints

I am trying to solve the below constraint on eda playground but it is timing out.

Given an integer n, create an array such that each value is repeated twice.
For example;
n=3->[1,1,2,2,3,3]
n=4->[1,1,2,2,3,3,4,4]

My solution:

module s1;
  
  class constraint_test;

    rand int arr[];
    int n = 4;
    constraint c7 {
      arr.size() == n*2;
      arr.sum with(int'(item==n)) == 2;
      arr.sum with(int'(item==n-1)) == 2;
      arr.sum with (int'(item==n-2)) == 2;
      arr.sum with (int'(item==n-3)) == 2;
    }
         
  endclass
  
  initial begin
    constraint_test t1;
    t1 = new();
    t1.randomize();
    foreach(t1.arr[i]) begin
      $display("arr[%d]:%d",i, t1.arr[i]);
    end
  end
endmodule

What is the problem with my code?

What is the problem with my code?

Do you seek the array elements to be in ascending order ?
If yes, you could call arr.sort() in post_randomize() function.

Also one suggestion would be to instead write a generic constraint

     foreach( arr[i] )                                        
    { 
      if( i < n ) 
      { arr.sum with( int'(item == (n-i) ) ) == 2; }
    }   
1 Like

This is leading to a hang too! Not sure if this is problem with eda playground itself.

You have run into a tool specific issue on EDAPlayground. Try any other tool.

Realize that you are trying to randomize a 128-bit random number with just a few solutions.

1 Like

Given an integer n, create an array such that each value is repeated twice.

If this is the only constraint, the following example code using post_randomize() would work.

  class constraint_test;

    rand int arr[];
    int n = 4;
    constraint c7 {arr.size() == n; }//n*2;

    function void post_randomize();
        super.post_randomize();
        begin
            int tmp_q[$];
            foreach(this.arr[i])
              repeat(2) tmp_q.push_back(this.arr[i]);
           this.arr.delete();
           this.arr = tmp_q;
        end
    endfunction
            
  endclass

Note that, each integer number is random, not sequential number like your showed as example.

For example;
n=3->[1,1,2,2,3,3]
n=4->[1,1,2,2,3,3,4,4]

If you are expecting like these, you don’t need to use randomize().

With little modification, your code works.

module my_tb;
  
class constraint_test;

    rand int arr[];
    int n = 4;
  constraint c0 {
  
    foreach(arr[i])
      arr[i] inside {[1:n]};
  }
  
    constraint c7 {
      arr.size() == n*2;
      arr.sum with (int'(item==n)) == 2;
      arr.sum with (int'(item==(n-1))) == 2;
      arr.sum with (int'(item==(n-2))) == 2;
      arr.sum with (int'((item==n-3))) == 2;
    }
         
  endclass
  
  initial begin
    constraint_test t1;
    t1 = new();
    t1.randomize();
    foreach(t1.arr[i]) begin
      $display("arr[%d]:%d",i, t1.arr[i]);
    end
  end
endmodule

I don’t see any need for classes, randomization or sum(). Is it required to use those elements? How about this solution:

// Given an integer n, create an array such that each value is repeated twice.
// This array is a solution for all n: '{1, 1}
// But let's add a few more constraints:
//  1. the array has 2*n entries
//  2. items in the array are between 1 and n
module tb;
  parameter N = 4;
  
  int b[N*2];
  initial begin
    foreach (b[i])
      b[i] = (i % N) + 1;
    foreach (b[i])
      $display("%0d: %0d", i, b[i]);
  end
endmodule