張金鳳 李耀南
(西安電子工程研究所 西安 710100)
近年來,F(xiàn)PGA在通信領(lǐng)域的應(yīng)用越來越廣泛,F(xiàn)PGA運(yùn)行速度快,容易實(shí)現(xiàn)大規(guī)模系統(tǒng)。隨著電子技術(shù)的發(fā)展,高速數(shù)據(jù)傳輸在現(xiàn)代電子系統(tǒng)中起著重要的作用。FPGA與普通計(jì)算機(jī)主要通過以太網(wǎng)接口、串口等連接。串口傳輸速度慢,難以實(shí)現(xiàn)高速數(shù)據(jù)傳輸,而且由于串口不能進(jìn)行遠(yuǎn)程數(shù)據(jù)傳輸,因此要求FPGA和PC機(jī)必需在同一地點(diǎn),這就限制了高速數(shù)據(jù)傳輸系統(tǒng)使用的靈活性及在特殊場(chǎng)合的應(yīng)用。以太網(wǎng)接口速度高,傳輸距離遠(yuǎn),便于構(gòu)建FPGA和PC機(jī)的高速數(shù)據(jù)傳輸系統(tǒng)?;谝蕴W(wǎng)實(shí)現(xiàn)FPGA和PC機(jī)的高速數(shù)據(jù)傳輸方法有兩種:一種是利用FPGA內(nèi)嵌的MAC硬核實(shí)現(xiàn),另一種是利用嵌入到FPGA的單片機(jī)實(shí)現(xiàn)[1]。后者邏輯控制繁瑣,而且需要額外的資源,給布線帶來很大的難處;前者利用FPGA自帶的資源,使用簡(jiǎn)單、方便。FPGA自帶的MAC硬核提供了MAC層與用戶和物理層的接口,用戶只需將需要發(fā)送的數(shù)據(jù)封裝成MAC幀傳輸?shù)組AC層與用戶接口,將接收到的數(shù)據(jù)解包、錯(cuò)誤檢驗(yàn)和存儲(chǔ)便可實(shí)現(xiàn)FPGA和PC機(jī)的高速數(shù)據(jù)互傳。
UDP和TCP是TCP/IP協(xié)議族中傳輸層的兩個(gè)主要協(xié)議,圖1給出了這兩種協(xié)議在TCP/IP協(xié)議族中的位置[2]。UDP、TCP主要為應(yīng)用程序傳來的數(shù)據(jù)提供傳輸服務(wù)。TCP提供面向連接的服務(wù),在傳送數(shù)據(jù)之前必須先建立連接,數(shù)據(jù)傳送結(jié)束后要釋放連接,它提供可靠的傳輸服務(wù),因此不可避免地增加了許多開銷,這不僅使協(xié)議數(shù)據(jù)單元的首部增大很多,還要占用許多FPGA資源。而UDP是無連接的,在傳送數(shù)據(jù)之前不需要先建立連接,因此減少了開銷和發(fā)送數(shù)據(jù)之前的時(shí)延。UDP對(duì)應(yīng)用程序交下來的報(bào)文,在添加首部后就向下交付給IP層,首部只有8個(gè)字節(jié),比TCP的20個(gè)字節(jié)的首部短,因此UDP易于實(shí)現(xiàn),占用資源也比較少。而且UDP沒有擁塞控制,因此網(wǎng)絡(luò)出現(xiàn)的擁塞不會(huì)使源主機(jī)的發(fā)送速率降低。所以本系統(tǒng)采用UDP進(jìn)行數(shù)據(jù)傳輸。
圖1 TCP/IP協(xié)議族
千兆以太網(wǎng)系統(tǒng)的FPGA設(shè)計(jì)工作包括以太網(wǎng)MAC層的FPGA設(shè)計(jì)、MAC層與上層協(xié)議的接口設(shè)計(jì)以及MAC層與物理層(PHY)的接口設(shè)計(jì)。該以太網(wǎng)控制器的總體結(jié)構(gòu)設(shè)計(jì)框圖如圖2所示,整個(gè)系統(tǒng)包括發(fā)送模塊、接收模塊和MAC控制模塊。發(fā)送模塊和接收模塊主要提供MAC幀的發(fā)送和接收功能,其主要操作有MAC幀的封裝和解包及錯(cuò)誤檢測(cè),它直接提供了到外部物理層芯片的并行數(shù)據(jù)接口,這也是本文的重點(diǎn)。MAC控制模塊用于執(zhí)行全雙工模式中的流量控制功能,由IPcore產(chǎn)生。
本系統(tǒng)基于Xilinx ML605評(píng)估板實(shí)現(xiàn),F(xiàn)PGA芯片為XC6VLX240T,它內(nèi)部集成的以太網(wǎng)MAC核支持MII/GMII、RGMII、SGMII等多種類型接口。以太網(wǎng) PHY芯片選用 Marvell公司 Alaska系列的88E1111芯片。88E1111是一款支持IEEE802.3u協(xié)議規(guī)定的自動(dòng)協(xié)商機(jī)制的物理層芯片,可以支持MII/GMII、RGMII及 SGMII等多種類型的 PHYMAC接口[3]。本系統(tǒng)MAC層與物理層采用GMII接口。
圖2 系統(tǒng)結(jié)構(gòu)圖
利用FPGA內(nèi)嵌的IPCore生成MAC控制器時(shí),Xilinx提供了一個(gè)以太網(wǎng)自發(fā)自收數(shù)據(jù)的例子程序,該例子程序是對(duì)MAC的最簡(jiǎn)最小封裝,但對(duì)本系統(tǒng)中使用FPGA進(jìn)行數(shù)據(jù)收發(fā)非常實(shí)用,如圖3所示。它簡(jiǎn)化了用戶和MAC數(shù)據(jù)交互程序的編寫,本系統(tǒng)對(duì)該例子程序做了一定修改,只利用LocalLink接口以下的程序。將地址交換模塊替換成數(shù)據(jù)發(fā)送和數(shù)據(jù)接收模塊,實(shí)現(xiàn)對(duì)網(wǎng)絡(luò)數(shù)據(jù)的封裝和解包。
圖3 Xilinx Gigabit Ethernet例子程序接口框圖
以太網(wǎng)MAC控制器與用戶邏輯的接口為L(zhǎng)ocalLink接口,該接口以包為單位進(jìn)行數(shù)據(jù)傳送,數(shù)據(jù)流由sof_n、eof_n、src_rdy_n和 dst_rdy_n四個(gè)信號(hào)控制,LocalLink接口的數(shù)據(jù)發(fā)送時(shí)序如圖4所示。這些控制信號(hào)都是低電平有效,當(dāng)sof_n、src_rdy_n和dst_rdy_n都為低時(shí)表示一個(gè)網(wǎng)絡(luò)數(shù)據(jù)包傳輸開始;當(dāng)src_rdy_n和dst_rdy_n都為低時(shí),表示正在進(jìn)行網(wǎng)絡(luò)數(shù)據(jù)包傳輸;當(dāng)eof_n、src_rdy_n和dst_rdy_n都為低時(shí),表示一個(gè)網(wǎng)絡(luò)數(shù)據(jù)包傳輸結(jié)束[4]。
圖4 LocalLink接口發(fā)送時(shí)序圖
標(biāo)準(zhǔn)的以太網(wǎng)幀結(jié)構(gòu)由五部分組成,如圖5所示。前兩個(gè)字段分別是6個(gè)字節(jié)長(zhǎng)的目的地址和源地址字段。第三個(gè)字段是2字節(jié)的類型字段,用來標(biāo)志上一層使用的是什么協(xié)議,以便把收到的MAC幀的數(shù)據(jù)上交給上一層的這個(gè)協(xié)議。第四個(gè)字段是數(shù)據(jù)字段,其長(zhǎng)度在46到1500字節(jié)之間。最后一個(gè)字段是4字節(jié)的幀檢驗(yàn)序列FCS[2]。
圖5 以太網(wǎng)MAC幀格式
本系統(tǒng)網(wǎng)絡(luò)層使用IP,傳輸層使用UDP。發(fā)送方的UDP對(duì)應(yīng)用程序交下來的報(bào)文,在添加首部后就向下交付給IP層,IP層數(shù)據(jù)添加IP首部后傳送到MAC層,在MAC層將數(shù)據(jù)組成MAC幀格式。從MAC子層向下傳到物理層時(shí)還要在幀的前面插入8字節(jié)(由硬件生成),它由兩個(gè)字段組成,第一個(gè)字段是7個(gè)字節(jié)的前同步碼(0x55),它的作用是使物理層做好發(fā)送接受準(zhǔn)備,第二個(gè)字段是幀開始定界符(0xD5),它是幀開始的標(biāo)志。
發(fā)送模塊是將用戶提供的數(shù)據(jù)封裝之后發(fā)送到以太網(wǎng)MAC層,實(shí)現(xiàn)數(shù)據(jù)從FPGA到PC機(jī)的傳輸。數(shù)據(jù)封裝主要是基于UDP將數(shù)據(jù)封裝成圖5所示的MAC幀格式,即在數(shù)據(jù)前添加UDP、IP以及MAC幀頭。
發(fā)送模塊與用戶邏輯之間的接口通過一個(gè)異步FIFO連接,將用戶要發(fā)送的數(shù)據(jù)先存入FIFO中,F(xiàn)IFO深度可以根據(jù)發(fā)送數(shù)據(jù)包長(zhǎng)度自行決定,但是FIFO寬度為32bit,這是為了后續(xù)封裝方便,根據(jù)FIFO的空滿信號(hào)控制FIFO寫數(shù)據(jù)和封裝開始信號(hào)。圖6為模塊的具體實(shí)現(xiàn)過程。
圖6 網(wǎng)絡(luò)數(shù)據(jù)封裝及發(fā)送原理結(jié)構(gòu)圖
數(shù)據(jù)封裝的具體實(shí)現(xiàn)過程如下:
整個(gè)過程由狀態(tài)機(jī)控制,該狀態(tài)機(jī)包括三個(gè)狀態(tài):TX_IDLE(初始狀態(tài))、TX_UDP_HEAD(幀頭封裝狀態(tài))、TX_UDP_READ(數(shù)據(jù)封裝狀態(tài))。
a.上層協(xié)議接到封裝開始信號(hào)時(shí),控制狀態(tài)機(jī)進(jìn)入TX_UDP_HEAD狀態(tài),幀頭計(jì)數(shù)器累加。標(biāo)識(shí)字段在系統(tǒng)中是一個(gè)計(jì)數(shù)器,每產(chǎn)生一個(gè)數(shù)據(jù)報(bào),計(jì)數(shù)器就加1,計(jì)數(shù)器為0時(shí)執(zhí)行此操作。計(jì)數(shù)器為3時(shí)開始計(jì)算頭部校驗(yàn)和,頭部校驗(yàn)和字段只檢驗(yàn)IP數(shù)據(jù)報(bào)的首部。先把IP數(shù)據(jù)報(bào)首部劃分為許多16bit的序列,并把校驗(yàn)和字段置零。用反碼算術(shù)運(yùn)算把所有16bit相加,總共需要6個(gè)時(shí)鐘周期,將最終得到的和的反碼寫入校驗(yàn)和字段。計(jì)數(shù)器為4時(shí),開始對(duì)IP數(shù)據(jù)首部協(xié)議字段之前的字段封裝,總共需要6個(gè)時(shí)鐘周期。
b.幀頭計(jì)數(shù)器為9時(shí),進(jìn)入TX_UDP_READ狀態(tài),此時(shí)數(shù)據(jù)計(jì)數(shù)器累加。計(jì)數(shù)器為0時(shí)開始IP首部的其他字段以及UDP首部和發(fā)送數(shù)據(jù)部分封裝,將IP首部的剩余字段和UDP首部字段完全封裝一共需要5個(gè)時(shí)鐘周期。數(shù)據(jù)封裝過程中關(guān)鍵部分是UDP校驗(yàn)和計(jì)算,因?yàn)閁DP校驗(yàn)和是把UDP偽首部、UDP首部以及發(fā)送數(shù)據(jù)一起檢驗(yàn),所以UDP校驗(yàn)和的計(jì)算是在發(fā)送狀態(tài)機(jī)將數(shù)據(jù)從FIFO讀出的過程中同時(shí)進(jìn)行。計(jì)數(shù)器為2時(shí)開始從FIFO讀取數(shù)據(jù),計(jì)數(shù)器為3時(shí)開始計(jì)算數(shù)據(jù)校驗(yàn)和,首先置UDP校驗(yàn)和初始值為0x0000,并添加到UDP校驗(yàn)和字段,其計(jì)算方法與IP首部校驗(yàn)和方法相同。計(jì)數(shù)器為4時(shí),開始數(shù)據(jù)封裝。計(jì)數(shù)器值等于數(shù)據(jù)長(zhǎng)度加4時(shí),從FIFO讀出的數(shù)據(jù)封裝結(jié)束。計(jì)數(shù)器值等于數(shù)據(jù)長(zhǎng)度加7時(shí),校驗(yàn)和計(jì)算完成,此時(shí)進(jìn)入TX_IDLE狀態(tài)。
c.整個(gè)系統(tǒng)采用流水線操作,將封裝數(shù)據(jù)和校驗(yàn)和分別存入FIFO中,利用FIFO的寫計(jì)數(shù)器計(jì)數(shù),當(dāng)計(jì)數(shù)器長(zhǎng)度為發(fā)送數(shù)據(jù)長(zhǎng)度時(shí),開始從FIFO中將數(shù)據(jù)讀出,寫入FIFO的校驗(yàn)和在寫入的下一個(gè)周期立即讀出,當(dāng)校驗(yàn)和使能有效時(shí),將計(jì)算所得的校驗(yàn)和重新寫入MAC幀的UDP校驗(yàn)和字段。最后所得MAC幀數(shù)據(jù)再經(jīng)過一個(gè)FIFO,根據(jù)以太網(wǎng)速度要求,控制讀出數(shù)據(jù)寬度,以千兆以太網(wǎng)為例,讀數(shù)寬度為8bit。
d.因?yàn)閿?shù)據(jù)以32bit進(jìn)行封裝,MAC首部、IP數(shù)據(jù)報(bào)首部和UDP數(shù)據(jù)報(bào)首部總長(zhǎng)度為42個(gè)字節(jié),即十個(gè)32 bit和一個(gè)16bit,不是32bit的整數(shù)倍,所以在數(shù)據(jù)包末尾多加了16bit的零數(shù)據(jù),雖然不影響UDP校驗(yàn)和計(jì)算,但它改變了數(shù)據(jù)長(zhǎng)度,所以發(fā)送之前必須把末尾多加的數(shù)據(jù)截掉。從FIFO讀出數(shù)據(jù)時(shí),根據(jù)數(shù)據(jù)有效信號(hào)按照?qǐng)D4所示的網(wǎng)絡(luò)數(shù)據(jù)發(fā)送時(shí)上層協(xié)議與以太網(wǎng)MAC層接口時(shí)序的要求產(chǎn)生 tx_ll_src_rdy_n、tx_ll_eof_n、tx_ll_sof_n 等控制信號(hào)就可以實(shí)現(xiàn)對(duì)網(wǎng)絡(luò)數(shù)據(jù)包的傳輸控制。發(fā)送到PC機(jī)的數(shù)據(jù)包,既可以通過WireShark抓包軟件抓包,也可以通過網(wǎng)絡(luò)調(diào)試助手將收到數(shù)據(jù)直接存儲(chǔ)起來,用于后續(xù)處理。
對(duì)于FPGA收到的數(shù)據(jù),在接收模塊內(nèi)完成MAC幀的解包和存儲(chǔ)。接收模塊相對(duì)于發(fā)送模塊而言邏輯設(shè)計(jì)簡(jiǎn)單。接收模塊收到的數(shù)據(jù)通過判斷首部校驗(yàn)和、校驗(yàn)和、目的MAC地址和協(xié)議類型字段判斷收到的數(shù)據(jù)是不是要發(fā)給本FPGA的,或發(fā)送的數(shù)據(jù)是否正確。
根據(jù)rx_ll_src_rdy_n、rx_ll_sof_n控制信號(hào)判斷數(shù)據(jù)起始位置,此時(shí)計(jì)數(shù)器累加,將數(shù)據(jù)的前6個(gè)字節(jié)鎖存起來,拼接成一個(gè)48bit的數(shù)據(jù)與本FPGA的MAC進(jìn)行比較。如果不是發(fā)給本FPGA的,直接將該包丟掉,不再進(jìn)行后續(xù)處理,否則,當(dāng)計(jì)數(shù)器為13時(shí),按照發(fā)送模塊中計(jì)算首部校驗(yàn)和的方法計(jì)算收到數(shù)據(jù)的首部校驗(yàn)和。計(jì)數(shù)器計(jì)到23時(shí),將該字節(jié)數(shù)據(jù)鎖存,判斷是否為UDP協(xié)議。計(jì)數(shù)器為25時(shí),開始計(jì)算校驗(yàn)和,計(jì)數(shù)器為34時(shí),頭部校驗(yàn)和計(jì)算結(jié)束,計(jì)數(shù)器為41時(shí),開始將數(shù)據(jù)存到FIFO中以便后續(xù)使用。當(dāng)rx_ll_eof_n信號(hào)抬高時(shí),計(jì)數(shù)器停止計(jì)數(shù),數(shù)據(jù)存儲(chǔ)結(jié)束,下一個(gè)時(shí)鐘周期校驗(yàn)和計(jì)算結(jié)束。如果判斷結(jié)果正確,且計(jì)算所得的校驗(yàn)和都為0XFFFF,將收到的數(shù)據(jù)用于后續(xù)處理,否則FIFO復(fù)位將該包數(shù)據(jù)丟掉。
本文基于千兆以太網(wǎng)實(shí)現(xiàn)FPGA和PC機(jī)的高速數(shù)據(jù)傳輸。采用UDP、IP協(xié)議的MAC幀格式,通過判斷頭部校驗(yàn)和和校驗(yàn)和字段,檢測(cè)數(shù)據(jù)在傳輸中是否有錯(cuò),提高數(shù)據(jù)傳輸?shù)目煽啃裕彝话l(fā)速率達(dá)到1Gbit/s。利用FPGA內(nèi)嵌的MAC核建立千兆以太網(wǎng)系統(tǒng),為高速數(shù)據(jù)傳輸提供了方便的途徑。
[1]羅侄敬.在嵌入FPGA的IP核8051上實(shí)現(xiàn)TCP/IP的設(shè)計(jì)[J].電子元器件應(yīng)用,2007,(4):44-50.
[2]謝希仁..計(jì)算機(jī)網(wǎng)絡(luò)(第5版)[M].北京:電子工業(yè)出版社,2010.
[3] MARVELL corp.88E1111 datasheet[CP].2004.
[4]Virtex-6 FPGA Embedded Tri-Mode Ethernet MAC user guide[M].XILINX.UG368(v1.2)[CP].January 17,2010.