Usage of variable in ##delay for SVA

Hi,

I want to use a variable for giving delay in my assertion.
Below is my code :

`define CHECK_ASSERT_TIMEOUT(i)\
  property ASSERT_TIMEOUT_``i;\
    int delay;\
    @(posedge ipg_clk) disable iff (reset == 1'b0)\
    (($rose(actv_state[i][2])), delay=tmOut_reg[i]) |-> first_match(`true ##[1:delay] ($rose(actv_state[i][4])));\
  endproperty\
  CHECK_ASSERT_TIMEOUT_``i : assert property (ASSERT_TIMEOUT_``i) begin\
    `uvm_info("CHECK_ASSERT_TIMEOUT","\n Comparison is done timely.",UVM_LOW);\
  end\
  else begin `uvm_error("CHECK_ASSERT_TIMEOUT","\n Timeout occured before the comparison was done.");\
  end

Here my intent is to check -
When actv_state[i][2] is asserted, within the ‘delay’ number of clk cycles actv_state[i][4] should get asserted.

Here Below Error is coming :

Illegal operand for constant expression [4(IEEE)].

Can anyone please help me with it !!!

In reply to birenkumar:
FIrst, I strongly suggest that you see my paper Understanding the SVA Engine

The use of SVA for this specific problem gets complicated because:

  1. You need to use the local variable for counting
  2. ##[1:dealy] is illegal if delay is dynamic; it must be statis
  3. You wanted the range.

Here is a much simpler solution, also tested at

Note that the work is done in an automatic task being called from the assertion.


// When a is asserted, within the 'delay' 
// number of clk cycles b should get asserted.
import uvm_pkg::*; `include "uvm_macros.svh" 
module top; 
	bit clk, a, b, reset;  
    int d=3;
	default clocking @(posedge clk); endclocking
	initial forever #10 clk=!clk;  
  task automatic t_ab(); 
    repeat(d) begin : r_delay
      @(posedge clk);
      if($rose(b)) begin : pass 
         `uvm_info("CHECK_ASSERT_TIMEOUT","\n Comparison is done timely.",UVM_LOW);
        return;
      end: pass
    end : r_delay
    // fail 
     `uvm_error("CHECK_ASSERT_TIMEOUT","\n Timeout occured before the comparison was done.");
    return; 
  endtask : t_ab
  
  ap_ab: assert property($rose(a) |-> (1, t_ab()));  
 initial begin 
     repeat(200) begin 
       @(posedge clk);   
       if (!randomize(a, b)  with 
           { a dist {1'b1:=1, 1'b0:=4};
             b dist {1'b1:=1, 1'b0:=2};

           }) `uvm_error("MYERR", "This is a randomize error")
       end 
       $stop; 
    end 
endmodule  
 

If you insist on using SVA, below is an extract from my SVA Handbook 4th Edition


//11.4.2 Range delay (e.g., ##[2:v] b
/*The first element of the range must be a constant, and cannot be a variable. The second element is a variable. Below is an equivalent assertion for : // /11.4/m5067_gen_options.sv */
ap_range_fix: assert property($rose(a) |-> ##[N:v] b);
property p_range_equivalent; // Equivalent implementation
 int local_v; // this is an internal local variable defined by the tool
 $rose(a) |-> (1, local_v = v-N)
  ##N 1'b1 ##0 first_match((1, local_v=local_v - 1)[*0:$] ##1 (b || local_v<=0))
  ##0 b;
endproperty
ap_range_equivalent: assert property(p_range_equivalent);
//generate option
generate for (genvar g_i=0; (g_i<8); g_i++) begin
  if (g_i >= N)
  ap_range_gen: assert property (v==g_i && $rose(a) |-> ##[N:g_i] b);
end endgenerate

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


In reply to ben@SystemVerilog.us:

Thank you Ben for the information.