Hi All,
LRM 2017 Section 16.14.6.1 mentions ::
// Assume for this example that (posedge clk) will not occur at time 0
always @(posedge clk) begin
int i = 10; // My Comment :: Incorrect , should be explicitly declared as static OR automatic here
for (i=0; i<10; i++) begin
a1: assert property (foo[i] && bar[i]); // My Comment :: Infers leading clock as @(posedge clk)
end
end
In any given clock cycle, each of these assertions will result in 10 queued executions.
Every execution of assertion a1, however, will be checking the value of (foo[10] && bar[10]) ,
since the sampled value of i will always be 10, its final value from the previous execution of the procedure
I have a few questions related to it
[Q1] I am not clear on the last line ::
Every execution of assertion a1, however, will be checking the value of (foo[10] && bar[10]),since the sampled value of i will always be 10
Why doesn’t it result in :: (foo[0] && bar[0]) , (foo[1] && bar[1]) , … (foo[9] && bar[9]) ?
My intuition is that the unlooping of for-loop would occur in Active region
whereas the concurrent assertion gets evaluated in Observed region.
Would the value of ‘i’ be 10 in Observed region ?
[Q2] Assume that variables ‘foo’ , ‘bar’ are declared as
logic [9:0] foo , bar ; // 10-bit wide
Essentially foo[10] , bar[10] are invalid indexes.
So won’t (foo[10] && bar[10]) result in ( 1’bX && 1’bX ) i.e 1’bX i.e False ?
[Q3] What if the assumption is not true i.e posedge of clk occurs at time 0 ? What difference would it make ?
[Q4] I want to add a fail action block to ‘a1’ that displays the index ( i.e ‘i’ ) for which the failure occurs. What would the correct way be ?
always @(posedge clk) begin
for ( int i=0; i<10; i++) begin // 'i' is now automatic
// Will the following approach work ?
a1: assert property (foo[i] && bar[i]) else $display("Failure for foo[%0d] is %1b, bar[%0d] is %1b",$sampled(i),foo[$sampled(i)],$sampled(i),bar[$sampled(i)]);
end
end