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
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
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.
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.