天津中興軟件有限責任公司 周恒箴
中興通訊股份有限公司 高鳳玲
隨著數字系統的規模越來越大、復雜程度越來越高,兩個或多個時鐘域在邏輯設計中的應用越來越多。在不同的時鐘域中,不可避免地會遇到數據的互相傳遞。由于兩個不同的時鐘之間會存在一定的相位差和短時的頻率抖動,為了使數據能夠可靠傳輸,在進行設計時,必須充分考慮時序對功能的影響,否則會照成兩個時鐘域之間的數據同步失敗。
將數據由異步時鐘域轉換到同步時鐘域通常采用雙口RAM緩存數據的方法來實現:用異步時鐘作為雙口RAM的寫時鐘,寫時鐘產生雙口RAM的寫地址,由寫時鐘在一個端口寫入數據;再用同步時鐘作為讀時鐘,并產生雙口RAM的讀地址,讀時鐘在另一個端口讀出數據;該雙口RAM深度是根據需要容忍的短時頻差范圍來確定。分別將讀寫地址用同步時鐘采樣并進行比較,以判斷讀寫地址之間的距離是否小于可能發生讀、寫沖突的最小距離,即“危險距離”[1-2],如果是,則將讀地址跳轉,轉到離當前位置最遠的地址后,再執行讀操作;否則不必調整讀地址,直接執行讀操作。這樣讀出來的數據時穩定且正確的,且屏蔽了異步時鐘和本地同步時鐘之間的相位差以及短時的頻率抖動。在讀寫指針沖突解決好后,可以有效處理異步時鐘域的數據同步問題。上述方法的缺陷在于需要依賴可編程邏輯器件中的RAM資源,此外,同步數據的延時時間較長,需要根據雙口RAM設計的深度決定。
本文在FPGA上通過解復用、復用實現數據同步,該方法不僅適用于兩個同源但傳輸延時有變化的時鐘,也可以適用于非同源的異步時鐘,該方法能減少數據傳輸的延時的同時,可以有效地節省可編程邏輯的資源,不占RAM資源。
FPGA的實現方法如圖1所示,由解復用模塊、同步模塊、復用模塊共3個功能模塊組成。

圖1 FPGA實現流程圖
解復用模塊用異步時鐘對異步數據進行1∶N解復用,使數據的速率下降到原來的1/N,解復用輸出N路數據。并對異步時鐘計數,輸出sync信號。
圖2所示是解復用和復用實現數據同步的時序圖,該異步時鐘采用上升沿處理,在t0時刻對輸入數據開始解復用,解復用后分別在接下來的t(1)到t(N)的N個時鐘周期,分別輸出D0、D1、D2、….DN-1共N路解復用的數據信號,數據的寬度為N個異步時鐘周期,sync信號以2N個異步時鐘寬度為周期,每N個異步時鐘寬度發生電平跳變,在t0時刻跳變,和D0位置對齊。

圖2 解復用和復用實現數據同步的時序圖
需要說明的是:sync的周期T是N的整數倍,為了保證同步時鐘能夠可靠采樣到,推薦sync的脈沖寬度至少大于2個異步時鐘周期。
同步模塊主要是用本地時鐘對異步的sync信號進行同步采樣,再對采樣后的信號計數。首先,解復用模塊輸出的sync信號送入同步模塊中進行同步處理。同步模塊采用同步時鐘作為主時鐘,圖3所示是同步模塊的結構示意圖,sync信號先送入信號同步單元內,信號同步單元用同步時鐘的上升沿或者下降沿對異步sync信號進行采樣,分別輸出同步1拍的信號sync1和同步2拍后的sync2信號給判斷模塊單元,用同步時鐘下降沿采sync信號,在k0時刻輸出sync1,在k1時刻輸出sync2。
其次,判斷模塊單元進行跳變沿的判斷:當同步時鐘判斷sync1不等于sync2時,發出沿觸發信號給M位計數器單元進行計數,M位計數器單元最后再將計數器的計數結果送給復用模塊。圖3所示的y0時刻出發信號給M位計數器單元進行計數。
M位計數器,M的取值為log2N的上取整(即M=┏log2N┐),該M位計數器的調整策略為:
(1)從0到N-1進行計數。當計數器記到為N-1時,再跳變為0。
(2)在沿觸發的y0時刻,如果上一次的計數值沒有超過預計的范圍,則不用調整,繼續按(1)進行計數,如果超過預計的范圍,則計數器清0。例如N=4時,預計的范圍為3、0、1,計數在此范圍不進行調整,直接加1;如果為2,表示超過范圍,需要調整為0。
復用模塊采用同步時鐘作輸入時鐘,按照同步輸出的同步計數器數值依次對解復用數據D0D1D2….DN-1進行采樣,并N∶1復用輸出。例如圖2所示,在y1時刻輸出D0,在y2時刻輸出D1,在y3時刻輸出D2,在y(N)時刻輸出DN-1。

