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.