In reply to ben@SystemVerilog.us:
Hi Ben,
I went through the paper that you mentioned above. Thanks for the detailed explanation on what happens underneath the hood for multiple threads.
I do want to specifically bring up the last 2 examples that you specified in this paper :
(1) first_match operator :
first_match(rose(a) ##[1:] b) |-> ##3 c;
(2) Goto operator
$rose(a) ##1 b[->1]) |-> ##3 c; // Use the goto operator
I want to explore the use of the above for this simple case : “Write an assertion for a transaction where a request is followed by an ack in 1-3 cycles”. Now if I use the same style solution as above :
$rose(req)|->##[1:3]ack
If my requests on each posedge are in the order you specified :
Posedge# Req Ack Comment
Posedge0 0 0
Posedge1 1 0 Request#1
Posedge2 1 0 Request#2
Posedge3 1 1 Request#3 and Ack for Req #1. But this ack will satisfy #Request2 too !!!.. How do you filter this out ? Using the first_match operator ?
Posedge4 0 1 Ack for Req #2
Posedge5 1 1 Ack for Req #3
Posedge6 1 1 Ack for Req #4
Posedge7 0 1 Ack for Req #5
My concern again is that the above assertion will fire for the 1st posedge and 5th posedge only and won’t fire for the other requests.
Now, if I were to rewrite this assertion as follows : Level sensitive ( not really ideal because of performance issues)
req |-> ##[1:3]ack
Here, I would fire a thread each time request was high, but then if you look at posedge #3, how do I avoid NOT counting the ack for request#1 towards request #2 ? Do I use the first_match operator here ? Should I rewrite it like this :
first_match(req |-> ##[1:3]ack)
Can you please clarify ? Sorry if this has already been addressed in other threads in this forum. I did search to see if I could find a similar discussion, but I could not find it.