Hi,
I am still learning SystemVerilog to improve my test cases.
Please have a look at the code below.
There are 5 tasks and 2-bit task input.
I would like to achieve a cyclic randomization.
Please suggest how I could improve it.
And also how would one create a covergroup to ensure all combinations are checked.
Thank you.
class Dadr_Sel;
randc bit [1:0] dadr;
endclass
initial
d = new();
for (i=0; i<250; i=i+1) begin
randsequence (main)
main : first second third forth;
first : on | off | ready | standby | sleep;
second : on | off | ready | standby | sleep;
third : on | off | ready | standby | sleep;
forth : on | off | ready | standby | sleep;
on : { assert (d.randomize()); `IC_ON(d.dadr); };
off : { assert (d.randomize()); `IC_OFF(d.dadr); };
ready : { assert (d.randomize()); `IC_RDY(d.dadr); };
standby : { assert (d.randomize()); `IC_STB(d.dadr); };
sleep : { assert (d.randomize()); `IC_SLP(d.dadr); };
endsequence
end
end
If you mean you want cyclic randomization of the 5 tasks, randsequence does not provide that capability. What you can do is add another randc variable, like a enum and use that in a case statement to select the task to call. Then it would be easy to create a covergroup in that class and cross the two variables to collect coverage.
Thank you for your reply.
While waiting for any reply, I had explored the randc option.
This is how my code looks like now.
Is there a better way to write the case statements?
The code is repetitive.
I may need to add dadr.d4, dadr.d5 etc.
typedef struct packed {
bit d0;
bit [2:0] d1, d2, d3;
} dadr_struct;
class Dadr_Sel;
randc dadr_struct dadr;
constraint c {
dadr.d0 < 2;
dadr.d1 < 5;
dadr.d2 < 5;
dadr.d3 < 5; }
endclass
Dadr_Sel d = new();
covergroup cg;
cp0 : coverpoint d.dadr.d0;
cp1 : coverpoint d.dadr.d1 { bins range[] = {[0:4]}; }
cp2 : coverpoint d.dadr.d2 { bins range[] = {[0:4]}; }
cp3 : coverpoint d.dadr.d3 { bins range[] = {[0:4]}; }
cpx: cross cp0, cp1, cp2, cp3;
endgroup // cg
cg cgi = new();
initial begin
for (i=0; i<250; i=i+1) begin
assert(d.randomize());
cgi.sample();
case(d.dadr.d0)
0 : `IC_ON (0);
1 : `IC_OFF(0);
endcase
case(d.dadr.d1)
0 : `IC_ON (1);
1 : `IC_OFF(1);
2 : `IC_RDY(1);
3 : `IC_STB(1);
4 : `IC_SLP(1);
endcase
case(d.dadr.d2)
0 : `IC_ON (2);
1 : `IC_OFF(2);
2 : `IC_RDY(2);
3 : `IC_STB(2);
4 : `IC_SLP(2);
endcase
case(d.dadr.d3)
0 : `IC_ON (3);
1 : `IC_OFF(3);
2 : `IC_RDY(3);
3 : `IC_STB(3);
4 : `IC_SLP(3);
endcase
...
Your latest example does not match your original behavior. The first production had five choices, now d0 only has two. Also, the argument passed to each task used to be random cyclic, but now it’s just sequential. You need to be very clear where you want random cycles.
I am sorry for the confusion.
I have realized that d0 only needs 2 states.
And also realized the order of setting the state didn’t matter
Example:
setting this IC_ON (0); -> IC_OFF(1) → IC_RDY(2); -> IC_STB(3);
can be considered same as
setting this IC_OFF (1); -> IC_STB(3) → IC_ON(0); -> IC_RDY(2);
These are just tasks to put the DUTs in a certain initial state.
The objective of the randomness would be to set 5 different states to the 3 DUTs and 2 different state for 1 DUT (d0)
That would be 2x5x5x5 = 250 combinations
I believe I have achieved it in my 2nd code.
Now, I am just wondering if there is a more efficient way of coding it so that I can easily expand it when I increase the number of DUTs. Perhaps using an array.