FPGA千兆網UDP協議實現
上一篇百兆網接口的設計與使用,我們接著來進行FPGA百兆網UDP(User Datagram Protocol)協議的設計。
1)UDP簡介
在此,參考博主夜雨翛然的博文“https://www.cnblogs.com/HPAHPA/p/7737531.html”關於UDP協議的簡介:“UDP傳輸與IP傳輸非常類似。你可以將UDP協議看作IP協議暴露在傳輸層的一個接口。UDP協議同樣以數據包(datagram)的方式傳輸,它的傳輸方式也是"Best Effort"的,所以UDP協議也是不可靠的(unreliable)。那麽,我們為什麽不直接使用IP協議而要額外增加一個UDP協議呢? 一個重要的原因是IP協議中並沒有端口(port)的概念
2)UDP協議
UDP的數據包同樣分為頭部(header)和數據(payload)兩部分。UDP是傳輸層(transport layer)協議,這意味著UDP的數據包需要經過IP協議的封裝(encapsulation),然後通過IP協議傳輸到目的電腦。隨後UDP包在目的電腦拆封,並將信息送到相應端口的緩存中。
圖 1: UDP數據格式
偽首部:只用於計算校驗和,傳輸數據時,只需要首部和數據
源IP:本設計固定為192.168.0.2
目的IP:本設計固定為192.168.0.3
UDP長度:首部+數據的長度,單位為字節
源端口: 固定為1000
目的端口 :固定位10001
長度:首部加數據的長度,單位為字節,8+data_len;
檢驗和: 計算的是偽首部+首部+數據部分的校驗和,其計算方式是:
a、每兩個字節為一組,然後相加,相加結果為17比特,則將最高比特位與低16位進行相加,得到一個16比特的數據;
b、所有字節都相加完後,最終得到的結果再取反,就是首部的校驗和。
3)整體報文格式
參考博主洋蔥洋蔥的“https://www.cnblogs.com/cofin/p/9306770.html”博文
圖 2: UDP協議整體報文發送格式
涉及到的IP層以及MAC層報文格式,這裏就不再詳細闡述了。
4)FPGA設計與實現(討論FPGA發送部份)
UDP協議的實現本質就是將數據按照上述圖2的格式封裝打包好,但是我這裏的MAC層打包采用的是alter千兆網的MAC IP核,數據傳輸帶寬是8bit,我會將數據封裝打包好後,每個時鐘周期以8bit的速率傳輸給MAC IP核進行MAC層的封裝打包,當然,也可以不采用IP核,直接將數據封裝打包好傳送到上位機,打包部分我用了兩個fifo,一個用於包文的存儲,一個用於計算包文的個數,校驗碼會在包文進行打包前就先計算好。
a、校驗碼的設計:
列舉IP層的檢驗碼計算方式,參考代碼如下:
always @(posedge clk or negedge rst_n)begin if(rst_n==1‘b0)begin assume_temp<= 0; end else if(add_cnt2)begin assume_temp <= assume_sum+ip_assume_add[143-cnt2*16 -:16]; end end always @(*)begin assume_sum <= assume_temp[16]+assume_temp[15:0]; end always @(posedge clk or negedge rst_n)begin if(rst_n==1‘b0)begin end_cnt2_ff0 <= 0; end else begin end_cnt2_ff0 <= end_cnt2; end end always @(posedge clk or negedge rst_n)begin if(rst_n==1‘b0)begin assume <= 0; end else if(end_cnt2_ff0)begin assume <= ~assume_sum; end end
b、sop、eop的設計
這點我一開始理解是有錯誤的,我理解成了僅是發送數據data的第一個字節與最後一個字節,其實sop、eop指整個包文發送的第一個與最後一個字節,正確設計如下:
always @(posedge clk or negedge rst_n)begin if(rst_n==1‘b0)begin ff_tx_sop <= 0; end else if(fifo_data_rd==1&&add_cnt1==1&&cnt1==1-1)begin ff_tx_sop <= 1; end else begin ff_tx_sop <= 0; end end always @(posedge clk or negedge rst_n)begin if(rst_n==1‘b0)begin ff_tx_eop <= 0; end else if(fifo_data_rd==1&&end_cnt1)begin ff_tx_eop <= 1; end else begin ff_tx_eop <= 0; end end
5)效果展示:
當然,這裏數據全部發ff也是不太合理的,至此,UDP數據打包發送完畢。
FPGA千兆網UDP協議實現