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