Get Smart About Reset: Think Local, Not Global。
對于複位信号的處理,為了友善我們習慣上采用全局複位,部落客在很長一段時間内都是将複位信号作為一個I/O口,通過撥碼開關硬體複位。後來也看了一些書籍,采用異步複位同步釋放,對自己設計的改進。
不過自從我研讀了Xilinx的White Paper後,讓我對複位有了更新的認識。
One of the commandments of digital design states,"Thou shalt have a master reset for all flip-flops so that the test engineer will love you, and your simulations will not remain undefined for time eternal."
這句是用來裝逼的。使用全局複位有利于我們仿真,所有的寄存器都是有初始值的,也可以在任意時刻讓你的寄存器恢複初值,是以驗證工程師很喜歡這樣的設計,但是Xilinx建議的是盡量避免使用全局複位,這是為什麼呢。
全局複位并不是好的處理方式
我們習慣上通常使用的複位有三種,
硬體開關:複位信号接一個撥碼開關。
電源晶片:上電時候電源晶片産生,可以長時間維持,直到穩定。
控制晶片:控制晶片産生複位脈沖。
這些複位信号和FPGA内部信号的變化比起來是比較慢的。複位按鈕最快也會到達毫秒級别,而FPGA内部信号都是納秒級别的變化。全局複位的周期遠大于系統時鐘的周期,是完全可以保證所有的觸發器被成功複位的。
但随着系統的頻率越來越快,全局複位信号的釋放形成一個高扇出的網絡。
Fan-out即扇出,子產品直接調用的下級子產品的個數,如果這個數值過大的話,在FPGA直接表現為net delay較大,不利于時序收斂。是以,在寫代碼時應盡量避免高扇出的情況。

如圖,全局複位的釋放需要傳輸到不同的觸發器。每一個觸發器需要被釋放複位,但是随着時鐘頻率的提高,加上複位路徑網絡的延遲,而且全局複位還是一個高扇出的網絡,是以這對系統的時序是一個大挑戰。
通常情況下,複位信号的異步釋放,沒有辦法保證所有的觸發器都能在同一時間内釋放。觸發器在A時刻接收到複位信号釋放是最穩定的,在下一個時鐘沿來臨被激活,但是如果在C時刻接收到複位信号釋放無法被激活,在B時刻收到複位信号釋放,則會引起亞穩态。
随着系統時鐘頻率的提高,并不是所有的觸發器都能在同一個時刻從複位狀态被釋放。
複位真的有那麼重要嗎?
白皮書上又說了,好的消息是99.9%的情況下,全局複位的異步釋放并不會出現問題。是以大多數電路都可以正常工作。但是,如果你有了第一次就不能工作的電路,那你就是遇到那0.01%的情況,很不幸你的複位信号被在錯誤的時刻重置。(哈哈,皮)
在一些情況下,複位釋放的時間并不重要。
當你的資料采用流水線操作的時候,複位釋放的時間并不重要,因為不管你流水線後面的觸發器複位釋放後是否出錯,隻需要一些周期後,整個流水線就又會正常工作了。白皮書上還說,這樣的複位也是沒有意義的。
但是有一些情況下,複位的釋放後是很重要的。
比如獨熱碼狀态機。如果表示獨熱碼狀态的第一個觸發器比第二個觸發器早釋放了一個時鐘周期,那狀态機的狀态機會跳轉到一個無效的狀态。如果所有的表示獨熱碼的寄存器無法在同一個周期内被釋放,那狀态機肯定會跳轉到一個無效的狀态。還有一些例子,請讀者自己看白皮書。
解決99.99%的情況
其實當Xilinx FPGA配置或重新配置時,所有的單元都會被初始化。白皮書稱為master reset,因為這可比你複位一些D觸發器要強得多,它甚至初始化了片内RAM。
Xilinx的器件也有嵌入處理的系列,軟核或硬核。在程式執行第一條指令前,程式和資料區域已經定義好了。有了上電複位,還用專門消耗邏輯資源去複位觸發器是沒有意義的。
解決0.01%的方法
當然,白皮書也給出了處理複位的建議和方法。
Think Local, Not Global。異步複位,同步釋放的方法。用内部定義複位信号的方法來複位觸發器,而不是全都直接使用全局複位信号。當進行複位操作時,所有的觸發器被預設為1。如上圖,移位寄存器的最後一個觸發器去操作子產品内部定義的複位網絡。當複位信号釋放時,移位寄存器經過移位,當最後一個觸發器由高電平變為低電平時,對本地的複位網絡進行複位操作。也就是異步複位,同步釋放。
複位的消耗的資源比你想象的要多
複位網絡占用大量布線資源。
提高了布局布線時間。
使用器件的邏輯資源。
會使你的設計變得更大。
占用更多的邏輯資源肯定會影響你的性能。
具體請參閱白皮書。
總結
并不是所有部分的設計都需要複位,是以設計者在設計過程中應該準确判斷需要被複位的部分,進而采用異步複位、同步釋放的方法進行對複位的嚴格處理。
當我們在設計每一個部分的時候,都要内心問問自己,這個bit需要被複位嗎?
那麼怎樣處理Xilinx FPGA中的複位呢?Xilinx的工程師也給出了解釋和方法。
https://www.eetimes.com/document.asp?doc_id=1278998www.eetimes.com
FPGA的複位方法幾種方法 | 電子創新網賽靈思中文社群xilinx.eetrend.com
White Paper獲得在微信訂閱号背景回複“wp272”即可獲得!
簡單總結就是,Xilinx的FPGA 應該盡量避免全局複位,有些部分的設計都可以不用複位,必需要複位的設計而采用 同步 高複位。
代碼如下。設計中需要複位的部分,使用産生的sys_rst信号進行同步複位,而且是同步 高複位。再次貼出下圖。
module Sys_Rst(
input clk,
input rst,
output sys_rst
);
reg rst_r0;
reg rst_r1;
always @(posedge clk or posedge rst)begin
if(rst)begin
rst_r0 <= 1'b1;
rst_r1 <= 1'b1;
end
else begin
rst_r0 <= 1'b0;
rst_r1 <= rst_r0;
end
end
assign sys_rst = rst_r1;
endmodule