System verilog : stable bus signal assertion

Hi Dave/Ben,
I have below system verilog property in my simulation,

  property p_must_static (i);
    ($stable(i));
  endproperty

  ASRT_1 : assert property(@(posedge clk) disable iff (reset) p_must_static(bus_signal[11:0]));

For some reason, I see as soon as clk starts for the first cycle assertion fails. I checked on the waveforms and reset signal is 0 , and as soon as the clk starts, assertion shows failure. Can anyone tell the reason?

Thank you and Regards.

In reply to megamind:

$stable(i) checks that the previous cycle of i == the current cycle of i.
At start, the previous version of i is defined as its initialization value.
What you need is


 property p_must_static (i);
   ##1 ($stable(i));
  endproperty

Ben SystemVerilog.us

In reply to ben@SystemVerilog.us:

Thank you very much Ben.
I was thinking variable “i” in the property definition should have been replaced by the signal I am passing.

After your your answer I thought I understood and hence I tried below exercise, which actually confused me more,

module asertion_ex;
  bit clk,rst;
  bit [3:0] a;
   
  //clock generation
  always #5 clk = ~clk;
   
  //generating 'a'
  initial begin
    rst = 1;
    #10 a = 1;
    #15 a = 0;
    #25 rst = 0;
    #75 $finish;
  end
   
  ASRT_2:  assert property(@(posedge clk) disable iff (rst) p_must_static(a));

  property p_must_static (i);
    //##1 $stable(i);  //attempt_1
    $stable(i);        //attempt_2
  endproperty

endmodule

As in above example, both attempt 1 and 2 worked well and no issues or assertion reported in the log, which seems okay. However in my verification environment I see a problem! Do you have a clue on this mystery? or it depends on the signals type? like logic/reg/bit etc?

Also when I tried your solution in my verification environment it worked! but not sure if that worked perfect and not falsely passing assertions(based on the above exercise confusion).

I have another case as below, in my verification environment, actually it works well, but wanted to confirm from the GOD of assertions, does it look okay or need any modification too?

  property p_value (i, v);
    if (v) ($countones(i) > 0) else ($countones(i) == 0);
  endproperty

  ASRT_2 : assert property(@(posedge clk) disable iff (reset) p_value(single_bit_signal,0));

Here I am checking, single_bit_signal should hold 0 or 1 value, based on the value I pass in argument.

Please clarify my confusions. Thank you.

In reply to megamind:
Code looks complex and a bit misleading. Usually, $countones(v) is used when v is a vector greater than one bit. Of course, a one-bit vector is still a vector, but the goal of an assertion is to make things clearer. What you have makes my mind spin around trying to figure it out; a lot of mental gyrations. Why not write


property p_value (i, v);
    if (v) (i==1'b1) else (i == 0); 
endproperty
// or even more simply 
property p_value (i, v);
    i==v; 
endproperty
// That looks more like a property of a D flip-flop. 
// We typically DO NOT WRITE Assertions FOR FLIP-FLOPS 
  ASRT_2 : assert property(@(posedge clk) disable iff (reset) p_value(single_bit_signal,0));

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


  1. SVA Alternative for Complex Assertions
    Verification Horizons - March 2018 Issue | Verification Academy
  2. SVA: Package for dynamic and range delays and repeats | Verification Academy
  3. SVA in a UVM Class-based Environment
    SVA in a UVM Class-based Environment | Verification Horizons | Verification Academy

In reply to ben@SystemVerilog.us:

Thank you Ben, I believe I was trying more than a bit vector earlier, so same assertion carried on further for single bit too, sorry to spin your top.

Can you please refer my earlier comment as I believe, while I was editing it, you have already responded the half portion of it. Can you please clarify all questions by referring my second comment.

In reply to megamind:
I don’t like the style you use to write the testbench/
See (1) - EDA Playground
Specifically,

  1. DON’T USE BLOCKING ASSIGNMENTS, use nonblocking assignments
    e.g., #10 a = 1; // NO
    #10 a <= 1;
  2. I am not fond of directed tests unless absolutely necessary, such as to demonstrate a particular case.
  3. Instead, use constrained-random tests e.g.,

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

The edaplayground link is my updated model per your testbench.
I’ll let you analyze that model, and reask your question. Try to be specific in your issues.


// import uvm_pkg::*; `include "uvm_macros.svh" 
module asertion_ex;
  bit clk,rst;
  bit [3:0] a;
 
  //clock generation
  //always #5 clk = ~clk;
  initial forever #5 clk=!clk; 
  default clocking @(posedge clk); endclocking  // <<<<<

  //generating 'a'
  initial begin   // Use nonblocking assignments 
    rst <= 1;
    #10 a <= 1;
    #15 a <= 0;
    #25 rst <= 0;
    #75 $finish;
  end
 
  /*initial begin 
    bit va, vb;
    repeat(200) begin 
        repeat(1) @(posedge clk);   
        if (!randomize(a, b)  with 
        { a dist {1'b1:=1, 1'b0:=1};
          b dist {1'b1:=1, 1'b0:=2};  
    }) `uvm_error("MYERR", "This is a randomize error");
    end 
    $stop; 
end  */

  
 
  ASRT_2:  assert property(@(posedge clk) disable iff (rst) p_must_static(a))
       $display("%t ASR_2 pass", $realtime); else  $display("%t ASR_2 fail", $realtime);
  ASRT_2OK:  assert property(@(posedge clk) disable iff (rst)  ##1 $stable(a))
    $display("%t ASR_2OK pass", $realtime); else  $display("%t ASR_2OK fail", $realtime);
 
  property p_must_static (i);
    //##1 $stable(i);  //attempt_1
    $stable(i);        //attempt_2 BAD USAGE 
  endproperty
 
endmodule
    

Ben SystemVerilog