FPGA——我们到底要怎么搭复位电路

    第一次看特权同学写的亚稳态的问题时,说实话,真的没有看懂。以前就是一直用的异步复位,同时也没有遇到过这样的问题。沉下心来,又仔细的看了一遍,发现了问题所在,特别是当你的工程特别大的时候,可能会非常严重。

异步复位:复位信号和系统时钟信号的触发可以在任何时刻。二者相互独立。
同步复位:在系统时钟信号的触发下,复位信号有效。
用verilog表示会更明显:

// 异步复位
reg a;
always @ (posedge clk or negedge rst_n) begin
    if(!rst_n)
        a <= 'd0;
    else
        a <= ~a;
end
//同步复位
reg b;
always @ (posedge clk)  begin
    if(!rst_n)
        b <= 'd0;
    else    
        b <= ~b;
end

如果复位信号的撤销发生在系统时钟的建立和保持时间这段时间内,系统此时检测到复位信号的状态就处在一个亚稳态,无法确定是0还是1。就有可能造成系统工作不同步的问题。

    特权同学在书中讲到同步复位发生的概率相对异步复位比较低,这一点,我在网上查了,也是很多人都这样认为,这个我还没有理解。

异步复位会影响寄存器的recovery时间,引起设计的稳定性问题,尤其对于状态机的无意识复位,将导致进入不确定的状态。
同步复位最主要的问题是对于不带同步复位专用端口的器件会增加额外的逻辑资源。
在书中,特权同学提到了一种取长补短的方法:异步复位、同步释放。

//异步复位、同步释放
reg rst_nr1;
reg rst_nr2;

always @ (posedge clk or negedge rst_n) begin
    if(!rst_n)
        rst_nr1 <= 'd0;
    else
        rst_nr1 <= 1'b1;
end

always @ (posedge clk or negedge rst_n) begin
    if(!rst_n)
        rst_nr2 <= 'd0;
    else
        rst_nr2 <= rst_nr1;
end

简单分析一下这个电路,当异步复位发生,rst_nr2直接拉低为0,并且由于rst_nr2是在时钟沿的作用下对rst_nr1进行采样,所以当rst_nr2的置1是和时钟沿同步的。也就是异步复位、同步释放。然后用信号rst_nr2作为系统复位时钟,就不发生亚稳态现象。

但是在我的理解看来,这两个触发器仍然是采用rst_n作为复位信号,所以必然会有亚稳态的现象发生,即rst_nr2还是 有可能在不应该复位的时间点复位,但是由rst_nr2作为系统复位信号的后级电路不会发生系统工作不同步的现象。

你可能感兴趣的:(FPGA)