FPGA功能模块---边沿检测edge_detector

1、 边沿检测介绍

1.1 目的

检测信号的跳变,即上升沿(0→1)或下降沿(1→0)。

1.2 应用

常用于检测1bit信号的电平跳变,例如光耦、按键、微动开关等器件在正常工作时会产生由0到1或者由1到0的跳变,检测到边沿的跳变后就能知道这些器件在什么时候被触发,方便进行其它的逻辑判断。

1.3 检测方法

设置两个寄存器A和B,分别寄存当前状态和后一状态,若当前状态和后一状态不同,则表示信号有跳变。具体判断逻辑如下:
(1)若A为High,而B为Low,则检测到上升沿;
(2)若A为Low,而B为High,则检测到下降沿;
(3)若A≠B,则检测到双边沿。
在这里插入图片描述

1.4 代码实现方式

上升沿 posedge = (A) & (~B)
下降沿 negedge = (~ A) & (B)
双边沿 bothedge= (A) ^ (B)

2、 Verilog代码

2.1 功能描述

(1)用于检测信号上升沿或者下降沿的模块。
(2)可以输出时钟同步后的信号,以及该信号的上升沿、下降沿、双边沿。
(3)边沿信号都是即时反馈的。
(4)模块输出的边沿信号与检测信号是同步的,没有延时。

2.2 输入输出信号

该模块的输出信号不仅包括了传统的上升沿信号和下降沿信号,还一并输出了同步后的检测信号以及双边沿信号,基本可以应对各种各样的应用场景。

module edge_detector
(
input		clk			,//系统时钟
input		rst_n		,//复位信号,低电平有效
input		signal		,//待检测信号

output wire	sig_sync	,//时钟同步后的检测信号
output wire	sig_posedge	,//sig_sync信号的上升沿标志
output wire	sig_negedge	,//sig_sync信号的下降沿标志
output wire	sig_bothedge //sig_sync信号的上升沿和下降沿标志
);

2.2 处理输入信号的亚稳态问题

(1)因为检测信号signal与系统时钟信号clk可能会不同步,所以在边沿检测的过程中需要处理亚稳态问题,即对输入信号多寄存一次。
(2)由于signal信号的上电初始值未知,将3个输入信号寄存器signal_temp赋值为1’bx可以避免生成多余的上升沿或者下降沿(详见时序图)。

