QUESTION:
Create a system verilog class with a random queue constrained with the following conditions:
1)It should have a random number of elements between 1 and 32
2)All the elements should have a value between 0 and 31
3)All the elements should be different
4)There should be a 30% probability of the elements to be in order(ascending or descending)
5)10% of the time it should be the smallest possible queue
6)10% of the time it should be the biggest possible queue
7)80% of the time should be equally distributed among the other possible sizes s

MY LOGIC:

class abc;
rand int q[$];
constraint c1 {foreach(q[i]) q[i] inside {[0:31]};}
constraint c2 {q.size dist {1:=10, 31:=10, [2:30]:=80};}
constraint c3 {unique {q};}
constraint c5 {foreach(q[i]) {
if (i>0) {q[i] dist {(q[i]>q[i-1]) := 30, q[i] := 70};}}
}
endclass
module exp;
abc a = new;
initial begin
repeat (10) begin
a.randomize();
$display ("### %p ###", a.q);
end
end
endmodule

I have one question though after looking into the link you have provided: here for my question, nothing is mentioned for unordered. How will the constraint interpret that as. The constraint says unordered 70% but how will the constraint know what unordered is.
Please let me know.

I interpreted “unordered” to mean “no constraint to be ordered” since there is no such thing as 1 or 2 element array without an ordering. If you want, you could add another constraint that says: if unordered and the size is greater than 2, then the elements must be out of order. I’ll leave that up to you to figure out. I can give you a hint not use the foreach construct for that.

Hi Dave,
Thank You for your response.
I understood not to use foreach but how can I tell randomization not to do something. I’m unable to get to that logic.
Can I just use q[i] as it is. Will that just put the remaining unordered elements as they come.
Also I’m curious how the randomization interprets if I do not specify any condition for the unordered.
Please let me know.
Thanks.

The problem with taking the unconstrained elements as they come is the for small sizes of q, there is a high probability of getting the elements in numerical order (q.size–3, 33% chance). That skews your desired probability of unordered to be 70%.

You tell the constraint solver to do or not something by putting it in terms of an equation that that must be true. I can convert the foreach loops to an array reduction and() method, and use the logical equivalence operator. This operator returns true of both LHS and RHS or both true or both false.

class abc;
rand int q[$];
rand enum {unordered_,ascending_,descending} ordering;
constraint c1 {foreach(q[i]) q[i] inside {[0:31]};}
constraint c2 {q.size dist {1:=10, 31:=10, [2:30]:/80};} // use :/ with a range
constraint c3 {unique {q};}
constraint c5 {
ordering dist {[ascending_:descending]:/30, unordered_:=70};
q.size() > 2 -> {
ordering == ascending_ <-> q.and() with (item.index == 0 ||
q[item.index-1] < item);
ordering == descending <-> q.and() with (item.index == 0 ||
q[item.index-1] > item);
}
}
endclass