Randomising a logic vector of more than 32 in System Verilog

I have following code. I am trying to randomise a 96-bit logic vector with unique values on every iteration. But I have a constraint. On a certain condition, the least significant 3 bits have to be set constant 1s.


typedef struct packed 
{  
  logic [95 : 0] pr ;   
} vec_config;

class Config ;

   randc vec_config pkt ;

   constraint pr_constr {
                         if (condition)  { pr [2 : 0] <= '1 ;}
                        }
endclass

The problem is when I call randomize() with condition = true, only most significant 32 bits are randomised.

Simulation results:

010011101101110110101001101111110000000000000000000000000000000000000000000000000000000000000111

100100100001110101101000010001010000000000000000000000000000000000000000000000000000000000000111

111000101001110111001001000010000000000000000000000000000000000000000000000000000000000000000111

010010100111110100111000100000110000000000000000000000000000000000000000000000000000000000000111

100101010011110110011001111011010000000000000000000000000000000000000000000000000000000000000111

111001011011110101011000001001100000000000000000000000000000000000000000000000000000000000000111

010011010100110111100001010101000000000000000000000000000000000000000000000000000000000000000111

100100011100110100000000110110010000000000000000000000000000000000000000000000000000000000000111

when I call randomize() with condition = false, this problem is not there. It is cycling through unique 96-bit random values.
Also, when I replace randc with rand, this problem disappears. But it will not generate unique values anymore. So it is useless.

How can I solve this problem and generate unique 96-bit random values?

In reply to Mitu Raj:

The SystemVerilog LRM allows implementations to limit the number of bits of a random variable that can be cyclic with randc. As soon as you add constraints to that variable, it becomes extremely difficult to figure out when you’ve cycled through all possible solutions.

You can try this brute force method using post_randomize and a queue.

class Config ;
   rand vec_config pkt ;
   vec_config pkt_q[$];
 
   constraint pr_constr {
                         if (condition)  { pkt.pr [2 : 0] <= '1 ;};
                        }
   constraint un_constr {
                        unique {pkt, pkt_q};
                        }
  function void post_randomize();
     pkt_q.push_back(pkt);
  endfunction
endclass

In reply to dave_59:

Is there any overhead to this queue implementation. Like will it make simulation slower or queue will take lot of memory if run for millions of test vectors?

In reply to Mitu Raj:

Yes, there will be lots of overhead for this if you expect to generate millions of random packets.

However, if you know that you only need 224 (10 million) unique vectors out of 296 possible vectors, you can limit the uniqueness to 24 bits.

class Config ;
   rand vec_config pkt ;
   randc bit [95:72] uniq;
 
   constraint pr_constr {
                         if (condition)  { pkt.pr [2 : 0] <= '1 ;};
                        }
   constraint un_constr {
                        pkt[95:72] == uniq;
                        }
endclass

In reply to dave_59:

Thanks Dave. I will try out both methods.

Any idea on why SV finds it “difficult” to randomize the 93 bits using randc, after constraining first three bits constant ?? I mean, if that constraint is not there, SV can cycle thru all 96-bit values in unique fashion. Then it should be able to cycle thru 93-bit values as well. And now I really doubt whether it is actually cycling thru 96-bit values, when I think about the memory limitations on randc mentioned in LRM.

In reply to Mitu Raj:

Your constraint is not result in a constant; it’s a value from 3’h0 to 3’h6. 3’h7 is missing which makes for nonconsecutive values in the overall solution. But any kind of constraint on a bit that is not a constant is difficult to build a cyclic random number generator with a large number of bits.

And you’re never going to cycle through a 93-bit number. Even if you could count at the speed of the fastest processor (~9GHz), it would take longer than the current estimated age of the universe to cycle through all the values.