异步复位,同步释放
异步复位有可能引发亚稳态问题,需将异步复位同步化以后,再输出给寄存器使用。
以低有效复位为例代,码如下:
reg rst_n_d1;
reg rst_n_d2;
always@(posedge clk or negedge rst_n)
begin
if(rst_n==1’b0)
begin
rst_n_d1 <= 1'b0;
rst_n_d2 <= 1'b0;//异步复位
end
else
begin
rst_n_d1 <= 1’b1;
rst_n_d2 <= rst_n_d1;//同步释放
end
end
异步复位:
在复位信号下降沿时刻,rst_n_d1以及rst_n_d2两个寄存器都异步复位了,变成了低电平。
同步释放:
在复位若干时刻后,rst_n信号随机拉高,解除复位。该时刻有可能发生在rst_n_d1的setup time时间窗口内,导致rst_n_d1发生亚稳态,其输出的Q值不可预料。
假设在解复位时刻在T0时钟与T1时钟之间。T0时钟,rst_n_d1与rst_n_d2都是低电平。
解复位时刻,假设
1.rst_n被rst_n_d1采集为0:
1)若rst_n被rst_n_d2采集为0,则rst_n_d1,rst_n_d2均处于复位状态;T1时钟,rst_n_d2输出低电平,rst_n_d1输出低电平。
2)若rst_n被rst_n_d2采集为1,则rst_n_d1,处于复位状态,但rst_n_d2不处于复位状态,T1时钟,rst_n_d2输出T0时钟rst_n_d1低电平,即rst_n_d2输出低电平(该输出仍为亚稳态的概率已经大大降低)。
2.rst_n被rst_n_d1采集为1:
分析同上。
其实只需看rst_n_d_d2采集rst_n是何值,无论是0还是1,T1时钟,rst_n_d_d2都输出固定0,但是T2时钟,rst_n_d_2有可能是0也可能是1(因为T1时钟,rst_n_d1可能输出0也可能输出1,这说明,同步器消除亚稳态,并不能保证输出的结果是正确的数值,他只是使得输出符合setup时序要求),但是因为rst_n_d2输出Q相比rst_n_d1的输出经过了一个延时,亚稳态的概率已经大大降低。
上述分析本质上和”多级寄存器级联(打拍同步器)为何可以消除亚稳态”的答案是一样的。
因此,可以采用简化的代码,直接利用时钟对复位信号rst_n打两拍,达到同步的效果。