董 劍,李同合
(西安交通大學(xué) 電子與信息工程學(xué)院微電子學(xué)系,陜西 西安 710049)
在USB數(shù)據(jù)傳輸中,為了保證數(shù)據(jù)的可靠性,需要對(duì)所傳輸?shù)臄?shù)據(jù)進(jìn)行NRZI編解碼、添加/去除位填充和串并/并串轉(zhuǎn)換[1-3]。NRZI編碼可以保證有足夠的跳變沿在接收端進(jìn)行時(shí)鐘恢復(fù);位填充是為了保證信號(hào)具有足夠的變化量;串并轉(zhuǎn)換可以降低后端數(shù)據(jù)處理模塊的工作頻率。
以USB 2.0設(shè)備控制器為例。在向主機(jī)發(fā)送數(shù)據(jù)時(shí),其收發(fā)器模塊先要將協(xié)議層傳來的8位(或16位)并行數(shù)據(jù)轉(zhuǎn)換成串行數(shù)據(jù),然后添加位填充(每6個(gè)連續(xù)的1后要加入一個(gè)0),最后進(jìn)行NRZI編碼。反之,在接收主機(jī)發(fā)來的數(shù)據(jù)時(shí),收發(fā)器模塊要先對(duì)數(shù)據(jù)進(jìn)行NRZI解碼,再去除位填充,最后轉(zhuǎn)換成8位(或16位)并行數(shù)據(jù)傳給協(xié)議層[4-6]。
USB 2.0設(shè)備控制器的收發(fā)器和后端協(xié)議層的工作時(shí)鐘頻率不同。對(duì)于具有高速(480 Mb/s)和全速(12 Mb/s)兩種傳輸速度的USB 2.0設(shè)備控制器來說,收發(fā)器在高速、全速模式下的工作時(shí)鐘頻率分別為480 MHz和12 MHz;而協(xié)議層在高速、全速模式下的工作時(shí)鐘頻率統(tǒng)一為60 MHz(8位并行數(shù)據(jù)時(shí),對(duì)于16位并行數(shù)據(jù)為30 MHz)[1-3]。
由于添加/去除位填充導(dǎo)致了每字節(jié)數(shù)據(jù)傳輸所需的時(shí)間的增加或減少,再加上收發(fā)器和協(xié)議層工作時(shí)鐘頻率的差別,可能會(huì)導(dǎo)致數(shù)據(jù)的紊亂。
假設(shè)USB 2.0設(shè)備控制器的收發(fā)器工作時(shí)鐘為clk,協(xié)議層使用8位并行數(shù)據(jù),工作時(shí)鐘為60 MHz的phy_clk,分析數(shù)據(jù)紊亂產(chǎn)生的原因。
USB 2.0協(xié)議中定義了信號(hào)RxValid表示接收數(shù)據(jù)有效,在phy_clk上升沿,若RxValid=1,協(xié)議層可以從收發(fā)器提取8位并行數(shù)據(jù)使用[1-3]。RxValid信號(hào)變化后至少需要保持1個(gè)phy_clk周期,才能保證其被協(xié)議層的phy_clk時(shí)鐘采樣。
圖1中Data_nrzi為已經(jīng)過NRZI解碼的串行輸入數(shù)據(jù);drop_bit為去位填充提示,當(dāng)drop_bit=1時(shí)說明出現(xiàn)了連續(xù)6個(gè)數(shù)據(jù)1,其后的數(shù)據(jù)0為位填充位應(yīng)該除去,不放入hold_reg中;Data_nrzi經(jīng)過去位填充后放入 hold_reg中,hold_reg收集了8個(gè)Data_nrzi數(shù)據(jù)后,將這8個(gè)數(shù)據(jù)以并行數(shù)據(jù)DataIn的形式傳給協(xié)議層。
從圖1中可以看出,在處理第二組8位數(shù)據(jù)時(shí),由于其中有一個(gè)位填充需要去除,故處理這組數(shù)據(jù)用了9個(gè)clk周期,導(dǎo)致第一組8位并行數(shù)據(jù)在DataIn中的持續(xù)時(shí)間為9個(gè)clk周期,比正常多了1個(gè)clk周期。這樣有兩個(gè)缺點(diǎn):
1)1個(gè)phy_clk周期為8個(gè)clk周期,第1組8位數(shù)據(jù)持續(xù)9個(gè)clk周期有可能會(huì)被協(xié)議層采樣兩次。如圖1中所示,第1組數(shù)跨越了兩個(gè)phy_clk的上升沿,被采樣兩次。雖然出現(xiàn)這種情況的概率較小,但并不是不存在,且隨著位填充數(shù)量的增多,這種多次采樣的可能性會(huì)增大。
2)每當(dāng)位填充的個(gè)數(shù)達(dá)到8個(gè),輸出的DataIn被協(xié)議層采樣到的并行數(shù)據(jù)總量會(huì)比正確的情況多1個(gè),從而導(dǎo)致數(shù)據(jù)接收錯(cuò)誤。
為了避免上述錯(cuò)誤,通常的做法是每當(dāng)去除了8個(gè)位填充數(shù)據(jù)時(shí),就令RxValid=0并持續(xù)1個(gè)phy_clk周期,使協(xié)議層暫停采樣一次,從而避免第2)類錯(cuò)誤的發(fā)生[7-8]。但這種做法不能完全避免第1)類錯(cuò)誤的發(fā)生。
USB 2.0協(xié)議中同樣定義了信號(hào)TxReady表示收發(fā)器準(zhǔn)備好發(fā)送數(shù)據(jù),在phy_clk上升沿,若TxReady=1,協(xié)議層便傳輸過來1個(gè)8位并行數(shù)據(jù)讓收發(fā)器發(fā)送出去[1-3]。同理TxReady信號(hào)變化后也至少要保持1個(gè)phy_clk周期。
圖2中,TxReady由0變?yōu)?代表收發(fā)器已將包的同步域發(fā)送完畢,開始發(fā)送早已從協(xié)議層傳來的第1組8位并行數(shù)據(jù);DataOut為協(xié)議層傳來的8位并行數(shù)據(jù);在clk上升沿,將DataOut數(shù)據(jù)讀取到暫存器hold_reg中;sd_raw為并串轉(zhuǎn)換后的串行數(shù)據(jù);stuff為添加位填充信號(hào),當(dāng)連續(xù)出現(xiàn)6個(gè)1時(shí),stuff=1在串行數(shù)據(jù)中添加1位位填充數(shù)據(jù)0;sd_bs為添加位填充后的數(shù)據(jù),對(duì)sd_bs進(jìn)行NRZI編碼后即可發(fā)送給主機(jī)。
從圖2中可以看出,高速發(fā)送模式出現(xiàn)了兩類錯(cuò)誤:
1)TxReady由 0變?yōu)?后開始發(fā)送第1組 8位并行數(shù)據(jù),而當(dāng)phy_clk上升沿來臨后 DataOut和hold_reg先后變?yōu)榱说?組8位并行數(shù)據(jù),此時(shí)第1組數(shù)據(jù)并不一定恰好剛剛發(fā)完,于是會(huì)造成數(shù)據(jù)缺失或重復(fù)發(fā)送,同時(shí)使后面的數(shù)據(jù)發(fā)送混亂。圖2中Txready變?yōu)?后sd_raw發(fā)送的第1個(gè)數(shù)據(jù)1為同步域的最后一位,接著發(fā)送的數(shù)據(jù)00為第1組數(shù)據(jù)中的2位,其余6位還未發(fā)送hold_reg中的數(shù)據(jù)已變成了第2組并行數(shù)據(jù)。
圖2 高速發(fā)送數(shù)據(jù)模式Fig.2 High-speed send datamode
2)處理第2組并行數(shù)據(jù)時(shí),由于需要添加位填充,故第2組數(shù)據(jù)的處理時(shí)間需要9個(gè)clk周期。由于phy_clk的周期為8個(gè)clk周期,故第2組并行數(shù)據(jù)的持續(xù)時(shí)間為8個(gè)clk周期。于是第2組并行數(shù)據(jù)的最后一位還未發(fā)送,第3組數(shù)據(jù)已取代了第2組數(shù)據(jù)。
避免上述錯(cuò)誤的常用方法是令hold_reg在其暫存的8位數(shù)都轉(zhuǎn)換成串行數(shù)據(jù)sd_raw后再讀取DataOut中的數(shù),而不是在每個(gè)clk上升沿都讀取。同時(shí),每當(dāng)添加了8個(gè)位填充數(shù)據(jù),就令TxReady=0并持續(xù)1個(gè)phy_clk周期,從而令DataOut暫停變化一次[7-8]。這樣做雖然解決了上述問題,但卻帶來了一個(gè)新的錯(cuò)誤,如圖3所示。
圖3 添加位填充造成的數(shù)據(jù)丟失Fig.3 Data loss caused by bit stuffing
圖3中,共要發(fā)送4組并行數(shù)據(jù)。假設(shè)發(fā)送完同步域后,hold_reg恰好在第一組數(shù)據(jù)的最后進(jìn)行采樣,則處理第2組數(shù)據(jù)時(shí)需要添加2個(gè)位填充位,處理時(shí)間為10個(gè)clk周期。同時(shí)由于位填充沒有達(dá)到8個(gè),TxReady持續(xù)為1,DataOut每過8個(gè)clk就變換一次。結(jié)果導(dǎo)致第3組數(shù)據(jù)被錯(cuò)過,沒有被hold_reg采樣到。這種錯(cuò)誤的發(fā)生概率雖然很小,但不能完全避免。
全速模式下clk的頻率為12 MHz,即1個(gè)clk周期為5個(gè)phy_clk周期[1-3]。在接收數(shù)據(jù)時(shí),當(dāng)hold_reg集齊8位數(shù)據(jù)后,將其傳輸?shù)紻ataIn中
并令RxValid=1且持續(xù)1個(gè)phy_clk,其余時(shí)刻令RxValid=0;在發(fā)送數(shù)據(jù)時(shí),當(dāng)hold_reg中的8位數(shù)據(jù)全部轉(zhuǎn)換成串行數(shù)據(jù)后,令 TxReady=1并持續(xù)1個(gè)phy_clk,其余時(shí)刻令TxReady=0[7-8]。因而RxValid和TxReady信號(hào)為離散脈沖形式,且脈沖寬度為1個(gè)phy_clk周期,不會(huì)出現(xiàn)上述錯(cuò)誤。
綜上所述,USB 2.0傳輸中位填充造成數(shù)據(jù)總量的增減會(huì)影響數(shù)據(jù)傳輸?shù)臏?zhǔn)確性,需加以解決。
通過在收發(fā)器和協(xié)議層之間添加一個(gè)2×8位的異步FIFO[9]作為緩存區(qū),可以解決上述問題。如圖4所示,異步FIFO的讀操作與寫操作分別由兩個(gè)異步時(shí)鐘clk1和clk2控制,異步復(fù)位信號(hào)rst同USB設(shè)備控制器的復(fù)位信號(hào)相同。
圖4 讀寫異步FIFO示意圖Fig.4 Read and write asynchronous FIFO schematic
接收數(shù)據(jù)時(shí),當(dāng)hold_reg集齊8位數(shù)據(jù),可在clk時(shí)鐘控制下將其中的數(shù)據(jù)寫入FIFO中;而在phy_clk上升沿,若FIFO中有數(shù)據(jù),則令RxValid=1并讀出1組并行數(shù)據(jù)傳給協(xié)議層,否則令RxValid=0且不讀數(shù)據(jù)。經(jīng)分析,此處使用1×8位的FIFO足以滿足要求,不會(huì)出現(xiàn)FIFO中有數(shù)據(jù)未讀出新數(shù)據(jù)又寫入的情況,但為了保證不出現(xiàn)特殊情況,這里使用2×8位的FIFO,以保證可靠性。
發(fā)送數(shù)據(jù)時(shí),在phy_clk上升沿,若FIFO有空間,則令TxReady=1并將DataOut中的數(shù)據(jù)寫入FIFO,否則令TxReady=0且不寫入數(shù)據(jù),當(dāng)協(xié)議層數(shù)據(jù)全部發(fā)送完畢令TxReady=0;在FIFO寫滿的同時(shí)也令 TxReady=0;當(dāng) hold_reg中的數(shù)據(jù)全部轉(zhuǎn)換為串行數(shù)據(jù)后,在clk時(shí)鐘控制下從FIFO中取出一組數(shù)據(jù)放入hold_reg中;當(dāng)FIFO中沒有數(shù)據(jù)時(shí),說明數(shù)據(jù)發(fā)送完畢,可以發(fā)包結(jié)束符。
當(dāng)位填充較多致使數(shù)據(jù)處理時(shí)間過長(zhǎng),導(dǎo)致FIFO中沒有數(shù)據(jù)時(shí),RxValid變?yōu)榱?且持續(xù)了1個(gè)phy_clk周期。從圖中可看出輸出數(shù)據(jù)DataIn在RxValid=1時(shí)的寬度都為1個(gè)phy_clk周期,沒有出現(xiàn)多于1個(gè)phy_clk周期的情況。
圖6為高速發(fā)送模式的仿真結(jié)果。從圖中可以看出,收發(fā)器工作正常,避免了上述錯(cuò)誤的發(fā)生。在收發(fā)器還在發(fā)送同步域時(shí),協(xié)議層就已經(jīng)開始向FIFO中寫數(shù)據(jù),當(dāng)寫滿FIFO后,TxReady變?yōu)?,協(xié)議層暫停向FIFO傳輸數(shù)據(jù),直到FIFO有空間后才繼續(xù)傳輸數(shù)據(jù)。同步域發(fā)送完畢后,hold_reg從FIFO中取出數(shù)據(jù)并依次發(fā)送,沒有出現(xiàn)數(shù)據(jù)缺失或重復(fù)發(fā)送。從圖中可看出從協(xié)議層輸入的數(shù)據(jù)DataOut在TxReady=1時(shí)的寬度都為1個(gè)phy_clk周期,沒有出現(xiàn)多于1個(gè)phy_clk周期的情況,從而不會(huì)被FIFO重復(fù)采樣。
圖5 使用異步FIFO的高速接收模式Fig.5 High-speed receivemode using asynchronous FIFO
圖6 使用異步FIFO的高速發(fā)送模式Fig.6 High-speed send mode using asynchronous FIFO
據(jù)1.3中所述,全速收發(fā)模式不會(huì)出現(xiàn)類似錯(cuò)誤,但若是全速高速模式使用不同的收發(fā)方式,會(huì)增加系統(tǒng)的復(fù)雜度和設(shè)計(jì)難度。異步FIFO同樣可以用于全速收發(fā)模式,只需要將clk的頻率變?yōu)?2MHz即可,其余與高速收發(fā)模式相同,在此不再贅述。
文中通過在收發(fā)器與協(xié)議層之間增加一個(gè)2×8位的異步FIFO作為緩存區(qū),解決了USB 2.0設(shè)備控制器在數(shù)據(jù)傳輸過程中因位填充而造成的數(shù)據(jù)紊亂問題,使數(shù)據(jù)不會(huì)出現(xiàn)缺失或重復(fù),類似方法和思想可以用于其他數(shù)據(jù)傳輸處理過程。
[1]Compaq, Intel, et al.Universal Serial Bus Specification Revision 2.0[S].Compaq Computer Corp,2000.
[2]Intel Corporation.USB 2.0 Transceiver Macrocell Interface(UTMI) Specification[S].Intel Corporation,2001.
[3]周立功.USB 2.0與OTG規(guī)范及開發(fā)指南[M].北京:北京航空航天大學(xué)出版社,2004:130-162.
[4]Babulu K,Rajan K S.FPGA Implemtation of USB Transceiver Macrocell[C]//First Interfanation Conference on Emerging Trends in Enginerring and Technology,IEEE,2008:966-970.
[5]Lin H Q, Chen Y.Design and implementation of USB 2.0 device controller IP soft core[J].Ship Electronic Engineering,2008,28(3):151-153.
[6]Jolfaei F A, Mohammadizadeh N.High Speed USB 2.0 Interface for FPGA Based Embedded Systems[C]//The 4th International Conference on Embedded and Multimedia Computing,2009:1-6.
[7]Elio A A,D M,Edgardo G,et al.A Low Cost FPGA based USB Device Core [C]//2008 4th Southern Conference on Programmable Logic, Proceedings,2008:149-154.
[8]田群朝.專用雙緩沖端點(diǎn)USB 2.0設(shè)備控制器的研究與設(shè)計(jì)[D].西安:西安交通大學(xué),2011.
[9]Lou T L.Using FIFOs to Realize the High Rates Data Communication between USB and DSP [C]//First International Workshop on Education Technology and Computer Science,2009:989-992.