Hi, I am writing an assertion in SystemVerilog, and I am encountering an interesting problem. I am using the assertion to verify that some counters are only incrementing when the enable bit is set. Here is my code:
generate
begin genvar i;
// Assertion - counters should only be incremented when enabled
for (i=0; i<NUM_CNTRS; i++) begin
property incr_cntrs_enabled_check;
@ (posedge clk)
disable iff(reset) (!(counter[i] != 12'b0 && i_enable_cntrs == 1'b0));
endproperty
a_incr_cntrs_enabled_check: assert property (incr_cntrs_enabled_check) else $error($time, "Counters incremented when disabled. Cnt: %h", counter[i]);
end
end
endgenerate
When I run it, my assertion keeps resulting in an error because the counters are "not equal to 0", because they are equal to 'X'! Is there an easy way I can just delay the start of my assertion a certain number of clock cycles until the counters are initialized, or is there a better solution in my case?
Why don’t you reset the counter and avoid 'X all along! If that is not possible, you can make use of $assertoff/$asserton untill counter resets/settles down to a known value.
Here advantage is, even if different counter takes different times to get known value, you can disable/enable each assertion separately accordingly.
Also, in Ben’s code the counter increment logic should look like this,
// Assertion - counters should only be incremented when enabled
property incr_cntrs_enabled_check2;
@(posedge clk) disable iff(reset)
ready && (i_enable_cntrs == 1'b1) |=> counter[i] == ($past(counter[i]) + 1'b1);
endproperty
Thanks for the replies. I played around with this for a bit and the solution that ended up working was using $isunknown (which I did not know about at the time).
In reply to MayurKubavat:
Thanks for correcting my code. Shows you why assertions should be reviewed.
We’re human… and we make mistakes. In tis case, I meant to use the $past/
Ben
Thanks for the replies. I played around with this for a bit and the solution that ended up working was using $isunknown (which I did not know about at the time).
Your assertion does NOT meet your requirements [i]“counters are only incrementing when the enable bit is set”*. What you have says " There should never be the case When not enable and counter[i] is not 0, or counter[i] is unknown". not(x && y) is same as !x or y, thus, you can say that what you wrote is same as
at every clock, !(counter[i] !=0) || ! enbale==0 || is unkown(counter).
I guess hat this means that at every clock, counter==0 || ebable ==1 || usunknown.
That does NOT meet your original requirements, sorry.