Coverage cross ignore values inside an external array

I have an array of an enumerated type that’s declared outside a covergroup and is used in several places to define which clients are READ_ONLY:

client_e read_only_clients[] = {CLIENT1, CLIENT2};

And this covergroup that samples clients and their direction captured, with a bin for each element of client_e in client_cp:

covergroup cg with function sample ( client_e client, dir_e dir );
  client_cp : coverpoint client;
  dir_cp : coverpoint dir;

  client_dir_cr : cross client_cp, dir_cp;
endgroup

I want to create an ignore_bins for the cross that will ignore the bins where client_cp falls within read_only_clients, and dir is WRITE, as these are invalid combinations.
Currently, I have the elements of read_only_clients listed again in the ignore_bins declaration like so:

client_dir_cr : cross client_cp, dir_cp {
  ignore_bins ignore_read_only_clients = binsof(client_cp) intersect {CLIENT1, CLIENT2} &&
                                         binsof(dir_cp) intersect {WRITE};
}

I’m not happy with this as I need to copy paste this list several times across multiple covergroups. So I’d like to just use the array. I’ve tried doing something like this:

client_dir_cr : cross client_cp, dir_cp {
  ignore_bins ignore_read_only_clients = binsof(client_cp) intersect {read_only_clients} &&
                                         binsof(dir_cp) intersect {WRITE};
}

and this:

client_dir_cr : cross client_cp, dir_cp {
  ignore_bins ignore_read_only_clients = client_dir_cr with (client_cp inside {read_only_clients} &&
                                                             dir_cp == WRITE);
}

But neither worked as I wanted. Any ideas?

In reply to Freeman0916:

Try

ignore_bins ignore_read_only_clients = client_dir_cr with (client_cp inside {read_only_clients} ) &&  binsof(dir_cp) intersect {WRITE};

In reply to dave_59:

In reply to Freeman0916:
Try

ignore_bins ignore_read_only_clients = client_dir_cr with (client_cp inside {read_only_clients} ) &&  binsof(dir_cp) intersect {WRITE};

Hey Dave, I tried this and got a compilation error “Illegal operand for constant expression” from read_only_clients.

In reply to Freeman0916:

If you want a response, it would help to provide a complete test case.

In reply to dave_59:


class trans;
  typedef enum {CLIENT1, CLIENT2, CLIENT3} client_e;
  typedef enum {READ, WRITE} dir_e;
  
  client_e all_clients[] = {CLIENT1, CLIENT2, CLIENT3};
  client_e read_only_clients[] = {CLIENT1, CLIENT2};
  
  covergroup cg with function sample(client_e client, dir_e dir);

    client_cp: coverpoint client;
    dir_cp: coverpoint dir;

    client_dir_cr : cross client_cp, dir_cp {
  	  ignore_bins ignore_read_only_clients = client_dir_cr with (client_cp inside {read_only_clients} &&
                                                                 dir_cp == WRITE);
	}

  endgroup
  
  function new();
    cg = new;
  endfunction
  
  function run();
    foreach(all_clients[i]) begin
      cg.sample(all_clients[i], READ);
      cg.sample(all_clients[i], WRITE);
    end 
  endfunction
endclass

module top;
  trans t = new();
  
  initial begin
    t.run();
    
  end
endmodule

Hey Dave, this was my test code I was using on EDAplayground.
After more testing, I decided on a whim to use the Mentor Questa simulator instead of Cadence Xcelium and this solution worked as I expected, as well as my original ignore bins declaration using the “with” clause.

It seems I was having an issue with Xcelium up until now, as that still gives me a “Illegal operand for constant expression” compile error with the same code.

So both of these solutions work in other simulators:


ignore_bins ignore_read_only_clients = client_dir_cr with (client_cp inside {read_only_clients} &&
dir_cp == WRITE);


ignore_bins ignore_read_only_clients = client_dir_cr with (client_cp inside {read_only_clients} ) &&  
binsof(dir_cp) intersect {WRITE};