reg signal_temp1 ;//待检测信号寄存1拍
reg signal_temp2 ;//待检测信号寄存2拍
reg signal_temp3 ;//待检测信号寄存3拍
always @(posedge clk or negedge rst_n) begin
	if(rst_n == 1'b0) begin
		signal_temp1 <= 1'bx ;//(1)signal信号的初始值未知,此处赋值1'bx可以避免生成多余的上升沿或者下降沿
		signal_temp2 <= 1'bx ;//(2)若此处为1'b0且signal复位前为1'b1,则进行边沿检测时,会多检测到1个上升沿
		signal_temp3 <= 1'bx ;//(3)若此处为1'b1且signal复位前为1'b0,则进行边沿检测时,会多检测到1个下降沿
	end
	else begin
		signal_temp1 <= signal ;
		signal_temp2 <= signal_temp1 ;
		signal_temp3 <= signal_temp2 ;
	end
end

2.3 时序图

2.3.1 正常状态

在这里插入图片描述

2.3.2 误判上升沿

若signal_temp复位之前为1’b0且signal复位前为1’b1,则进行边沿检测时,就会多检测到1个上升沿,如下图红色区域所示。
在这里插入图片描述

2.3.3 误判下降沿

若signal_temp复位之前为1’b1且signal复位前为1’b0,则进行边沿检测时,就会多检测到1个下降沿,如下图红色区域所示。
在这里插入图片描述

2.5 源代码及TestBench仿真文件

源代码:

// ***************************************************************************************************
// 作者	:DingXY的硬件笔记本**************************************************************************
// 邮箱	:1324830818@qq.com	**************************************************************************
// 版本	:V1.0				**************************************************************************
// 日期	:2023/12/15		**************************************************************************
// 功能	:********************************************************************************************
//	1、用于检测信号上升沿或者下降沿的模块*************************************************************
//	2、可以输出时钟同步后的信号,以及该信号的上升沿、下降沿、双边沿***********************************
//	3、边沿信号都是即时反馈的*************************************************************************
// ***************************************************************************************************

module edge_detector
(
input		clk			,//系统时钟
input		rst_n		,//复位信号,低电平有效
input		signal		,//待检测信号

output wire	sig_sync	,//时钟同步后的检测信号
output wire	sig_posedge	,//sig_sync信号的上升沿标志
output wire	sig_negedge	,//sig_sync信号的下降沿标志
output wire	sig_bothedge //sig_sync信号的上升沿和下降沿标志
);

// ***************************************************************************************************
// 同步不同时钟域的信号,防止亚稳态*******************************************************************
// ***************************************************************************************************
reg signal_temp1 ;//待检测信号寄存1拍
reg signal_temp2 ;//待检测信号寄存2拍
reg signal_temp3 ;//待检测信号寄存3拍
always @(posedge clk or negedge rst_n) begin
	if(rst_n == 1'b0) begin
		signal_temp1 <= 1'bx ;//(1)signal信号的初始值未知,此处赋值1'bx可以避免生成多余的上升沿或者下降沿
		signal_temp2 <= 1'bx ;//(2)若此处为1'b0且signal复位前为1'b1,则进行边沿检测时,会多检测到1个上升沿
		signal_temp3 <= 1'bx ;//(3)若此处为1'b1且signal复位前为1'b0,则进行边沿检测时,会多检测到1个下降沿
	end
	else begin
		signal_temp1 <= signal ;
		signal_temp2 <= signal_temp1 ;
		signal_temp3 <= signal_temp2 ;
	end
end

// ***************************************************************************************************
// 时钟同步后的检测信号及其边沿标志*******************************************************************
// ***************************************************************************************************
assign sig_sync 	= 	signal_temp2 ;
assign sig_posedge	=   signal_temp2  & (~ signal_temp3) ;
assign sig_negedge	= (~signal_temp2) & (  signal_temp3) ;
assign sig_bothedge	=   signal_temp2  ^    signal_temp3  ;

endmodule

TestBench仿真文件:

`timescale 1ns/1ns	//定义时间刻度

module edge_detector_tb();

reg 	clk			;//系统时钟
reg 	rst_n		;//复位信号,低电平有效
reg 	signal		;//待检测信号

wire	sig_sync	;//时钟同步后的检测信号
wire	sig_posedge	;//sig_sync信号的上升沿标志
wire	sig_negedge	;//sig_sync信号的下降沿标志
wire	sig_bothedge;//sig_sync信号的上升沿和下降沿标志

always #10 clk = ~ clk	;//定义主时钟,周期20ns,频率50MHz

initial begin
	clk <= 1'b0 ;
	rst_n <= 1'b0 ;
	signal <= 1'b1 ;
	#20	//系统开始工作
		rst_n <= 1'b1 ;
	#80
		signal <= 1'b0 ;
	#70
		signal <= 1'b1 ;
	#90
		signal <= 1'b0 ;
	#50
		signal <= 1'b1 ;
	#30
		signal <= 1'b1 ;
	#80
		$finish ;//结束仿真
end

// 例化edge_detector模块
// 用于读取传感器信号时,要求待检测信号:触发时低电平
edge_detector
edge_detector_inst0(
.clk		 (clk			),//系统时钟
.rst_n		 (rst_n			),//复位信号,低电平有效
.signal		 (signal		),//待检测信号

.sig_sync	 (sig_sync		),//时钟同步后的检测信号
.sig_posedge (sig_posedge	),//sig_sync信号的上升沿标志
.sig_negedge (sig_negedge 	),//sig_sync信号的下降沿标志
.sig_bothedge(sig_bothedge	) //sig_sync信号的上升沿和下降沿标志
);


endmodule

2.6 仿真结果

在这里插入图片描述
更多内容请关注微信公众号:
在这里插入图片描述

  • 26
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值