基于FPGA的边沿检测

一、定义

边沿检测,即信号上升沿或者下降沿的检测。在检测到所需要的边沿后产生一个高电平的脉冲。
使用高频的时钟对信号进行采样,时钟频率至少要在信号最高频率的2倍以上。

二、原理

data_i tri_1 pos_edge neg_edge
1 0 1 0
0 0 0 0
0 1 0 1
1 1 0 0
由真值表可得:
pos_edge = (~tri_1) & data_i
neg_edge = (~data_i) & tri_1;
double_edge = data_i ^ tri_1;

在这里插入图片描述
rx_t是对rx打一拍存储的触发器,当某时刻rx低,rx_t高的时候,说明是下降沿。
电路图:感觉这图画错了
基于FPGA的边沿检测_第1张图片
应该是我画的这样:
基于FPGA的边沿检测_第2张图片

三、单触发器的verilog实现

//one trigger
module edge_detect(
input clk_i, rst_n_i, data_i, //输入端口
output posedge_o,negedge_o		//输出端口
);

//one regester
reg tri_1;

always@(posedge clk_i or negedge rst_n_i)
begin
    if (! rst_n_i)			//置位
    begin
        tri_1 <= 1'b0;
    end
    else
    begin
        tri_1 <= data_i;	//触发器
    end
end

assign negedge_o = tri_1 & (~data_i); 		//下降沿检测
assign posedge_o = (~tri_1) & data_i;     	//上升沿检测
endmodule

testbench:

module tb_test();

reg clk_i,rst_n_i,data_i;
wire posedge_o, negedge_o;

//模块调用
edge_detect u1(
.clk_i(clk_i),
.rst_n_i(rst_n_i),
.data_i(data_i),
.posedge_o(posedge_o),
.negedge_o(negedge_o)
);

//initial
initial begin
clk_i = 0;
rst_n_i = 0;
#10
rst_n_i = 1;
data_i = 0;
#13
data_i = 1; 	//上升沿
#20
data_i = 0;		//下降沿
#15
data_i = 1;		//上升沿
#10
data_i = 0;		//下降沿
end
//clk 信号
always #5 clk_i = ~clk_i;
endmodule

结果分析:如果在一个时钟内输入信号发生变化,输出便会产生一个“尖峰”,跟随data_i,而不受时钟节拍约束。专业名词称为glitch。前一时刻通过D触发器已经统一到FPGA的时钟域,而当前时刻直接从外部输入,与FPGA整体逻辑电路不在同一时钟域。

23ps 25
data_i 1 1
tri_1 =15ns d_i=0 =25ns d_i=1
pos_edge 1 0

仿真:
基于FPGA的边沿检测_第3张图片

四、双触发器的verilog实现

reg tri_1;
reg tri_2;
always@(posedge clk_i or negedge rst_n_i)
begin
    if (! rst_n_i)			//置位
    begin
        tri_1 <= 1'b0;
        tri_2 <= 1'b0;
    end
    else
    begin
        tri_1 <= data_i; 
        tri_2 <= tri_1;  	//二级触发器
    end
end
assign negedge_o = tri_2 & (~tri_1);		//下降沿检测
assign posedge_o = (~tri_2) & tri_1;		//上升沿检测
assign double_edge_o = tri_1 ^ tri_2;		//双边沿检测

RTL电路:
基于FPGA的边沿检测_第4张图片
仿真:
基于FPGA的边沿检测_第5张图片
实质区别在于方案一是输入数据时钟域和tri_1所在的本地时钟域作用,而方案2tri_1将输入与时钟同步,保存了t0时刻的信号。利用CLK打两拍,实现了上一时刻信号和本时刻信号和FPGA整体逻辑电路统一到同一时钟域。
加几级触发器,消除抖动,使得信号更稳定,但是级数越多,延迟越高。
这里要加两级的触发器的另一个原因,因触发器跳转产生滞后信号只能在时钟的上升沿,而被检测信号tigger并不一定是在一级触发器跳转的时钟上升沿到来,这样一级触发器所产生的滞后信号与tigger相差就达不到一个CLK周期,所以产生的脉冲信号就小于一个CLK周期了,不利于后面电路对其的应用。
注意:
(1)增大CLK信号可以增强边沿检测的效率,但不能滤去跳变的杂波。
(2)减少CLK可以有效滤去跳变的杂波,但不能及时检测到边沿跳变。
(3)增加D触发器能更好的滤除杂波,寄存信号,但同时检测延时大。

组合逻辑还是时序逻辑?

其实就是差一拍的事。
基于FPGA的边沿检测_第6张图片
1用时序逻辑

always@(posedge sys_clk ornegedge sys_rst_n)
    if(sys_rst_n ==1'b0)
       podge <=1'b0;
    else   if((data)&&(~data_reg)) 
       podge <=1'b1;
    else  
       podge <=1'b0;

2用组合逻辑
如前文中的assign

边沿检测应用:

(1)将时钟边沿使能转换为边沿检测使能,使时钟同步化。
(2)捕获信号的突变(UART,SPI等信号使能突变)已遇到
(3)逻辑分析仪中信号的边沿检测。

参考资料:
https://blog.csdn.net/vivid117/article/details/90757350
https://blog.csdn.net/GOGOmusic/article/details/54667746

你可能感兴趣的:(FPGA示例与典型模块,fpga)