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
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.