FPGA边缘检测(上升沿、下降沿、双边沿)的三种实现方案

边缘检测在数字电路设计中非常常见,通常包含上升沿检测(posedge)下降沿检测(negedge)、以及双边沿检测(double edge)

边缘检测虽然实现非常简单,但有一些值得注意的地方,在设计中一不留神可能就会出现边沿漏检的情况。下面结合代码、电路图以及仿真时序,来扒一扒里面的坑。

第一种

先来看一种,这是最常见的一种边沿检测设计方案,但其中存在很大的隐患,非常容易漏检:

module edge_detect1(
input	clk,
input	signal,
output	pe,		//上升沿
output	ne,		//下降沿
output	de		//双边沿
);

reg reg1;

always@(posedge clk) begin
	reg1	<= signal;
end

assign pe	= (~reg1) & signal;
assign ne	= reg1 & (~signal);
assign de	= pe | ne; // 或 reg1 ^ signal

endmodule

对应的电路结构如下

在这里插入图片描述

该结构的边沿检测模块,仅使用到1个寄存器,其边沿输出通过信号 signal 与前一时刻的 signal 做逻辑运算得到,正因此,其一旦signal信号发生变动,其边沿信号也会随之改变,其优点是边沿信号响应迅速,而缺点是边沿信号高电平时间小于一个 clk 周期,因此容易出现漏检。其时序仿真如下

在这里插入图片描述

第二种

既然第一种边沿检测模块的问题出在边沿信号随 signal 信号实时改变,因此我们很容易想到解决的方法:在信号输出端口添加寄存器,从而使边沿信号高电平维持一个时钟周期。

module edge_detect2(
input		clk,
input		signal,
output	reg	pe,		//上升沿
output	reg	ne,		//下降沿
output	reg	de		//双边沿
);

reg reg1;

always@(posedge clk) begin
	reg1	<= signal;
	
	pe		<= (~reg1) & signal;
	ne		<= reg1 & (~signal);
	de		<= reg1 ^ signal;
end

endmodule

在这里插入图片描述

通过在输出端口添加寄存器,可以有效削弱输出信号对输入信号的依赖,从而提高系统的稳定性,时序仿真如下

在这里插入图片描述

可以看到,其边沿信号响应会略有迟滞,迟滞时间小于一个时钟周期,而边沿信号高电平时间将维持一个时钟周期。

第三种

第二种边沿检测方案尽管解决了边沿信号高电平时间过短的问题,但需要消耗4个寄存器,我们能不能减少寄存器,而达到同样的效果呢?我们第二种方案维持信号的方式是直接寄存输出信号的值,但实际上我们也可以通过寄存 signal 信号达到信号保持的目的。

module edge_detect3(
input	clk,
input	signal,
output	pe,		//上升沿
output	ne,		//下降沿
output	de		//双边沿
);

reg reg1,reg_2;

always@(posedge clk) begin
	reg1	<= signal;
	reg2	<= reg1;
end

assign pe	= reg1 & (~reg2);
assign ne	= (~reg1) & reg2;
assign de	= reg1 ^ reg2;

endmodule

该方案中,对 signal 进行连续两次寄存,两寄存器 reg1、reg2 相串联,而边沿信号通过 reg1 和 reg2 逻辑运算得到。

在这里插入图片描述

在这里插入图片描述

此种方案下,其逻辑功能与第二种方案完全一致,但只需要两个寄存器,在资源受限的情况下可以采用该方案,从而达到节省逻辑资源的目的。

根据引用\[2\]中的Verilog代码,可以实现多位寄存器检测上升下降沿的功能。在该代码中,使用了两级寄存器来检测下降沿。每个寄存器都会在时钟上升沿时更新,并将前一级寄存器的值存储在当前级寄存器中。通过对两级寄存器的值进行逻辑运算,可以得到下降沿指示信号。具体的代码如下: ```verilog module detect_multi ( input sys_clk, // 时钟(设定为 50MHz) input sys_rst_n, // 复位信号(n 表示低电平有效) input \[N-1:0\] in, // 需要进行上升下降沿检测的输入信号(N为位宽) output \[N-1:0\] in_pos, // 输出的上升沿指示信号 output \[N-1:0\] in_neg // 输出的下降沿指示信号 ); reg \[N-1:0\] in_d1; // 一级寄存器 reg \[N-1:0\] in_d2; // 二级寄存器 assign in_neg = ~in_d1 & in_d2; // 组合逻辑得到下降沿 assign in_pos = in & ~in_d1; // 组合逻辑得到上升沿 always @(posedge sys_clk or negedge sys_rst_n) begin if (!sys_rst_n) begin in_d1 <= {N{1'b0}}; // 复位清零 in_d2 <= {N{1'b0}}; end else begin in_d1 <= in; // 寄存一拍 in_d2 <= in_d1; // 寄存二拍 end end endmodule ``` 在这个代码中,`N`表示输入信号的位宽。通过使用多级寄存器,我们可以同时检测多位输入信号的上升和下降沿。 #### 引用[.reference_title] - *1* *2* *3* [FPGA实现边沿检测电路(上升沿下降沿)](https://blog.csdn.net/wuzhikaidetb/article/details/112187021)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

今朝无言

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值