I’m trying to check B is assert between 2 pulses of A, where both A and B should only be high for 1 cycle, A can be close together or far apart, second pulse of A must be assert. I tried to write the assertion be either it’s way too complicate or it’s keep missing some situation.
Using multiple implications in one property almost never works the way you wanted to. I would also separate the assertion that both A and B have to be high for one cycle.
I think the within operator might be more appropriate in this context. Here’s an example that I haven’t tried, so consider this a hint.
assert property (@(posedge clk) disable iff (!rst_n)
// Start on each rising edge of A
$rose(A)
|->
// B must rise after this A and before the next A
(##[1:$] $rose(B))
within
( (! $rose(A))[->1] ##1 $rose(A) )
);
property one_cycle(sig);
@(posedge clk) $rose(sig) |=> !sig;
endproperty
assert property(one_cycle(A));
assert property(one_cycle(B));
You need to clarify the situation for the second pulse of A. with this assertion, it will start a new assertion thread. Is that OK or do you need to keep them separated?
But will it check for the second A, I thought it need to use strong statement to make sure second A is asserted before end of the sim. I want to catch that if something like below happen, second A never assert before sim end, it will result error.
A __||__________
B _______||_____
So the assertion that you wrote is checking ABAABA… ?
And if I want to check ABABAB… that B must be assert after A before end of the sim, should I use $rose(A) |-> s_eventually((##[1:$] $rose(B)) && ! $rose(A)) with the two one_cycle?
It would be very helpful to create a test case that tests the scenarios you’re concerned about. This makes it easier for everyone to test their suggestions.