1. 程式人生 > >千兆乙太網TCP協議的FPGA實現

千兆乙太網TCP協議的FPGA實現

轉自https://blog.csdn.net/zhipao6108/article/details/82386355

千兆乙太網TCP協議的FPGA實現

Lzx

2017/4/20

         寫在前面,這應該是我大四最後一個工程性的作品了,以後要養成寫文件記錄的習慣。說明下,本工程為純verilog實現的硬體TCP收發器,不同於其他的使用MCU構建軟體協議棧的方案,如有同學學習實驗需要用到,可以找我拿程式碼,商用的話不好意思,還請Pay。

聯絡方式QQ:929259243

         本文將從以下幾個方面進行講述:

1、 乙太網基礎(主要講下tcp協議)。

2、 基於FPGA的TCP協議實現方案。

3、 除錯方法。

4、 問題記錄。

5、 實驗過程。

 

一、乙太網基礎:(這裡只是說下大概念,具體詳細的討論、認知,推薦看《計算機網路》(謝希仁))

 

乙太網主要分為資料鏈路層、網路層、運輸層、應用層。

                    

         資料鏈路層,某種程度可以理解成乙太網的MAC層。我們來看下它的具體定義:

         “所謂鏈路,就是從一個結點到相鄰結點的一段物理線路,中間沒有任何其他的交換結點。資料鏈路則是另外一個概念。因為當需要在一條線路上傳送資料時,必須有一條物理線路外,還必須有一些必要的通訊協議來控制這些資料的傳輸。把實現這些協議的硬體和軟體加到鏈路上,就構成了資料鏈路”簡而言之,也就是說資料鏈路層負責處理物理硬體介面細節。它定義了將資料組成正確幀的規範和在網路中傳輸幀的規範。

 

         網路層,網路層位於資料鏈路層之上,它負責處理分組在網路中的活動。同時,它負責提供網際網路的“虛擬網路”映象(可以理解成IP地址)。本層定義了網路中傳輸的“資訊包”格式,以及從一個終端到達另一個終端的路由轉發機制(路由器轉發)。本層包括IP、ICMP、IGMP、ARP等協議。

 

         運輸層,在乙太網通訊中我們面臨這樣一個問題,前面所述的協議可以實現電腦A到電腦B的通訊。然而A、B上都有很多的程序在跑,光用上面的協議是不能實現電腦A上的程序1到電腦B上的程序2的通訊,也就是我們說的端到端的通訊。為解決這個問題便有了TCP協議和UDP協議。TCP協議是面向連線的(兩個程序要傳輸資料要先建立一個連結),它提供可靠的資料傳輸服務,提供諸如流量控制、擁塞控制、超時重傳等功能。UDP協議是面向無連線的傳輸協議,不提供可靠的傳輸,但保證實時性。舉個例子,如果你通過乙太網傳送一封郵件,那麼你的側重點一定是對方收到郵件一定是跟我發的一模一樣才好。這時候傳輸用的就是TCP協議了,它能保證可靠性。再比如,如果一公司正在開網路視訊會議,你一定希望畫面能是及時畫面,而不是因為某些原因導致的10s、20s前的畫面,這時候使用的UDP協議。

 

         應用層:定義了應用程式使用網際網路的規範,負責處理特定的應用程式細節。如FTP、SMTP、Telnet等。

  

講了這麼多概念,我們來看下一次完整的網際網路是資料傳輸是如何進行的。

 

主機H1將資料通過層層打包後傳輸給R1(路由器),R1對從H1傳來的包解析(解析道網路層),並根據提取出的目的IP找尋到下一個可轉發路由器的硬體地址R2(或者主機硬體地址)。然後將資料包重新打包,改變源地址、目的地址,發給R2。以此類推,傳送給主機H2,解包後交給應用程序。值得注意的是,這個過程中,資料包的源、目的IP始終不變,但它的源、目的硬體地址卻是一直在改變的。從這個大家應該也可以體會出IP地址和硬體地址的區別了吧。

 

上面用了一個“層層打包”的籠統詞彙,然而具體的打包是如何進行的呢?

舉個例子:如上圖這是從網路層到資料鏈路層的打包,IP資料包包裹了成MAC幀發出。其他各層也是如此的包含關係。(如下圖)

               

以上為一點基礎知識,讓大家大概的瞭解下乙太網,如果要想有點更深入的體會,還是要多讀下《計算機網路》這本書。

         下面詳細說下TCP通訊過程。

1、 建立連結。

 

如上圖,TCP建立連線,也就是我們常說的三次握手,它需要三步完成。在TCP的三次握手中,傳送第一個SYN的一端執行的是主動開啟。而接收這個SYN併發回下一個SYN的另一端執行的是被動開啟。

 

這裡以客戶端向伺服器發起連線來說明。

 

1)   第1步:客戶端向伺服器傳送一個同步資料包請求建立連線,該資料包中,初始序列號(seq)是客戶端隨機產生的一個值,確認號是0;

2)   第2步:伺服器收到這個同步請求資料包後,會對客戶端進行一個同步確認。這個資料包中,序列號(seq)是伺服器隨機產生的一個值,確認號是客戶端的初始序列號+1; 

