1. 程式人生 > >FPGA非同步復位同步釋放解析

FPGA非同步復位同步釋放解析

FPGA開發中,一種最常用的復位技術就是“非同步復位同步釋放”,這個技術比較難以理解,很多資料對其說得並不透徹,沒有講到本質,但是它又很重要,所以對它必須理解,這裡給出我的看法。
講到這個之前,我們要先熟悉recovery time和removal time的概念。如下圖:


對於非同步復位而言,假設是低電平有效,那麼很容易碰到的情況就是我在釋放該訊號的時候,發現它的釋放沿居然跟時鐘跳變沿太接近了!這會導致D觸發器處於亞穩態。我們知道,上圖的reset_n訊號是接D觸發器的直接復位端的。如果兩個跳變沿過於接近,那麼D觸發器就有可能發現自己該取樣了,但是復位訊號還沒取消呢!採還是不採就不能確定。所以,我們要求reset_n訊號釋放的時候,必須遠離clock上升沿recovery time +removal time這麼大的時間區域,其中clock上升沿之前的必須遠離的那段時間叫做recovery time,上升沿之後必須遠離的那段時間叫做removel time

。簡單的講,兩者不能同時跳變,或者接近同時跳變

為了避免釋放的時候造成亞穩態問題,提出了“非同步復位,同步釋放”的解決辦法。所謂非同步復位,就是復位訊號可以直接不受時鐘訊號影響,在任意時刻只要是低電平就能復位(假如約定低電平復位),也就是說,復位訊號不需要和時鐘同步。而同步釋放就很有意思了,它的意思是讓復位訊號取消的時候,必須跟時鐘訊號同步,也就是說正好跟時鐘同沿。這就奇怪了!因為之前我們剛講,要避免復位釋放沿跟時鐘沿同步。這裡為什麼就可以了呢?

我們先看一個非同步復位同步釋放的程式碼,Verilog程式碼如下:

module prac (

        clk,
        reset_n,
        dataa,
        datab,
        outa,
        outb
    );
    input        clk;
    input        reset_n;
    input        dataa;
    input        datab;
    output        outa;
    output        outb;
    reg            reg1;
    reg            reg2;
    reg            reg3;
    reg            reg4;
    assign    outa    = reg1;
    assign    outb    = reg2;
    assign    rst_n    = reg4;
    always @ (posedge clk or negedge reset_n)      //“非同步復位同步釋放”的復位模組


    begin
        if (!reset_n)
            begin
                reg3    <= 1'b0;
                reg4    <= 1'b0;
            end
        else
            begin
                reg3    <= 1'b1;
                reg4    <= reg3;
            end
    end


    always @ (posedge clk or negedge rst_n

)   //功能模組,注意rst_n是沿變驅動。
    begin
        if (!rst_n)
            begin
                reg1    <= 1'b0;
                reg2    <= 1'b0;
            end
        else
            begin
                reg1    <= dataa;
                reg2    <= datab;
            end
    end
endmodule

綜合後的RTL圖表如下:


ScreenShot004

下面對上面的圖進行解說。我們看到,真正驅動reg2和reg1等功能模組工作的復位訊號其實是rst_n訊號,而rst_n訊號則是非同步復位端reset_n經過reg3和reg4兩級寄器之後的產生的新的復位訊號。其中reset_n為非同步復位,而rst_n則是經過同步釋放得到的新的復位驅動訊號。rst_n將與時鐘沿同步,所以它本質上是同步復位訊號。

這樣,通過reg3和reg4兩級鎖存,就把reset_n從一個非同步復位埠,加工成了一個輸出同步復位rst_n的模組。

reg3的輸入端永遠接“1”,所以某時刻,正常情況下,reg3和reg4都輸出“1”。假設在某時刻,reset_n訊號被拉為低電平,這將導致reg3直接復位,輸出為“0”,而此時reg4需要下一個時鐘週期才會變成“0”;而且reg4是在時鐘沿作用下采樣,所以reg4從“1”跳變為“0”的時刻一定跟時鐘沿是同步的,這就得到了一個同步釋放的結果。而reg2和reg1都是時鐘沿驅動,所以這種同步釋放的rst_n將可以有效的驅動後面的復位,不會造成亞穩態效應

我們看到,其實最後我們也就是實現了同步復位的功能,那我們為什麼不直接使用同步復位來寫呢?原因在於,很多模組本身不具有同步復位埠,但是基本都支援非同步復位,所以使用非同步復位更加節省資源,如果一定要實現同步復位,那麼會生成更多組合邏輯。比如圖中所有暫存器的CLR埠其實就是非同步復位埠。而通過上面多加了reg4觸發,我們讓CLR這個非同步復位的埠實現了同步復位的功能,而同步復位訊號效果更好,對毛刺抑制能力強,這就是“非同步復位同步釋放”的意義。所以讓非同步復位埠實現同步復位功能,這才是“非同步復位同步釋放的本質”