Crossing only explicit coverage points

I want to cross multiple coverpoints and define explicit coverage bins which will still be autocrossed with the remaining bins. For example:

c1 : coverpoint reg1 {
  bins a = {0};
  bins b = {1};
  bins c = {2};
}

c2 : coverpoint reg2 {
  bins on = {1};
  bins off = {0};
}

c3 : coverpoint reg3 {
  bins top = {0};
  bins bottom = {1};
}

cross1 : cross c1, c2, c3 {
  bins off = binsof(c2.off) && (binsof(c3.top) || binsof(c3.bottom));         // this means all bins in cross with c2.off is lumped into "off"
                                                                                                     // I want a bin that will be autocrossed with c1 so I will have an "off" bin for c1.a, c1.b, and c1.c without having to explicitly define 3 cross bins for them
}

It would help to explicitly state the bins you want. Your off bin is really just binsof(c2.off). I’m assuming you want 3 separate bins

bin offa = binsof(c2.off) && binsof(c1.a)
bin offb = binsof(c2.off) && binsof(c1.b)
bin offc = binsof(c2.off) && binsof(c1.c)

My suggestion would be to change your coverpoint bin specification to get the cross bins you are looking for. That may mean adding additional coverpoints and crosses. For example:

covergroup cg;
  option.auto_bin_max=1;
  c1 : coverpoint reg1 {
    bins a = {0};
    bins b = {1};
    bins c = {2};
  }
  c2on : coverpoint reg2 {
    bins on = {1};
  }
  c2off: coverpoint reg2 {
    bins off = {0};
  }
  c3 : coverpoint reg3 {
    bins top = {0};
    bins bottom = {1};
  }
  cross1 : cross c1, c2off, reg3; // this gives you same three bins offa, offb, offc 
  cross2 : cross c1, c2on,  c3; // this gives you the remaining "on" crosses
endgroup

In reply to dave_59:

This will not help me if I’m crossing more than two of these types of variables. For example if I had 2 of these on/off coverpoints, I’ll need to make 4 crosses for on1 on2, off1 off2, on1 off2, off1 on2. The reason I need a way to specify this behavior in one cross is because I’m crossing too many variables that I can specify by hand.

In reply to atomiccow:

That is a new question with more requirements. When you have too many variables to specify by hand, that implies you should be using arrays. I would need to know more about what you need to cover in order to tell you how to cover it. You may need to rethink how you collect coverage before you get to the point of needed a cross. Perhaps even creating multiple covergroups using covegroup arguments instead of trying to fit everything inside of one covergroup.

In reply to dave_59:

I appreciate the help, maybe this example will explain want I need better.

Say I am crossing the following coverpoints: c_type, c1_state, c1_mode, c1_select, c2_state, c2_mode, c2_select. These cover the registers of the same name so each value of reg_type has its own value for the reg1 and reg2. However, when either reg1_state or reg2_state is off, I don’t care about the value in the respective mode and select registers. To cover this, I need to cross all coverpoints and define explicit bins for reg1_state.off and reg2_state.off. However, because each value of reg_type has its own reg1 and reg2, I need the explicit bins for reg1_state.off and reg2_state.off to remain crossed with reg_type. Defining explicit bins as below will not be able to do this.

c_type : coverpoint reg_type {
bins type_0 = {0};
bins type_1 = {1};
bins type_2 = {2};
}

c1_state : coverpoint reg1_state {
bins off = {0};
bins on = {1};
}

c1_mode : coverpoint reg1_mode {
bins mode_0 = {0};
bins mode_1 = {1};
bins mode_2 = {2};
bins mode_3 = {3};
}

c1_select : coverpoint reg1_select {
bins sel_0 = {0};
bins sel_1 = {1};
bins sel_2 = {2};
}

c2_state : coverpoint reg2_state {
bins off = {0};
bins on = {1};
}

c2_mode : coverpoint reg2_mode {
bins mode_0 = {0};
bins mode_1 = {1};
bins mode_2 = {2};
bins mode_3 = {3};
bins mode_4 = {4};
}

c2_select : coverpoint reg2_select {
bins sel_0 = {0};
bins sel_1 = {1};
bins sel_2 = {2};
bins sel_3 = {3};
}

typeXstate1Xmode1Xsel1Xstate2Xmode2Xsel2: cross c_type, c1_state, c1_mode, c1_select, c2_state, c2_mode, c2_select {
// autocross covers all points for c1_state.on and c2_state.on correctly
bins reg1_off = binsof(c1_state.off); // this lumps all points with c1_state.off to one point, it does not maintain cross with c_type
bins reg2_off = binsof(c2_state.off); // this lumps all points with c2_state.off to one point, it does not maintain cross with c_type
}

The above cross will create:
c1 on/c2 on c1 off/c2 off
3 x (4 x 3) x (5 x 4) + 2 coverpoints
I need:
c1 on/c2 on c1 on/c2 off c2 off/c2 on c1 off/c2 off
3 x (4 x 3) x (5 x 4) + 3 x (4 x 3) + 3 x (5 x 4) + 3 x 2 coverpoints

I can split c1_state and c2_state to separate coverpoints: c1_state_on, c1_state_off, c2_state_on, c2_state_off. However then I will need to make a separate cross for each combination: (c1_state_on, c2_state_on), (c1_state_on, c2_state_off), (c1_state_off, c2_state_on), (c1_state_off, c2_state_off). And for each additional register added in the cross that has on/off toggle, you’d need another ^2 crosses.

Is there a way to specify within the cross that an explicit bin will contain only values that are included in bins expression while maintaining autocross with all bins not included? IE:

typeXstate1Xmode1Xsel1Xstate2Xmode2Xsel2: cross c_type, c1_state, c1_mode, c1_select, c2_state, c2_mode, c2_select {
// autocross covers all points for c1_state.on and c2_state.on correctly
bins reg1_off = binsof(c1_state.off) || binsof(c1_mode) || binsof(c1_mode); // create set of bins reg1_off that lumps c1_state.off and all values of c1_mode and c1_select that is still crossed with c_type and c2 coverpoints
bins reg2_off = binsof(c2_state.off) || binsof(c2_mode) || binsof(c2_mode); // create set of bins reg2_off that lumps c2_state.off and all values of c2_mode and c2_select that is still crossed with c_type and c1 coverpoints
}

In reply to atomiccow:

I have a question on the similar lines…

Suppose if c1 coverpoints are automatically generated like this

bit [1:0] reg1

c1 : coverpoint reg1;

c2 : coverpoint reg2 {
bins on = {1};
bins off = {0};
}

c3 : coverpoint reg3 {
bins top = {0};
bins bottom = {1};
}

now, we don’t have the names for the bins. In this case can we use something like this ?

bin offa = binsof(c2.off) && binsof(c1.autobin[0]) ;
bin offa = binsof(c2.off) && binsof(c1.autobin[1]) ;
bin offa = binsof(c2.off) && binsof(c1.autobin[2]) ;

and then continue further ?

Thanks