system-verilogsystem-verilog-assertions

Why the assertion happens but its pass count is zero in the coverage result?


Consider the below code. The assert property is hit and passed according to the output but its pass count is zero in the coverage result. Why?

module tb;
    reg Krdy;
    reg Drdy;
    reg EN;
    reg CLK;
    reg RSTn;

    property check_dout;
        @(posedge CLK) disable iff (~RSTn)
        (
            (
                (
                    (EN & Krdy)
                    ##1
                    (
                        ((EN & Krdy) == 0)
                        throughout
                        (
                            ((EN & Krdy) == 0)
                            ##[0:$]
                            (EN & Drdy & ~Krdy)
                        )
                    )
                )
                ##1
                (EN [-> 1])
            ), $display("antecedent happened at time=%t", $time)
        )
        |=> (1==1, $display("consequent happended at time=%t", $time));
    endproperty

    assert property (check_dout)
    else $error("Error at time=%t", $time);

    always #5 CLK = ~CLK;

    initial begin
        CLK = 0;
        RSTn = 1;
        EN = 1;
        @(posedge CLK);
        Krdy = 1;
        Drdy = 0;
        @(posedge CLK);
        Krdy = 0;
        Drdy = 1;
        @(posedge CLK);
        Drdy = 0;
        repeat (3) @(posedge CLK);
        $stop;
    end

endmodule

I use the following commands in Questasim:

vlog +cover MCVE.sv

vsim -c -assertcover tb -do "run -all;coverage report -detail -assert"

And get the following output:

# run -all
# antecedent happened at time=                  35
# consequent happended at time=                  45
# ** Note: $stop    : MCVE.sv(50)
#    Time: 55 ns  Iteration: 1  Instance: /tb
# Break in Module tb at MCVE.sv line 50
# Stopped at MCVE.sv line 50
# coverage report -detail -assert
# 
# ASSERTION RESULTS:
# --------------------------------------------------------------------------------------------------------------------------------
# Name                 File(Line)                   Failure      Pass     Vacuous    Disable    Attempt     Active Peak Active ATV
#                                                   Count        Count    Count      Count      Count       Count  Count          
# --------------------------------------------------------------------------------------------------------------------------------
# /tb/assert__check_dout
#                      MCVE.sv(32)                        0          0          4          0          5          1           - off

After inverting the consequence of the property, i.e., 1!=1 and running the above commands, I get:

# run -all
# antecedent happened at time=                  35
# ** Error: Error at time=                  45
#    Time: 45 ns Started: 15 ns  Scope: tb File: MCVE.sv Line: 33
# ** Note: $stop    : MCVE.sv(50)
#    Time: 55 ns  Iteration: 1  Instance: /tb
# Break in Module tb at MCVE.sv line 50
# Stopped at MCVE.sv line 50
# coverage report -detail -assert
# 
# ASSERTION RESULTS:
# --------------------------------------------------------------------------------------------------------------------------------
# Name                 File(Line)                   Failure      Pass     Vacuous    Disable    Attempt     Active Peak Active ATV
#                                                   Count        Count    Count      Count      Count       Count  Count          
# --------------------------------------------------------------------------------------------------------------------------------
# /tb/assert__check_dout
#                      MCVE.sv(32)                        1          0          4          0          5          0           - off

Solution

  • The pass count is not incremented because not all the threads of an attempt have succeeded. The use of ##[0:$] causes multiple threads to be created many of which never succeed till the end of the simulation. Thus, the attempt is considered to be active (not passed) till the end of the simulation although one of its threads have passed. That is why there is an active count in the results. More information can be found here:

    https://verificationacademy.com/forums/systemverilog/assertion-attempt-getting-incomplete