数字IC经典电路设计
经典电路设计是数字IC设计里基础中的基础,盖大房子的第一部是打造结实可靠的地基,每一篇笔者都会分门别类给出设计原理、设计方法、verilog代码、Testbench、仿真波形。然而实际的数字IC设计过程中考虑的问题远多于此,通过本系列希望大家对数字IC中一些经典电路的设计有初步入门了解。能力有限,纰漏难免,欢迎大家交流指正。快速导航链接如下:
一、边沿检测原理
数字IC边沿检测是指检测数字信号中从高电平到低电平或从低电平到高电平变化的过程,也就是信号的边缘。边沿检测在许多数字电路和通信系统中都很重要,因为它可以用来同步信号和数据,提取数据时序和时钟信号,并且能够处理数字信号的快速变化。
如何实现边沿检测呢?最直接简单的方法是对信号进行打拍。
如下图所示,输入信号din在经过一级触发器打一拍子后输出延迟一个时钟周期输出,即对原始信号进行延迟操作得到din_r,din_r作为慢一拍的信号状态,可与最初状态信号进行组合逻辑运算变可得到上升沿检测信号(如下图左)、下降沿检测信号(如下图右)以及双边沿检测信号。
简而言之,可以将din_r与din理解为状态的前一刻和后一刻。
逻辑的实现部分则为:
assign up_edge = ~din_r & din;
assign down_edge = din_r & ~din;
assign both_edge = din_r ^ din;
二、上升沿检测、下降沿检测、双边沿检测
Verilog代码
module edge_detector(
input clk,
input rst_n,
input din,
output up_edge,
output down_edge,
output both_edge
);
reg din_r;
always@(posedge clk or negedge rst_n) begin
if(!rst_n) begin
din_r <= 1'b0;
end
else begin
din_r <= din;
end
end
assign up_edge = ~din_r & din;
assign down_edge = din_r & ~din;
assign both_edge = din_r ^ din;
endmodule
RTL电路
Testbench
`timescale 1ns / 1ps
module edge_detector_tb () ;
reg clk;
reg rst_n;
reg din;
wire up_edge;
wire down_edge;
wire both_edge;
edge_detector u_edge_detector(
.clk (clk),
.rst_n (rst_n),
.din (din),
.up_edge (up_edge),
.down_edge (down_edge),
.both_edge (both_edge));
always #5 clk = ~clk;
initial begin
clk = 0;
rst_n = 1;
din = 0;
#5 rst_n = 0;
#5 rst_n = 1;
#10 din = 1;
#20 din = 0;
#40 $stop;
end
endmodule
仿真结果
当检测到上升沿时, pos_edge信号输出一个时钟周期的高电平; 检测到下降沿时,neg_edge输出一个时钟周期的高电平。
三、改进——增强稳定性
要实现边沿检测,最直接的想法是用两级寄存器,第二级寄存器锁存住某个时钟上升沿到来时的输入电平,第一级寄存器锁存住下一个时钟沿到来时的输入电平,如果这两个寄存器锁存住的电平信号不同,就说明检测到了边沿,具体是上升沿还是下降沿可以通过组合逻辑来实现。
通过上文可知,主要借助的是触发器延迟进行操作。一般而言,多级延迟触发器有如下两点作用:
①_简单的延时:多级延迟触发器最原始的作用单纯的对原始信号做延迟操作。
②降低亚稳态往后级传输的概率_:如果输入信号相对 clk时钟信号属于不稳定信号,则延迟输出信号相对 clk时钟信号属于相对稳定信号,从而有效地降低了亚稳态往后级传输的概率。
上文给出的电路似乎很简单地实现了边沿检测的功能,但是仔细分析就可以发现这种方法存在一个潜在的风险:当待测信号是一个异步信号时,输出可能是亚稳态。例如,信号的变化刚好发生在clk时钟信号的建立时间和保持时间之内,那么第一级寄存器的输出就会进入亚稳态,从而使得整个电路的输出进入亚稳态,进而影响下一级电路的正常工作,甚至导致整个系统崩溃!
那么有什么办法可以改进吗?
答案是增加寄存器的数目来减小亚稳态的发生概率。例如,增加多级寄存器可以几乎消除亚稳态带来的影响(亚稳态还是存在不过概率极小)。
四、总结
边沿检测的核心思想是“打拍子+逻辑运算”,核心为以下几点:
打拍子:通过寄存器寄存延迟一拍输出,因为寄存器的特性,当信号发生改变时,下一级寄存器输出不会立刻改变而会在下一个时钟周期改变。
Tips:有时候为避免亚稳态的影响而加入多级寄存器,相当于打多拍。
逻辑运算:逻辑的实现部分为,可以将din_r与din理解为状态的前一刻和后一刻。
assign up_edge = ~din_r & din;
assign down_edge = din_r & ~din;
assign both_edge = din_r ^ din;
更多可查看个人主页链接
软件版本:Modelsim 10.6c
不定期纠错补充,欢迎随时交流
最后修改日期:2023.6.2