I am trying to do something like this:
assert property (#(posedge clk) disable iff (!rst) a[*c] -> $rose(b))
Here c is not a 'constant' but a value coming from some bits of a register. eg: reg[4:0] which is written only once. The check is to see if b is asserted only when a is high for "c" number of cycles.
However, SVAs do not accept a variable like this : [*reg[4:0]]. Any ideas??
Introduce a local variable ctr. At every posedge a new assertion with a new instance of ctr will be created. Set ctr equal to the value in reg1. Check that a is true throughout the down count. Decrement the counter as long as it is larger than zero. The (ctr>0, ctr--)[*0:$] statement will count down until ctr == 0 is true.
You might want to change (ctr>0, ctr--)[*0:$] to (ctr>0, ctr--)[*1:$], depending on what results you expect if reg == 0.
property pr_aRegTimes;
integer ctr;
disable iff (!rst)
#(posedge clk)
(1, ctr = reg1) ##0 a throughout ((ctr>0, ctr--)[*0:$] ##1 (ctr == 0)) |-> $rose(b);
endproperty
as_aRegTimes: assert property (pr_aRegTimes)
else $error("aRegTimes failed");
Working example:
http://www.edaplayground.com/x/Xh9
Sources:
https://www.doulos.com/knowhow/sysverilog/tutorial/assertions/
http://www.win.tue.nl/~jschmalt/teaching/2IMF20/SvaFvTutorialHVC2013.pdf
property pr_aRegTimes;
integer ctr;
disable iff (!rst)
#(posedge clk)
($rose(a), ctr = reg1) ##0 (a&&ctr>0,ctr--)[*] |-> $rose(b);
endproperty
Related
Suppose I have an assertion as follows. Now here I want signal A to remain stable for some time after rising up. That is, A should be high until the first occurrence of D == 4 after that it can go low at any time it wants.
Also I dont want to use ##[0:$] in this assertion.
Any help/advice would be very much appreciated. Thank you.
property p_check(A,B,C,D,E);
#(posedge clk) disable iff(!resetn)
$rose(A) ##1 B ##0 (C == 3) ##0 (D != 2) |=> (D == 4)[->1] ##[0:2] (!E throughout A);
endproperty : p_check
You should write this as a separate property.
#(posedge clk) disable iff(!resetn)
$rose(A) |=> $stable(A) until (D==4);
For this code, I see both assertions fail. It seems that disable iff (value) is evaluated later than the expression itself. Can someone explain this.
module tb();
reg clk = 1;
always #5 clk = !clk;
reg rst = 1;
always # (posedge clk)
rst <= 0;
initial #11ns $finish();
assert property (# (posedge clk) disable iff (rst) 1 |-> 0);
assert property (# (posedge clk) rst |-> 0);
endmodule
Followup, how would one test this:
always_ff # (posedge clk or posedge rst) begin
if (rst) q <= 0;
else q <= d;
end
where rst is deasserted based on a delay:
always_ff # (posedge clk)
rst <= rst_a;
Seems like disable iff would no longer work. as it evaluates rst late.
The expression within disable iff (expr) is asynchronous and uses unsampled values. The property gets evaluated as part of the observed region, which comes after the NBA region.
For the first assertion, rst is already low by the time of the first attempt to evaluate the property at time 10 in the observed region. So the disable iff does not prevent an attempt to evaluate the property, which always fails.
For the second property, the sampled value of rst is still 1 at the time of the first attempt to evaluate the property, so it must fail too.
Followup,
I think you may be worrying about an impractical case. How likely will the antecedent be true after reset? And if it were true, then the assertion should be still be valid. For example, suppose you had a counter with an assertion to check that it rolls over when hitting the maximum value
assert property (# (posedge clk) disable iff (rst) (counter==maxval) |=> (counter ==0) );
If the reset value of the counter was the maximum value, you would not want the assertion disabled.
I am learning SVA and trying to get my head around this check: data can only change every 8 cycles.
I know I can do that check by adding a counter that counts clock cycles and checking against it that way:
bit[2:0] count;
always #(posedge clk)
begin
count++;
end
change_n8cycles: assert property (#(posedge clk) $changed(data) |-> count == 0);
However, I'm interested in a way to do that with only SVA. So far, I was thinking of something like that (which doesn't compile)
property change_n8cycles(valid, ready, data);
#(posedge clk)
$changed(data) |=> $stable(data)[*7] ##1 ($stable(data)[*8])[0:$] ##0 $changed(data);
endproperty : change_n8cycles
I feel there is an elegant way using an approach similar; or using recursive properties. However, I couldn't find it.
I would propose to use local variable in order to verify that
property change_n8cycles(valid, ready, data);
int lv_cnt;
#(posedge clk)
($changed(data), lv_cnt=0) ##1 ($stable(data), lv_cnt=lv_cnt+1)[*1:$] ##1 $changed(data) |-> lv_cnt == 8;
endproperty
Or use some modeling layer
always #(posedge clk) begin
if($changed(data))
count=0;
else
count++;
end
property change_n8cycles(data);
#(posedge clk)
$changed(data) |-> $past(count) == 8;
endproperty
I want to write a property in SVA to formally verify a behavior.
Here is what I want to:
property prop1(sig1,sig2,sig3,sig4);
#(posedge clk)
$fell(sig1) ##[1:$] first_match($fell(sig2)) ##0 sig3 |-> sig4 == sig3;
endproperty
How can I rewrite the above property so that after sig1 falls, it stays LOW during remaining Evaluation cycles?
Note: I do not want to put sig1 as disable iff (sig1)
property prop1(sig1,sig2,sig3,sig4);
#(posedge clk)
(!sig1) throughout (##[1:$] first_match($fell(sig2)) ##0 sig3)
|-> sig4 == sig3;
endproperty
See section 16.9.9 Conditions over sequences in the 1800-2012 LRM
I have this assertion in order to check clk freq:
assert property clk_freq;
int cnt;
#(posedge fast_clk, clk_1MHz) disable_iff(!enable_check)
($rose(clk_1MHz), cnt=0) |=> (!$rose(clk_1MHz),cnt++) [*0:$] ##1 $rose(clk_1MHz), cnt==fast_clk_freq;
endproperty
fast_clk starts to toggle during (not from beginning) of the simulation after disable_check is asserted.
The problem is that it seems that the assertion ignores the disable_iff
Question: is a $rose(clk_1Mhz) event "registered" even though the assertion is disabled (or am I missing something else ?)
There is no disable_iff keywords, it is disable iff (without the underscore). Properties can have local variables but the local variables cannot be defined inline with assert. Separate the property definition and the assertion instantiation.
The clock sampling doesn't seem to be correct. #(posedge fast_clk, clk_1MHz) mean on rising fast_clk or any change to clk_1MHz. clk_1MHz is the sampled data value, therefore it should not be a clock.
$rose(clk_1MHz), cnt==fast_clk_freq is ilegal syntax, sugest: $rose(clk_1MHz) ##0 cnt==fast_clk_freq
Suggested property definition and the assertion instantiation:
property p_clk_freq;
int cnt;
#(posedge fast_clk) disable iff(!enable_check)
($rose(clk_1MHz), cnt=0) |=> (!$rose(clk_1MHz),cnt++)[*0:$] ##1 $rose(clk_1MHz) ##0 cnt==fast_clk_freq;
endproperty
a_clk_freq : assert property(p_clk_freq);
For more on assertions refer to section 16 of IEEE Std 1800-2012.