整個設(shè)計最好采用唯一的時鐘域可以簡化時序分析以及減少很多與多時鐘域有關(guān)的問題,但是由于FPGA外各種系統(tǒng)限制,只使用一個時鐘常常又不現(xiàn)實。FPGA時常需要在兩個不同時鐘頻率系統(tǒng)之間交換數(shù)據(jù),在系統(tǒng)之間通過多I/O接口接收和發(fā)送數(shù)據(jù),處理異步信號,以及為帶門控時鐘的低功耗ASIC 進行原型驗證。
這里提到的時鐘域,是指一組邏輯,這組邏輯中的所有同步單元(觸發(fā)器、同步RAM塊以及流水乘法器等)都使用同一個網(wǎng)絡(luò)作為時鐘。假如設(shè)計中所有的觸發(fā)器都使用一個全局網(wǎng)絡(luò),比如FPGA的主時鐘輸入,那么我們說這個設(shè)計只有一個時鐘域。假如設(shè)計有兩個輸入時鐘,如圖6-1所示,一個時鐘給接口1使用,另一給接口2使用,那么我們說這個設(shè)計中有兩個時鐘域。
圖6-1:雙時鐘域設(shè)計
平時我們在設(shè)計中遇到的門控時鐘、衍生時鐘以及事件驅(qū)動的觸發(fā)器都可歸為時鐘域類別。如圖6-2所示,通過一個簡單門控時鐘創(chuàng)建了一個新的時鐘域。我們知道,這類時鐘控制在FPGA設(shè)計中并不被推崇(可以使用時鐘使能替代時鐘門控),然而它卻非常有利于我們理解時鐘域這一概念。
本章我們將著重詳細討論以下主題:
l 兩個不同時鐘域之間傳輸信號。
n 亞穩(wěn)態(tài)的產(chǎn)生以及對設(shè)計的可靠性的影響
n 通過相位控制避免亞穩(wěn)態(tài)
n 在時鐘域之間傳輸單個信號,將信號打兩拍
n 使用FIFO在時鐘域之間傳輸多位數(shù)據(jù)
n 使用分區(qū)同步器模塊提高設(shè)計的組織架構(gòu)
l 處理ASIC驗證原型里的門控時鐘
n 建立一個單時鐘模塊
n 自動門控移除
圖6-2:通過門控時鐘創(chuàng)建的時鐘域
[page]
6.1 跨時鐘域
設(shè)計中包含多時鐘域,首先要解決的是在不同時鐘域之間傳輸信號的問題。信號跨時鐘域傳輸將會是一個大問題,原因如下:
1、 信號跨時鐘域傳輸產(chǎn)生的故障總是不太容易復現(xiàn)。設(shè)計中如果存在兩個異步時鐘域,故障往往與這兩個時鐘沿的相對時序有關(guān)。來自片外時鐘源的時鐘通常與器件實際功能并無任何關(guān)聯(lián)。
2、 根據(jù)技術(shù)的不同,問題也不一樣。(盡管由于其他因素的影響,這種情況并不總是成立)我們常常會發(fā)現(xiàn),如果約束較小的建立和保持時間,從統(tǒng)計上來說高速設(shè)計技術(shù)比低速設(shè)計技術(shù)更不容易產(chǎn)生故障。同時,其它因素,比如同步器件中設(shè)計實現(xiàn)對輸出的緩沖,也會對一個可能的故障產(chǎn)生顯著影響。
3、 EDA工具一般不會探測和標注這類問題,靜態(tài)時序分析工具是基于獨立的時鐘區(qū)域來進行時序分析,而且只有在特定的方式下根據(jù)指定的要求才能進行跨時鐘域的時序分析。
4、 通常來說,如果沒有很好地理解,跨時鐘域故障難以探測且難以調(diào)試。所以所有跨時鐘域接口都必須要在任何功能實現(xiàn)之前被很好地定義和處理。
讓我們首先來看看在不同時鐘域之間傳輸信號到底會產(chǎn)生什么錯誤??紤]圖6-3所示的情況,一個信號在兩個時鐘域之間傳播。
如圖6-4所示,低速時鐘的周期是高速時鐘周期的兩倍。低速時鐘上升沿與高速時鐘上升沿之間的間隔為常量,而且總是等于dC。由于這兩個時鐘的這種相位匹配關(guān)系,dC總是保持不變(假定頻率沒有漂移),而且在這個例子中,dC總是大于邏輯延時與高速時鐘驅(qū)動的觸發(fā)器建立時間之和。
圖6-3:時鐘域之間的簡單信號傳輸
圖6-4:兩個時鐘域之間的時序關(guān)系
當這些時鐘一啟動,它們之間存在一個固定的相位關(guān)系,如此可以避免任何建立時間和保持時間違規(guī)。只要時鐘沒有漂移,就沒有任何時序違規(guī)出現(xiàn),并且器件會如預想那樣工作?,F(xiàn)在我們再考慮另外一種情況,同樣的時鐘上電后的相位關(guān)系如圖6-5所示。
圖6-5:會造成時序違規(guī)的時鐘相位關(guān)系
圖6-5中兩個時鐘之間的這種相位關(guān)系就會造成時序問題。這種情況會在任意頻率的兩個時鐘域之間。然而,如果時鐘的頻率匹配不對,這種時序問題在這種情況下也不會發(fā)生。
總結(jié)來說,時鐘同步問題在FPGA設(shè)計中通常是一種不可復現(xiàn)的問題,而且會對設(shè)計的可靠性帶來嚴重后果。后面我們會討論解決這類問題的方案,在此之前,我們必須要討論當建立和保持時間違規(guī)時到底會發(fā)生什么。下一小節(jié)就是關(guān)于這個主題。
6.1.1 亞穩(wěn)態(tài)
觸發(fā)器的建立時間和保持時間在時鐘上升沿左右定義了一個時間窗口,如果觸發(fā)器的數(shù)據(jù)輸入端口上數(shù)據(jù)在這個時間窗口內(nèi)發(fā)生變化(或者數(shù)據(jù)更新),那么就會產(chǎn)生時序違規(guī)。存在這個時序違規(guī)是因為建立時間要求和保持時間要求被違反了,此時觸發(fā)器內(nèi)部的一個節(jié)點(一個內(nèi)部節(jié)點或者要輸出到外部節(jié)點)可能會在一個電壓范圍內(nèi)浮動,無法穩(wěn)定在邏輯0或者邏輯1狀態(tài)。換句話說,如果數(shù)據(jù)在上述窗口中被采集,觸發(fā)器中的晶體管不能可靠地設(shè)置為邏輯0或者邏輯1對應的電平上。所以此時的晶體管并未處于飽和區(qū)對應的高或者低電平,而是在穩(wěn)定到一個確定電平之前,徘徊在一個中間電平狀態(tài)(這個中間電平或許是一個正確值,也許不是)。如圖6-6所示,這就是所謂的亞穩(wěn)態(tài)。
圖6-6:時序違規(guī)導致亞穩(wěn)態(tài)
如圖6-6的波形所示,信號的跳變發(fā)生在建立和保持邊界組成的時間窗口內(nèi),這意味著輸出不會是邏輯0或邏輯1對應的確定電平,而是它們之間的一個中間電平。如果觸發(fā)器包含有一個輸出緩沖,那么亞穩(wěn)態(tài)本身就可以稱為隨著內(nèi)部信號的逐漸穩(wěn)定而在輸出上表現(xiàn)的雜散過渡。輸出保持亞穩(wěn)態(tài)的時間是隨機的,甚至可能在整個時鐘周期內(nèi)都保持亞穩(wěn)態(tài)。那么,如果這個亞穩(wěn)態(tài)值輸入到組合邏輯,根據(jù)邏輯門電路的切換門檻,錯誤的操作就可以發(fā)生。從時序收斂的角度來說,兩個觸發(fā)器之間的組合邏輯延時都要求要小于最小的時鐘周期,但是這種亞穩(wěn)態(tài)信號保持亞穩(wěn)態(tài)的時間,本身就是變相地增加了邏輯延時。很顯然,一個亞穩(wěn)態(tài)信號會給設(shè)計帶來致命的功能故障,而且該信號也將無法在各個時鐘沿上采集到一致的結(jié)果。
事實上需要注意的是,在FPGA設(shè)計流程中想通過仿真來確定亞穩(wěn)態(tài)對設(shè)計的危害是非常困難的。純數(shù)字的仿真器并不能檢查到建立和保持違規(guī),從而在違規(guī)發(fā)生時,仿真出一個邏輯“X”(未知)值。而普通的RTL仿真,并不會出現(xiàn)建立和保持違規(guī),所以也就不會有信號出現(xiàn)亞穩(wěn)態(tài)狀態(tài)。盡管門級仿真的時候會檢查建立和保持是否違規(guī),但是仿真由兩個異步信號對齊而導致一個同步故障依然是一件十分困難的事情。尤其困難的是,設(shè)計或者驗證工程師并不是在設(shè)計伊始即查找問題。那么,理解如何保持設(shè)計的可靠性以及如何避免需要通過仿真來揭露設(shè)計的同步問題,就顯得十分重要了。解決亞穩(wěn)態(tài)的方法有很多,后面我們將逐一進行討論。
[page]
6.1.2 解決亞穩(wěn)態(tài)方案1:相位控制
考慮這樣一個設(shè)計,兩個時鐘域的周期不同,而且相位關(guān)系任意。如果至少有一個時鐘由FPGA內(nèi)部的PLL或者DLL控制,而且在PLL或者DLL的精度范圍內(nèi),其中一個時鐘的周期是另外一個時鐘周期的數(shù)倍。那么如圖6-7所示,通過相位對齊可以避免實現(xiàn)違規(guī)。
考慮這樣一個例子,一個信號從低速時鐘域傳遞進入另一個時鐘域,而此時鐘域的周期是低速時鐘域的一半。根據(jù)前面的分析,如果沒有任何相位關(guān)系的保證,那么時序違規(guī)就有可能發(fā)生。然后,通過使用DLL由低速時鐘派生這個高速時鐘,那么相位對齊就可以達成。
圖6-7中,DLL調(diào)整高速時鐘(采集)的相位來對齊低速時鐘(發(fā)送)。數(shù)據(jù)在兩個時鐘域之間傳遞的時間是dC,該傳遞時間總是處于其最大可能值。本例中,只要從低速觸發(fā)器到高速觸發(fā)器的傳播延時小于高速時鐘周期,那么就不會有建立時間違規(guī)發(fā)生。如果因為時鐘歪斜不夠小而導致保持時間要求無法滿足,那么可以通過配置實用高速時鐘的下降沿來采集信號,當然前提是有足夠的時序余量能確保建立時間要求得到滿足。
圖6-7:使用DLL對齊相位
總結(jié)來說,相位控制技術(shù)可以在一個時鐘頻率是另外一個時鐘的數(shù)倍且其中一個時鐘可以由FPGA內(nèi)部PLL或者DLL控制時使用。
在很多例子中,設(shè)計控制時鐘域之間的相位關(guān)系是很奢侈的。尤其是時序要求由FPG**外的芯片施加,或者時鐘域之間沒有任何確定相位關(guān)系的時候。舉例來說,如果FPGA在兩個系統(tǒng)之間提供了一個接口,而這兩個系統(tǒng)施加在芯片輸入輸出延時上的時序要求非常緊張,調(diào)整任何這兩個系統(tǒng)的時鐘相位是不可能的。類似這種例子在實踐中會經(jīng)常遇到,所以需要使用新的方法來解決,下一節(jié)將討論這種新的方法。
6.1.3 解決亞穩(wěn)態(tài)方案2:打兩拍處理,即寄存兩拍
跨越兩個異步時鐘域傳輸單比特信號時,可以使用打兩拍技術(shù)。根據(jù)上一節(jié)的討論,建立或保持時間違規(guī)會導致一個觸發(fā)器內(nèi)節(jié)點上電平徘徊在一個中間狀態(tài),從而產(chǎn)生亞穩(wěn)態(tài)問題,而且信號從這種中間狀態(tài)到一個穩(wěn)定狀態(tài)需要時間,此時間的長度未知。這個未知的時間會被加入到時鐘到輸出的時間(Tco)里(影響隨后路徑上的延時),且會在下一級導致一個時序違規(guī)。如果該信號輸入到一個控制分支或者一個判決樹,那將是非常危險的。不幸的是,沒有很好的辦法來預測這種亞穩(wěn)態(tài)將會持續(xù)多長時間,也沒有很好的辦法將這些信息反標注到時序分析工具以及優(yōu)化工具。假定兩個時鐘域之間完全異步(即無法實現(xiàn)相位控制),那么盡可能避免亞穩(wěn)態(tài)的一個最簡單辦法就是使用雙觸發(fā)。在其它也許教科書中也稱這種方法為同步位、兩級觸發(fā)器或兩級同步器。
圖6-8所示的配置中,同步器電路(其輸入為Din)中的第一拍后也許會產(chǎn)生亞穩(wěn)態(tài),但是信號有機會在其被第二級鎖存以及被其它邏輯看到之前穩(wěn)定下來,如圖6-9所示。
圖6-8:打兩拍處理
圖6-9:打兩拍重同步器
圖6-9中,Dsync是同步器中第一個觸發(fā)器的輸出,而Dout是第二個觸發(fā)器的輸出。Dout本質(zhì)上是等到同步后的信號一旦穩(wěn)定下來后將其往下傳,并且確保其它電路不會收到亞穩(wěn)態(tài)信號。同步器兩級觸發(fā)器之間不要添加任何邏輯,這樣可以使得信號獲得盡可能長的時間來回到穩(wěn)定狀態(tài)。所以總結(jié)來說,打兩拍同步器在單比特信號跨異步時鐘傳輸時,用來將該單比特信號重新同步到異步時鐘域。
理論上來說,第一個觸發(fā)器的輸出應該一直保持不確定的亞穩(wěn)態(tài),但是在現(xiàn)實中它會受到實際系統(tǒng)一系列因素影響后穩(wěn)定下來。打個比方,想象一下一個皮球穩(wěn)定地停住在一個山尖上,從任何方向上輕推一下球,它都會由相反的方向從山上滾落。同樣,處于亞穩(wěn)態(tài)的一個邏輯門,由發(fā)熱、輻射等產(chǎn)生的隨機波動都會促使該亞穩(wěn)態(tài)回到邏輯0或者邏輯1對應的穩(wěn)態(tài)。
使用打兩拍技術(shù)采樣一個異步信號時,無法完全預知我們想要的信號跳變,將在當前時鐘發(fā)生還是下一個時鐘發(fā)生。當信號屬于一個數(shù)據(jù)總線中的一部分(有些數(shù)據(jù)位比其它比特晚一個時鐘周期跳變)時,或者關(guān)鍵數(shù)據(jù)必須要精確到單個時鐘周期內(nèi)到達時,這種打兩拍技術(shù)是沒有幫助的。不過,對于控制信號來說,如果它們可以忍受正負一個或更多個時鐘周期的變化,這種技術(shù)還是非常有用的。
舉例來說,一個外部事件控制一個比特來觸發(fā)FPGA內(nèi)部動作,這個觸發(fā)動作發(fā)生的頻率可以非常的低,比如兩個事件之間的間隔可以達到微秒甚至毫秒級。在這個例子中,一些額外的數(shù)納秒的延時并不會影響該事件的行為。如果由外部事件驅(qū)動的改比特輸入到一個狀態(tài)機的控制結(jié)構(gòu)中,通過同步器打兩拍處理,那么想要的信號變化只是被延遲了一個時鐘周期。然而,如果沒有進行打兩拍處理,那么判決邏輯也許會從該異步信號的亞穩(wěn)態(tài)狀態(tài)解碼出不同狀態(tài)跳轉(zhuǎn)信息,并使得狀態(tài)機同時跳轉(zhuǎn)到不同的分支。
除了純數(shù)字系統(tǒng)外,還有一種混合信號系統(tǒng),這種系統(tǒng)會通常會產(chǎn)生異步反饋信號到FPGA,如圖6-10所示。
圖6-10:重新同步模擬反饋
上述對異步信號打兩拍的同步器的Verilog代碼如下所示:
module analog_interface(
...
output regfbr2,
input feedback);
reg fbr1;
always @ (posedge clk) begin
fbr1<=feedback;
fbr2<=fbr1;//;doubleflop
end
...
反饋信號會產(chǎn)生時序違規(guī),而且fbr1在時鐘沿后一個不確定的時間內(nèi)處于亞穩(wěn)態(tài)。那么,其它邏輯只可以使用的信號fbr2。
使用打兩拍同步處理技術(shù)時指定時序約束是非常重要的,需要施加的約束是將位于第一個和第二個寄存器時鐘域之間的信號路徑指定為假路徑,即讓時序分析器部分此路徑。因為打兩拍同步器結(jié)構(gòu)用于重新同步信號,在這兩個時鐘域之間并沒有需要分析的同步路徑。此外,如前所述這兩個觸發(fā)器之間的時序要盡可能的小,這樣可以減小亞穩(wěn)態(tài)被傳播到第二級觸發(fā)器的可能性。
[page]
6.1.4 解決亞穩(wěn)態(tài)方案3:使用FIFO結(jié)構(gòu)
跨時鐘域傳輸數(shù)據(jù)用得最多的方法就是使用先入先出(即FIFO)結(jié)構(gòu)。FIFO可以用于在兩個異步時鐘域之間傳輸多個比特信號。我們通??吹降腇IFO應用包括在兩個標準總線之間傳輸數(shù)據(jù),以及從可突發(fā)訪問的存儲器中讀出數(shù)據(jù)或者對其寫入數(shù)據(jù)。例如,如圖6-11所示,顯示的是一個可突發(fā)訪問存儲器與一個 PCI總線之間的接口。
圖6-11:FIFO在PCI應用中
在很多不同的應用中,F(xiàn)IFO都是一種非常有用的數(shù)據(jù)結(jié)構(gòu),不過這里我們僅僅關(guān)注其處理跨時鐘域突發(fā)數(shù)據(jù)的能力。
FIFO非常類似于在超市里的結(jié)賬通道,每個客戶到達結(jié)賬臺的時間多少有點隨機性,結(jié)賬速度在一定意義上說是勻速的。有時候結(jié)賬客戶可能會很少,而其他某些時候又會突發(fā)很多客戶需要結(jié)賬,收款員不可能立刻為每個客戶服務(wù),所以需要排隊。抽象地來說,我們稱這種排成一隊的數(shù)據(jù)為一個序列。隨后,收款員會以或多或少平均的速度為每一個顧客服務(wù),并不會理會隊列的長度。假如需要結(jié)賬的顧客涌入收銀臺的速度超過了收款員的服務(wù)速度,那么這種收款結(jié)構(gòu)就無法支撐了。那么此時,就需要采取措施,要么加快收款員的服務(wù)速率,要么減少新增顧客數(shù)。
同樣的道理也存在于數(shù)據(jù)傳輸中,數(shù)據(jù)可能到達某個時鐘域的間隔是完全隨機的,有時候或許會面臨一個很大突發(fā)數(shù)據(jù)塊。這種情況下,處在另一個時鐘域的接收設(shè)備只能以指定的速率來處理數(shù)據(jù)。如圖6-12所示,一個FIFO被用于緩存數(shù)據(jù),這樣在設(shè)備中就形成了一個數(shù)據(jù)序列。
圖6-12:異步FIFO
通過使用異步FIFO,數(shù)據(jù)發(fā)送端可以以隨意的間隔發(fā)送數(shù)據(jù),而接收端也可以以其固有的帶寬從數(shù)據(jù)序列里取出數(shù)據(jù)并進行處理。由于任何由FIFO實現(xiàn)的數(shù)據(jù)序列的長度都不能無限制,所以需要一些控制來防止FIFO溢出。這時候,有兩種選項可以采用:
l 事先定義好的發(fā)送速率(可突發(fā)或不可突發(fā)),最小接收速率以及對應最大的序列尺寸。
l 握手控制。
注意,發(fā)送設(shè)備的時鐘頻率沒有必要高于接收端設(shè)備,否則容易造成溢出。以較慢的頻率將數(shù)據(jù)送入FIFO,那么數(shù)據(jù)寫入FIFO的時鐘周期數(shù)要少于接收端將要處理數(shù)據(jù)的時鐘周期數(shù)。那么,如果不采取握手控制,就必須要理解以上描述會產(chǎn)生溢出的最壞的情況。
在任何一段時間內(nèi),假設(shè)數(shù)據(jù)發(fā)送寫FIFO的速率大于接收處理數(shù)據(jù)的速率,那么很輕易地使系統(tǒng)無法維持。因為沒有任何存儲設(shè)備可以存得下無限的數(shù)據(jù),這種問題需要在系統(tǒng)結(jié)構(gòu)層級才能解決。通常來說,突發(fā)發(fā)送一般是以小周期性或非周期性發(fā)生。所以FIFO的最大尺寸要大于等于(具體還要根據(jù)數(shù)據(jù)接收器的屬性)突發(fā)的尺寸。
在很多例子中,不管是突發(fā)尺寸還是數(shù)據(jù)到達的分配都無法很好地定義。這種時候,就有必要使用握手控制來防止FIFO產(chǎn)生數(shù)據(jù)溢出。如圖6-13所示,這種握手控制通常由一些標志信號來實現(xiàn)。這些標志信號,一個是發(fā)送側(cè)的滿標志,用于提示FIFO沒有多余空間存儲數(shù)據(jù)了,另一個是而空標志,用于提示接收側(cè),F(xiàn)IFO中沒有數(shù)據(jù)需要處理了。管理這些握手信號可能還需要一個狀態(tài)機,正如圖6-13所示。
圖6-13:FIFO的握手控制
FIFO在FPGA內(nèi)一般是通過封裝一個雙口RAM來實現(xiàn)。表面上看微不足道的標志信號如空和滿指示等,實際上是實現(xiàn)起來反而比較困難。原因就在于輸入控制常常需要依據(jù)輸出來產(chǎn)生,同樣的輸出控制也常常需要依據(jù)輸入來產(chǎn)生。例如,驅(qū)動輸入的邏輯必須要知道FIFO是否已滿,而這只能通過獲取從輸出端讀出的數(shù)據(jù)數(shù)量才能得知。同樣的道理,在輸出側(cè)從FIFO讀數(shù)據(jù)的邏輯必須要了解FIFO中是否還有數(shù)據(jù)(即FIFO是否已空),而這只能通過輸入端口的寫指針才能判決。
這里我們探討使用FIFO在兩個異步時鐘域之間傳輸數(shù)據(jù),不過同樣會面臨實現(xiàn)FIFO本身時遇到的握手標志問題。為了在兩個時鐘域之間傳遞必要的信號,我們必須重回上一節(jié)討論到的打兩拍技術(shù)。下面我們以圖6-14所示的簡單異步FIFO框圖為例進行闡述。
圖6-14:異步FIFO簡單框圖
圖6-14中,在產(chǎn)生空和滿信號時,寫地址和讀地址都必須是異步傳遞到對方時鐘域中。這樣在重新同步多比特地址總線時,問題就來了,即根據(jù)各個比特不同的走線,總線中某些比特可能會比其它比特晚一個時鐘周期。換句話說,由于兩個時鐘域異步的自然屬性,使得地址總線有些比特在一個時鐘沿上被采集,而另一些比特卻在下一個時鐘沿上被采集,當然這取決于數(shù)據(jù)是否在第一個觸發(fā)器的時鐘沿到達之前提前足夠長時間有效。如果上述情況發(fā)生,那么會給系統(tǒng)帶來嚴重后果,因為二進制地址中有些位變化有些位卻沒有,因此接收邏輯將會得到一個完全無效的地址,這個地址既不是當前地址也不是上一個地址。
這個問題可以通過將二進制地址轉(zhuǎn)換為格雷碼來解決。格雷碼是一種非常特殊的計數(shù)器,兩個相鄰地址中只有一個比特是不同的。所以當?shù)刂犯淖儠r,只需要改變地址中的一個比特即可,這樣就可以避免上面提到的問題。如果發(fā)生變化的那個比特并沒有被下一個時鐘正確采集,地址線上會“同步地”保留舊的地址值。那么,任何不正確的地址(即既不是當前地址也不是舊地址)操作都被消除了。所以總結(jié)來說,格雷碼常用來在異步時鐘域之間傳遞多比特計數(shù)值,且多用于FIFO內(nèi)。
需要額外注意的一點是,由于只有讀寫地址是需要在異步時鐘域之間傳遞,所以地址就有可能比預想的晚一個時鐘周期,同時意味著空或者滿標志置位晚一個時鐘周期,但是這并不表示錯誤導致了數(shù)據(jù)溢出狀況。如果這種情況在傳遞地址到讀時鐘域時,讀邏輯將簡單地認為數(shù)據(jù)沒有寫入,且將認為FIFO已空盡管此時 FIFO已經(jīng)被寫入一個數(shù)據(jù)。這只會對總的吞吐率有一些小影響,但是不會導致下溢(即讀已空的FIFO)狀況發(fā)生。同樣地,當?shù)刂繁粋鬟f到寫時鐘域時,如果讀地址被延時了,那么寫邏輯會認為FIFO里沒有多余空間,盡管此時FIFO還未滿。這同樣只會對總的數(shù)據(jù)吞吐率有些微小影響,卻不會造成上溢(寫已滿的FIFO)發(fā)生。
FIFO是一種足夠通用的模塊,大部分FPGA供應商都提供了工具,可以讓客戶根據(jù)自己的要求來自動產(chǎn)生軟核。這些用戶FIFO可以像其它IP模塊那樣由用戶手動地在設(shè)計中例化。那么,在一個FPGA設(shè)計中使用自己的FIFO時,上述討論的問題很可能將不必由設(shè)計自己來解決。當然,同樣的問題也經(jīng)常在異步時鐘域之間傳遞數(shù)據(jù)的時候發(fā)生,所以理解這類設(shè)計實踐對于一個高級FPGA設(shè)計者來說非常重要。
[page]
6.1.5 設(shè)計分區(qū)同步器模塊
在頂層為設(shè)計劃分好設(shè)計分區(qū)是一個好的設(shè)計實踐行為,這樣任何功能模塊外面都包含一個獨立的同步器模塊。這樣有利于在劃分模塊的基礎(chǔ)上實現(xiàn)所謂的理想時鐘域情況(即整個設(shè)計模塊只有一個時鐘),如圖6-15所示。
圖6-15:設(shè)計分區(qū)同步器模塊
對設(shè)計進行分區(qū)有很多理由。首先,對每個獨立的功能模塊進行時序分析變得簡易,因為模塊都是完全的同步設(shè)計。其次,整個同步模塊中的時序例外也很容易得到定義。再次,底層模塊的同步器加時序例外在代入到設(shè)計頂層時,大大降低了由于人為失誤造成的疏漏。所以,同步寄存器應該在功能模塊外單獨分區(qū)。還有很多類似的設(shè)計實踐在使用FPGA作為ASIC的設(shè)計原型時得到應用,下一節(jié)我們將再進行詳細地討論。
6.2 ASIC原型設(shè)計中的門控時鐘
ASIC設(shè)計一般對功耗非常敏感,同時ASIC的時鐘樹設(shè)計又非常靈活,所以會在整個設(shè)計中經(jīng)常使用門控時鐘在邏輯不需要活動的時候來去使能這些邏輯。雖然使用FPGA作為ASIC的原型可以模擬整個邏輯功能,但是二者之間的有些物理屬性,如功耗方面,還是不太一樣。那么,要求FPGA來模擬ASIC的整個低功耗優(yōu)化是沒有必要的。實際上,正是由于FPGA的粗放式的時鐘資源,讓其模擬這方面功能也是不太可能的。這一節(jié)我們將討論一些解決這個問題方法,并且再討論一些可以應用于ASIC設(shè)計的技術(shù)來使FPGA原型設(shè)計更加容易。對于門控時鐘更詳細的容易可以參考前面第三章。
6.2.1 時鐘模塊
如果一個ASIC設(shè)計中使用了大量的門控時鐘,建議將所有這些門控操作統(tǒng)一放在一個專門的時鐘生成模塊中,并與功能模塊隔離,如圖6-16所示。
圖6-16:統(tǒng)一的時鐘模塊
通過將時鐘門控置于一個單一的模塊,不但可以是約束處理更簡單,而且當要對FPGA原型進行任何修改時也更容易。例如,如果設(shè)計者選擇某次編譯時刪除所有門控單元,那么一個單一的模塊里很容易實現(xiàn)。下一節(jié)我們將對此進行詳細討論。
6.2.2 時鐘門控移除
有很多辦法可以從FPGA原型里刪除時鐘門控,下面的例子就顯示了一個很明顯,但卻也是很麻煩的一個方法。這個例子的代碼如下所示,該代碼是刪除FPGA原型里所有的門控功能。
‘define FPGA
//‘define ASIC
module clocks_block(...)
‘ifdef ASIC
assign clock_domain_1=system_clock_1&clock_enable_1;
‘else
assign clock_domain_1=system_clock_1;
‘endif
如果上述代碼需要開放時鐘門控,那么在FPGA原型設(shè)計中只需要修改宏定義即可。不足之處是,任何時候要將FPGA原型轉(zhuǎn)化為ASIC設(shè)計時總是需要做出一些修改(其實就是修改宏定義)。很多設(shè)計者對此會感覺不是太舒服,因為他們認為二者使用的不是一樣的RTL。一個更好的辦法是使用一個自動門控刪除工具來消除任何認為造成失誤的可能。許多現(xiàn)代的綜合工具通過正確的約束,現(xiàn)在都提供這項功能。例如,Synplify就有一個稱為“Fix gated clocks”選項,就是用于自動地從時鐘線上將門控操作刪除,并將其移動到數(shù)據(jù)路徑上。我們來看下面這個代碼示例:
module clockstest(
output reg oDat,
input iClk,iEnable,
input iDat);
wire gated_clock=iClk&iEnable;
always @ (posedge gated_clock)
oDat<=iDat;
endmodule
在上面的代碼中,系統(tǒng)時鐘被一個使能信號門控產(chǎn)生一個門控時鐘。這個門控時鐘被用于驅(qū)動觸發(fā)器oDat,而oDat用于寄存器輸入iDat。如果沒有啟用“fixing the clock gating”選項,那么綜合工具將會直接實現(xiàn)邏輯功能,如圖6-17所示。
圖6-17:直接時鐘門控
圖6-17的邏輯實現(xiàn)中,在時鐘線上放置了門控操作。那么設(shè)計中現(xiàn)在有了兩個時鐘域,必須分別對它們進行約束,而且必須分別將它們布局到時鐘資源。但是,如果啟動了時鐘門控刪除,這個邏輯門就會比較容易地被移動到數(shù)據(jù)路徑上,如圖6-18所示。
圖6-18:時鐘門控刪除
現(xiàn)在大部分邏輯器件里邏輯單元都提供了一個時鐘使能輸入,有了該使能輸入就可以不使用本方案。然而,如果一個特定的技術(shù)并未提供觸發(fā)器時鐘使能,那么只能使用本技術(shù)來刪除時鐘門控,只是這樣就將會在數(shù)據(jù)路徑上增加延時。
6.3要點總結(jié)
l 時鐘同步問題通常是不可復現(xiàn)的問題,并且會給FPGA設(shè)計帶來可靠性問題。
l 亞穩(wěn)態(tài)會給FPGA帶來災難性故障。
l 相位控制技術(shù)在一個時鐘頻率是另外一個的數(shù)倍且其中一個時鐘可以由內(nèi)部PLL或者DLL控制的時候使用。
l 打兩拍技術(shù)可用于在異步時鐘域之間同步單比特信號。
l 在打兩拍同步器中,時序分析應該忽略第一個觸發(fā)器,同時要確保兩個同步觸發(fā)器之間的延時最小。
l FIFO用于在兩個異步時鐘域之間傳遞多比特信號。
l 格雷碼用于在兩個異步時鐘域之間傳遞計數(shù)值數(shù)據(jù),而且多用在FIFO內(nèi)部。
l 同步寄存器應該在功能模塊外面獨立分區(qū)。
l 如果可能,請盡量不要使用時鐘門控。若必須使用,請將所有的門控時鐘放置在一個專門的時鐘模塊中,并與其它功能模塊隔離。
相關(guān)閱讀:
【原創(chuàng)】初學者實用:數(shù)電和FPGA中常用觸發(fā)器的介紹
Altera的FPGA和SoC技術(shù)在DesignCon中贏得了設(shè)計創(chuàng)意獎
使用FPGA進行工業(yè)設(shè)計的五大優(yōu)勢