Code
sequence clk_seq(sig,real val);
realtime t1,t2;
@(posedge sig) (1,t1=$realtime) ##1 @(negedge sig) (1,t2=$realtime,val = t2 - t1);
endsequence
function automatic void calculate (real val1,val2,val3,jitter,percent,min_cycle);
bit result1,result2;
$display( "%f,%f,%f",val1,val2,val3);
result1 = ($abs(val2 - val1) > jitter) ? 1 : 0;
result2 = ($abs(val2 - val3) > jitter) ? 1 : 0;
if(result1&result2) begin
if((val2>val1) || (val2>val3)) begin
$display("[CLOCK INFO] [%m] @%0t, clock div switch happend, m0_cycle:%f,ml_cyclel:%f,m2_cyclel:%f",$time,val1,val2,val3);
end
else begin
if((val2 < val1*percent) || (val2 < val3*percent)) begin
$display("ERROR [CLOCK INFO] [%m] @%0t, error clock div switch happend, m0_cycle:%f,ml_cyclel:%f,m2_cyclel:%f",$time,val1,val2,val3);
end
end
end
else if (result1^result2) begin
$display("[CLOCK INFO] [%m] @%0t, clock div switch happend, m0_cycle:%f,ml_cyclel:%f,m2_cyclel:%f",$time,val1,val2,val3);
end
if (val2 < 0.9*min_cycle/2.0) begin
$display("ERROR [CLOCK INFO] [%m] @%0t, clock delta glitch happend, current:%f, min:%f",$time,val2,min_cycle/2);
end
endfunction
property p_clk_half_cycle(en,sig,jitter,percent,min_cycle);
real val1,val2,val3;
disable iff (!en) @(posedge sig) clk_seq(sig,val1) ##1 clk_seq(sig,val2) ##1 clk_seq(sig,val3) ##0 (1,calculate(val1,val2,val3,jitter,percent,min_cycle));
endproperty
a_mon_clk: assert property(p_clk_half_cycle(.en(1),.sig(sys_clk),.jitter(0.002),.percent(0.5),.min_cycle(1)));
The property p_clk_half_cycle
always sampled the contiguous three half-high clocks and do calculate
. You can modify the function calculate
to meet your own project.
en
: enable assertion
sig
:asserted clock signal
jitter
:the tolerance for clock jitter
percent
:When clock switch happened, filter the unexpected high frequency clock cycle.
min_cycle
: the tolerance for clock glitch
Example Wave
sys_clk
switch from50Mhz
to100Mhz
.
- When glitch happend ,report error.