Assertion Check

In reply to rkg_:


// You are using the following definition of what a sequence is: 
sequence_expr ::= 
| (sequence_expr {, sequence_match_item}) 
// NOTE: before the "," is a sequence, after the "," is a sequence_match_item
// and a sequence_match item is  
sequence_match_item ::=
  operator_assignment
   | inc_or_dec_expression
   | subroutine_call
// Your antecedent 
 ( $rose (o_fll_sar_eoc) , i_fll_unlock_prog == 2'b00, inc_count=0, dec_count=0) 
// <--sequence_expr-->   , <---------------- sequence_match_item -------------->
i_fll_unlock_prog == 2'b00 // is NOT  an operator_assignment or inc_or_dec_expression 
// It is a comparison (T or F), thus illegal. 
// You meant to say in the sequence_expr.  Thus,

 ( $rose (o_fll_sar_eoc) && i_fll_unlock_prog == 2'b00, inc_count=0, dec_count=0) 
// Also OK

 ( $rose (o_fll_sar_eoc) ##0 i_fll_unlock_prog == 2'b00, inc_count=0, dec_count=0)  

In reply to ben@SystemVerilog.us:

I am writing assertion to check the o_fll_lock deassertion.

Specification :- At posedge of o_fll_lock happen , four consecutive of o_fll_inc signal or fll_dec signal detected , o_fll_lock should be de-asserted.

property p_unlock_condition_check_unlock_prog_00; 
        int inc_count, dec_count;
 @(posedge sampled_monclk) disable iff (!i_en_fll)
   ( $rose (o_fll_lock) && i_fll_unlock_prog == 2'b00, inc_count=0, dec_count=0)   |=> 
            (##1 (1, inc_count+= (o_fll_inc==1),dec_count+= (fll_dec==1)))##0 
            !o_fll_lock==(inc_count==4 || dec_count==4);
    endproperty

Problem :- assertion is getting finished before the o_fll_lock de assertion.

Could someone help, what mistake i am doing and how can i print the value of inc_count in my log ?

In reply to rkg_:
You are missing the [*6], also using both |=> ##1, and missing the o_fll_lock de assertion if needed

 
property p_unlock_condition_check_unlock_prog_00; 
        int inc_count, dec_count;
 @(posedge sampled_monclk) disable iff (!i_en_fll)
   ( $rose (o_fll_lock) && i_fll_unlock_prog == 2'b00, inc_count=0, dec_count=0) |-> 
            ##1 (1, inc_count+= (o_fll_inc==1),dec_count+= (fll_dec==1))[*6] ##0 
            !o_fll_lock==(inc_count==4 || dec_count==4) 
     ##0 !o_fll_lock; // if needed 
endproperty
// note the " |-> ##1 (expr1)[*6] ##0..." 
// this is different from 
// " |-> (##1 (expr1))[*6] ##0.."
// 

Ben systemverilog.us

In reply to ben@SystemVerilog.us:

Hi Ben,

Thank you for reply .

what is the use of [*6} ?
for lock de-assertion it can happen at any number of sampled clk unlike lock condition . only thing is four consecutive fll_inc or fll_dec after the lock assertion .

May i know the difference between
// note the " |-> ##1 (expr1)[*6] ##0…"
// this is different from
// " |-> (##1 (expr1))[*6] ##0…" ??

In reply to rkg_:
Addressing your second question first
http://systemverilog.us/vf/rpt2.sv


// After the |-> ##1 the sequence (b} is repeated twice
ap2: assert property(a |-> ##1 (b)[*2]); 

// After the |-> the sequence (##1 b) is repeated twice
ap2_1: assert property(a |-> (##1 b)[*2]); 
  

what is the use of [*6} ?
for lock de-assertion it can happen at any number of sampled clk unlike lock condition . only thing is four consecutive fll_inc or fll_dec after the lock assertion .

The [*6} came from your original requirements … based on value of a, number of cycle (between 1 to 6 clock cycle of ref_clk)
Also, without a repeat operator how could the local variable inc_count, dec_count ever be ==4? SOmething is missing in your requirements. With poorly expressed requirements, I am doing my best to make assumptions, hoping that you’ll get the idea as to what best todo.
It might be a good idea to express again all the requirements in English.
As to you last comments for lock de-assertion it can happen at any number of sampled clk unlike lock condition . only thing is four consecutive fll_inc or fll_dec after the lock assertion . You could change the property to something like:


// Fix as needed per requirements 
property p_unlock_condition_check_unlock_prog_00; 
        int inc_count, dec_count;
 @(posedge sampled_monclk) disable iff (!i_en_fll)
   ( $rose (o_fll_lock) && i_fll_unlock_prog == 2'b00, inc_count=0, dec_count=0) |-> 
            ##1 (1, inc_count+= (o_fll_inc==1),dec_count+= (fll_dec==1))[*6] ##0 
            !o_fll_lock==(inc_count==4 || dec_count==4) 
     ##0 !o_fll_lock[->1]; // if needed 

Ben Cohen
http://www.systemverilog.us/ ben@systemverilog.us
For training, consulting, services: contact http://cvcblr.com/home.html
** SVA Handbook 4th Edition, 2016 ISBN 978-1518681448

  1. SVA Package: Dynamic and range delays and repeats SVA: Package for dynamic and range delays and repeats - SystemVerilog - Verification Academy
  2. Free books: Component Design by Example https://rb.gy/9tcbhl
    Real Chip Design and Verification Using Verilog and VHDL($3) https://rb.gy/cwy7nb
  3. Papers:

In reply to ben@SystemVerilog.us:

Hi Ben,

Thank you for reply. let me tell my requirement. I have basically two reequipment. one is for fll_lock assertion and second is for fll_lock deassertion.

1st requirement (fll_lock_assertion):- FLL LOCK is asserted on detecting two positive edges of FLL INC or FLL DEC only when (fll_sar_eoc == 1). and two positive edge of fll_inc or fll_dec ([b]consecutive is not necessary ) between 1 to 6 clock cycle of sampled_clk[/b]

property p_lock_condition_check_unlock_prog_00;

        int inc_count, dec_count;
 @(posedge sampled_monclk) disable iff (!i_en_fll)
  ( ( o_fll_sar_eoc == 1) && i_fll_unlock_prog == 2'b00, inc_count=0, dec_count=0)   |=> 
            (##1 (1, inc_count+= $rose(o_fll_inc),dec_count+= $rose(fll_dec)))[*1:6] ##0 
            o_fll_lock==(inc_count==2 || dec_count==2);
    endproperty

2nd requirement (fll_lock de assertion ) :- FLL lock is de-asserted on detecting of four consecutive of o_fll_inc signal or fll_dec signal. here the.
Note :- 1. for requirement two : positive edge is not needed but consecutive of fll_dec or
fll_inc is must. 1 to 6 clock cycle is [b]not required[/b].

property p_unlock_condition_check_unlock_prog_00; 
        int inc_count, dec_count;
 @(posedge sampled_monclk) disable iff (!i_en_fll)
   ( $rose (o_fll_lock) && i_fll_unlock_prog == 2'b00, inc_count=0, dec_count=0) |-> 
            ##1 (1, inc_count+= (o_fll_inc==1),dec_count+= (fll_dec==1))[*6] ##0 
            !o_fll_lock==(inc_count==4 || dec_count==4) 
     ##0 !o_fll_lock[->1]; // if needed

I have added the waveform for lock assertion and de- assertion :

In reply to rkg_:
See if the following works. Make sure you use the |-> ##1 (consequent)[*n] and NOT the
|-> (##1 consequent)[*n]


module m; 
    bit[1:0] o_fll_sar_eoc, i_fll_unlock_prog;
    bit o_fll_inc, o_fll_lock, sampled_monclk, i_en_fll, fll_dec; 
// 1st requirement (fll_lock_assertion):- FLL LOCK is asserted on detecting two positive edges 
// of FLL INC or FLL DEC only when (fll_sar_eoc == 1). 
// and two positive edge of fll_inc or fll_dec (**consecutive is not necessary ) 
//between 1 to 6 clock cycle of sampled_clk**

property p_lock_condition_check_unlock_prog_00; // Using |-> ##1 (consequent)
    int inc_count, dec_count;
    @(posedge sampled_monclk) disable iff (!i_en_fll)
      ( (o_fll_sar_eoc == 1) && i_fll_unlock_prog == 2'b00, inc_count=0, dec_count=0)   |-> 
            ##1 (1, inc_count+= $rose(o_fll_inc), dec_count+= $rose(fll_dec))[*1:6] ##0 
            o_fll_lock==(inc_count==2 || dec_count==2);
endproperty

property p_lock_condition_check_unlock_prog_00_v0; // OK too, using the |=> (consequent)
    int inc_count, dec_count;
    @(posedge sampled_monclk) disable iff (!i_en_fll)
      ( (o_fll_sar_eoc == 1) && i_fll_unlock_prog == 2'b00, inc_count=0, dec_count=0)   |=> 
            (1, inc_count+= $rose(o_fll_inc), dec_count+= $rose(fll_dec))[*1:6] ##0 
            o_fll_lock==(inc_count==2 || dec_count==2);
endproperty
//---------------------------------------
//2nd requirement (fll_lock de assertion ) :- FLL lock is de-asserted on detecting of four consecutive 
// of o_fll_inc signal or fll_dec signal. here the.
// Note :- 1. for requirement two : positive edge is not needed but consecutive of fll_dec or
// fll_inc is must. 1 to 6 clock cycle is **not required**.

property p_unlock_condition_check_unlock_prog_00_v1; // NOT per requirements
  int inc_count, dec_count;
  @(posedge sampled_monclk) disable iff (!i_en_fll)
  ($rose (o_fll_lock) && i_fll_unlock_prog == 2'b00, inc_count=0, dec_count=0) |-> 
            ##1 (1, inc_count+= (o_fll_inc==1),dec_count+= (fll_dec==1))[*6] ##0 
            // does not satisfy "consecutive of fll_dec or fll_inc is must"
            !o_fll_lock==(inc_count==4 || dec_count==4) 
     ##0 !o_fll_lock[->1]; // This !o_fll_lock occurs at any time later
endproperty 

// Upon a rose of 0_fll_lock and i_fll_unlock_prog == 2'b00 then 
// at anytime thereafter (the ##[1:$]) any 4 sequential occurrence of 
// o_fll_inc or 4 sequential occurrence of fll_dec the o_fll_lock==0 at that 4th occurrence
property p_unlock_condition_check_unlock_prog_00_v2; //One option
    // int inc_count, dec_count;
    @(posedge sampled_monclk) disable iff (!i_en_fll)
    ($rose (o_fll_lock) && i_fll_unlock_prog == 2'b00)  |-> 
       first_match(##[1:$] (o_fll_inc==1)[*4] or (fll_dec==1)[*4]) ##0  !o_fll_lock;
         // ##1 (1, inc_count+= (o_fll_inc==1),dec_count+= (fll_dec==1))[*6] ##0 
              // does not satisfy "consecutive of fll_dec or fll_inc is must"
              // !o_fll_lock==(inc_count==4 || dec_count==4) 
              // ##0 !o_fll_lock[->1]; // This !o_fll_lock occurs at any time later
endproperty 

// If the "at anytime" is constrained to "n" static cycles, 
let n=10; 
// Upon a rose of 0_fll_lock and i_fll_unlock_prog == 2'b00 then 
// at anytime thereafter (the ##[1:$]) any 4 sequential occurrence of 
// o_fll_inc or 4 sequential occurrence of fll_dec the o_fll_lock==0 at that 4th occurrence
property p_unlock_condition_check_unlock_prog_00; //One option
    // int inc_count, dec_count;
    @(posedge sampled_monclk) disable iff (!i_en_fll)
    ($rose (o_fll_lock) && i_fll_unlock_prog == 2'b00)  |-> 
       first_match(##[1:$] (o_fll_inc==1)[*4] or (fll_dec==1)[*4] intersect 1'b1[*n]) ##0  !o_fll_lock;
         // ##1 (1, inc_count+= (o_fll_inc==1),dec_count+= (fll_dec==1))[*6] ##0 
              // does not satisfy "consecutive of fll_dec or fll_inc is must"
              // !o_fll_lock==(inc_count==4 || dec_count==4) 
              // ##0 !o_fll_lock[->1]; // This !o_fll_lock occurs at any time later
  endproperty 
endmodule 

Ben Cohen
http://www.systemverilog.us/ ben@systemverilog.us
For training, consulting, services: contact http://cvcblr.com/home.html
** SVA Handbook 4th Edition, 2016 ISBN 978-1518681448

  1. SVA Package: Dynamic and range delays and repeats SVA: Package for dynamic and range delays and repeats | Verification Academy
  2. Free books: Component Design by Example FREE BOOK: Component Design by Example … A Step-by-Step Process Using VHDL with UART as Vehicle | Verification Academy
    Real Chip Design and Verification Using Verilog and VHDL($3) https://rb.gy/cwy7nb
  3. Papers:

In reply to ben@SystemVerilog.us:

An option for your 1st property using the Non-consecutive repetition, Boolean([=n]

property p_lock_condition_check_unlock_prog_00_Voption; // Using |-> ##1 (consequent)
    //int inc_count, dec_count;
    @(posedge sampled_monclk) disable iff (!i_en_fll)
      ( (o_fll_sar_eoc == 1) && i_fll_unlock_prog == 2'b00)   |-> 
            ##1 (($rose(o_fll_inc)[=2] or $rose(fll_dec)[=2]) intersect 1'b1[*1:6])
            ##0 o_fll_lock;
endproperty 

In reply to ben@SystemVerilog.us:

In reply to ben@SystemVerilog.us:
An option for your 1st property using the Non-consecutive repetition, Boolean([=n]

property p_lock_condition_check_unlock_prog_00_Voption; // Using |-> ##1 (consequent)
//int inc_count, dec_count;
@(posedge sampled_monclk) disable iff (!i_en_fll)
( (o_fll_sar_eoc == 1) && i_fll_unlock_prog == 2'b00)   |-> 
##1 (($rose(o_fll_inc)[=2] or $rose(fll_dec)[=2]) intersect 1'b1[*1:6])
##0 o_fll_lock;
endproperty 

Hi Ben

Thank you for all your suggestion. and “p_lock_condition_check_unlock_prog_00_Voption” is not working. But others are working well.

In reply to rkg_:
The following test model worked OK for me


ap_a2b2c: assert property(@ (posedge clk) 
       $rose(a) |-> ##1 ((b[=2] or c[=2]) intersect 1[*1:6]));  


http://systemverilog.us/vf/twoabc.sv

//code


module top;
    timeunit 1ns;  timeprecision 100ps;    
    `include "uvm_macros.svh"     import uvm_pkg::*;
    bit clk, a, b, c, reset_n;
    default clocking @(posedge clk);
    endclocking
    initial forever #10 clk = !clk;
    
    ap_a2b2c: assert property(@ (posedge clk) 
       $rose(a) |-> ##1 ((b[=2] or c[=2]) intersect 1[*1:6]));  

    initial begin
      repeat (200) begin
        @(posedge clk);
        if (!randomize(a, b, c) with {
          a dist {1'b1 := 1, 1'b0 := 3};
          b dist {1'b1 := 1, 1'b0 := 2};
          c dist {1'b1 := 1, 1'b0 := 2};
        })
          `uvm_error("MYERR", "This is a randomize error");
      end
      $finish;
    end
  endmodule
  

Ben Cohen
http://www.systemverilog.us/ ben@systemverilog.us
For training, consulting, services: contact http://cvcblr.com/home.html
** SVA Handbook 4th Edition, 2016 ISBN 978-1518681448

  1. SVA Package: Dynamic and range delays and repeats SVA: Package for dynamic and range delays and repeats - SystemVerilog - Verification Academy
  2. Free books: Component Design by Example https://rb.gy/9tcbhl
    Real Chip Design and Verification Using Verilog and VHDL($3) https://rb.gy/cwy7nb
  3. Papers:

In reply to ben@SystemVerilog.us:

Hi Ben,

property p_lock_condition_check_unlock_prog_00_v0; // OK too, using the |=> (consequent)
    int inc_count, dec_count;
    @(posedge sampled_monclk) disable iff (!i_en_fll)
      ( (o_fll_sar_eoc == 1) && i_fll_unlock_prog == 2'b00, inc_count=0, dec_count=0)   |=> 
            (1, inc_count+= $rose(o_fll_inc), dec_count+= $rose(fll_dec))[*1:6] ##0 
            o_fll_lock==(inc_count==2 || dec_count==2);
endproperty

This assertion is failing even after lock is asserted ( just after 6 posedge of sampled_monclk after lock assertion ). Do we need to put some extra logic so that one lock is asserted it should not check until the next packet will come ?

In reply to rkg_:
After every successful antecedent, a new thread is fired, and that thread is independent of any other previously fired thread. That can cause errors if you want to check the packets independently. Below is a simulatable example where I used the block.


/*property p_lock_condition_check_unlock_prog_00_v0; // OK too, using the |=> (consequent)
    int inc_count, dec_count;
    @(posedge sampled_monclk) disable iff (!i_en_fll)
      ( (o_fll_sar_eoc == 1) && i_fll_unlock_prog == 2'b00, inc_count=0, dec_count=0)   |=> 
            (1, inc_count+= $rose(o_fll_inc), dec_count+= $rose(fll_dec))[*1:6] ##0 
            o_fll_lock==(inc_count==2 || dec_count==2);
endproperty
This assertion is failing even after lock is asserted ( just after 6 posedge of sampled_monclk after lock assertion ). 
Do we need to put some extra logic so that one lock is asserted it should not check until the next packet will come ? */ 
module top;
    timeunit 1ns;  timeprecision 100ps;    
    `include "uvm_macros.svh"     import uvm_pkg::*;
    bit clk, a, b, c, reset_n, block; 
    initial forever #10 clk = !clk;
    
    function void set_block(bit x);
        block=x;        
    endfunction

    ap_a2b2c: assert property(@ (posedge clk) 
       $rose(a) |-> ##1 ((b[=2] or c[=2]) intersect 1[*1:6]));  

    ap_a2b2cBLOCK: assert property(@ (posedge clk) 
       ($rose(a) && block==0, set_block(1)) |-> ##1 ((b[=2] or c[=2]) intersect 1[*1:6])) 
         set_block(0); else set_block(0) ;  

    initial begin
      repeat (200) begin
        @(posedge clk);
        if (!randomize(a, b, c) with {
          a dist {1'b1 := 1, 1'b0 := 3};
          b dist {1'b1 := 1, 1'b0 := 4};
          c dist {1'b1 := 1, 1'b0 := 4};
        })
          `uvm_error("MYERR", "This is a randomize error");
      end
      $finish;
    end
  endmodule
  

In reply to ben@SystemVerilog.us:

In reply to rkg_:
Addressing your second question first
http://systemverilog.us/vf/rpt2.sv


// After the |-> ##1 the sequence (b} is repeated twice
ap2: assert property(a |-> ##1 (b)[*2]); 
// After the |-> the sequence (##1 b) is repeated twice
ap2_1: assert property(a |-> (##1 b)[*2]); 

Hi Ben, I don’t get the difference. When I see both and try to rewrite the repetition operator I get

##1 b ##1 b

for both style. What am I missing?

In reply to emin:
In this case, there is no difference because the sequence is one term. However, let the sequence to be repeated is longer than one term.


|-> ##1 (b ##2 c)[*2]); // same as 
##1 (b ##2 c) ##1 (b ##2 c)

|-> (##1 b ##2 c)[*2]); // same as 
(##1 b ##2 c) ##1 (##1 b ##2 c)  
// The difference : 
##1 (b ##2 c) ##1     (b ##2 c)  // |->  ##1 (b ##2 c)[*2]); 
(##1 b ##2 c) ##1 (##1 b ##2 c)  // |-> (##1  b ##2 c)[*2]); 
//                 ^^^

In reply to ben@SystemVerilog.us:

Ben,

a[=3] ##1 b; //3 non consecutive/consecutive a and then b anytime after last a
a[->3] ##1 b; //3 non consecutive/consecutive a and then b immediately after one clock cycle of a

If above understanding is correct , then can we use ##5 instead of ##1 in the first case?

In reply to ben@SystemVerilog.us:

In reply to emin:
In this case, there is no difference because the sequence is one term.

Great. Thank you for clarifying!
But we see different behaviour here,

In reply to ben@SystemVerilog.us:

In reply to rkg_:

How did ap2_1’s first thread did pass even though there we have b deasserted? I thought that must fail as well at the same time as ap2 since you said there is no difference.

In reply to emin:
OOPs! I spoke too fast, my apologies, the two ARE different.
Humans make mistakes :)


|-> ##1 (b)[*2]); 
##1 b ##1 b 

|-> (##1 b)[*2]
(##1 b) ##1 (##1 b)

In reply to ben@SystemVerilog.us:

That makes sense :) Thank you Ben! I appreciate.

In reply to emin:

Hi Ben,

Property :-
// 1st requirement (fll_lock_assertion):- FLL LOCK is asserted on detecting two positive edges
// of FLL INC or FLL DEC only when (fll_sar_eoc == 1). and fll_inc or fll_dec anytime after (sar_eoc==1) but once any thing (posedge of dec or inc) comes second comes between 1 to 8 (since prog_unlock is 1 here) then only lock should asserted.
// and two positive edge of fll_inc or fll_dec (consecutive is not necessary )
//between 1 to 6 clock cycle of sampled_clk

Type - 1

property p_lock_condition_check_unlock_prog_01; 
        int inc_count, dec_count;
 @(posedge sampled_monclk) disable iff (!i_en_fll)
   ( o_fll_sar_eoc == 1 && i_fll_unlock_prog == 2'b01, inc_count=0, dec_count=0 )   |=> 
             (1, inc_count+= $rose(o_fll_inc),dec_count+= $rose(fll_dec))[*1:8] ##0 
            o_fll_lock==(inc_count==2 || dec_count==2);
    endproperty

Problem 1 :-lock is asserted after 22 clk cycle of sample_monclk. and above assertion is not able to caught. (marked in purple)
Problem 2 :- assertion failing after de-assertion of lock. (marked in red )
problem 3:- Unexpected triggered (marked in blue colour)

waveform attached.

Type -2 :

property p_lock_condition_check_unlock_prog_01; 
         @(posedge sampled_monclk) disable iff (!i_en_fll)
      ( (o_fll_sar_eoc == 1) && i_fll_unlock_prog == 2'b01 )   |-> 
            ##1 (($rose(o_fll_inc)[=2] or $rose(fll_dec)[=2]) intersect 1'b1[*1:8])
            ##0 o_fll_lock;
    endproperty

Problem -1 :- Assertion triggered but it start checking fll_inc or fll_dec right after the sar_eoc assertion till the 1 to 8 clock cycle of sample clk (instead it should wait and check fll_inc or fll_dec anytime after (sar_eoc==1) but once any thing (two posedge of dec or inc whoever come early ) between 1 to 8 of sample_monclk (since prog_unlock is 1 here) then only lock should asserted.[/b])

Waveform :-

do you see any issue ?

In reply to rkg_:

  • Looking at the waveforms, I see the antecedent being true for many cycles.
    ( o_fll_sar_eoc == 1 && i_fll_unlock_prog == 2’b01, inc_count=0, dec_count=0 )
    That creates multiple successful attempts, and each attempt triggers its own consequent thread that is independent of other threads. That can provide unexpected failures.
    See my paper - Understanding the SVA Engine.
    Verification Horizons - July 2020 | Verification Academy
    Try ($rose(o_fll_sar_eoc == 1) && i_fll_unlock_prog == 2’b01[/b], inc_count=0, dec_count=0 )
  • It is very difficult for someone (me included) to debug an assertion without understanding the complete image. My best advice is to run your assertion in a small testbench environment with the simulation tool in a debug mode. In that mode, you can view the threads and the local variables and understand why the tool is telling of a pass or failure. The tool (if correct, most likely so) will do what SVA expresses, not what you wish. Thus you need to understand why SVA is behaving this way.
  • Assertion never got triggered Check your testbench. Test your assertions separately in a small testbench.

Ben Cohen
http://www.systemverilog.us/ ben@systemverilog.us
For training, consulting, services: contact http://cvcblr.com/home.html
** SVA Handbook 4th Edition, 2016 ISBN 978-1518681448

  1. SVA Package: Dynamic and range delays and repeats SVA: Package for dynamic and range delays and repeats | Verification Academy
  2. Free books: Component Design by Example FREE BOOK: Component Design by Example … A Step-by-Step Process Using VHDL with UART as Vehicle | Verification Academy
    Real Chip Design and Verification Using Verilog and VHDL($3) https://rb.gy/cwy7nb
  3. Papers: