Ignoring array of bins in cross

Suppose I have the coverpoints and crosses shown in the code below. Can you please let me know why is my code not working and any alternative that I could try.


bit[31:0] ro_reg_addr[2] = {'h0008_0000,'h0008_000C};
covergroup my_covergroup;
    my_data: coverpoint data {
      bins data[] = {4'ha,4'hb,4'hc};
    }
    example_covpoint: coverpoint addr {
      bins address['h4] = {['h0008_0000:'h0008_000F]};
    }
    my_cross: cross example_covpoint , my_data {
      ignore_bins ro_regs = (binsof(example_covpoint) intersect ro_reg_addr && binsof(my_data) intersect {'hb,'hc}) //-> Doesn't work
      //ignore_bins ro_regs = (binsof(example_covpoint) intersect {ro_reg_addr} && binsof(my_data) intersect {'hb,'hc}) -> Doesn't Work
      //ignore_bins ro_regs = (binsof(example_covpoint) intersect {ro_reg_addr[0],ro_reg_addr[1]} && binsof(my_data) intersect {'hb,'hc}) -> Works fine
      //ignore_bins ro_regs = (binsof(example_covpoint) intersect {'h0008_0008,'h0008_000C} && binsof(my_data) intersect {'hb,'hc}) -> Works fine
endgroup

this might be because each bin of example_coverpoint is a range of 4 values ?
why are you clubbing 4 addresses in 1 bin?

In reply to sohan_b:

Hi Sohan,
Please check my last comment. That is working fine. I just want to know why can’t I use an array instead of explicitly mentioning individual addresses. The example I shared above is giving compilation errors.

why are you clubbing 4 addresses in 1 bin?

These addresses are for registers (32 bits) in a byte addressed memory. So, 0008_0000 - 0008_003 belongs to single register.

Can anybody help me out?

In reply to kavish.ahmad1:

The intersect clause allows limited expressions. You want the with clause

ignore_bins ro_regs = (binsof(example_covpoint) with (example_coverpoint inside {ro_reg_addr} && binsof(my_data) intersect {'hb,'hc}) //-> Doesn't work

See 19.6.1.2 Cross bin with covergroup expressions in the 1800-2017 LRM

I am having a similar situation wherein I need to ignore the array of bins in cross coverage. I tried with the “with” clause but it is not working. It is resulting in a compilation error stating An expression with an unpacked array datatype is not allowed in this context [SystemVerilog]. Any suggestions here?

bit[31:0] ro_reg_addr[2] = {'h0008_0000,'h0008_000C};
covergroup my_covergroup;
    my_data: coverpoint data {
      bins data[] = {4'ha,4'hb,4'hc};
    }
    example_covpoint: coverpoint addr {
      bins address['h4] = {['h0008_0000:'h0008_000F]};
    }
    my_cross: cross example_covpoint , my_data {
     ignore_bins ro_regs = (binsof(example_covpoint) with (example_coverpoint inside {ro_reg_addr} && binsof(my_data) intersect {'hb,'hc});

endgroup

You have a couple of typos in the code shown. This work for me.

    my_cross: cross example_covpoint , my_data {
      ignore_bins ro_regs = (binsof(example_covpoint) with (example_covpoint inside {ro_reg_addr}) && binsof(my_data) intersect {'hb,'hc});
    }

Thank you Dave for your reply.
But the solution is not working for me.

I am creating an array of covergroup classes and my code snippet is as shown below:

// covergroup class
class wrapper_cg;
   
    covergroup cg_test(int DS, string name_cg, int ignore_bitpos_f0[3]) with function sample(int bit_pos, bit fi_val);
        option.per_instance = 1;
        option.name = name_cg;

        BIT_POS : coverpoint bit_pos {
            bins pos[] = {[0:(DS-1)]} ;
        }

        FORCED_VALUE : coverpoint fi_val {
            bins f0 = {0};
            bins f1 = {1};
        }

        BIT_POS_X_FORCED_VALUE : cross BIT_POS, FORCED_VALUE {
           
            ignore_bins ign_bins = (binsof(BIT_POS) with (BIT_POS inside {ignore_bitpos_f0}) && binsof(FORCED_VALUE) intersect {0});

        }

    endgroup: cg_test

    function new(int ds, string n, int ign_bitpos_f0[3]);
        this.cg_test = new(ds, n, ign_bitpos_f0);
    endfunction
endclass

// test
class test extends base_test;
......
wrapper_cg cg_wrapper [];
.......
endclass

//new
function test::new (string name, uvm_component parent);
// create an array of cover group wrapper class
    cg_wrapper = new[50];
    foreach (cg_wrapper[i]) begin
        cg_wrapper[i] = new(data_length_q[i], path_q[i], '{1, 2, 3});
    end
endfunction: new

task test::run_phase(uvm_phase phase);
.....
cg_wrapper[path_id].cg_test.sample(bit_pos, curr_val);
.....
endtask

The code does not result in any compilation or elaboration errors, but the ignore_bins is not effective.

It would help to provide a minimal, complete, reproducible example like below. This correctly removes three bins <pos[1]/f0>,<pos[2]/f0>, and <pos[3]/f0> from the cross:

class wrapper_cg;
    covergroup cg_test(int DS, string name_cg, int ignore_bitpos_f0[3]) with function sample(int bit_pos, bit fi_val);
        option.per_instance = 1;
        option.name = name_cg;
        BIT_POS : coverpoint bit_pos {
            bins pos[] = {[0:(DS-1)]} ;
        }
        FORCED_VALUE : coverpoint fi_val {
            bins f0 = {0};
            bins f1 = {1};
        }
        BIT_POS_X_FORCED_VALUE : cross BIT_POS, FORCED_VALUE {
            ignore_bins ign_bins = (binsof(BIT_POS) with (BIT_POS inside {ignore_bitpos_f0}) && binsof(FORCED_VALUE) intersect {0});
        }
    endgroup: cg_test
    function new(int ds, string n, int ign_bitpos_f0[3]);
        this.cg_test = new(ds, n, ign_bitpos_f0);
    endfunction
endclass

// test
module top;
  wrapper_cg cg_wrapper [];
  initial begin
    // create an array of cover group wrapper class
    cg_wrapper = new[50];
    foreach (cg_wrapper[i]) begin
      cg_wrapper[i] = new(5, $sformatf("cg_%0d",i), '{1, 2, 3});
    end
  end
endmodule

Thank you for your reply.
I did follow the above approach to ignore the cross coverage bins but it is not working as expected. Instead of 3 bins, only one bin (pos[1]/f0) is ignored.

May I know which simulator you are using?

I work for Siemens, therefore, I use Questa.