Random associative array

Hello
Can anyone share an example usage of random associative array with enum index. If possible also an example of constraining the array. How can I keep the array empty by default.
Thanks

In reply to jjose:
use the string as index in associative array . arrary size put as 0 . for default constraint use soft so array can be overriden for later use

class assoc ;

typedef enum bit[1:0] {A,B,C,D} t_e;
t_e d_e;
rand int arry[string];

constraint c_array {
  soft arry.num ==0 ;

} 

......
  
endclass

In reply to kddholak:
Your answer makes no sense. You cannot constrain the size of an associative array.

You cannot add or remove elements of associative array with randomize() except inside pre_/post_randomize) You can only randomize individual elements of an associative array and constrain them with a foreach loop.

In reply to dave_59:

Thanks David,
Will you be able to share an example ? i ended up getting a constraint error related to array size .

Please make sure variable XXXXX is within the array size.

I am doing it the wrong way…

In reply to jjose:
If you are getting errors it would really help to show the code you are using. This works for me.

module top;
   typedef enum bit[1:0] {A,B,C,D} t_e;
   class assoc;
     rand bit [7:0] aa[t_e] = '{default:0};
     constraint c { foreach(aa[ii]) aa[ii] < 10; }
   endclass

   assoc h;
   initial begin
      h = new;
      void'(h.randomize());
      $display("%p",h.aa);
      h.aa[A] = 0;
      h.aa[B] = 0;
      void'(h.randomize());
      $display("%p",h.aa);      
      h.aa[D] = 0;
      void'(h.randomize());
      $display("%p",h.aa);      
      void'(h.randomize());
      $display("%p",h.aa);      
   end
endmodule : top

# '{ }
# '{A:3, B:8 }
# '{A:9, B:4, D:3 }
# '{A:1, B:8, D:6 }

In reply to dave_59:

Thank you David for your help. This works for me…

In reply to dave_59:

Hey Dave,

Is it supposed to be supported to randomize a specific entry in the array without a foreach loop?

Based on your example :


module top;
   typedef enum bit[1:0] {A,B,C,D} t_e;
   class assoc;
     rand bit [7:0] aa[t_e];
   endclass
 
   assoc h;
   initial begin
      h = new;
      void'(h.randomize() with {aa[B] == 1;};);
      $display("%p",h.aa); 
   end
endmodule : top

In reply to galpa:
Yes, but randomize() never constructs anything. In your example, you have to allocate array element aa[B] before calling randomize().

In reply to dave_59:

I meant randomizing it without ‘allocation’ prior to the randomize call (just as I wrote it).

Thanks for the quick reply.

In reply to jjose:

module abc;
  int a[int];
  int q1[$],q2[$];
  
  initial begin
  
    for(int i=0;i<10;i++)
      begin
        a[$urandom] = $urandom;
      end
    
    $display("%p",a);
  foreach (a[i]) begin
    if(a[i]%2==0)
      q2.push_back(a[i]);
    else
      q1.push_back(a[i]);
  end
  $display("%p %p",q1,q2);
  end
endmodule

I try above method to randomize 10 random locations of associate array and then put even and odd elements on 2 different queues.

Output:-

vsim -voptargs=+acc=npr 
# run -all
# '{-1992863214:-1295874971, -1309649309:-2071669239, -1143836041:1924134885, -1064739199:303379748, -720121174:-487095099, -482925370:2097015289, 114806029:15983361, 512609597:992211318, 1177417612:1993627629, 1189058957:112818957 }
# '{-1295874971, -2071669239, 1924134885, -487095099, 2097015289, 15983361, 1993627629, 112818957} '{303379748, 992211318}
# exit

Hope this can help!!

In reply to dave_59:

Hi Dave,

In case the array size is large, can you please explain with respect to the example, how one can allocate all elements using a loop/foreach construct/any other method to solve this issue? Thanks.

In reply to rahuls_2912:

The point of using an associate array is usually that you do not intend to allocate all elements of every index value.

If you just want to know how to iterate over all enum values, you can use a do-while loop

module top;
   typedef enum bit[1:0] {A,B,C,D} t_e;
   class assoc;
     rand bit [7:0] aa[t_e] = '{default:0};
     constraint c { foreach(aa[ii]) aa[ii] < 10; }
   endclass
 
   assoc h;
   t_e itr; // itorator
   initial begin
      h = new;
      itr = itr.first();
      do begin
         h.aa[itr] = 0;
         itr = itr.next();
      while (itr != itr.first());
      void'(h.randomize());
      $display("%p",h.aa);
   end
endmodule : top

In reply to dave_59:

Hi Dave, can you please explain why the first display statement prints an empty array {}? Also, why do you do the following:
h.aa[A] = 0;
h.aa[B] = 0;
h.aa[D] = 0;

In reply to vk7715:

The first display statement prints an empty array because no elements have been written to yet. The other statements are used to initialize each element.

In reply to dave_59:

Hi Dave, thank you for your answer. Can you please let me know if my understanding is correct?
An associative array allocates storage only upon usage, so when you do h.aa[A] = 0, h.aa[B] = 0 and h.aa[D] = 0; you are allocating memory only for those indices, hence h.aa[C] never gets displayed because it has no memory to store a randomized value. Am I right?

In reply to vk7715:
Correct. An associative array allocates storage only upon a write access to an element.

In reply to dave_59:

Hi Dave, thank you for your answer. I have a follow up question. You mentioned in one of the answers above that we cannot constrain the size of an associative array. Can you please tell me why that is so? Can’t we constrain the user to insert only 5 elements into an associative array or something like that?

In reply to vk7715:

As stated above, the point of using an associative array is allocating some, but not all, indexes value of the array (a sparse or noncontiguous array). If you wanted to constrain the size of an associative array to 5 elements, what would the index values be? If you say 0 through size-1, then you might as well use a dynamic array.