Search code examples
system-verilogfunction-coverage

How to cover latency between request and response


Let's say we have a protocol where request req is asserted with req_id and corresponding rsp will be asserted with rsp_id. These can be out of order. I want to cover the number of clks or latency between req with particular req_id and rsp with the same id. I tried something like this. Is this correct way of doing? Is there any other efficient way?

covergroup cg with function sample(int a);
  coverpoint a {
  a1: bins short_latency = {[0:10]};
  a2: bins med_latency = {[11:100]};
  a3: bins long_latency = {[101:1000]};
  }
endgroup
// Somewhere in code
cg cg_inst = new();

sequence s;
  int lat;
  int id;
  @(posedge clk) disable iff (~rst)
    (req, id = req_id, lat = 0) |-> ##[1:$] ((1'b1, lat++) and (rsp && rsp_id == id, cg_inst.sample(lat)));
endsequence

Solution

  • You're trying to use the |-> operator inside a sequence, which is only allowed inside a property.

    If rsp can only come one cycle after req, then this code should work:

    property trans;
        int lat, id;
    
        (req, id = req_id, lat = 0) |=> (1, lat++) [*0:$] ##1 rsp && rsp_id == id
          ##0 (1, $display("lat = %0d", lat));
    endproperty
    

    The element after ##0 is there for debugging. You can omit it in production code.

    I wouldn't mix assertions and coverage like this, though, as I've seen that the implication operators can cause issues with variable flow (i.e. lat won't get updated properly). You should have a property that just covers that you've seen a matching response after a request:

    property cov_trans;
        int lat, id;
    
        (req, id = req_id, lat = 0) ##1 (1, lat++) [*0:$] ##1 rsp && rsp_id == id
          ##0 (1, $display("cov_lat = %0d", lat));
    endproperty
    
    cover property (cov_trans);
    

    Notice that I've used ##1 to separate the request from the response.