FPGA復位電路設計及其時序分析


  通常同步電路由兩種復位方式,即同步復位和異步復位。同步復位同步於寄存器的時鍾域,異步復位則是立即自然地作用於寄存器,與其寄存器所在的時鍾域之間沒有確定的時序關系。同步化的異步復位是FPGA電路設計時復位電路的首選。

1 同步復位

1.1 同步復位在外部的情況

代碼:

module sync_reset_ext(
input           clock,
input           reset_n,
input           data_a,
input           data_b,
output          out_a,
output          out_b
    );
reg             reg1,reg2;
assign          out_a = reg1;
assign          out_b = reg2;

always @(posedge clock) begin
    if(!reset_n) begin
        reg1 <= 1'b0;
        reg2 <= 1'b0;
    end
    else begin
        reg1 <= data_a;
        reg2 <= data_b;
    end
end
endmodule

Vivado工具綜合出來的RTL如下圖所示:

  這里用到的是MUX(也可以使用與門來實現),這種方式需要考慮額外的門延遲,復位信號數據經過MUX邏輯電路使得復位信號到達時間(Data Arrival Time)會增加,在這種情況下,建立時間的slack可能為負值。同步復位總是比異步復位來的慢,在FPGA中不是最好的復位方式。

1.2 同步復位在內部的情況

 代碼:

module sync_reset(
input           clock,
input           reset_n,
input           data_a,
input           data_b,
output          out_a,
output          out_b
    );
reg             reg1,reg2;
reg             reg3,reg4;
wire            rst_n;
assign          out_a = reg1;
assign          out_b = reg2;
assign          rst_n = reg4;
always @(posedge clock) begin
    if(!rst_n) begin
        reg1 <= 1'b0;
        reg2 <= 1'b0;
    end
    else begin
        reg1 <= data_a;
        reg2 <= data_b;
    end
end
always @(posedge clock) begin
    reg3 <= reset_n;
    reg4 <= reg3;
end
endmodule

Vivado綜合出來的RTL如下圖:

  跟1.1的區別是,復位信號打了兩拍。為什么要這么做?因為大部分時候,輸入到FPGA的復位信號是異步信號,在這種情況下,復位信號必須在內部先同步后再送達寄存器。既然輸入的是異步信號,那么常常有可能該異步信號的脈寬比較小(小於一個時鍾周期)。這種異步信號比時鍾脈寬小的缺點是,異步信號同步時必須保證脈寬至少是一個時鍾周期長,。才能保證異步復位信號在第一個同步寄存器被捕獲;優點是,脈寬段可以增加其抗噪性能,在異步輸入上的一些虛假脈沖,例如毛刺,很難在第一個寄存器被捕獲,也就不會誤觸發同步復位。

2 異步復位

   異步復位最大的優點,是沒有像同步復位那樣插入到數據路徑中,因此異步復位對寄存器之間的數據到達時間不會產生負面影響。另一個優點是,異步復位是立即生效的。

代碼:

module aync_reset(
input           clock,
input           reset_n,
input           data_a,
output          out_a
    );
reg             reg1,reg2,reg3;
assign          out_a = reg3;
always @(posedge clock,negedge reset_n) begin
    if(!reset_n) begin
        reg1 <= 1'b0;
    end
    else begin
        reg1 <= data_a;
    end
end
always @(posedge clock) begin
    reg2 <= reg1;
    reg3 <= reg2;
end
endmodule

Vivado綜合出來的電路圖:

  但是,異步復位在復位被釋放的時候可能會出現問題。異步復位在釋放的時候,可以出現在時鍾的任何一個時候,復位信號在撤除是,復位信號的邊沿可能會落入時鍾的一個亞穩態區域。亞穩態帶來的后果是寄存器的輸出需要花費更多的時間來恢復穩定或者正確的狀態。這個額外的增加的時間可能會導致寄存器下一級的建立時間失敗,從而導致系統錯誤。那么,如果這個異步復位信號,能夠被同步到clock時鍾域下,那么這個問題也就解決了,也就是接下來要說的異步復位同步釋放的設計。

3 異步復位同步化

代碼:

module sync_async_reset(
input           clock,
input           reset_n,
input           data_a,
input           data_b,
output          out_a,
output          out_b
    );
reg             reg1,reg2;
reg             reg3,reg4;
wire            rst_n;
assign          out_a = reg1;
assign          out_b = reg2;
assign          rst_n = reg4;

always @(posedge clock,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 clock,negedge rst_n) begin
    if(!rst_n) begin
        reg1 <= 1'b0;
        reg2 <= 1'b0;
    end
    else begin
        reg1 <= data_a;
        reg2 <= data_b;
    end
end
endmodule

 

  第一個always塊用來產生同步復位輸出rst_n,作為第二個always塊的異步復位,第二個將這個已經同步化了的復位信號當做異步復位使用。兩個進程模塊的復位信號都位於各自的敏感列表中。同步器中的寄存器級數(打拍級數)可以視情況而定,但是要確保同步后的異步復位信號至少有一個時鍾周期的長度。

Vivado綜合出來的RTL如下圖所示:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM