Cross of transition cover points

I have a question regarding cross of transition cover points.

A : coverpoint {signal_A}
{ bins 1_cyc_trans = (0=>1);
bins 2_cyc_trans = (0[*2]=>1);
bins 3_cyc_trans = (0[*3]=>1);
bins 4_cyc_trans = (0[*4]=>1);
bins 5_cyc_trans = (0[*5]=>1);}

B : coverpoint {signal_B}
{ bins 0_to_1_trans = {0=>1};}

A_X_B : cross A, B;

My intention is to cover transition of A (0->1)from 1 to 5 cycles after B transition from 0->1.
But my doubt is when does this cross is covered? At the end of the A transition 0->1 in that case when 5_cyc_trans cross with B is covered it will cover all other bins also right?
Is that true?

Is there a simpler way to write coverage to cover ±5 cycle sweep of any signal transition with other signal transition.
I can generate 5 signals by %past and write bins that way.

Also another question Is transition coverage consumes more cpu time?
From the below two coverage code which is efficient?
E.g A : coverpoint signal
{ bins o_to_1 = (0=>1); }

or
A : coverpoint {signal, signal_d1}
{ bins 0_to_1 = {2’b01}; }

You’re trying to cover temporal behavior and for this a cover property (similar to a concurrent assertion) would probably be best. The key here, as you ask, is knowing when to sample.

You could write such a property, but you’d probably need to pair it up with a cover group to be able to show that you covered all possibilities. The property would be triggered by a transition on B. At each evaluation you’d need some counter to figure out after how many clocks the transition on A occurred. I haven’t ever done this, so I’m not sure if this is the best way to go. Ben Cohen frequents this forum (and he wrote an SVA book) so maybe he’ll give us a definite answer.

What I could come up with is this:


module top;
  bit clk;
  bit sig_a, sig_b;

  always #1 clk = ~clk;

  initial begin
    // B transition
    @(posedge clk);
    sig_b <= 1;

    // A transition 2 cycles after B
    @(posedge clk);
    sig_b <= 0;

    @(posedge clk);
    sig_a <= 1;

    @(posedge clk);
    sig_a <= 0;

    @(posedge clk);
    $finish();
  end // initial begin


  // need this as a dummy variable
  int unsigned num_cycles;
  
  covergroup a_rose_after_b_cg;
    coverpoint num_cycles {
      bins valid[] = { [1:5] };
    }
  endgroup // a_rose_after_b

  a_rose_after_b_cg a_rose_after_b = new();

  
  // triggers at rise of B
  // expects a rise of A in 1-5 cycles after
  // counts how many cycles in between and samples the covergroup
  property a_after_b;
    int unsigned num_cycles;
    ($rose(sig_b), num_cycles = 1)
    ##1 (!$rose(sig_a), num_cycles++)[*0:$]
    ##1 ($rose(sig_a) && (num_cycles <= 5), cover_num_cycles(num_cycles));
  endproperty

  cover property(@(posedge clk) a_after_b);

  function void cover_num_cycles(int unsigned num_cyc);
    num_cycles = num_cyc;
    $display("num_cycles = %d", num_cycles);
    a_rose_after_b.sample();
  endfunction // cover_num_cycles

endmodule // top

The property doesn’t have to be a cover. It can just as well be an assert (with some small modifications) if it’s a hard requirement that A must transition 1-5 cycles after B.