Need help to write an assertion

I need help to write an assertion that checks that every “req” is followed by “ack” between 1 to 10 clocks.
If there is 2nd “req” signal comes even before the “ack” (for 1st req )is enabled , then it should not be a pass.

(Picture submission link in post is not working, so I have to show waveform in as below… sorry for this)

| || || || || || || | CLK

| || |___ REQ

______________| | ACK

In given diagram, 2nd req will make assertion pass on ack 1 as well. How can we solve this, because, 2nd ack might not come due to a bug.

In reply to kapil_kumar:

$rose(req) |=>!req[*1:9] ##0 ack;

Would this work for you?
Ben systemverilog.us

Hi Ben,

Probably he means even if the another request assertion should not fail.
I think what he is trying to check is for first request check first acknowledge even though as many requests can come after that.
It is like he is checking for one to one mapping between request and acknowledgement. Seems to be interesting question, will be waiting for your input

Thanks,

In reply to ben@SystemVerilog.us:

Thank you Ben.
Probably I should explain my query further-

If first req is asserted and first ack comes within [1:10] of first req, then assertion passes.
But if 1 more req comes , even before first ack is asserted, then also assertion passes because of 2nd req and the first req is waste. This is what I don’t want.

You can say, I am checking one to one mapping type thing here. So, If 2 req comes, and only 1 ack comes (within [1:10] of first req), then second assertion should fail.

I hope I am able to explain my query now.

In reply to kk@007:
To solve this, you eed a tag that is reset by the controlling first req (see check_tag()).
All other secondary req’s will instantly fail. the tag is reset by the first req if it succeeds. If you need something more specific, you can use my task method as described in the verification Horizons (see link below).
http://SystemVerilog.us/fv/reqack_special.sv


import uvm_pkg::*; `include "uvm_macros.svh" 
module top; 
  timeunit 1ns;     timeprecision 100ps;    
	bit clk,req, ack, tag;  
	default clocking @(posedge clk); endclocking
    initial forever #10 clk=!clk;  
    function bit check_tag();
      if(tag) return 1'b0;
      else begin
          tag=1'b1; 
          return 1'b1;
      end
    endfunction

    function void reset_tag();
        tag =1'b0;
    endfunction
    property reqack;
        bit go;
        @(posedge clk) ($rose(req), go=check_tag()) |-> 
             go ##[1:10] (ack, reset_tag()); // locks all future req until success
    endproperty
    ap_reqack: assert property(reqack);  Tag no longer reset 
                // tag <=1'b0; else tag<= 1'b0; // works for one 2nd req

    ap_reqack_continue: assert property(reqack)  // ******
                 tag <=1'b0; else tag<= 1'b0; // works for another 2nd req
    
    initial begin 
      repeat(100) begin 
        @(posedge clk); #1;  
        if (!randomize(req, ack)  with 
        { req dist {1'b1:=1, 1'b0:=3};
          ack dist {1'b1:=1, 1'b0:=5};       
      }) `uvm_error("MYERR", "This is a randomize error")
    end 
      repeat(200) begin
          @(posedge clk); #1
          if (!randomize(req, ack)  with 
          { req dist {1'b1:=1, 1'b0:=3};
            ack dist {1'b1:=0, 1'b0:=1};       
        }) `uvm_error("MYERR", "This is a randomize error")
      end
    $stop; 
  end 
endmodule    

Ben Cohen
http://www.systemverilog.us/ ben@systemverilog.us
For training, consulting, services: contact http://cvcblr.com/home


See Paper: VF Horizons:PAPER: SVA Alternative for Complex Assertions - SystemVerilog - Verification Academy

In reply to sa5691:

Check my solution on this is

One small change from my book, I would add the first_match(), as shown below.


module fifo_aa;
  bit clk, push, pop;
  int ticket, now_serving;
  bit [7:0] in_data, out_data;
  initial forever #5 clk=!clk;
  function void inc_ticket();
    ticket = ticket + 1'b1;
  endfunction
  property p_data_unique;
    bit [7:0] push_data;
    int v_serving_ticket;
    @(posedge clk) (push, push_data=in_data[7:0], v_serving_ticket=ticket, inc_ticket())
    |-> first_match(##[1:10] pop && now_serving==v_serving_ticket)
                                         ##0 (out_data == push_data);
  endproperty
  
  ap_data_unique: assert property(p_data_unique)
                              now_serving =now_serving+1;
                         else now_serving =now_serving+1; 

Ben Cohen
http://www.systemverilog.us/ ben@systemverilog.us
For training, consulting, services: contact Home - My cvcblr


See Paper: VF Horizons:PAPER: SVA Alternative for Complex Assertions | Verification Academy

In reply to ben@SystemVerilog.us:

Thank you Ben for your help.