Coverage bins sampling an uninitialized virtual interface object

I want to cover the middle bits of data_pos (refer to the third bins definition), but I’m getting an Error : uninitialized virtual interface object at runtime, specifically at time 0 and the simulation terminates immediately.

covergroup cg_my_fcov;
   cp_covdata : coverpoint(vif.blkB_top_vif[1].subB_vif[ID].data_pos) {
      bins data_pos_lo = { 1'bx, {542{1'bx}}, 1'b1 };
      bins data_pos_hi = { 1'b1, {542{1'bx}}, 1'bx };
      bins data_mid_0 = { 1'bx, vif.blkB_top_vif[1].subB_vif[ID].data_pos[50:1], {493{1'bx}} };
   }
endgroup : cg_my_fcov

What could be causing the issue ?

If I comment out the third bins the test proceeds just fine. Any suggestions on how to cover the middle bits like that ?

I have 2 remarks:
(1) what is the value of coverage for 'x values?
(2) Could you please show some more code, kike the declaration of your variables.

I’m not sure what you’re trying to achieve, but there are two issues with the code you provided.

Firstly, a bin is not a concatenation; it’s a list of values. It looks like you are trying to write a concatenation of 544 bits.

Secondly, when you create a covergroup, it uses the values of the bin expressions at the specific time point of construction. That means vif.blkB_top_vif[1].subB_vif[ID] needs to be a valid reference at that point in time.

You likely want to create three coverpoints with a single bin instead of one coverpoint with three bins.

covergroup cg_my_fcov;
   cp_covdata_lo : coverpoint vif.blkB_top_vif[1].subB_vif[ID].data_pos[0] {
      bins data_pos_lo = { 1'b1 };
}
   cp_covdata_hi : coverpoint vif.blkB_top_vif[1].subB_vif[ID].data_pos[543] {
      bins data_pos_hi = { 1'b1 };
}
   cp_covdata_mid : coverpoint vif.blkB_top_vif[1].subB_vif[ID].data_pos[542:493] != 0  {
      bins data_pos_mid = { 1'b1 };
}
endgroup : cg_my_fcov

Hi @dave_59 , you got what I wanted to cover. Basically, data_pos is a 544-bit data wherein I’m interested to know whether bits 0 and 544 were ever set to 1 at the time I sample the covergroup. These are the most important bits for me.

I also like to know whether the middle bits were also set to 1, albeit at a lesser importance than bits 0 and 544. However, [542:1] is too big a picture for me. So, I wanted to have a finer granularity in covering these middle bits. Do I have to manually divide it into several coverpoints or is there a more efficient way of doing it ?

Example :

   cp_covdata_mid_0 : coverpoint vif.blkB_top_vif[1].subB_vif[ID].data_pos[542:493] != 0 {
      bins data_pos_mid_0  = { 1'b1 };
   }
cp_covdata_mid_1 : coverpoint vif.blkB_top_vif[1].subB_vif[ID].data_pos[492:453] != 0 {
      bins data_pos_mid_1  = { 1'b1 };
   }
   // and so on until [52:1] ? or is there a better way so that the middle bits can be covered, say, 20 bits each ?

Coverage collection is driven by a design specification. It’s not clear what you mean by a lesser importance. It would be easier to divide the metal bits into ranges of values like below

   cp_covdata_mid : coverpoint vif.blkB_top_vif[1].subB_vif[ID].data_pos[542:493]  {
      bins data_pos_mid[20] = { [1:$] };
}

Indeed coverage should be driven by design specification, and this is exactly why hitting bits 0 and 543 are very important to ensure that the design works properly with those bits set to 1.

The middle bits with less importance does not mean they’re not important at all. Otherwise I would have just ignored them completely. Perhaps what I wanted to convey is : Since hitting all the middle bits might not be possible considering resource constraints like project schedule, machines, regression times, etc., then it should be ‘OK’ if at least we see only some of those middle bits covered.

Then, what I suggested should work.