In reply to mchen76:
If I uderstand the design, you have a “keep_alive” (or refresh) signal and a timer count that gets reset at every occurrence of keep_alive.
You call the keep_alive signal “pet” Thus upon a $fell(pet) you expect pet==1 within that count period (teminal_count value)
The way I see it, your assertion has an accept_on($rose(pet, @(posedge clk), which is the refresh or keep_alive signal On an accept_on the assertion is vacuous
For a failure, you expect a keep_alive within that timeout cout, or
*keep_alive within (1, v=count) ##0 first_match((1, v=v-1’b1) [0:$] ##1 v<=0);
Thus, your main assertion looks like
// Checks that expire occurs before delay or that pet occurs sometime between that period
sequence q_dynamic_delay_or_keep_alive(count, keep_alive);
int v;
keep_alive within (1, v=count) ##0 first_match((1, v=v-1'b1) [*0:$] ##1 v<=0);
endsequence
// SEE EDIT in next post
ap_accept_OK: assert property (accept_on($rose(pet, @(posedge clk) )) @(posedge clk) $fell(pet) |->
// ****************** USE "pet" instead of "expire" ************
(q_dynamic_delay_or_keep_alive(terminal_count, expire))) else $error("WDT failure");
This is my testbench
import uvm_pkg::*; `include "uvm_macros.svh"
module top;
timeunit 1ns; timeprecision 100ps;
bit clk, a, b, pet, expire;
bit[3:0] terminal_count=3;
default clocking @(posedge clk);
endclocking
initial forever #10 clk=!clk;
sequence q_dynamic_delay(count);
int v;
(1, v=count) ##0 first_match((1, v=v-1'b1) [*0:$] ##1 v<=0);
endsequence
sequence q_dynamic_delay_or_keep_alive(count, keep_alive);
int v;
keep_alive within (1, v=count) ##0 first_match((1, v=v-1'b1) [*0:$] ##1 v<=0);
endsequence
// Checks that expire occurs without any expire occurring before delay or that pet occurs sometime between that period
// ************* DO NOT USE ************* xxxxxxxxxxxxxxxx
ap_pet_tc_BAD: assert property (@(posedge clk) $fell(pet) |-> // BAD ASSERTION
(1 [*0:$] ##0 pet) or
(!expire throughout q_dynamic_delay(terminal_count) ##1 expire)) else $error("WDT failure");
// *************** OK Assertion ******************
// Checks that expire occurs before delay or that pet occurs sometime between that period
ap_accept_OK: assert property (accept_on($rose(pet, @(posedge clk) )) @(posedge clk) $fell(pet) |->
// (1 [*0:$] ##0 pet) or
(q_dynamic_delay_or_keep_alive(terminal_count, expire))) else $error("WDT failure");
/*But I can't seem to get it to fail when the dynamic delay value is purposefully set lower
which leads me to think maybe one of the sequences are evaluating to true all the time.
I also wonder if vivado reacts properly to this sequence definition, I put something like
assert property (@(posedge clk) 1 |=> 0) else $error("Checking error works");
after the sequence definition and it wouldn't give any errors unless it was pasted before the sequence def. Very odd.*/
initial begin
bit vpet, vexpire;
repeat(200) begin
@(posedge clk);
if (!randomize(vpet, vexpire) with
{ vpet dist {1'b1:=1, 1'b0:=7};
vexpire dist {1'b1:=1, 1'b0:=5};
}) `uvm_error("MYERR", "This is a randomize error")
#2;
pet <= vpet;
expire <= vexpire;
end
$stop;
end
endmodule
Ben Cohen
http://www.systemverilog.us/ ben@systemverilog.us
For training, consulting, services: contact Home - My cvcblr
- SVA Alternative for Complex Assertions
https://verificationacademy.com/news/verification-horizons-march-2018-issue
- SVA: Package for dynamic and range delays and repeats - SystemVerilog - Verification Academy
- SVA in a UVM Class-based Environment
https://verificationacademy.com/verification-horizons/february-2013-volume-9-issue-1/SVA-in-a-UVM-Class-based-Environment