(($rose(A) & B & $changed(C))|($rose(D) & E & $changed(F))) & (~($rose(G)) | ~($fell(H))) |=> (##[1:4]$rose(I) or ##[1:4]$rose(J)
) else $fatal (1,“Blah Reads to AXIM port should occur within 1 to 4 cycles”);
I see that the $rose and other expressions are getting calculated correctly, but $changed (tried ~$stable also) isn’t working great.
Hard to help you without knowing what the difference between working and not working is. We need to see a timing diagram or complete code example. (MCVE)
In reply to dave_59:
This is a lengthy and complex assertion. A few design review types of comments:
For logical conditions, use logical operators instead of bitwise operators
This is because the meaning/intent is different. Here you mean “logical” AND, OR, NOT. When a reader sees the bitwise operators, he initially visualizes the bitwise operations, then has to go through a mental contortion to realize that Verilog is loose on this, and for single bits the bitwise and logical are the same. My point, it does not read well.
1800’2012 30.4.4.1 Conditional expression
& bitwise AND
| bitwise OR
&& logical AND
|| logical OR
! logical NOT
When using $changed or $stable in an antecedent, consider prefacing the antecedent with a ##1. This is needed to cover the very first cycle. Thus,
##1 $changed(a) |-> b;
Write multiple simpler assertions
Tried to make sense of your property
sva_top_assert_temp_axim_latency_p1a: assert property (
( ##1 // For the 1st cycle, can ignore if condition never happens in the very 1st cycle
($rose(A) && B && $changed(C))||
($rose(D) && E && $changed(F))
) &&
(!($rose(G)) || !($fell(H)))
|=> (##[1:4]$rose(I) or ##[1:4]$rose(J)
) else $fatal (1,"Blah Reads to AXIM port should occur within 1 to 4 cycles");
I suggest you write the requirements in English and break these requirements into smaller assertions.