I have written assertion to wait in same state st = a when cnt is less than 5.
but I have used always block to increment the cnt.
—Is there any other way to write this?
—Is there a way to write incrementing cnt inside property?
always @(posedge clk) begin
if (rst)
cnt = 0;
else begin
if(st == a)
cnt = cnt +1;
else
end
property cnt_p;
@(posedge clk) disable iff (rst)
(st == a)&&(cnt < 5) |-> (st == a);
endproperty
cnt_assert : assert(cnt_p);
There is probably a better way to write your assertion, but the way you have written it, (st == a) has to be true just once, and the count is irrelevant.
Let’s say if I write it in a way such that
(st==a)&& (cnt=0) |->(st == a)&&(cnt < 5);
Si that antecedent is true just once… But still count cannot be irrelevant right??
Only local variables are allowed to be modified inside property, so you need to call some method from property to increment the counter. you can try something like this -
module top();
bit clk;
int count;
always #1 clk = !clk;
initial begin
repeat(10) @(posedge clk);
$finish;
end
property cnt_p();
//@(posedge clk) (1) |-> (1,count=count+1);
@(posedge clk) (1) |-> (1,t_inc_counter());
endproperty
count_ap: assert property(cnt_p());
task automatic t_inc_counter();
count++;
endtask
endmodule
In reply to dave_59:
requirements are ambiguous. However,
// "I have written assertion to wait in same state st = A when cnt is less than 5."
// Reading into your requirements:
// When state goes into 'A', it shall stay in that state for a total of 5 cycle.
// (i.e., for 4 more cycles)
// BTW, use upper case for states enumerations, it's a convention
property cnt_p;
@(posedge clk) disable iff (rst)
$rose(st == A) |-> ##1 st==A [*4] ##1 st !=A; // updated
endproperty
cnt_assert : assert(cnt_p);
The requirement is that FSM should wait in (st == A) till 5 clk cycles. If it by force or by mistake moves to next state it assertion should be triggered as error
In reply to Timus:
You mean, when the FSM enters in state A then it should stay (not wait)
in that state (st == A) for a total of 5 clk cycles. Afterwards the fsm goes to a different state.
My previous assertion does that.
// When state goes into 'A', it shall stay in that state for a total of 5 cycle.
// (i.e., for 4 more cycles)
//
property cnt_p;
@(posedge clk) disable iff (rst)
$rose(st == A) |-> ##1 st==A [*4] ##1 st !=A; // updated
endproperty
cnt_assert : assert(cnt_p);
In reply to Timus:
Following conditions are met in this assertion,
When rst is deasserted (when FSM comes out of reset) and st == a, then it should remain in this state for minimum 5 cycles.
You can remove $fell(rst), if for anytime st == a then it should be in this state for minimum 5 cycles.
// should not remove the $fell, but instead use the or
$fell(rst) && (st == a) or $rose(st==a) |=> $stable(st)[*4] ##1 $changed(st);
// to account for the change in the 6th cycle