圖3 同步模塊單元的結構圖
以下是利用該方法在Altera FPGA器件上設計一個同源的、但有傳輸延時變化的時鐘之間的數據同步:圖4是利用解復用/復用方法實現數據同步過程的時序圖。

圖4 FPGA實例利用復用、解復用實現數據同步過程時序圖
(1)先用異步時鐘I_clk_wr對輸入數據i_data將進行1∶3解復用,解復用出8路解復用后的數據S0_i_data、S1_i_data、S2_i_data和1路同步信號S_sync。
(2)在同步模塊單元中,信號同步模塊采用同步時鐘I_clk_rd的下降沿對輸入的S_sync進行兩次同步,S_sync1和S_sync2。
判斷模塊進行跳變沿的判斷:當同步時鐘判斷S_sync1不等于S_sync2時,發出沿觸發信號給2位計數器模塊進行計數M=┏log23┐=2,S_flag_cnt是3位的計數器,該計數器的預計范圍2,當計數到2時,再跳變為0。在輸出觸發信號的時刻需要判斷上一拍的計數器是否為2,如果是2,計數器變為0。如果不為2,則計數器清0,其他時刻計數器依次累加。
(3)復用模塊,采用同步時鐘I_clk_rd作采樣時鐘,按照同步計數器數值依次對解復用數據S0_i_data、S1_i_data、S2_i_data進行采樣,并3∶1復用輸出,圖4中的O_data為復用的輸出數據。
調用Altera的DPRAM IPcore生成雙口RAM濾波器模塊[8],設計一個位寬為8bit,深度為32字節的雙口RAM,與上述方法進行仿真對比,如圖5所示,O1_data是利用復用、解復用方法實現數據同步的輸出結果,O2_data是利用DPRAM IPCORE輸出的結果,對比數據,說明兩種方法的輸出數據一致。

圖5 與調用DPRAM IPCORE方法進行數據同步的結果對比
上述的查階躍響應法的實例只需要寄存器單元就可以實現,如果采用Altera Cyclone IV系列器件,型號為EP4CGX150(該器件具有149,760LEs(邏輯單元)和6,480Kbit嵌入式存儲器[9]),編譯工程進行對比,該方法只需要使用92LEs;而采用Altera DPRAM IPcore實現,需要占用32 LEs、256Memory Bits和1個M9K。如果輸入數據的位寬比較大,節約RAM的優勢更加明顯。因此,采用解復用/復用方法實現的數據同步,可以節省FPGA的RAM資源。
從仿真和實驗結果可以看出,解復用、復用實現數據同步的方法不僅可以適用于非同源的異步時鐘,也可以適用于同源但有傳輸延時變化的時鐘,這種方法能有效地減少數據傳輸的延時,如實例中延時小于3個時鐘周期;同時采用寄存器實現,有效地節省可編程邏輯的資源,不占RAM資源。
[1]莫毅群,方有綱,王峰.一種可編程邏輯器件實現數據交換的方法及其結構[P].CN200510130524.3,2005-12-14.
[2]孟慶鋒.一種將異步時鐘域轉換成同步時鐘域的方法[P].中國.CN03153668.9,2003-8-19.
[3]傅仙偉,趙翠芳,張長江.基于FPGA的高速采樣系統實現[J].微型機與應用,2012,31(6):19-21.
[4]謝修祥,王廣生.異步多時鐘系統的同步設計技術[J].電子工程師,2005,31(5):33-37.
[5]陳立萬,黃青龍,劉萬里.基于FPGA的數據采集系統的設計[J].合肥工業大學學報(自然科學版),2011,34(3):359-362.
[6]柳震,郭黎利,王鵬宇.通信數據同步中基于FPGA的一種有限任意長FIFO的生成辦法[J].自動化技術與應用,2011(3):40-42.
[7]廖艷,王廣君,高楊.FPGA異步時鐘設計中的同步策略[J].自動化技術與應用,2006,25(1):67-68.
[8]Altera Corporation.Internal Memory(RAM and ROM)User Guide[M].2012.11:Chapter 3.
[9]Altera Corporation.Cyclone Device Handbook[M].2012,10,Volume 1.