Exclude randomized value from range in dist constraint

Hello Guys !

I want to create an array that includes random values in defined range. I need to choose random value in this range and the occurrence probability of this value in the array should be 80% , all others values in range should have only summarized 20%.

Here is my code :


class test;
  rand int numbers_array[];
  rand int random_number ;  

  int range = 4;
  int array_size = 100;
  
  typedef integer queue_of_int[$]; 
  
  // called from cnstr 
  function queue_of_int get_queue(int delete_num);

    queue_of_int ret;	
    ret = {0,1,2,3};
   
    ret.delete(delete_num);
    
    return ret;
    
  endfunction
  
  constraint random_number_c {
    random_number inside {[0:range-1]};
  }
  	
  constraint numbers_array_c {     
     
    foreach(numbers_array[i]) {
      numbers_array[i] dist {random_number:/80 , get_queue(random_number):/20};
    } 
    numbers_array.size == array_size ;  
   }
   

  function new();   
  endfunction

endclass  

It looks like random_number variable is not randomized before get_queue calling.
Why it doesn’t work ? And is there any solution for what I want to do ?

In reply to egorman44:
For the future, It always helps if you can say more than just “it doesn’t work”; like what results you saw versus what you expect.

Your code should not have even compiled. The LRM does not allow non-integral expressions in a constraint, and the function get_queue() returns an aggregate result. Even if some simulators allow this, the next problem is you have a cyclic set of constraint dependencies. random_number is used as both a input argument to a function, and in a constraint involving the same function output.

I think the following code does what you want

class test;
   rand int number_array[];
   rand int random_number ;  
   int range = 4;
   int array_size = 100;
   
   constraint random_number_c {
      random_number inside {[0:range-1]};
   }
   constraint array_size_c {
    number_array.size == array_size ;  
   }
   constraint number_array_c {     
      foreach(number_array[i]) {
         number_array[i] inside {[0:range-1]};
         (number_array[i] == random_number) dist {1:=80 , 0:=20};
      }
   } 
 endclass

Thank you Dave for your reply.

In reply to dave_59:

For the future, It always helps if you can say more than just “it doesn’t work”; like what results you saw versus what you expect.

I got it , will try to hold on :)

Yesterday I tried to compile my code on the one simulator , it let me down gently and compiled my code. The output is:

KERNEL: delete_num is 0

KERNEL: ret[ 0] = 1

KERNEL: ret[ 1] = 2

KERNEL: ret[ 2] = 3

KERNEL: numbers_array[70] = 00000001

KERNEL: numbers_array[92] = 00000002

KERNEL: numbers_array[93] = 00000002

KERNEL: numbers_array[94] = 00000002

KERNEL: numbers_array[95] = 00000003

KERNEL: numbers_array[96] = 00000002

KERNEL: numbers_array[97] = 00000002

KERNEL: numbers_array[98] = 00000002

KERNEL: numbers_array[99] = 00000002

KERNEL:

KERNEL:

KERNEL: ------------------------------------------

KERNEL: random number is 2

, it excludes 0 from queue , however the rand_number = 2.

Today I used commercial simulator and it didn’t forgive me for aggregate data in dist constraint , I had supposed that I could do it as we can use aggregate datatype in inside.

And your code works perfect. It’s what I expected . thx !