The following is an example given in SV LRM Section 16.6 ::
bit [2:0] count;
realtime t;
initial count = 0;
always @(posedge clk) begin
if (count == 0) t = $realtime; //capture t in a procedural context
count++;
end
property p1;
@(posedge clk) count == 7 |-> $realtime – t < 50.5;
endproperty
The LRM says :: " The comparison between values of time captured in the different contexts yields an inconsistent result"
However I am not sure what the issue is . Why won’t the above logic work ?
In reply to hisingh:
The point of 1800:16.6 Boolean expressions is that “Assertions that perform checks based on time values should capture these values in the same context. It is not recommended to capture time outside of the assertion. Time should be captured within the assertion using local variables”. The main issue is that assertions use sampling values in the Preponed Region, whereas values within the always @(posedge clk) are in the Active region and may not be the same as the sampled values.
I modeled this example as shown in Edit code - EDA Playground
and I did not see any assertion errors. However, I still stand by what the point made in 16.6.
A general guideline for SystemVerilog is to always stick to strict coding rules so that the simulation emulates concurrency per the modeling of the evaluation regions:
For assertions, use sampled values for signals. Any timing measurements should be related to sampled values of signals.
Clocked signals should be updated using the nonblocking <= operator
Never mix blocking and nonblocking assignments to signals (except for initialization.
One critique on the bad modeling style addressed is that the assertion
@(posedge clk) count == 7 |-> $realtime – t < 50.5;
evaluates in ONE cycle, though it checks 2 events that occur at different times. Those events are count==0 and count==7. That p1 assertion lacks that depth of definition because the “t” was defined somewhere else.
However, p2 clearly clarifies the requirements:
(count == 0, l_t = $realtime) ##1 (count == 7)[->1] |-> $realtime – l_t < 50.5;