Multiple clocking events

Hi Forum,
I was trying a code to check whether multiple clocking events are valid for concurrent assertions


module  tb;
 bit  clk1 , a , b ; 
 event  evnt ;

 initial forever #5  clk1  =  !clk1 ;

 property  multi_clk;
   @( posedge clk1 or evnt )  a  ##1  b;  
 endproperty

 aprop:assert property( multi_clk )  $display("time:%0t Pass",$time);
                          else  $display("time:%0t Fails",$time);

 initial  begin
   #4 ; a = 1 ; 
   #6 ; b = 1 ; 
   #1 ; -> evnt ;
   #5 ; $finish();
 end
endmodule

I observe that assertion passes twice


T:11 Pass
T:15 Pass

On 1st attempt due to posedge of clk1 at time:5 as ‘a’ is true , ‘b’ would be evaluated at next clocking event. Since ‘evnt’ is triggered at time:11, ‘b’ be evaluated.
Hence assertion passes at time:11.

How is it that assertion passes at time:15 ? Isn’t the 2nd attempt (due to posedge of clock at time:15) incomplete ?

In reply to mohabhat:

(1) - EDA Playground code
EPWave Waveform Viewer wave
Your rationale is incorrect because you are missing the attempts
In the following code, I added debugging features so that you can see what is happening;


module  tb;
 bit  clk1 , a , b, ev, attempt; 
 event  evnt ;
 
 initial forever #5  clk1  =  !clk1 ;
 function automatic void f(); attempt=!attempt; endfunction 
 
 property  multi_clk;
   @( posedge clk1 or evnt )  (a, f())  ##1  b;  
 endproperty
 
 aprop:assert property( multi_clk )  $display("time:%0t Pass",$time);
                          else  $display("time:%0t Fails",$time);
 
 initial  begin
    $dumpfile("dump.vcd"); $dumpvars;
   #4 ; a = 1 ; 
   #6 ; b = 1 ; 
   #1 ; -> evnt ; ev=!ev; 
   #15 ; $finish();
 end
endmodule
// sim results: 
# time:11 Pass
# time:15 Pass
# time:25 Pass
// 1st attempt at t5 because of posedge clk1, sig attempt toggle, thread1_attempt_1 
// 2nd attempt at t11 because of event; sig attempt toggles, thread1_attempt2
// Also at 11, thread1_attempt_1 evaluates the "b==1", thread1_attempt_1 passes
//    ...thus, # time:11 Pass, thread1_attempt_1  completes 
// At 15, posedge clk1, thread1_attempt2 evaluates the "b==1", thread1_attempt2 passes  
//   .. # time:15 Pass for thread1_attempt2 
// at t15 another attempt thread1_attempt3 
// at t25, posedge clk1, thread1_attempt3 completes.  # time:25 Pass

You would benefit from m paper: Understanding the SVA Engine (link below)
Ben Cohen
Ben@systemverilog.us
Link to the list of papers and books that I wrote, many are now donated.

In reply to ben@SystemVerilog.us:

Thank you Sir.

// 1st attempt at t5 because of posedge clk1, sig attempt toggle, thread1_attempt_1
// 2nd attempt at t11 because of event; sig attempt toggles, thread1_attempt2
// Also at 11, thread1_attempt_1 evaluates the “b==1”, thread1_attempt_1 passes
// …thus, # time:11 Pass, thread1_attempt_1 completes
// At 15, posedge clk1, thread1_attempt2 evaluates the “b==1”, thread1_attempt2 passes
// … # time:15 Pass for thread1_attempt2
// at t15 another attempt thread1_attempt3