Coverage for array elements in sequence

Hi
I have a fixed size array and I want to cover values of the array elements in a particular order.
For example,
typedef enum {RED,GREEN,BLUE,YELLOW,PURPLE, ORANGE, WHITE, UNDEF }colors_e;

rand colors_e my_colors[5];
constraint ct { unique{my_colors}};

I want to see if all the following patterns are covered:
1)
my_colors = {RED,GREEN,BLUE,YELLOW,ORANGE};

my_colors = {GREEN,RED,BLUE,YELLOW,ORANGE};

my_colors = {YELLOW,GREEN,BLUE,RED,ORANGE};

and so on.

Along with each pattern, there are other control signals that I would like to cross with.

How can I achieve it.

Thanks

In reply to kartavya:
You can create a parameter (or variable) to match each pattern as a coverpoint, and then cross with signals as needed.

typedef enum {RED,GREEN,BLUE,YELLOW,PURPLE, ORANGE, WHITE, UNDEF }colors_e;

module top;
class C;
  rand colors_e my_colors[5];
  constraint ct { unique{my_colors};}

  parameter colors_e my_colors1[5] = {RED,GREEN,BLUE,YELLOW,ORANGE};
  parameter colors_e my_colors2[5] = {GREEN,RED,BLUE,YELLOW,ORANGE};
  parameter colors_e my_colors3[5]  = {YELLOW,GREEN,BLUE,RED,ORANGE};

  covergroup cg;
    cp1: coverpoint my_colors == my_colors1 {bins hit = {1};}
    cp2: coverpoint my_colors == my_colors2 {bins hit = {1};}
    cp3: coverpoint my_colors == my_colors3 {bins hit = {1};}
  endgroup

  function new;
    cg = new;
  endfunction
endclass
  
C c = new;
  initial repeat (100) begin
    assert(c.randomize);
    c.cg.sample;
  end
endmodule

In reply to dave_59:

Hi Dave,
Thanks.
My list is huge and I was looking for some alternative to listing down all the possible combinations.

In reply to kartavya:

How can we achieve the same, if it is a queue instead of a fixed size array. ie.,
rand colors_e my_colors[$];

In reply to dave_59:

Hi Dave,
In your code,you have used parameter. What is the advantage of using parameter in this context,instead of a variable.

In reply to kartavya:

I make it a habit of using parameters to create meaningful symbolic names for literals. Like for π,
parameter pi = 3.14;
. You could use a variable if you need to change the values later. Making it a parameter leaves room for compiler optimizations.

You can certainly use queues instead of fixed sized arrays, but comparing two queues means they have to be the same size to match.

You need to explain in more detail what you are trying to cover. In your example, there is an enum with 8 values, and patterns with 5 values. Did you mean all possible combinations 8C5 = 56 possibilities, or all possible permutations 8P5 = 6720 possibilities? How does this scale with your real application? There might be other ways of approaching your problem.

In reply to dave_59:
Hi Dave,
I will reduce the number of values in enum to 3 and explain my requirement:
I have queue

typedef enum {RED,GREEN,BLUE }colors_e;

rand colors_e my_colors[$];
constraint ct { unique{my_colors}};

I need to cover all the following patterns

my_colors1 = {};
my_colors1 = {RED};
my_colors1 = {GREEN};
my_colors1 = {BLUE};
my_colors1 = {RED,GREEN};
my_colors1 = {GREEN,RED};
my_colors1 = {RED,BLUE};
my_colors1 = {BLUE,RED};
my_colors1 = {GREEN,BLUE};
my_colors1 = {BLUE,GREEN};
my_colors1 = {RED,GREEN,BLUE};
my_colors1 = {RED,BLUE,GREEN};
my_colors1 = {GREEN,BLUE,RED};
my_colors1 = {GREEN,RED,BLUE};
my_colors1 = {BLUE,RED,GREEN};
my_colors1 = {BLUE,GREEN,RED};

Is there a way to achieve this without listing out all the patterns

Thanks

In reply to kartavya:

If you can come up with a list of patterns, you can create an array of covergroups for each pattern. Then sample the entire array of covergroups for each value of my_colors. That’s the easy part. The harder part is coming up with an algorithm that generates all the patterns you want to cover. I’ve got one here for your latest example, but you’ll probably want to use a recursive approach for larger sets of patterns.

typedef enum {RED,GREEN,BLUE }colors_e;

covergroup cg(colors_e pattern[$], ref colors_e value[$]);
  option.per_instance = 1;
  coverpoint pattern == value {bins hit = {1};}
endgroup

class C;
 
rand colors_e my_colors[$];
  cg cg_inst[];

function new;
  colors_e itor1, itor2, itor3, list[$][$];
  list.push_back('{});
  do begin
    list.push_back('{itor1});
    do begin
      if (itor1 != itor2)
        list.push_back('{itor1, itor2});
      do begin
        if (itor1 != itor2 && itor1 != itor3 && itor2 != itor3)
          list.push_back('{itor1, itor2, itor3});
      end while ((itor3 = itor3.next()) != itor3.first());
    end while ((itor2 = itor2.next()) != itor2.first());
  end while ((itor1 = itor1.next()) != itor1.first());
  cg_inst = new[list.size];
  foreach(cg_inst[n]) cg_inst[n] = new(list[n],my_colors);
endfunction

// samples entire array of covergroups
function void cg_sample; 
  foreach(cg_inst[n]) cg_inst[n].sample;
endfunction
endclass

In reply to dave_59:

Thanks Dave.It works !