cssuss 发表于 2013-5-24 15:52:04

异步复位,同步置位为什么要采用两级寄存器?

为了保证在复位信号消失时时钟有效边沿到达而是寄存器产生的亚稳态,一般推荐采用异步复位,同步置位的方法。
比如http://www.cnblogs.com/qiweiwang/archive/2010/11/25/1887888.html中的代码:

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

其它的文章也是采用类似的方式。
我的问题是为什么大家都是采用2级寄存器进行缓冲,而不是像下面的代码:
module test
(
input clk,
input rst_n,
output reg rst_out
);
always @ (posedge clk,negedge rst_n)
    if(!rst_n)
      rst_out<=1'b0;
   else
      rst_out<=1'b1;                        
endmodule
只使用一级寄存器来实现异步复位,同步置位?二者的效果应该是一样的,采用两级寄存器完全没有必要吧?

mitchell 发表于 2013-5-24 16:23:35

减小亚稳态传递的概率

zkf0100007 发表于 2013-5-24 17:03:24

楼上正解

cssuss 发表于 2013-5-25 15:22:06

mitchell 发表于 2013-5-24 16:23 static/image/common/back.gif
减小亚稳态传递的概率

但是文章中的电路在输入复位信号和时钟边沿同时变化时并不能保证复位信号的稳定。
我问了一下别人,他们说下面这种电路更好。但是为什么我在网上找到的所有资料都是按照1L的原理图进行说明的?

jm2011 发表于 2013-5-28 11:20:01

上面的这个电路是不好的,需要多次锁存来减小亚稳态的概率;

skyxjh 发表于 2013-5-28 23:17:39

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

always @ (posedge clk,negedge rst_n)
    if(!rst_n)
      rst_out<=1'b0;
   else
      rst_out<=1'b1;                        

这两种代码的差别是,前一种的置位信号会晚一个时钟周期到达。

skyxjh 发表于 2013-5-28 23:21:31

在这一个时钟周期内如果rst_n再次变为低的话,置位信号不会送出。
页: [1]
查看完整版本: 异步复位,同步置位为什么要采用两级寄存器?