How the "dist" works in constraint if we create the object every time vs one time

Hello,

System verilog has distribution support in constraints. I have a question that if the distribution changes if I do new for each randomize call versus doing new once and randomize multiple times.

Below is the sample code.

class packet;
  rand bit [3:0] addr;
  constraint addr_range { addr dist { 2 := 5, 7 := 8, 10 := 12 }; }
endclass

module constr_dist;
  initial begin
    packet pkt;
    int num;
    num = 100;
    $display("------------------------------------");
    repeat(num) begin
      pkt = new(); //============> Doing new every time before randomize
      pkt.randomize();
      endcase 
    end
    $display("------------------------------------");
  end
endmodule
========================================
class packet;
  rand bit [3:0] addr;
  constraint addr_range { addr dist { 2 := 5, 7 := 8, 10 := 12 }; }
endclass

module constr_dist;
  initial begin
    packet pkt;
    int num;

    pkt = new(); //============> Doing new once and randomize multiple time
    num = 100;
    $display("------------------------------------");
    repeat(num) begin
      
      pkt.randomize();
      endcase 
    end
    $display("------------------------------------");
  end
endmodule

Thanks,
Jay

In reply to Jay Shah:

In your example, it should not matter. Calling new() and randomize() both consume 1 RNG state. So the probability remains the same.

In reply to dave_59:

Thanks for the response.

In reply to dave_59:

Hi Dave ,

I have a question regarding RNGs

I believe if the addr were declared as randc and No dist Constraint be present the above 2 Codes would have different results .

(a) If its not too much to ask could you give an example where the 2 Codes ( where one is
constructed repeatedly and the other randomized repeatedly ) would have different
results when the variable is declared as rand .

(b) From the above 2 Codes ( where one is constructed repeatedly and the other randomized
repeatedly ) does any one have a benefit over the other ?

 One point I can think of is when the Object is Constructed repeatedly it would consume 
 more memory 

Regards,
AGIS

In reply to Etrx91:

It is possible the two examples produce the same results with randc, but not guaranteed.
Realize in order to achieve random stability, every unique RNG value returns the exact same solution. If seeding a new object and calling randomize() advances the next RNG in the same manner, they will produce the same cycle of random addr values.

If you are sending this packet into a queue (as you would do as a umm_sequence_item), you are going to need to construct a new object each time it is sent. You can either randomize the same object and clone it before sending, or randomize new objects and send them.

The benefit of randomizing the same object is when you need state information from the previous packet to randomize the next packet. The problem with that is forgetting to clone the object before sending, and debugging why you only see the last packet in the queue.

In reply to dave_59:

This is the exact issue I had in my previous project at work. I was writing a random test case and, was (newing) the object only once and, randomizing it say 100’s of times, storing that result of that in an associative array. When I was going to call my Sequence with the data retrieved from the associative array what I saw was all the values being the same (And that being from the last iteration). But in the log file it did appear the object did get randomized (As I had debug statements to print the transaction post randomize) but, the thing here was I was randomizing the same single object every single time, so it was just simply overwriting the transaction with new values each time.

Agreed this was a typo but, it took a couple of hours to figure out this as I did not imagine to do this silly thing.