Hi, I would like to take a peek at randc variables today, and then talk about implementing it in a way with only rand variables.
For starter, let’s take a look at the definition of randc modifier. It’s defined in RFM 18.4.2.
Variables declared with the randc keyword are random-cyclic variables that cycle through all the values in a random permutation of their declared range. The basic idea is that randc randomly iterates over all the values in the range and that no value is repeated within an iteration. When the iteration finishes, a new iteration automatically starts.
For example, if we have the following variable
randc bit [1:0] y;
The variables y can take on the values 0, 1, 2, and 3. Each permutation, y is going to take on all the values before it moves to the next permutation.
There are a few things worth mentioning here based on my experience:
- Size limitation
- Constraint solver priority
Different vendors may impose a limit on the maximum size of a randc variable. The size shall be no less than 8 bits, which means the value can only go up to 255 if we define it as unsigned. When we are dealing with large numbers, we have to figure something else to accomplish this.
If we take the solution distribution into consideration, we have to watch closely over randc variables as well. Randc variables are solved before other random variables which can mess up the solution probability distribution and sometimes cause constraint failures.
An alternative way to implement the randc function without incurring the issues is listed below:
The basic idea is to add a queue. Within each permutation, all the generated values are pushed onto the queue, and the newly generated value should be different from all the values that are already stored in the queue. When the queue’s size reaches the number of values defined in each permutation, we clear the queue and start the next permutation.
We can use set membership in constraints to guarantee that the newly generated values are not already stored in the queue. We can perform the push and clear functions in the post_randomize function. The code is listed below:
class c1;
//queue to store generated variables
bit [1:0] q [$];
rand bit [1:0] y;
//set the membership
//y should not be generated before
constraint c {
!(y inside {q});
}
function void post_randomize();
q.push_front(y);
//if the size equals to the number of all combinations, clear the queue
if(q.size()==4)
q.delete();
endfunction
endclass
c1 c1_h;
initial begin
c1_h = new();
repeat(20) begin
if(c1_h.randomize())
$display("y is %b",c1_h.y);
end
end
endprogram
That’s all I would like to share on this topic today. If you have any questions, please leave me a comment below. Thank you for reading.
This is a tricky question asked in interview.
Finally I got the answer. Nice article.