3)   第3步:客戶端收到這個同步確認資料包後,再對伺服器進行一個確認。該資料包中,序列號是上一個同步請求資料包中的確認號值,確認號是伺服器的初始序列號+1。 

注意:因為一個SYN將佔用一個序號,所以要加1。

 

初始序列號(seq)隨時間而變化的,而且不同的作業系統也會有不同的實現方式,所以每個連線的初始序列號是不同的。TCP連線兩端會在建立連線時,互動一些資訊,如視窗大小、MSS等,以便為接著的資料傳輸做準備。

 

RFC793指出ISN可以看作是一個32bit的計數器,每4ms加1,這樣選擇序號的目的在於防止在網路中被延遲的分組在以後被重複傳輸,而導致某個連線的一端對它作錯誤的判斷。

 

2、傳輸:(以客戶端向伺服器發資料說明)

1次傳輸資料包時(記為A),其序列號(seq)和應答號(ack)應與建立連線第3步發出的包的相同。

伺服器返回的應答包(第一次到第N次)(記為B)的seq應與A的ack相同。它的ack為A的seq+所傳資料長度。

第二次到第N次傳輸包C,它的seq與上一次的應答包的ack相同,ack與上一次的應答包的seq相同。

例:傳輸態:

                    Client(傳送資料包)                                        Sever(返回的應答包)

1、S=01 0F C9 65                                                                       S=68EF 8D 53

      A=68 EF 8D 53                                                                       A=01 0FC9 81

 

2、S=01 0F C9 81                                                                       S=68EF 8D 53

      A=68 EF 8D 53                                                                       A=010F C9 9D

 

……

  

 

3、釋放連線。

                               

如圖,這裡我就不過多累述了。簡要說明一下,圖中的關閉時雙向的,即AàB關閉了連結,BàA仍然可以傳輸資料。所以關閉時候記得全都關了,它才會釋放連結。

 

二、FPGA實現方案

         這裡,我們實現的是FPGA TCP協議的自環測試,框圖如下:

                                    

         注:程式碼中MDIO沒有實現,因為後來我發現用PHY預設的配置即可。PHY其實可以理解成一個AD+DA+具有自協商功能的控制器。

         其他都很好理解,TCP控制模組負責接收端和傳送端的協調溝通。

其中TCP控制模組狀態機如圖:

                                                                                      

                                                

  

這裡給出傳送狀態機:

 

接收的與傳送的類似,就不上圖了。這裡貼上各包的包頭格式,方便查閱:

 

TCP首部

三、除錯工具和方法:

         軟體:

1、Wireshark:從網絡卡上直接抓取資料,並可以對資料進行簡單的分析檢查。如校驗校驗和。注(這裡抓出來的看不到前導碼和MAC幀的校驗和。顯示出來說明上述都正確,若不顯示,最基本的MAC幀也是錯誤的)

2、 NetAssist:上位機軟體。可以設定埠,用於顯示傳到該埠的資料,可以設成伺服器、客戶機、UDP三種工作方式。

3、 Chipscope:dataport設小一些,這個很佔資源,不然編譯出來的東西在125M下跑很容易出問題,最好就去掉它,少用。

4、 Modelsim:有時候邏輯上的問題去做模擬是個好選擇。

硬體:

1、 交叉網線一條:不是普通網線。為什麼不是普通網線呢,因為普通網線不能實現PC對PC對發。對發可以讓我們採集到一些標準資料,可以跟我們的實驗資料對比,方便我們排查問題。

2、 兩臺電腦。

3、 ALX516開發板一塊。

 

除錯的方法:

採集標準資料,對照除錯自己的程式碼。如,你想看正確的建立連結這個過程和你寫的有什麼區別,可以用兩臺PC對發,用wireshark抓取建立連結的包,在與自己程式碼產生的對比,往往就能知道自己寫的哪裡出了問題。

一般先做模擬,確認邏輯無誤後,再上板除錯。

 

四、問題記錄:

1、TCP協議不支援廣播。

2、建立連線時第一個資料包一定要帶OPTION選項。

3、由於頻率較高(125M),缺少FPGA片內訊號直接觀察的手段。(加上chipscope常常會使時序惡化,本身這個東西就是ram,非常佔資源。)外部只有500M取樣的示波器,看不了。除錯只能使用插入標誌位,讓led燈亮滅顯示狀態的笨辦法來確定問題。

4、傳送端有一處設計缺陷,即從ram中取出資料計算校驗和時候,是以雙字為單位,判斷門限設定不恰當,造成傳送模組只能傳送以4位元組為倍數的字串。尚待改進。

5、wireshark看別人發來的資料一般完整,看自己發給別人的資料一般校驗和都有問題。不過無大礙,可以用。

 

五、實驗步驟:

1、在傳送模組目的地址,請修改成你pc的網絡卡地址,並重新編譯。如圖:

                 

 

2、 請將網路介面卡的IPV4設成如圖:

3、 開啟NetAssiant,開啟TCP Sever,設定成如圖,點連線。

 

 

4、 這時可以打入8位元組、12位元組(4的倍數)的字串,點發送,完成自環測試。如果不按4的倍數傳送的話,請重新輸入。

5、 最後請不要忘記點斷開按鈕,畢竟TCP協議是個嚴謹的東西。