写在前面的话
在项目设计中,我们经常需要检测信号由高到低或者由低到高的跳变。本节,梦翼师兄和大家一起学习一个经典的边沿检测电路,通过该电路,我们可以在信号出现跳变沿的时候产生尖峰脉冲,从而驱动其他电路模块进行相应的动作。
电路原理分析
我们来分析一下这个电路结构和工作原理
(1) 当系统处于复位状态即rst_n信号为低电平时,假设输入信号为低电平,寄存器inst清零端生效,寄存器输出端Q清零。由于Q端分别是“与门”inst1和inst2的输入端,而系统输出端neg_edge和pos_edge都是寄存器输出端Q和输入信号signial相与的结果,系统输出端neg_edge和pos_edge一直都是低电平,系统处于复位状态。
(2) 复位结束以后,假设输入信号signial在某个“当前周期”从低电平跳变到高电平,那么由于寄存器的特性,寄存器输出端Q只有在“下一周期”才会出现跳变。
“与门”inst1的“1号”输入端通过“非门”直接连接到了输入端signial,所以在“当前周期”下“1号”端口的电平为低,而“2号”端口的电平为“上一个”周期的低电平,所以输出端neg_edge=0,保持低电平。
“与门”inst2的“3号”输入端直接连接到了输入端signial,所以在“当前周期”下“3号”端口的电平为高,而“4号”端口的电平为“上一个”周期的低电平取反,所以“4号”端口的电平也为高,输出端pos_edge=1,保持高电平。
(3) 当“下一周期”到来以后Q端输出为1,则“4号”端口的电平由高变为低,系统输出端pos_edge又恢复为低电平。也就是说当时钟上升沿到来以后,pos_edge能且只能保持一个时钟周期(输入信号必须是同步的)的高电平,在这里我们叫做“尖峰脉冲”。
下降沿的检测原理与上述类似,在此不再赘述,通过这张经典的电路图我们总结出以下两点:
(1)当信号出现上升沿以后(信号由低电平跳变到高电平),pos_edge会出现一个时钟周期的“尖峰脉冲”。
(2)当信号出现下降沿以后(信号由高电平跳变到低电平),neg_edge会出现一个时钟周期的“尖峰脉冲”。
掌握边沿检测原理以后,我们就可以用硬件描述语言来描述出这样的电路。
顶层框图
顶层模块端口介绍
端口名 |
端口说明 |
clk |
系统50MHz时钟输入 |
rst_n |
系统低电平复位 |
signial |
系统外部信号输入 |
neg_edge |
下降沿产生标志 |
pos_edge |
上升沿产生标志 |
代码实现
/**************************************************** * Engineer : 梦翼师兄 * QQ : 761664056 * The module function:信号边沿检测模块 *****************************************************/ 01 module edge_check( 02 clk, //系统时钟输入 03 rst_n, //系统复位(低电平有效) 04 signial, //外部按键输入 05 06 pos_edge, //上升沿检测标志 07 neg_edge //下降沿检测标志 08 ); 09 10 //----------------系统输入--------------- 11 input clk; //系统时钟输入 12 input rst_n; //系统复位(低电平有效) 13 input signial; //外部按键输入 14 15 //----------------系统输出--------------- 16 output pos_edge; //上升沿检测标志 17 output neg_edge; //下降沿检测标志 18 19 //---------------寄存器定义-------------- 20 reg signial_r; //输入信号寄存器 21 22 //---------------边沿检测---------------- 23 always @ ( posedge clk or negedge rst_n ) 24 begin 25 if(!rst_n) 26 begin 27 signial_r <= 1'b0; //输入信号寄存器赋初值 28 end 29 else 30 begin 31 signial_r <= signial; //把输入信号的值给寄存器 32 end 33 end 34 //当外部输入signial由1变为0时,neg_edge的值变为高,维持一个时钟周期 35 assign neg_edge = signial_r & (~signial); 36 //当外部输入signial由0变为1时,pos_edge的值变为高,维持一个时钟周期 37 assign pos_edge = (~signial_r) & signial; 38 39 endmodule |
edge_check模块代码说明:第23~33行描述的是一个D触发器,对应我们开始解释的原理图中的inst块;第35行描述的是一个与门,对应inst2块,其中“signial”连接到了inst1的“3”输入端,“~signial_r”连接到了inst2的“4”输入端;第37行描述的也是一个与门,对应inst1块,其中“~signial”连接到了inst1的“1”输入端,“signial_r”连接到了inst1的“2”输入端。
测试代码如下:
/**************************************************** * Engineer : 梦翼师兄 * QQ : 761664056 * The module function:信号边沿检测测试模块 *****************************************************/ 01 `timescale 1ns/1ps 02 module tb; 03 //--------------系统输入----------- 04 reg clk; //系统时钟输入 05 reg rst_n; //系统复位(低电平有效) 06 reg signial; //外部按键输入 07 //--------------系统输出----------- 08 wire pos_edge; //上升沿检测标志 09 wire neg_edge; //下降沿检测标志 10 11 initial 12 begin 13 clk=0; 14 rst_n=0; 15 signal=1; 16 # 1000.1 rst_n=1; 17 # 200 signal=0; 18 # 200 signal=1; 19 # 200 signal=0; 20 # 200 signal=1; 21 end 22 23 always #10 clk=~clk; //周期为20ns的时钟 24 25 edge_check edge_check( 26 .clk(clk), //系统时钟输入 27 .rst_n(rst_n), //系统复位(低电平有效) 28 .signial (signial), //外部信号输入 29 .pos_edge(pos_edge), //上升沿检测标志 30 .neg_edge(neg_edge) //下降沿检测标志 31 ); 32 33 endmodule |
仿真波分析
从波形图可以看出,当外部输入信号signial由高电平跳变到低电平的时候,neg_edge会出现一个尖峰脉冲,当signial没有任何变化的时候,neg_edge保持不变一直是低电平;当外部输入信号signial由低电平跳变到高电平的时候,pos_edge会出现一个尖峰脉冲,当signial没有任何变化的时候,pos_edge保持不变一直是低电平。
总结发现我们分析的经典电路的结论和现在的仿真波形得出的结论是相同的,可以证明我们的设计是正确的。