【CPLD Verilog】CPLD实现时钟检测

  • 格式:pdf
  • 大小:124.11 KB
  • 文档页数:6

CPLD实现时钟检测
1 实现原理
时钟检测包括有无检测和频率检测,在一般场景下,检测时间有无就能满足需求了。

下面介绍时钟有无的检测,检测原理如下图所示,被检时钟分频,一般需要分到主时钟两倍以下,检测跳变检测8个时钟周期以上。

2 CPLD代码
module clk_dec (
clk, //全局主时钟24MHz
reset, //全局复位信号
clk_dec, //被检测时钟,50MHz
clk_dec_result, //时钟检测结果
/////////////////////for debug////////////////////////////////////////
clk_dec_div, //分频时钟
clk_dec_pulse, //同步时钟脉冲
counter_dec //时钟脉冲检测计数
);
input clk;
input reset;
input clk_dec;
output clk_dec_result;
////////////////////////debug ///////////////////////////////////////
output clk_dec_pulse;
output counter_dec;
output clk_dec_div;
//////////////////////////be dectect clock div 被检时钟16分频////////////////////////////
reg[3:0] counter_div;
reg clk_dec_div;
always@(posedge clk_dec or negedge reset) //被检测时钟分频
begin
if(reset == 1'b0)
begin
counter_div <= 4'h0;
clk_dec_div <= 1'b0;
end
else if(&counter_div[2:0] == 1'b1) //计数一半时,时钟反转,占空比50% begin
counter_div <= counter_div+1;
clk_dec_div <= ~clk_dec_div;
end
else if(&counter_div[3:0] == 1'b1) //时钟16分频
begin
counter_div <= counter_div+1;
clk_dec_div <= ~clk_dec_div;
end
else
begin
counter_div <= counter_div+1;
end
end
/////////////////////////clock sync 时钟同步/////////////////////////////////////
reg [1:0] clk_dec_dly;
wire clk_dec_pulse;
always@(posedge clk or negedge reset)
begin
if(reset == 1'b0)
begin
clk_dec_dly <= 2'b00;
end
else
begin
clk_dec_dly <= { clk_dec_dly[0],clk_dec_div };
end
end
assign clk_dec_pulse = (clk_dec_dly==2'b01) ? 1'b1 : 1'b0; //上升沿跳变输出高电平脉冲,一
//个主时钟周期宽度
//////////////////////clock dec 时钟检测////////////////////////////////////////
reg[3:0] counter_dec;
always@(posedge clk or negedge reset)
begin
if(reset == 1'b0)
begin
counter_dec <= 4'h0; //默认计数为0,时钟正常
end
else if(clk_dec_pulse == 1'b1) //有被检时钟脉冲时,计数清0
begin
counter_dec <= 4'h0;
end
else if(counter_dec == 4'hf) //计数值满,保持,直到被检时钟有跳变begin
;
end
else
begin
counter_dec <= counter_dec+1'b1; //主时钟跳变,时钟检测计数增加
end
end
//////////////////////clock dec result out 时钟检测结果输出//////////////////////////////////////// reg clk_dec_result;
always@(posedge clk or negedge reset)
begin
if(reset == 1'b0)
begin
clk_dec_result <= 1'b1; //默认时钟正常,高电平有效
end
else if(counter_dec == 4'hf) //如果被检时钟异常,常高或常低,计数值满,输出异常。

begin
clk_dec_result <= 1'b0;
end
else
begin
clk_dec_result <= 1'b1;
end
end
endmodule
3 仿真结果
被检时钟正常:时钟检测输出结果正常。

被检时钟常高:时钟检测输出结果异常。

被检时钟常低:时钟检测输出结果异常。