同步复位、异步复位、异步复位同步释放、多时钟域复位桥电路和全局复位信号
复位
同步复位
1 module test
2 (
3 input clk,
4 input rst_n,
5 input data_in,
6 output reg out
7 );
8 always @ (posedge clk )
9 if(!rst_n) out <= 1'b0;
10 else out <= data_in;
11 endmodule
优点:
1.因为他只有在时钟有效电平到来时才有效,所以可以滤除高于时钟频率的毛刺。
2.降低亚稳态出现的概率。(可以对rst信号先打一拍,然后在输入给rst_n,这样就可以降低亚稳态。)
缺点:
1.复位信号的有效时长必须大于时钟周期,才能真正被系统识别并完成复位任务。
2.倘若采用同步复位的话,综合器就会在寄存器的数据输入端口插入组合逻辑,这样就会耗费较多的逻辑资源。
异步复位
1 module test
2 (
3 input clk,
4 input rst_n,
5 input data_in,
6 output reg out
7 );
8 always @ (posedge clk or negedge rst_n)
9 if(!rst_n) out <= 1'b0;
10 else out <= data_in;
11 endmodule
优点
大多数目标器件库的dff都有异步复位端口,因此采用异步复位可以节省资源。
缺点:
1.在复位信号释放(release)的时候容易出现问题。具体就是说:倘若复位释放时恰恰在时钟有效沿附近,就很容易使寄存器输出出现亚稳态,从而导致亚稳态。
2.复位信号容易受到毛刺的影响。
同步复位异步释放
同步复位异步释放:既解决了同步复位的资源消耗问题,也解决了异步复位的亚稳态问题。其根本思想,也是将异步信号同步化。
以两级寄存器异步复位为例说明存在的问题
1 module test
2 (
3 input clk,
4 input rst_n,
5 input a,
6 output reg c
7 );
8
9 reg b;
10 always @ (posedge clk or negedge rst_n)
11 if(!rst_n) b <= 1'b0;
12 else b <= a;
13
14 always @ (posedge clk or negedge rst_n)
15 if(!rst_n) c <= 1'b0;
16 else c <= b;
17
18 endmodule
正常情况下,clk的上升沿c更新为b,b更新为a。一旦进入复位,b,c都清零;但是我们不能确定复位信号rst_n会在什么时候结束。如果结束于b_reg0和c_reg0的{launch edge –stup,launch edge+hold}时间只外,那么一切都会正常。但如果恰恰相反,会出现什么情况呢? rst_n的上升变化出现在了clk上升的建立保持时间上,此时clk检测到的rst_n的状态就会是一个亚稳态(是0是1不确定)。从代码里我们看到如果此时b_reg0和c_reg0认为rst_n为0,那么依然保持复位清零,而如果认为rst_n为1,那么就跳出复位。因为此时的rst_n的不确定性,就可能出现4种情况,即b_reg0和c_reg0都复位或者都跳出复位,再或者一个复位一个跳出复位。那么后者就会造成了系统工作不同步的问题,在这个简单的两级异步复位实例中这种危害表现的并不明显,但是我们试想一个大的工程项目里众多的寄存器出现如此情况又会是如何一番景象呢?
在大工程项目里,如果采用异步复位,那么当亚稳态来临时候,所有寄存器都会随机复位或者跳出复位,导致系统进入未知的或者错误的工作状态。
解决方法------异步复位同步释放
第一种方式:
1 module test
2 (
3 input clk,
4 input rst_n,
5 input a,
6 output reg c
7 );
8
9 reg b,rst_nr;
10 always @ (posedge clk)
11 rst_nr <= rst_n;
12
13 always @ (posedge clk or negedge rst_nr)
14 if(!rst_nr) b <= 1'b0;
15 else b <= a;
16
17 always @ (posedge clk or negedge rst_nr)
18 if(!rst_nr) c <= 1'b0;
19 else c <= b;
20
21 endmodule
将第一种方式的复位信号简化后则形成第二种方式。
第二种方式:
1 module test
2 (
3 input clk,
4 input rst_n,
5 output reg rst_out
6 );
7
8 always @ (posedge clk,negedge rst_n)
9 if(!rst_n)
10 rst_out<=1'b0;
11 else
12 rst_out<=1'b1;
13 endmodule
前两种方式都是属于异步复位同步释放,但是当出现一个毛刺信号时候,由于毛刺信号复位时间特别小,而信号变化需要一段时间,所以毛刺信号可能导致复位不彻底(即有些寄存器已经复位,有一些没有复位),系统出现错误的状态(即系统出现混乱),所以不可取。如果将该毛刺信号的复位延迟一个时钟周期,即系统检测到毛刺信号的下降沿后复位,等一个时钟后(即打一拍)再进行还原,可以有效避免这种情况出现。这就是我们所说的第三种方法。
第三种方式
module rst
(
input clk,
input rst_n,
output reg rst_out
);
reg R1;
always @ (posedge clk,negedge rst_n)
if(!rst_n)
begin
R1 <= 1'b0;
rst_out <= 1'b0;
end
else
begin
R1 <= 1'b1;
rst_out <= R1;
end
endmodule
异步复位,同步释放的好处是:
1.不要求复位信号必须大于一个时钟周期;
2.因为释放过程和时钟同步,所以有效降低了亚稳态出现的概率。
3.消除毛刺信号的影响。
参考博客
https://www.cnblogs.com/qiweiwang/archive/2010/11/25/1887888.html
复位电路设计
全局复位(GSR)
在很多FPGA中采用全局复位信号,即整个FPGA的所有触发器都使用同一个复位信号。所以GSR信号(全局复位信号)是一个高扇出的信号。
对于多数FPGA,均有专用的全局异步复位/置位资源(GSR,GlobalSetReset)。使用GSR资源,异步复位到达所有寄存器的偏斜最小。
多时钟域复位桥电路
每个时钟域都要有自己的复位信号,而且复位信号要与该时钟域的时钟同步。如下图所示,复位信号在进入每个时钟域前都先进行异步复位同步释放操作,使得复位信号和该时钟域的时钟同步。
按键复位信号电路
按键信号一般有抖动,所以在使用前需要消抖处理。
这里有两种去抖动方案供大家参考:
第一种:
1.每隔20ms采集一次信号rst
2.对rst信号打一拍,进行边沿检测。(这里需要对上升沿和下降沿都进行检测)
如果检测到下降沿,则认为复位有效,系统进行复位。如果检测到上升沿,则认为复位释放。
//===========================================================================
// 采样按键值,20ms扫描一次,采样频率小于按键毛刺频率,相当于滤除掉了高频毛刺信号。
//===========================================================================
always @(posedge clk or negedge rst_n) //检测时钟的上升沿和复位的下降沿
begin
if(!rst_n) //复位信号低有效
count <= 20'd0; //计数器清0
else
begin
if(count ==20'd999_999) //20ms扫描一次按键,20ms计数(50M/50-1=999_999)
begin
count <= 20'b0; //计数器计到20ms,计数器清零
key_scan <= key_in; //采样按键输入电平
end
else
count <= count + 20'b1; //计数器加1
end
end
//===========================================================================
// 按键信号锁存一个时钟节拍
//===========================================================================
reg [3:0] key_scan_r;
always @(posedge clk)
key_scan_r <= key_scan;
wire [3:0] flag_key = key_scan_r[3:0] & (~key_scan[3:0]); //当检测到按键有下降沿变化时,代表该按键被按下,按键有效
第二种方法:
1.先进行上升沿检测
2.检测到上升沿后,开始计数20ms,采集20ms后的复位信号rst1
3.如果rst1为高电平且上升沿有效,则认为复位释放。
同理复位有效也是这样处理。
常见的复位方式
为什么大多数电路上的复位信号都是低电平有效?
这是为了统一电路处理,使得上电复位过程和按键复位过程处理电路一致。一个板子在没有上电时候,各个管脚的信号可以认为是低电平的。并且电路上电和按键被按下时刻,数字电路的行为应该是一样的。而上电时刻,复位信号接一个高电平的模拟延时电路,从而保证时钟比复位信号早到(此时复位信号是低电平),如此芯片在工作开始前就复位了。
我们习惯上通常使用的复位有三种方式:
硬件开关:复位信号接一个拨码开关或按键,或者RC电路
电源芯片:上电时候电源芯片产生,可以长时间维持,直到稳定。
控制芯片:控制芯片产生复位脉冲。