国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹)

這篇具有很好參考價值的文章主要介紹了FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹)

0 致讀者

此篇為專欄《紫光同創(chuàng)FPGA開發(fā)筆記》的第六篇,同時也是 FPGA 以太網(wǎng)入門第二篇,記錄我的學(xué)習(xí) FPGA 的一些開發(fā)過程和心得感悟,剛接觸 FPGA 的朋友們可以先去此博客 《FPGA零基礎(chǔ)入門學(xué)習(xí)路線》來做最基礎(chǔ)的掃盲。

本篇內(nèi)容基于筆者實際開發(fā)過程和正點原子資料撰寫,將會詳細(xì)講解此 FPGA 實驗的全流程,誠摯地歡迎各位讀者在評論區(qū)或者私信我交流!

在以太網(wǎng)中,一個主機和另一個主機進(jìn)行通信,必須要知道目的主機的 MAC 地址(物理地址),而目的 MAC 地址的獲取由 ARP 協(xié)議完成。本文我們來學(xué)習(xí)如何通過 FPGA 開發(fā)板實現(xiàn) ARP 協(xié)議的功能。

本文的工程文件開源地址如下(基于ATK-DFPGL22G,大家 clone 到本地就可以直接跑仿真,如果要上板請根據(jù)自己的開發(fā)板更改約束即可):

https://github.com/ChinaRyan666/PDS_ARP_TEST



1 實驗任務(wù)

本節(jié)實驗任務(wù)是使用 ATK-DFPGL22G 開發(fā)板上的以太網(wǎng)接口,和上位機實現(xiàn) ARP 請求和應(yīng)答的功能。當(dāng)上位機發(fā)送 ARP 請求時,開發(fā)板返回 ARP 應(yīng)答數(shù)據(jù)。當(dāng)按下開發(fā)板的觸摸按鍵時,開發(fā)板發(fā)送 ARP 請求,此時上位機返回應(yīng)答數(shù)據(jù)。



2 簡介

2.1 ARP 概述

ARPAddress Resolution Protocol),即地址解析協(xié)議,是根據(jù) IP 地址(邏輯地址)獲取 MAC 地址的一種 TCP/IP 協(xié)議。在以太網(wǎng)通信中,數(shù)據(jù)是以 “幀” 的格式進(jìn)行傳輸?shù)?,幀格式里面包含目的主機的 MAC 地址。源主機的應(yīng)用程序知道目的主機的 IP 地址,卻不知道目的主機的 MAC 地址。而目的主機的 MAC 地址直接被網(wǎng)卡接收和解析,當(dāng)解析到目的 MAC 地址非本地 MAC 地址時,則直接丟棄該包數(shù)據(jù),因此在通信前需要先獲得目的的 MAC 地址,而 ARP 協(xié)議正是實現(xiàn)了此功能。

ARP 協(xié)議的基本功能是通過目的設(shè)備的 IP 地址,查詢目的設(shè)備的 MAC 地址,以保證通信的順利進(jìn)行。MAC 地址在網(wǎng)絡(luò)中表示網(wǎng)卡的 ID,每個網(wǎng)卡都需要并有且僅有一個 MAC 地址。在獲取到目的 MAC 地址之后,將目的 MAC 地址更新至 ARP 緩存表中,稱為 ARP 映射,下次通信時,可以直接從 ARP 緩存表中獲取,而不用重新通過 ARP 獲取 MAC 地址。但一般 ARP 緩存表會有過期時間,過期后需要重新通過 ARP 協(xié)議進(jìn)行獲取。

ARP 映射是指將 IP 地址和 MAC 地址映射起來,分為靜態(tài)映射和動態(tài)映射。

靜態(tài)映射指手動創(chuàng)建一張 ARP 表,把 IP 地址和 MAC 地址關(guān)聯(lián)起來。手動綁定之后,源主機在通信之前,就可以直接從 ARP 表中直接找到 IP 地址對應(yīng)的 MAC 地址,但這樣做有一定的局限性,因為 MAC 地址可能會變化,比如:

  1. 機器可能更換 NIC(網(wǎng)絡(luò)適配器),結(jié)果變成一個新的物理地址;

  2. 在某些局域網(wǎng)中,每當(dāng)計算機加電時,他的物理地址都要改變一次;

  3. 移動電腦可以從一個物理網(wǎng)絡(luò)轉(zhuǎn)移到另一個物理網(wǎng)絡(luò),這樣會改變物理地址。

要避免這些問題出現(xiàn),必須定期維護(hù)更新 ARP 表,此類比較麻煩而且會影響網(wǎng)絡(luò)性能。動態(tài)映射指使用協(xié)議來獲取相對應(yīng)的物理地址,之所以用動態(tài)這個詞是因為這個過程是自動完成的,一般應(yīng)用程序的用戶或系統(tǒng)管理員不必關(guān)心。

已經(jīng)設(shè)計出用于實現(xiàn)動態(tài)映射協(xié)議的有 ARPRARP(逆地址解析協(xié)議)兩種,如下圖所示。

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip

ARPIP 地址映射為物理地址,RARP 把物理地址映射為 IP 地址。RRAP 是被那些沒有磁盤驅(qū)動器的系統(tǒng)使用(一般是無盤工作站或 X 終端),此類應(yīng)用較少,本章不做討論。

ARP 協(xié)議分為 ARP 請求和 ARP 應(yīng)答,源主機發(fā)起查詢目的 MAC 地址的報文稱為 ARP 請求,目的主機響應(yīng)源主機并發(fā)送包含本地 MAC 地址的報文稱為 ARP 應(yīng)答。

當(dāng)主機需要找出這個網(wǎng)絡(luò)中的另一個主機的物理地址時,它就可以發(fā)送一個 ARP 請求報文,這個報文包含了發(fā)送方的 MAC 地址和 IP 地址以及接收方的 IP 地址。因為發(fā)送方不知道接收方的物理地址,所以這個查詢分組會在網(wǎng)絡(luò)層中進(jìn)行廣播,即 ARP 請求時發(fā)送的接收方物理地址為廣播地址,用 48’hff_ff_ff_ff_ff_ff 表示。

ARP 請求的示意圖如下圖所示。

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip

上圖中的主機 A 發(fā)起 ARP 請求,由于發(fā)送的目的 MAC 地址為廣播地址,所以此時局域網(wǎng)中的所有主機都會進(jìn)行接收并處理這個 ARP 請求報文,然后進(jìn)行驗證,查看接收方的 IP 地址是不是自己的地址。是則返回 ARP 應(yīng)答報文,不是則不響應(yīng)。

只有驗證成功的主機才會返回一個 ARP 應(yīng)答報文,這個應(yīng)答報文包含接收方的 IP 地址和物理地址。

ARP 應(yīng)答的示意圖如下圖所示。

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip

主機 B 利用收到的 ARP 請求報文中的請求方物理地址,以單播的方式直接發(fā)送給主機 A,主機 A 將收到的 ARP 應(yīng)答報文中的目的 MAC 地址解析出來,將目的 MAC 地址和目的 IP 地址更新至 ARP 緩存表中。當(dāng)再次和主機 A 通信時,可以直接從 ARP 緩存表中獲取,而不用重新發(fā)起 ARP 請求報文。需要說明的是,ARP 緩存表中的表項有過期時間(一般為 20 分鐘),過期之后,需要重新發(fā)起 ARP 請求以獲取目的 MAC 地址。

ARP 協(xié)議通過以太網(wǎng)進(jìn)行傳輸,那么必須也要按照以太網(wǎng)所規(guī)定的格式進(jìn)行傳輸,我們先來介紹下以太網(wǎng)的幀格式,隨后再來向大家詳細(xì)介紹 ARP 協(xié)議的具體格式。

以太網(wǎng)是目前應(yīng)用最廣泛的局域網(wǎng)通訊方式,同時也是一種協(xié)議。以太網(wǎng)協(xié)議定義了一系列軟件和硬件標(biāo)準(zhǔn),從而將不同的計算機設(shè)備連接在一起。我們知道串口通信單次只傳輸一個字節(jié),而以太網(wǎng)通信是以數(shù)據(jù)包的形式傳輸,其單包數(shù)據(jù)量達(dá)到幾十,甚至成百上千個字節(jié)。下圖為以太網(wǎng)通過 ARP 傳輸單包數(shù)據(jù)的格式,從圖中可以看出,以太網(wǎng)的數(shù)據(jù)包就是對協(xié)議的封裝來實現(xiàn)數(shù)據(jù)的傳輸,即 ARP 數(shù)據(jù)位于以太網(wǎng)幀格式的數(shù)據(jù)段。這里只是讓大家了解下以太網(wǎng)數(shù)據(jù)包的格式,后面會逐個展開來講。

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip


2.2 以太網(wǎng) MAC 幀格式

以太網(wǎng)技術(shù)的正式標(biāo)準(zhǔn)是 IEEE 802.3,它規(guī)定了以太網(wǎng)傳輸數(shù)據(jù)的幀結(jié)構(gòu),我們可以把以太網(wǎng) MAC 層理解成高速公路,我們必須遵循它的規(guī)則才能在上面通行,以太網(wǎng) MAC 層幀格式如圖下圖所示。

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip

以太網(wǎng)傳輸數(shù)據(jù)時按照上面的順序從頭到尾依次被發(fā)送和接收,我下面進(jìn)一步解釋各個區(qū)域。

名稱 功能
前導(dǎo)碼(Preamble 為了實現(xiàn)底層數(shù)據(jù)的正確闡述,物理層使用 7 個字節(jié)同步碼【01 交替(55-55-55-55-55-55-55)】實現(xiàn)數(shù)據(jù)的同步。
幀起始界定符(SFD,Start Frame Delimiter 使用 1 個字節(jié)的 SFD(固定值為 0xd5)來表示一幀的開始,即后面緊跟著傳輸?shù)木褪且蕴W(wǎng)的幀頭。
目的 MAC 地址 即接收端物理 MAC 地址,占用 6 個字節(jié)。MAC 地址從應(yīng)用上可分為單播地址、組播地址和廣播地址。單播地址: 第一個字節(jié)的最低位為 0,比如 00-00-00-11-11-11,一般用于標(biāo)志唯一的設(shè)備;組播地址: 第一個字節(jié)的最低位為 1,比如 01-00-00-11-11-11,一般用于標(biāo)志同屬一組的多個設(shè)備;廣播地址: 所有 48bit 全為 1,即 FF-FF-FF-FF-FF-FF,它用于標(biāo)志同一網(wǎng)段中的所有設(shè)備。
MAC 地址 即發(fā)送端物理 MAC 地址,占用 6 個字節(jié)。
長度/類型 上圖中的長度/類型具有兩個意義,當(dāng)這兩個字節(jié)的值小于 1536(十六進(jìn)制為 0x0600)時,代表該以太網(wǎng)中數(shù)據(jù)段的長度;如果這兩個字節(jié)的值大于 1536,則表示該以太網(wǎng)中的數(shù)據(jù)屬于哪個上層協(xié)議,例如 0x0800 代表 IP 協(xié)議(網(wǎng)際協(xié)議)、0x0806 代表 ARP 協(xié)議(地址解析協(xié)議)等。
數(shù)據(jù) 以太網(wǎng)中的數(shù)據(jù)段長度最小 46 個字節(jié), 最大 1500 個字節(jié)。最大值 1500 稱為以太網(wǎng)的最大傳輸單元(MTU, Maximum Transmission Unit),之所以限制最大傳輸單元是因為在多個計算機的數(shù)據(jù)幀排隊等待傳輸時,如果某個數(shù)據(jù)幀太大的話,那么其它數(shù)據(jù)幀等待的時間就會加長,導(dǎo)致體驗變差,這就像一個十字路口的紅綠燈,你可以讓綠燈持續(xù)亮一小時,但是等紅燈的人一定不愿意的。另外還要考慮網(wǎng)絡(luò) I/O 控制器緩存區(qū)資源以及網(wǎng)絡(luò)最大的承載能力等因素,因此最大傳輸單元是由各種綜合因素決定的。為了避免增加額外的配置,通常以太網(wǎng)的有效數(shù)據(jù)字段小于 1500 個字節(jié)。
幀檢驗序列(FCS, Frame Check Sequence 為了確保數(shù)據(jù)的正確傳輸,在數(shù)據(jù)的尾部加入了 4 個字節(jié)的循環(huán)冗余校驗碼(CRC 校驗)來檢測數(shù)據(jù)是否傳輸錯誤。CRC 數(shù)據(jù)校驗從以太網(wǎng)幀頭開始即不包含前導(dǎo)碼和幀起始界定符。通用的 CRC 標(biāo)準(zhǔn)有 CRC-8、CRC-16、CRC-32、CRC-CCIT,其中在網(wǎng)絡(luò)通信系統(tǒng)中應(yīng)用最廣泛的是 CRC-32 標(biāo)準(zhǔn)。

在這里還有一個要注意的地方就是以太網(wǎng)相鄰兩幀之間的時間間隔,即幀間隙(IFG, Interpacket Gap)。

幀間隙的時間就是網(wǎng)絡(luò)設(shè)備和組件在接收一幀之后,需要短暫的時間來恢復(fù)并為接收下一幀做準(zhǔn)備的時間,IFG 的最小值是 96 bit time,即在媒介中發(fā)送 96 位原始數(shù)據(jù)所需要的時間,在不同媒介中 IFG 的最小值是不一樣的。不管 10M/100M/1000M 的以太網(wǎng),兩幀之間最少要有 96bit time,IFG 的最少間隔。

時間計算方法如下:

10Mbit/s 最小時間為:96*100ns = 9600ns;
100Mbit/s 最小時間為:96*10ns = 960ns
1000Mbit/s 最小時間為:96*1ns = 96ns。

接下來我來介紹 ARP 協(xié)議以及它和以太網(wǎng) MAC 層的關(guān)系。在介紹 ARP 協(xié)議之前,我們先了解下 TCP(傳輸控制協(xié)議)/ IP(網(wǎng)際協(xié)議)協(xié)議簇。TCP/IP 是網(wǎng)絡(luò)使用中最基本的通信協(xié)議,雖然從名字看上去 TCP/IP 包括兩個協(xié)議,TCPIP,但 TCP/IP 實際上是一組協(xié)議,它包括上百個各種功能的協(xié)議,如:TCPIP、ARP、UDP 等。 而 TCP 協(xié)議和 IP 協(xié)議是保證數(shù)據(jù)完整傳輸?shù)膬蓚€重要的協(xié)議,因此 TCP/IP 協(xié)議用來表示 Internet 協(xié)議簇。

TCP/IP 協(xié)議不僅可以運行在以太網(wǎng)上,也可以運行在 FDDI(光纖分布式數(shù)據(jù)接口)和 WLAN(無線局域網(wǎng))上。反過來,以太網(wǎng)的高層協(xié)議不僅可以是 TCP/IP 協(xié)議,也可以是 IPX 協(xié)議(互聯(lián)網(wǎng)分組交換協(xié)議)等,只不過以太網(wǎng) + TCP/IP 成為 IT 行業(yè)中應(yīng)用最普遍的技術(shù)。下面我們來熟悉下 ARP 協(xié)議。


2.3 ARP 協(xié)議

ARP 協(xié)議屬于 TCP/IP 協(xié)議簇的一種,從前面介紹的圖(以太網(wǎng)ARP 數(shù)據(jù)包格式)可以看出,ARP 協(xié)議位于以太網(wǎng) MAC 幀格式的數(shù)據(jù)段,ARP 數(shù)據(jù)包格式如下圖所示。

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip

名稱 功能
硬件類型(Hardware type 硬件地址的類型,1 表示以太網(wǎng)地址。
協(xié)議類型(Protocol type 要映射的協(xié)議地址類型,ARP 協(xié)議的上層協(xié)議為 IP 協(xié)議,因此該協(xié)議類型為 IP 協(xié)議,其值為 0x0800
硬件地址長度(Hardware size 硬件地址(MAC 地址)的長度,以字節(jié)為單位。對于以太網(wǎng)上 IP 地址的 ARP 請求或者應(yīng)答來說,該值為 6。
協(xié)議地址長度(Protocol size IP 地址的長度,以字節(jié)為單位。對于以太網(wǎng)上 IP 地址的 ARP 請求或者應(yīng)答來說,該值為 4
OPOpcode 操作碼,用于表示該數(shù)據(jù)包為 ARP 請求或者 ARP 應(yīng)答。1 表示 ARP 請求,2 表示 ARP 應(yīng)答。
MAC 地址 發(fā)送端的硬件地址。
IP 地址 發(fā)送端的協(xié)議(IP)地址,如 192.168.1.102。
目的 MAC 地址 接收端的硬件地址,在 ARP 請求時由于不知道接收端 MAC 地址,因此該字段為廣播地址, 即 48’hff_ff_ff_ff_ff_ff。
目的 IP 地址 接收端的協(xié)議(IP)地址,如 192.168.1.10

以太網(wǎng)的幀格式、ARP 數(shù)據(jù)格式到這里已經(jīng)全部介紹完了,關(guān)于通過以太網(wǎng)傳輸 ARP 報文的格式如下圖所示。

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip

由上圖可知,28 字節(jié)的 ARP 數(shù)據(jù)位于以太網(wǎng)幀格式的數(shù)據(jù)段。由于以太網(wǎng)數(shù)據(jù)段最少為 46 個字節(jié),而 ARP 數(shù)據(jù)包總長度為 28 個字節(jié),因此在 ARP 數(shù)據(jù)段后面需要填充 18 個字節(jié)的數(shù)據(jù),以滿足以太網(wǎng)傳輸格式的要求。這個填充的過程稱為 Padding(填充),填充的數(shù)據(jù)可以為任意值,但一般為 0。


2.4 RGMII 接口介紹

以太網(wǎng)的通信離不開物理層 PHY 芯片的支持,以太網(wǎng) MACPHY 之間有一個接口,常用的接口有 MII、RMII、GMII、RGMII 等。

名稱 功能
MIIMedium Independent Interface,媒體獨立接口) MII 支持 10Mbps100Mbps 的操作,數(shù)據(jù)位寬為 4 位,在 100Mbps 傳輸速率下,時鐘頻率為 25Mhz
RMIIReduced MII RMIIMII 的簡化版,數(shù)據(jù)位寬為 2 位,在 100Mbps 傳輸速率下,時鐘頻率為 50Mhz。
GMIIGigabit MII GMII 接口向下兼容 MII 接口,支持 10Mbps100Mbps1000Mbps 的操作,數(shù)據(jù)位寬為 8 位,在 1000Mbps 傳輸速率下,時鐘頻率為 125Mhz
RGMIIReduced GMII RGMIIGMII 的簡化版,數(shù)據(jù)位寬為 4 位,在 1000Mbps 傳輸速率下,時鐘頻率為 125Mhz,在時鐘的上下沿同時采樣數(shù)據(jù)。在 100Mbps10Mbps 通信速率下,為單個時鐘沿采樣。

在千兆以太網(wǎng)中,常用的接口為 RGMIIGMII 接口。RGMII 接口的優(yōu)勢是同時適用于 10M/100M/1000Mbps 通信速率,同時占用的引腳數(shù)較少。但 RGMII 接口也有其缺點,就是在 PCB 布線時需要盡可能對時鐘、控制和數(shù)據(jù)線進(jìn)行等長處理,且時序約束相對也更為嚴(yán)格。

為了節(jié)省引腳,目前市面上大部分 FPGA 開發(fā)板板載的 PHY 芯片采用的接口為 RGMII 接口,下圖是 MAC 側(cè)與 PHY 側(cè)接口的連接。

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip

名稱 功能
ETH_RXC 接收數(shù)據(jù)參考時鐘,1000Mbps 速率下,時鐘頻率為 125MHz,時鐘為上下沿同時采樣;100Mbps 速率下,時鐘頻率為 25MHz;10Mbps 速率下,時鐘頻率為 2.5MHz,ETH_RXCPHY 側(cè)提供。
ETH_RXCTLETH_RX_DV 接收數(shù)據(jù)控制信號。
ETH_RXD 四位并行的接收數(shù)據(jù)線。
ETH_TXC 發(fā)送參考時鐘,1000Mbps 速率下,時鐘頻率為 125MHz,時鐘為上下沿同時采樣;100Mbps 速率下,時鐘頻率為 25MHz;10Mbps 速率下,時鐘頻率為 2.5MHz,ETH_TXCMAC 側(cè)提供。
ETH_TXCTLETH_TXEN 發(fā)送數(shù)據(jù)控制信號。
ETH_TXD 四位并行的發(fā)送數(shù)據(jù)線。
ETH_RESET_N 芯片復(fù)位信號,低電平有效。
ETH_MDC 數(shù)據(jù)管理時鐘(Management Data Clock),該引腳對 ETH_MDIO 信號提供了一個同步的時鐘。
ETH_MDIO 數(shù)據(jù)輸入/輸出管理(Management Data Input/Output),該引腳提供了一個雙向信號用于傳遞管理信息。

其中 ETH_RXC、ETH_RXCTLETH_RXDMAC 接收側(cè)引腳;ETH_TXC、ETH_TXCTLETH_TXDMAC 發(fā)送側(cè)引腳;ETH_MDCETH_MDIOMDIO 接口引腳,用于配置 PHY 芯片內(nèi)部寄存器;ETH_RST_NPHY 芯片硬件復(fù)位信號。

由于 PHY 芯片的內(nèi)部寄存器在默認(rèn)配置下也可以正常工作,因此本次實驗沒有對 MDIO 接口進(jìn)行讀寫操作,只用到了以太網(wǎng)的 RGMII 接口信號和復(fù)位信號。

RGMII 使用 4bit 數(shù)據(jù)接口,在 1000Mbps 通信速率下,ETH_TXCETH_RXC 的時鐘頻率為 125Mhz,采用上下沿 DDRDouble Data Rate)的方式在一個時鐘周期內(nèi)傳輸 8 位數(shù)據(jù)信號,即上升沿發(fā)送/接收低 4 位數(shù)據(jù),下降沿發(fā)送/接收高 4 位數(shù)據(jù)。

ETH_TXCTLETH_RXCTL 控制信號同樣采用 DDR 的方式在一個時鐘周期內(nèi)傳輸兩位控制信號,即上升沿發(fā)送/接收數(shù)據(jù)使能(TX_EN/RX_DV)信號,下降沿發(fā)送 / 接收使能信號與錯誤信號的異或值(TX_ERR xor TX_ENRX_ERR xor RX_DV)。

當(dāng) RX_DV 為高電平(表示數(shù)據(jù)有效),RX_ERR 為低電平(表示數(shù)據(jù)無錯誤),則異或的結(jié)果值為高電平,因此只有當(dāng) ETH_RXCTLETH_TXCTL 信號的上下沿同時為高電平時,發(fā)送和接收的數(shù)據(jù)有效且正確。

當(dāng) RGMII 工作在 100Mbps 時,ETH_TXCETH_RXC 的時鐘頻率為 25Mhz,采用上升沿 SDR 的方式在一個周期內(nèi)傳輸 4 位數(shù)據(jù)。不過此時 ETH_TXCTLETH_RXCTL 控制信號仍采用上下沿 DDR 的傳輸方式。

當(dāng) RGMII 工作在 10Mbps 時,ETH_TXCETH_RXC 的時鐘頻率為 2.5Mhz,采用上升沿 SDR 的方式在一個周期內(nèi)傳輸 4 位數(shù)據(jù)。ETH_TXCTLETH_RXCTL 控制信號也采用 SDR 的傳輸方式。


2.5 RGMII 接口時序

PHY 芯片的 RGMII 接口時序,其時鐘、控制信號和數(shù)據(jù)的對齊方式,一般由 MDIO 接口或者硬件上的特殊引腳進(jìn)行配置。

RGMII 接收端口時鐘、控制信號和數(shù)據(jù)對齊的時序圖如下所示。

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip

由上圖可知,RXC 的上下邊沿與 RXDRX_CTL 信號對齊,相位相同。

RGMII 接收端口時鐘和控制 / 數(shù)據(jù)信號增加延時的時序圖如下圖所示。

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip

由上圖可知,RXC 的上下邊沿與 RXDRX_CTL 信號的中間位置對齊,RXC 的時鐘周期為 8ns,單個高電平或者低電平為 4nsRXC 相對于 RXDRX_CTL 延時約 2ns。

YT8511 RGMII 接收端口的信號對齊模式由硬件上的特殊引腳外接上下拉電阻進(jìn)行配置,如下圖所示。

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip

從上圖中可以看出,當(dāng)管腳 LED_10_100 接上拉電阻時,表示 RXC 時鐘相對于 RXD 信號,會增加約 2ns 的延時。

我做本次實驗使用的ATK-DFPGL22G 硬件原理圖中 YT8511 的管腳 LED_10_100 連接的是上拉電阻,因此 RXCRXD 之間會有約 2ns 的延時。

RGMII 發(fā)送端口正常模式時序圖如下所示。

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip

由上圖可知,RGMII 發(fā)送端口正常模式下,需要滿足 TXC 的上下邊沿與 TXDTX_CTL 信號對齊,相位相同。YT8511 在硬件上面沒有做 TX 端的 delay 模式,可根據(jù)實際情況,選擇是否在代碼中進(jìn)行延時(因為一般對端設(shè)備的接收端會有延時處理的功能,因此發(fā)送端也可以不延時),延時后的時序圖如下圖所示。

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip

RGMII 的接口時序可知,RGMII 發(fā)送端口在 TXC 時鐘的上升沿傳輸 TXD 的低 4 位和 TX_CTL 的使能信號;下降沿傳輸 TXD 的高 4 位和 TX_CTL 的錯誤信號(實際上是使能信號和錯誤信號的異或值);RGMII 接收端口在 RXC 時鐘的上升沿傳輸 RXD 的低 4 位和 RX_CTL 的使能信號;下降沿傳輸 RXD 的高 4 位和 RX_CTL 的錯誤信號(實際上是使能信號和錯誤信號的異或值)。

至此,關(guān)于本實驗的理論知識講解完畢。為了更高效的完成設(shè)計,我用到了原語,這是本頻道的公開實驗中第一次用到原語,下面我會給大家詳細(xì)的進(jìn)行講解。



3 Pango 原語

原語,即 primitive,原語類似最底層的描述方法,是不同廠商針對自己 FPGA 芯片提供的底邏輯資源的描述。因此不同的廠商,原語不同,同一家的 FPGA,由于不同系列的芯片內(nèi)部資源一般不同,原語也是不通用的。使用原語的好處,可以直接例化使用,不用定制 IP。我們在進(jìn)行 FPGA 開發(fā)時的 HDL 代碼在進(jìn)行綜合后的輸出就是由原語組成的邏輯網(wǎng)表,因此原語是不會參于綜合過程的。

我們在集成開發(fā)工具中能夠例化的原語模板實質(zhì)不是真正的原語,為了設(shè)計人員設(shè)計方便其已經(jīng)經(jīng)過一層封裝,不過通常還是將其稱為原語。正如前面所說,原語是對底層資源的直接描述,因此其抽象層次低,是需要考慮實現(xiàn)細(xì)節(jié)更多的一種實現(xiàn),采用原語的設(shè)計方式對于 FPGA 底層資源理解要高。一般在實際 HDL 代碼編寫中,不需要去進(jìn)行原語的調(diào)用,我們進(jìn)行 HDL 代碼這種抽象層次更高的設(shè)計,將具體細(xì)節(jié)交給了集成開發(fā)環(huán)境完成。

本文中講解的原語基于紫光同創(chuàng),是 Pango 器件底層硬件中的功能模塊,它使用專用的資源來實現(xiàn)一系列的功能。相比于 IP 核,原語的調(diào)用方法更簡單,但是一般只用于實現(xiàn)一些簡單的功能。本文主要用到了 GTP_OUTBUFT、IDDR、ODDR,接下來給大家進(jìn)行詳細(xì)的講解。


3.1 GTP_OUTBUFT 使用說明

1) 功能介紹

GTP_OUTBUFT: 是一個三態(tài)輸出 BUFFER,如下圖所示。

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip

2) 端口描述

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip

3) 參數(shù)描述

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip

4) 實例模板

GTP_OUTBUFT #(
.IOSTANDARD 	("DEFAULT"),
.SLEW_RATE 		("SLOW "),
.DRIVE_STRENGTH (8)
)
GTP_OUTBUFT_inst (
.I (i),
.O (o),
.T (t)
);

3.2 GTP_OSERDES 使用說明

Output DDR 的主要功能是把來自 Fabric 的數(shù)據(jù),從 CLK_SYS 轉(zhuǎn)移到 SERCLK 時鐘域,并轉(zhuǎn)換成高速的串行數(shù)據(jù)流發(fā)送出去。每個 Output DDR 單元可支持輸出速率轉(zhuǎn)換 2:1,4:1,7:18:1

Output DDR 單元可通過參數(shù) OSERDES_MODE 配置成不同的工作模式,這些工作模式包括:ODDR,OMDDR,OSER4,OMSER4OSER7,OSER8OMSER8。PDS 軟件庫為方便用戶使用 Output DDR 單元提供了專用原語,用戶可以在源代碼(Verilog/VHDL)中例化 GTP_OSERDES 原型模塊。以 Verilog 例化為例:

GTP_OSERDES #(
.OSERDES_MODE (“ODDR” ),
.WL_EXTEND 	  (“FALSE” ),
.GRS_EN 	  (“TRUE” ),
.LRS_EN 	  (“TRUE” ),
.TSDDR_INIT   (1'b0 )
)
u_OSERDES(
.DO 	(DO ),
.TQ 	(TQ ),
.DI 	(DI ),
.TI 	(TI ),
.RCLK   (RCLK ),
.SERCLK (SERCLK ),
.OCLK   (OCLK ),
.RST    (RST )
);	

GTP_OSERDES 的參數(shù)及信號說明如下:

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip
GTP_OSERDES 通常跟 GTP_OUTBUF,GTP_OUTBUFDS,GTP_OUTBUFCO,GTP_OUTBUFTCOGTP_OUTBUFTDSGTP_OUTBUFT 一起使用。下圖以 GTP_OUTBUFT 為例,說明了 GTP_OSERDES 與之連接的關(guān)系,GTP_OUTBUFT 的詳細(xì)說明如下圖所示。

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip
在使用 GTP_OSERDES 時,分為有三態(tài)控制和沒有三態(tài)控制兩類模式。當(dāng)沒有三態(tài)控制時,GTP_OSERDES 是不開放 TITQ 的。

下面分別介紹 Output DDR 不同的工作模式。


3.2.1 ODDR

當(dāng) Output DDR 配置為 ODDR 模式時,其功能圖可化簡為下圖。

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip

ODDR 時序圖如下所示。

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip

ODDROMDDROSER4,OMSER4,OSER8OMSER8 均有兩種形態(tài),一種為如上圖所示的帶三態(tài)控制 TS_TO 的輸出,另一種為不帶三態(tài)輸出的輸出,OSER7 只有不帶 TS_TO 的輸出。


3.2.2 OMDDR

當(dāng) Output DDR 配置為 OMDDR 模式時,其功能圖可化簡為下圖。

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip

ODDR 相比,OMDDR 多一次從 CLK_SYSOCLK 的時鐘域轉(zhuǎn)換,時序圖如下圖所示。

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip

3.2.3 OSER4

當(dāng) Output DDR 配置為 OSER4 模式時,與 GTP_OUTBUFTGTP_OUTBUFTDSGTP_OUTBUFTCO 配合使用。其功能圖可化簡為下圖。

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip

OSER4 時序圖如下圖所示。

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip

3.2.4 OMSER4

當(dāng) Output DDR 配置為 OMSER4 模式時,其功能圖可化簡為下圖。

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip

OSER4 相比,OMSER4 增加了從 SERCLKOCLK 的時鐘域轉(zhuǎn)換。OMSER4 的時序圖如下圖所示。

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip


3.2.5 OSER7

當(dāng) Output DDR 配置為 OSER7 模式時,與 GTP_OUTBUF,GTP_OUTBUFDSGTP_OUTBUFCO 配合使用。其功能圖可化簡為下圖。

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip

OSER7 時序圖如下圖所示。

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip

3.2.6 OSER8

當(dāng) Output DDR 配置為 OSER8 模式時,使用方法與 OSER4 相同。其功能圖可化簡為下圖。

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip

OSER8 時序圖如下圖所示。

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip

3.2.7 OMSER8

當(dāng) Output DDR 配置為 OMSER8 模式時,其功能圖可化簡為下圖。

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip

這里的 CLK_R 選擇是 DQSL 接口時鐘相移 180 度。

OSER8 相比,OMSER8 增加了從 SERCLKOCLK 的時鐘域轉(zhuǎn)換。

OMSER8 時序圖如下圖所示。

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip

3.3 GTP_ISERDES 使用說明

Input DDR 單元主要由 IFIFOGEAR LOGIC 兩部分組成。其中,IFIFO 主要作用于 DDR memory interface 中,其功能包括從外部非連續(xù) DQS 到內(nèi)部連續(xù)時鐘的時鐘域轉(zhuǎn)換,DDR3 讀數(shù)據(jù)的 realign,一些特殊的 Generic DDR 應(yīng)用以及補償采樣時鐘和內(nèi)部時鐘的相位差;GEAR LOGIC 的主要功能是擴(kuò)展采樣后的數(shù)據(jù)的位寬,并把它從高速的 DESCLK 轉(zhuǎn)移到較低速的系統(tǒng)時鐘域,以方便 Fabric 處理。

Input DDR 單元可通過參數(shù) ISERDES_MODE 配置成不同的工作模式,這些工作模式包括:IDDR,IMDDR,IDES4IMDES4,IDES7IDES8IMDES8。PDS 軟件庫為方便用戶使用 Input DDR 單元提供了專用原語,用戶可以在源代碼(Verilog/VHDL)中例化 GTP_ISERDES 原型模塊。以 Verilog 例化為例:

GTP_ISERDES #(
.ISERDES_MODE	(“IDDR” ),
.GRS_EN			(“TRUE” ),
.LRS_EN			(“TRUE” )
) 
u_ISERDES(
.DI 	(DI ),
.ICLK 	(ICLK ),
.DESCLK (DESCLK ),
.RCLK	(RCLK ),
.WADDR 	(WADDR ),
.RADDR 	(RADDR ),
.RST 	(RST ),
.DO 	(DO )
);

GTP_ISERDES 的參數(shù)及信號說明如下:

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip
GTP_ISERDES 通常會與 GTP_INBUF,GTP_INBUFGGTP_INBUFDSGTP_INBUFGDS 一起使用,下圖以 GTP_INBUFDS 為例說明 GTP_ISERDES 與之連接的方式。

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip
下面分別介紹 Input DDR 的不同工作模式。


3.3.1 IDDR

當(dāng) Input DDR 配置為 IDDR 模式時,其功能圖可化簡為下圖。

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip
IDDR 時序圖如下圖所示:

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip

注:時序圖中的 a,bc,d 等字母用以代表 bit 數(shù)據(jù)的位置信息, 就數(shù)據(jù)而言數(shù)值為 ‘0’‘1’。


3.3.2 IMDDR

當(dāng) Input DDR 配置為 IMDDR 模式時,與 IDDR 結(jié)構(gòu)相比,IMDDR 使能了其中的 IFIFO。其功能圖可簡化為下面的圖例。

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip

IMDDR 時序圖如下圖所示。

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip


3.3.3 IDES4

當(dāng) Input DDR 配置為 IDES4 時,與 GTP_INBUFGTP_INBUFG,GTP_INBUFDSGTP_INBUFGDS 配合使用。其功能圖可簡化為下面的圖例。

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip

IDES4 時序圖如下圖所示。

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip


3.3.4 IMDES4

當(dāng) Input DDR 配置為 IMDES4 時,與 IDES4 相比,IMDES4 使能了其中的 IFIFO。其功能圖可簡化為如下圖例。

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip

IMDES4 時序圖如下圖所示。

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip

upd 信號在異步 RESET 之后的 1clk 周期后,開始起作用,并且每兩個 CLK_IO 有效一次。


3.3.5 IDES7

當(dāng) Input DDR 配置為 IDES7 時,使用方法與 IDES4 相同。其功能圖可簡化為如下圖例。

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip

IDES7 時序圖如下圖所示。

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip

3.3.6 IDES8

當(dāng) Input DDR 配置為 IDES8 時,使用方法與 IDES4 相同。其功能圖可簡化為如下圖例。

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip

IDES8 時序圖如下圖所示。

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip

3.3.7 IMDES8

當(dāng) Input DDR 配置為 IMDES8 時,與 IDES8 相比,IMDES8 使能了其中的 IFIFO。其功能圖可簡化為如下圖例。

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip

IMDES8 時序圖如下圖所示。

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip

IMDES8 功能時,upd 信號在異步 rst 之后的 2clk 周期后,開始起作用,并且每 4clk 周期有效一次。



3 程序設(shè)計

3.1 總體設(shè)計

學(xué)習(xí)了以上的基本概念,接下來就可以開始程序的設(shè)計了,我們先回顧下實驗任務(wù),如下圖所示。

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip

根據(jù)實驗任務(wù),我們可以大致規(guī)劃出系統(tǒng)的控制流程:首先我們需要完成 RGMII 接口數(shù)據(jù)和 GMII 接口數(shù)據(jù)的轉(zhuǎn)換,以方便數(shù)據(jù)的采集和解析,在數(shù)據(jù)采集過程中所用到的延時原語參考時鐘由鎖相環(huán)輸出的時鐘提供;其次整個以太網(wǎng)幀格式與 ARP 協(xié)議的實現(xiàn)由 ARP 頂層模塊完成;ARP 控制模塊負(fù)責(zé)檢測輸入的觸摸按鍵是否被按下,控制 ARP 頂層模塊發(fā)起請求與產(chǎn)生應(yīng)答等操作。

由此畫出系統(tǒng)的功能框圖如下圖所示:

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip

GMII TO RGMII 模塊負(fù)責(zé)將雙沿(DDR)數(shù)據(jù)和單沿(SDR)數(shù)據(jù)之間的轉(zhuǎn)換;ARP 頂層模塊實現(xiàn)了以太網(wǎng) ARP 數(shù)據(jù)包的接收、發(fā)送以及 CRC 校驗的功能;ARP 控制模塊根據(jù)輸入的按鍵觸摸信號和接收到的 ARP 請求信號,控制 ARP 頂層模塊發(fā)送 ARP 請求或者 ARP 應(yīng)答。

FPGA 頂層模塊例化了以下四個模塊, 網(wǎng)口復(fù)位模塊(reset_dly)、GMII TO RGMII 模塊(gmii_to_rgmii)、ARP 頂層模塊(arp)和 ARP 控制模塊(arp_ctrl),實現(xiàn)了各模塊之間的數(shù)據(jù)交互。

其中 ARP 頂層模塊和 GMII TO RGMII 模塊內(nèi)部也例化了多個其它模塊,這樣設(shè)計的目的是為了方便模塊的重用。

頂層模塊的代碼如下:

module eth_arp_test(
    input              sys_clk   , //系統(tǒng)時鐘
    input              sys_rst_n , //系統(tǒng)復(fù)位信號,低電平有效 
    input              touch_key , //觸摸按鍵,用于觸發(fā)開發(fā)板發(fā)出ARP請求
    //PL以太網(wǎng)RGMII接口   
    input              eth_rxc   , //RGMII接收數(shù)據(jù)時鐘
    input              eth_rx_ctl, //RGMII輸入數(shù)據(jù)有效信號
    input       [3:0]  eth_rxd   , //RGMII輸入數(shù)據(jù)
    output             eth_txc   , //RGMII發(fā)送數(shù)據(jù)時鐘    
    output             eth_tx_ctl, //RGMII輸出數(shù)據(jù)有效信號
    output      [3:0]  eth_txd   , //RGMII輸出數(shù)據(jù)          
    output             eth_rst_n   //以太網(wǎng)芯片復(fù)位信號,低電平有效   
    );

//parameter define
//開發(fā)板MAC地址 00-11-22-33-44-55
parameter  BOARD_MAC = 48'h00_11_22_33_44_55;
//開發(fā)板IP地址 192.168.1.10     
parameter  BOARD_IP  = {8'd192,8'd168,8'd1,8'd10};
//目的MAC地址 ff_ff_ff_ff_ff_ff
parameter  DES_MAC   = 48'hff_ff_ff_ff_ff_ff;
//目的IP地址 192.168.1.102
parameter  DES_IP    = {8'd192,8'd168,8'd1,8'd102};

//wire define
wire  [7:0]   gmii_txd    ; //GMII發(fā)送數(shù)據(jù)
wire          gmii_tx_en  ; //GMII發(fā)送數(shù)據(jù)使能信號
wire          gmii_tx_clk ; //GMII發(fā)送時鐘
wire  [7:0]   gmii_rxd    ; //GMII接收數(shù)據(jù) 
wire          gmii_rx_dv  ; //GMII接收數(shù)據(jù)有效信號
wire          gmii_rx_clk ; //GMII接收時鐘

wire          arp_rx_done ; //ARP接收完成信號
wire          arp_rx_type ; //ARP接收類型 0:請求  1:應(yīng)答
wire  [47:0]  src_mac     ; //接收到目的MAC地址
wire  [31:0]  src_ip      ; //接收到目的IP地址    
wire          arp_tx_en   ; //ARP發(fā)送使能信號
wire          arp_tx_type ; //ARP發(fā)送類型 0:請求  1:應(yīng)答
wire          tx_done     ; //ARP發(fā)送完成信號 
wire  [47:0]  des_mac     ; //發(fā)送的目標(biāo)IP地址
wire  [31:0]  des_ip      ; //以太網(wǎng)發(fā)送完成信號
//*****************************************************
//**                    main code
//*****************************************************
assign des_mac = src_mac;
assign des_ip = src_ip;

//輸出網(wǎng)口復(fù)位信號
reset_dly delay_u0(
    .clk           (sys_clk  ),
    .rst_n         (sys_rst_n),
    .rst_n_dly     (eth_rst_n)
);

gmii_to_rgmii u_gmii_to_rgmii(
	.rgmii_txd              (eth_txd   ),
	.rgmii_tx_ctl           (eth_tx_ctl),
	.rgmii_txc              (eth_txc   ),
	.rgmii_rxd              (eth_rxd   ),
	.rgmii_rx_ctl           (eth_rx_ctl),
    .rgmii_rxc              (eth_rxc   ),
    
	.gmii_rx_clk            (gmii_rx_clk),
	.gmii_txd               (gmii_txd   ),
	.gmii_tx_en             (gmii_tx_en ),
	.gmii_tx_clk            (gmii_tx_clk),
	.gmii_rxd               (gmii_rxd   ),
	.gmii_rx_dv             (gmii_rx_dv )
	);

//ARP通信
arp                                             
   #(
    .BOARD_MAC     (BOARD_MAC),      //參數(shù)例化
    .BOARD_IP      (BOARD_IP ),
    .DES_MAC       (DES_MAC  ),
    .DES_IP        (DES_IP   )
    )
   u_arp(
    .rst_n         (sys_rst_n  ),
                    
    .gmii_rx_clk   (gmii_rx_clk),
    .gmii_rx_dv    (gmii_rx_dv ),
    .gmii_rxd      (gmii_rxd   ),
    .gmii_tx_clk   (gmii_tx_clk),
    .gmii_tx_en    (gmii_tx_en ),
    .gmii_txd      (gmii_txd   ),
                    
    .arp_rx_done   (arp_rx_done),
    .arp_rx_type   (arp_rx_type),
    .src_mac       (src_mac    ),
    .src_ip        (src_ip     ),
    .arp_tx_en     (arp_tx_en  ),
    .arp_tx_type   (arp_tx_type),
    .des_mac       (des_mac    ),
    .des_ip        (des_ip     ),
    .tx_done       (tx_done    )
    );

//ARP控制
arp_ctrl u_arp_ctrl(
    .clk           (gmii_rx_clk),
    .rst_n         (sys_rst_n  ),
 
    .touch_key     (touch_key  ),
    .arp_rx_done   (arp_rx_done),
    .arp_rx_type   (arp_rx_type),
    .arp_tx_en     (arp_tx_en  ),
    .arp_tx_type   (arp_tx_type)
    );

endmodule

頂層模塊主要完成對其余模塊的例化。在程序的第 16 行至第 23 行代碼定義了開發(fā)板的 MAC 地址、IP 地址、默認(rèn)的目的 MAC 地址和目的 IP 地址。

開發(fā)板的 MAC 地址為 00:11:22:33:44:55;可開發(fā)板的 IP 地址為 192.168.1.10;默認(rèn)目的 MAC 地址為 ff:ff:ff:ff:ff:ff,這是一個廣播 MAC 地址,在收到上位機的請求或者應(yīng)答之后,ARP 模塊會替換成實際的目的 MAC 地址。目的 IP 地址這里設(shè)置為 192.168.1.102,因此大家在做本次實驗時,需要把電腦的以太網(wǎng)的 IP 地址改成 192.168.1.102,或者將代碼中定義的 DES_IP 改成電腦的 IP 地址。

這部分非常重要!否則上板實驗無法成功,關(guān)于如何修改 IP 見本文第四部分(下載驗證)。

程序的第 45 行和 46 行代碼將收到的對端設(shè)備 MAC 地址和目的 IP 地址,作為開發(fā)板發(fā)送時的目的 MAC 地址和 IP 地址。


3.2 gmii_to_rgmii 模塊設(shè)計

gmii_to_rgmii 模塊代碼如下:

module gmii_to_rgmii(
    //以太網(wǎng)GMII接口
    output             gmii_rx_clk , //GMII接收時鐘
    output             gmii_rx_dv  , //GMII接收數(shù)據(jù)有效信號
    output      [7:0]  gmii_rxd    , //GMII接收數(shù)據(jù)
    output             gmii_tx_clk , //GMII發(fā)送時鐘
    input              gmii_tx_en  , //GMII發(fā)送數(shù)據(jù)使能信號
    input       [7:0]  gmii_txd    , //GMII發(fā)送數(shù)據(jù)            
    //以太網(wǎng)RGMII接口   
    input              rgmii_rxc   , //RGMII接收時鐘
    input              rgmii_rx_ctl, //RGMII接收數(shù)據(jù)控制信號
    input       [3:0]  rgmii_rxd   , //RGMII接收數(shù)據(jù)
    output             rgmii_txc   , //RGMII發(fā)送時鐘    
    output             rgmii_tx_ctl, //RGMII發(fā)送數(shù)據(jù)控制信號
    output      [3:0]  rgmii_txd     //RGMII發(fā)送數(shù)據(jù)          
    );
//wire
wire   pll_lock  ;
wire   gmii_tx_er;
//*****************************************************
//**                    main code
//*****************************************************
assign gmii_tx_clk = gmii_rx_clk;
//RGMII接收
rgmii_rx u_rgmii_rx(
    .rgmii_rxc        (rgmii_rxc      ),
    .rgmii_rx_ctl     (rgmii_rx_ctl   ),
    .rgmii_rxd        (rgmii_rxd      ),
                      
    .gmii_rx_clk      (gmii_rx_clk    ),
    .gmii_rx_dv       (gmii_rx_dv     ),
    .gmii_rxd         (gmii_rxd       ),
    .gmii_tx_clk_deg  (gmii_tx_clk_deg),
    .pll_lock         (pll_lock       )
    );

//RGMII發(fā)送
rgmii_tx u_rgmii_tx(
    .reset            (1'b0           ),

    .gmii_tx_er       (1'b0           ),
    .gmii_tx_clk      (gmii_tx_clk    ),
    .gmii_tx_en       (gmii_tx_en     ),
    .gmii_txd         (gmii_txd       ),
    .gmii_tx_clk_deg  (gmii_tx_clk_deg),
    
    .rgmii_txc        (rgmii_txc      ),
    .rgmii_tx_ctl     (rgmii_tx_ctl   ),
    .rgmii_txd        (rgmii_txd      )
    );

endmodule

由該模塊的端口可知,該模塊實現(xiàn)了雙沿(DDR)數(shù)據(jù)和單沿(SDR)數(shù)據(jù)之間的轉(zhuǎn)換。程序中第 23 行將 GMII 接收時鐘賦值給 GMII 發(fā)送時鐘,因此 GMII 的發(fā)送時鐘和接收時鐘實際上為同一個時鐘。GMII TO RGMII 模塊例化了 rgmii_rx 模塊和 rgmii_tx 模塊。

rgmii_rx 模塊代碼如下所示:

module rgmii_rx(
    //以太網(wǎng)RGMII接口
    input              rgmii_rxc      , //RGMII接收時鐘
    input              rgmii_rx_ctl   , //RGMII接收數(shù)據(jù)控制信號
    input       [3:0]  rgmii_rxd      , //RGMII接收數(shù)據(jù)    

    //以太網(wǎng)GMII接口
    output             gmii_rx_clk    , //GMII接收時鐘
    output  reg        gmii_rx_dv     , //GMII接收數(shù)據(jù)有效信號
    output  reg  [7:0] gmii_rxd       , //GMII接收數(shù)據(jù) 
    output             gmii_tx_clk_deg,
    output             pll_lock
    );
    
//define wire
wire            gmii_rx_dv_s;
wire  [ 7:0]    gmii_rxd_s;
//*****************************************************
//**                    main code
//*****************************************************
pll_sft U_pll_phase_shift(   
    .clkout0   (gmii_rx_clk    ),   //125MHz
    .clkout1   (gmii_tx_clk_deg),
    .clkin1    (rgmii_rxc      ),
    .clkfb     (gmii_rx_clk    ),
    .pll_rst   (1'b0           ),
    .pll_lock  (pll_lock       )
    );
    

always @(posedge gmii_rx_clk)
begin
    gmii_rxd   = gmii_rxd_s;
    gmii_rx_dv = gmii_rx_dv_s;
end

wire [5:0] nc1;
GTP_ISERDES #(
    .ISERDES_MODE    ("IDDR"),  //"IDDR","IMDDR","IGDES4","IMDES4","IGDES7","IGDES8","IMDES8"
    .GRS_EN          ("TRUE"),  //"TRUE"; "FALSE"
    .LRS_EN          ("TRUE")   //"TRUE"; "FALSE"
) igddr1(         
    .DI              (rgmii_rxd[0]),
    .ICLK            (1'd0        ),
    .DESCLK          (gmii_rx_clk ),
    .RCLK            (gmii_rx_clk ),
    .WADDR           (3'd0        ),
    .RADDR           (3'd0        ),
    .RST             (1'b0        ),
    .DO              ({gmii_rxd_s[4],gmii_rxd_s[0],nc1})
);

wire [5:0] nc2;
GTP_ISERDES #(
    .ISERDES_MODE    ("IDDR"),  //"IDDR","IMDDR","IGDES4","IMDES4","IGDES7","IGDES8","IMDES8"
    .GRS_EN          ("TRUE"),  //"TRUE"; "FALSE"
    .LRS_EN          ("TRUE")   //"TRUE"; "FALSE"
) igddr2(
    .DI              (rgmii_rxd[1]),
    .ICLK            (1'd0        ),
    .DESCLK          (gmii_rx_clk ),
    .RCLK            (gmii_rx_clk ),
    .WADDR           (3'd0        ),
    .RADDR           (3'd0        ),
    .RST             (1'b0        ),
    .DO              ({gmii_rxd_s[5],gmii_rxd_s[1],nc2})
);

wire [5:0] nc3;
GTP_ISERDES #(
    .ISERDES_MODE    ("IDDR"),  //"IDDR","IMDDR","IGDES4","IMDES4","IGDES7","IGDES8","IMDES8"
    .GRS_EN          ("TRUE"),  //"TRUE"; "FALSE"
    .LRS_EN          ("TRUE")   //"TRUE"; "FALSE"
) igddr3(
    .DI              (rgmii_rxd[2]),
    .ICLK            (1'd0        ),
    .DESCLK          (gmii_rx_clk ),
    .RCLK            (gmii_rx_clk ),
    .WADDR           (3'd0        ),
    .RADDR           (3'd0        ),
    .RST             (1'b0        ),
    .DO              ({gmii_rxd_s[6],gmii_rxd_s[2],nc3})
);

wire [5:0] nc4;
GTP_ISERDES #(
    .ISERDES_MODE    ("IDDR"),  //"IDDR","IMDDR","IGDES4","IMDES4","IGDES7","IGDES8","IMDES8"
    .GRS_EN          ("TRUE"),  //"TRUE"; "FALSE"
    .LRS_EN          ("TRUE")   //"TRUE"; "FALSE"
) igddr4(
    .DI              (rgmii_rxd[3]),
    .ICLK            (1'd0        ),
    .DESCLK          (gmii_rx_clk ),
    .RCLK            (gmii_rx_clk ),
    .WADDR           (3'd0        ),
    .RADDR           (3'd0        ),
    .RST             (1'b0        ),
    .DO              ({gmii_rxd_s[7],gmii_rxd_s[3],nc4})
);

wire [5:0] nc5;
GTP_ISERDES #(
    .ISERDES_MODE    ("IDDR"),  //"IDDR","IMDDR","IGDES4","IMDES4","IGDES7","IGDES8","IMDES8"
    .GRS_EN          ("TRUE"),  //"TRUE"; "FALSE"
    .LRS_EN          ("TRUE")   //"TRUE"; "FALSE"
) igddr5(
    .DI              (rgmii_rx_ctl),
    .ICLK            (1'd0        ),
    .DESCLK          (gmii_rx_clk ),
    .RCLK            (gmii_rx_clk ),
    .WADDR           (3'd0        ),
    .RADDR           (3'd0        ),
    .RST             (1'b0        ),
    .DO              ({rgmii_rx_ctl_s,gmii_rx_dv_s,nc5})
);

endmodule

該模塊通過調(diào)用 GTP_ISERDES 原語,實現(xiàn)了 RGMII 接口輸入的 DDR 數(shù)據(jù)到 SDR 數(shù)據(jù)的轉(zhuǎn)換,輸入的 rgmii_rx_ctl 控制信號的轉(zhuǎn)換方法同樣類似。rgmii_rx 模塊信號轉(zhuǎn)換示意圖如下圖所示:

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip
時鐘專用引腳輸入的 rgmii_rxc 時鐘經(jīng)過 PLL 后,得到 rgmii_rx_clk

rgmii_rx_ctl 控制信號和 4rgmii_rxd 數(shù)據(jù)先經(jīng)過 GTP_ISERDESIDDR 模式) 將雙沿 1 位數(shù)據(jù)轉(zhuǎn)換成單沿兩位數(shù)據(jù)。

另外,在程序的第 40 行至 122 行代碼是對 GTP_ISERDES 的 5 次例化。

rgmii_tx 模塊代碼如下所示:

module rgmii_tx(
    input              reset,
    //GMII發(fā)送端口
    input              gmii_tx_er     , //GMII輸出數(shù)據(jù)有效信號
    input              gmii_tx_clk    , //GMII發(fā)送時鐘    
    input              gmii_tx_en     , //GMII發(fā)送數(shù)據(jù)使能信號
    input       [7:0]  gmii_txd       , //GMII輸出數(shù)據(jù)    
    input              gmii_tx_clk_deg, //GMII發(fā)送時鐘相位偏移45度
    //RGMII發(fā)送端口
    output             rgmii_txc      , //RGMII發(fā)送數(shù)據(jù)時鐘    
    output             rgmii_tx_ctl   , //RGMII輸出數(shù)據(jù)有效信號
    output      [3:0]  rgmii_txd        //RGMII輸出數(shù)據(jù)
    );
// registers
reg             tx_reset_d1    ;
reg             tx_reset_sync  ;
reg             rx_reset_d1    ;

reg   [ 7:0]    gmii_txd_r     ;
reg   [ 7:0]    gmii_txd_r_d1  ;

reg             gmii_tx_en_r   ;
reg             gmii_tx_en_r_d1;

reg             gmii_tx_er_r   ;

reg             rgmii_tx_ctl_r ;
reg   [ 3:0]    gmii_txd_low   ;

// wire
wire            padt1   ;
wire            padt2   ;
wire            padt3   ;
wire            padt4   ;
wire            padt5   ;
wire            padt6   ;
wire            stx_txc ;
wire            stx_ctr ;
wire  [3:0]     stxd_rgm;
//*****************************************************
//**                    main code
//*****************************************************
always @(posedge gmii_tx_clk) begin
    tx_reset_d1   <= reset;
    tx_reset_sync <= tx_reset_d1;
end

always @(posedge gmii_tx_clk) begin
    if (tx_reset_sync == 1'b1) begin
        gmii_txd_r   <= 8'h0;
        gmii_tx_en_r <= 1'b0;
        gmii_tx_er_r <= 1'b0;
    end
    else
    begin
        gmii_txd_r      <= gmii_txd;
        gmii_tx_en_r    <= gmii_tx_en;
        gmii_tx_er_r    <= gmii_tx_er;
        gmii_txd_r_d1   <= gmii_txd_r;
        gmii_tx_en_r_d1 <= gmii_tx_en_r;
    end
end

always @(posedge gmii_tx_clk)
begin
    rgmii_tx_ctl_r = gmii_tx_en_r ^ gmii_tx_er_r;
    gmii_txd_low   = gmii_txd_r[7:4];
end

//輸出雙沿采樣寄存器 (rgmii_txd)
GTP_OSERDES #(
    .OSERDES_MODE    ("ODDR" ),  //"ODDR","OMDDR","OGSER4","OMSER4","OGSER7","OGSER8",OMSER8"
    .WL_EXTEND       ("FALSE"),  //"TRUE"; "FALSE"
    .GRS_EN          ("TRUE" ),  //"TRUE"; "FALSE"
    .LRS_EN          ("TRUE" ),  //"TRUE"; "FALSE"
    .TSDDR_INIT      (1'b0   )   //1'b0;1'b1
) gtp_ogddr6(     
    .DO              (stx_txc        ),
    .TQ              (padt6          ),
    .DI              ({7'd0,1'b1}    ),
    .TI              (4'd0           ),
    .RCLK            (gmii_tx_clk_deg),
    .SERCLK          (gmii_tx_clk_deg),
    .OCLK            (1'd0           ),
    .RST             (tx_reset_sync  )
);
GTP_OUTBUFT  gtp_outbuft6
(
    .I    (stx_txc  ),
    .T    (padt6    ),
    .O    (rgmii_txc)
);


GTP_OSERDES #(
    .OSERDES_MODE    ("ODDR" ),  //"ODDR","OMDDR","OGSER4","OMSER4","OGSER7","OGSER8",OMSER8"
    .WL_EXTEND       ("FALSE"),  //"TRUE"; "FALSE"
    .GRS_EN          ("TRUE" ),  //"TRUE"; "FALSE"
    .LRS_EN          ("TRUE" ),  //"TRUE"; "FALSE"
    .TSDDR_INIT      (1'b0   )   //1'b0;1'b1
) gtp_ogddr2(     
    .DO              (stxd_rgm[3]  ),
    .TQ              (padt2        ),
    .DI              ({6'd0,gmii_txd_low[3],gmii_txd_r_d1[3]}),
    .TI              (4'd0         ),
    .RCLK            (gmii_tx_clk  ),
    .SERCLK          (gmii_tx_clk  ),
    .OCLK            (1'd0         ),
    .RST             (tx_reset_sync)
); 
GTP_OUTBUFT  gtp_outbuft2
(
    .I    (stxd_rgm[3]),
    .T    (padt2      ),
    .O    (rgmii_txd[3])
);


GTP_OSERDES #(
    .OSERDES_MODE    ("ODDR" ),  //"ODDR","OMDDR","OGSER4","OMSER4","OGSER7","OGSER8",OMSER8"
    .WL_EXTEND       ("FALSE"),  //"TRUE"; "FALSE"
    .GRS_EN          ("TRUE" ),  //"TRUE"; "FALSE"
    .LRS_EN          ("TRUE" ),  //"TRUE"; "FALSE"
    .TSDDR_INIT      (1'b0   )   //1'b0;1'b1
) gtp_ogddr3(     
    .DO              (stxd_rgm[2]  ),
    .TQ              (padt3        ),
    .DI              ({6'd0,gmii_txd_low[2],gmii_txd_r_d1[2]}),
    .TI              (4'd0         ),
    .RCLK            (gmii_tx_clk  ),
    .SERCLK          (gmii_tx_clk  ),
    .OCLK            (1'd0         ),
    .RST             (tx_reset_sync)
); 
GTP_OUTBUFT  gtp_outbuft3
(    
    .I    (stxd_rgm[2]),
    .T    (padt3      ),
    .O    (rgmii_txd[2])
);


GTP_OSERDES #(
    .OSERDES_MODE    ("ODDR" ),  //"ODDR","OMDDR","OGSER4","OMSER4","OGSER7","OGSER8",OMSER8"
    .WL_EXTEND       ("FALSE"),  //"TRUE"; "FALSE"
    .GRS_EN          ("TRUE" ),  //"TRUE"; "FALSE"
    .LRS_EN          ("TRUE" ),  //"TRUE"; "FALSE"
    .TSDDR_INIT      (1'b0   )   //1'b0;1'b1
) gtp_ogddr4(     
    .DO              (stxd_rgm[1]  ),
    .TQ              (padt4        ),
    .DI              ({6'd0,gmii_txd_low[1],gmii_txd_r_d1[1]}),
    .TI              (4'd0         ),
    .RCLK            (gmii_tx_clk  ),
    .SERCLK          (gmii_tx_clk  ),
    .OCLK            (1'd0         ),
    .RST             (tx_reset_sync)
); 
GTP_OUTBUFT  gtp_outbuft4
(
    .I    (stxd_rgm[1]),
    .T    (padt4      ),
    .O    (rgmii_txd[1])
);


GTP_OSERDES #(
    .OSERDES_MODE    ("ODDR" ),  //"ODDR","OMDDR","OGSER4","OMSER4","OGSER7","OGSER8",OMSER8"
    .WL_EXTEND       ("FALSE"),  //"TRUE"; "FALSE"
    .GRS_EN          ("TRUE" ),  //"TRUE"; "FALSE"
    .LRS_EN          ("TRUE" ),  //"TRUE"; "FALSE"
    .TSDDR_INIT      (1'b0   )   //1'b0;1'b1
) gtp_ogddr5(     
    .DO              (stxd_rgm[0]  ),
    .TQ              (padt5        ),
    .DI              ({6'd0,gmii_txd_low[0],gmii_txd_r_d1[0]}),
    .TI              (4'd0         ),
    .RCLK            (gmii_tx_clk  ),
    .SERCLK          (gmii_tx_clk  ),
    .OCLK            (1'd0         ),
    .RST             (tx_reset_sync)
); 
GTP_OUTBUFT  gtp_outbuft5
(
    .I    (stxd_rgm[0]),
    .T    (padt5      ),
    .O    (rgmii_txd[0])
);


//輸出雙沿采樣寄存器 (rgmii_tx_ctl)
GTP_OSERDES #( 
    .OSERDES_MODE    ("ODDR" ),  //"ODDR","OMDDR","OGSER4","OMSER4","OGSER7","OGSER8",OMSER8"
    .WL_EXTEND       ("FALSE"),  //"TRUE"; "FALSE"
    .GRS_EN          ("TRUE" ),  //"TRUE"; "FALSE"
    .LRS_EN          ("TRUE" ),  //"TRUE"; "FALSE"
    .TSDDR_INIT      (1'b0   )   //1'b0;1'b1
) gtp_ogddr1(     
    .DO              (stx_ctr      ),
    .TQ              (padt1        ),
    .DI              ({6'd0,rgmii_tx_ctl_r,gmii_tx_en_r_d1}),
    .TI              (4'd0         ),
    .RCLK            (gmii_tx_clk  ),
    .SERCLK          (gmii_tx_clk  ),
    .OCLK            (1'd0         ),
    .RST             (tx_reset_sync)
); 
GTP_OUTBUFT  gtp_outbuft1
(
    .I    (stx_ctr     ),
    .T    (padt1       ),
    .O    (rgmii_tx_ctl)
);

endmodule

該模塊通過調(diào)用 ODDR 原語將輸入的單沿 8 位數(shù)據(jù)(gmii_txd)轉(zhuǎn)換成雙沿采樣的 4 位數(shù)據(jù)(rgmii_txd),gmii_tx_enrgmii_tx_ctl 信號的處理方法同樣類似。rgmii_tx 模塊信號轉(zhuǎn)換示意圖如下圖所示:

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip
gmii_tx_en 數(shù)據(jù)使能信號、gmii_tx_er 輸出數(shù)據(jù)有效信號和 8gmii_txd 數(shù)據(jù)經(jīng)過 GTP_OSERDESODDR 模式將單沿 2 位數(shù)據(jù)轉(zhuǎn)換成雙沿 1 位數(shù)據(jù)。GTP_OSERDES 通常跟 GTP_OUTBUF 一起使用。


3.3 ARP 模塊設(shè)計

ARP 頂層模塊實現(xiàn)了整個以太網(wǎng)幀格式與 ARP 協(xié)議的功能,ARP 頂層模塊例化了 ARP 接收模塊(arp_rx)、ARP 發(fā)送模塊(arp_tx)和 CRC 校驗?zāi)K(crc32_d8)。

ARP 接收模塊(arp_rx):ARP 接收模塊負(fù)責(zé)解析以太網(wǎng)的數(shù)據(jù),判斷目的 MAC 地址和目的 IP 地址是否為開發(fā)板的地址,然后按照 ARP 協(xié)議將數(shù)據(jù)解析出來。當(dāng)解析到正確的 ARP 數(shù)據(jù)包后,拉高 arp_rx_done 信號,持續(xù)一個時鐘周期。

arp_rx_type 用于表示 ARP 數(shù)據(jù)包的類型,0 表示收到 ARP 請求包,1 表示收到 ARP 應(yīng)答包。src_macsrc_ip 分別是解析出的對端設(shè)備 MAC 地址和 IP 地址。

ARP 發(fā)送模塊(arp_tx):ARP 發(fā)送模塊根據(jù)以太網(wǎng)幀格式和 ARP 協(xié)議發(fā)送 ARP 請求或者 ARP 應(yīng)答數(shù)據(jù)。 arp_tx_enarp_tx_type 分別表示 ARP 發(fā)送模塊的使能信號和發(fā)送 ARP 類型。dec_macdec_ip 分別設(shè)置對端設(shè)備 MAC 地址和 IP 地址。

CRC 校驗?zāi)K(crc32_d8):CRC 校驗?zāi)K是對 ARP 發(fā)送模塊的數(shù)據(jù)(不包括前導(dǎo)碼和幀起始界定符) 做校驗,把校驗結(jié)果值拼在以太網(wǎng)幀格式的 FCS 字段, 如果 CRC 校驗值計算錯誤或者沒有的話, 那么電腦網(wǎng)卡會直接丟棄該幀導(dǎo)致收不到數(shù)據(jù)(有些網(wǎng)卡是可以設(shè)置不做校驗的) 。CRC32 校驗在 FPGA 實現(xiàn)的原理是 LFSRLinear Feedback Shift Register,線性反饋移位寄存器),其思想是各個寄存器儲存著上一次 CRC32 運算的結(jié)果,寄存器的輸出即為 CRC32 的值。需要說明的是,本次實驗只對發(fā)送模塊做校驗,沒有對接收模塊做校驗。這是由于我們可以直接通過解析出的數(shù)據(jù)來大致判斷接收是否正確,而發(fā)送模塊必須發(fā)送正確的校驗數(shù)據(jù),否則發(fā)送的數(shù)據(jù)直接被電腦的網(wǎng)卡丟棄,導(dǎo)致 ARP 請求或者應(yīng)答失敗。

在簡介部分我向大家介紹過,ARP 的數(shù)據(jù)包格式包括 前導(dǎo)碼 + SFD、以太網(wǎng)幀頭、ARP 數(shù)據(jù)(包括填充部分?jǐn)?shù)據(jù))和 CRC 校驗。在接收以太網(wǎng)數(shù)據(jù)的過程中,這些不同部分的數(shù)據(jù)可以剛好對應(yīng)狀態(tài)機的不同狀態(tài)位,因此我們可以通過狀態(tài)機來解析以太網(wǎng)的數(shù)據(jù)。

ARP 接收模塊通過狀態(tài)機來解析數(shù)據(jù),其狀態(tài)跳轉(zhuǎn)圖如下圖所示:

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip

接收模塊使用三段式狀態(tài)機來解析以太網(wǎng)包,從上圖可以比較直觀的看到每個狀態(tài)實現(xiàn)的功能以及跳轉(zhuǎn)到下一個狀態(tài)的條件。

這里需要注意的一點是,在中間狀態(tài)如前導(dǎo)碼錯誤、MAC 地址錯誤以及 IP 地址等錯誤時跳轉(zhuǎn)到 st_rx_end 狀態(tài),而不是跳轉(zhuǎn)到 st_idle 狀態(tài)。因為中間狀態(tài)在解析到數(shù)據(jù)錯誤時,單包數(shù)據(jù)的接收還沒有結(jié)束,如果此時跳轉(zhuǎn)到 st_idle 狀態(tài)會誤把有效數(shù)據(jù)當(dāng)成前導(dǎo)碼來解析,所以狀態(tài)跳轉(zhuǎn)到 st_rx_end。而 gmii_rx_dv 信號為 0 時,單包數(shù)據(jù)才算接收結(jié)束,所以 st_rx_end 跳轉(zhuǎn)到 st_idle 的條件是 eth_rxdv = 0,準(zhǔn)備接收下一包數(shù)據(jù)。

因為代碼較長,我只粘貼了第三段狀態(tài)機的接收 ARP 數(shù)據(jù)狀態(tài)和接收結(jié)束狀態(tài)源代碼,代碼如下:

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip

st_arp_data 狀態(tài)根據(jù) ARP 協(xié)議解析數(shù)據(jù),在程序的第 16 行至第 17 行代碼判斷目的 IP 地址和 OP 操作碼是否正確,如果錯誤,則丟棄該包數(shù)據(jù)。在程序的第 211 行至第 214 行代碼根據(jù)操作碼為 arp_rx_type(接收到的 ARP 數(shù)據(jù)包類型)賦值,當(dāng)接收到 ARP 請求包時,arp_rx_type 等于 0;當(dāng)接收到 ARP 應(yīng)答包時,arp_rx_type 等于 1。

ARP 接收過程中仿真的波形圖如下圖所示,gmii_rx_dv 信號拉高表示此時輸入的數(shù)據(jù)有效,根據(jù) gmii_rxd 的值來解析數(shù)據(jù)。從圖中可以看出, 發(fā)送端的 MAC 地址和 ip 地址,以及當(dāng)前接收到的以太網(wǎng)數(shù)據(jù)包類型為 ARP0x0806)。在接收完 ARP 數(shù)據(jù)包之后,拉高 arp_rx_done 信號表示接收完成,圖中 arp_rx_type 信號為低電平,表示當(dāng)前接收到的是 ARP 請求數(shù)據(jù)包。

arp 模塊的仿真代碼如下所示:

module  tb_arp;

//parameter  define
parameter  T = 8;                       //時鐘周期為8ns
parameter  OP_CYCLE = 100;              //操作周期

//開發(fā)板MAC地址 00-11-22-33-44-55
parameter  BOARD_MAC = 48'h00_11_22_33_44_55;     
//開發(fā)板IP地址 192.168.1.10     
parameter  BOARD_IP  = {8'd192,8'd168,8'd1,8'd10};
//目的MAC地址 ff_ff_ff_ff_ff_ff
parameter  DES_MAC   = 48'hff_ff_ff_ff_ff_ff;
//目的IP地址 192.168.1.10
parameter  DES_IP    = {8'd192,8'd168,8'd1,8'd10};

//reg define
reg           gmii_clk;    //時鐘信號
reg           sys_rst_n;   //復(fù)位信號

reg           arp_tx_en  ; //ARP發(fā)送使能信號
reg           arp_tx_type; //ARP發(fā)送類型 0:請求  1:應(yīng)答
reg   [3:0]   flow_cnt   ;
reg   [13:0]  delay_cnt  ;

wire          gmii_rx_clk; //GMII接收時鐘
wire          gmii_rx_dv ; //GMII接收數(shù)據(jù)有效信號
wire  [7:0]   gmii_rxd   ; //GMII接收數(shù)據(jù)
wire          gmii_tx_clk; //GMII發(fā)送時鐘
wire          gmii_tx_en ; //GMII發(fā)送數(shù)據(jù)使能信號
wire  [7:0]   gmii_txd   ; //GMII發(fā)送數(shù)據(jù)
              
wire          arp_rx_done; //ARP接收完成信號
wire          arp_rx_type; //ARP接收類型 0:請求  1:應(yīng)答
wire  [47:0]  src_mac    ; //接收到目的MAC地址
wire  [31:0]  src_ip     ; //接收到目的IP地址    
wire  [47:0]  des_mac    ; //發(fā)送的目標(biāo)MAC地址
wire  [31:0]  des_ip     ; //發(fā)送的目標(biāo)IP地址
wire          tx_done    ; //以太網(wǎng)發(fā)送完成信號 

//*****************************************************
//**                    main code
//*****************************************************

assign gmii_rx_clk = gmii_clk   ;
assign gmii_tx_clk = gmii_clk   ;
assign gmii_rx_dv  = gmii_tx_en ;
assign gmii_rxd    = gmii_txd   ;

assign des_mac = src_mac;
assign des_ip  = src_ip;

//給輸入信號初始值
initial begin
    gmii_clk           = 1'b0;
    sys_rst_n          = 1'b0;     //復(fù)位
    #(T+1)  sys_rst_n  = 1'b1;     //在第(T+1)ns的時候復(fù)位信號信號拉高
end

//125Mhz的時鐘,周期則為1/125Mhz=8ns,所以每4ns,電平取反一次
always #(T/2) gmii_clk = ~gmii_clk;

always @(posedge gmii_clk or negedge sys_rst_n) begin
    if(!sys_rst_n) begin
        arp_tx_en <= 1'b0;
        arp_tx_type <= 1'b0;
        delay_cnt <= 1'b0;
        flow_cnt <= 1'b0;
    end
    else begin
        case(flow_cnt)
            'd0 : flow_cnt <= flow_cnt + 1'b1;
            'd1 : begin
                arp_tx_en <= 1'b1;
                arp_tx_type <= 1'b0;  //發(fā)送ARP請求
                flow_cnt <= flow_cnt + 1'b1;
            end
            'd2 : begin 
                arp_tx_en <= 1'b0;
                flow_cnt <= flow_cnt + 1'b1;
            end    
            'd3 : begin
                if(tx_done)
                    flow_cnt <= flow_cnt + 1'b1;
            end
            'd4 : begin
                delay_cnt <= delay_cnt + 1'b1;
                if(delay_cnt == OP_CYCLE - 1'b1)
                    flow_cnt <= flow_cnt + 1'b1;
            end
            'd5 : begin
                arp_tx_en <= 1'b1;
                arp_tx_type <= 1'b1;  //發(fā)送ARP應(yīng)答   
                flow_cnt <= flow_cnt + 1'b1;                
            end
            'd6 : begin 
                arp_tx_en <= 1'b0;
                flow_cnt <= flow_cnt + 1'b1;
            end 
            'd7 : begin
                if(tx_done)
                    flow_cnt <= flow_cnt + 1'b1;
            end
            default:;
        endcase    
    end
end

//ARP通信
arp                                             
   #(
    .BOARD_MAC     (BOARD_MAC),      //參數(shù)例化
    .BOARD_IP      (BOARD_IP ),
    .DES_MAC       (DES_MAC  ),
    .DES_IP        (DES_IP   )
    )
   u_arp(
    .rst_n         (sys_rst_n  ),
                    
    .gmii_rx_clk   (gmii_rx_clk),
    .gmii_rx_dv    (gmii_rx_dv ),
    .gmii_rxd      (gmii_rxd   ),
    .gmii_tx_clk   (gmii_tx_clk),
    .gmii_tx_en    (gmii_tx_en ),
    .gmii_txd      (gmii_txd   ),
                    
    .arp_rx_done   (arp_rx_done),
    .arp_rx_type   (arp_rx_type),
    .src_mac       (src_mac    ),
    .src_ip        (src_ip     ),
    .arp_tx_en     (arp_tx_en  ),
    .arp_tx_type   (arp_tx_type),
    .des_mac       (des_mac    ),
    .des_ip        (des_ip     ),
    .tx_done       (tx_done    )
    );

endmodule

14 行代碼將目的 ip 地址改寫成與開發(fā)板的 ip 地址一樣,因為仿真的原理是 arp 的環(huán)回,既將 arp 的發(fā)送數(shù)據(jù)直接發(fā)送給 arp 的接收數(shù)據(jù),如果兩個 ip 地址不一樣 error_en 信號會拉高報錯。

ARP 接收采集波形圖如下圖所示。
FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip
ARP 發(fā)送模塊則是根據(jù)以太網(wǎng)幀格式是 ARP 協(xié)議發(fā)送數(shù)據(jù),也就是接收模塊的逆過程, 同樣也非常適合使用狀態(tài)機來完成發(fā)送數(shù)據(jù)的功能,狀態(tài)跳轉(zhuǎn)圖如下圖所示:

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip

發(fā)送模塊接收模塊有很多相似之處,同樣使用三段式狀態(tài)機來發(fā)送以太網(wǎng)包,從上圖可以比較直觀的看到每個狀態(tài)實現(xiàn)的功能以及跳轉(zhuǎn)到下一個狀態(tài)的條件。

發(fā)送模塊的代碼中定義了數(shù)組來存儲前導(dǎo)碼 + 幀頭、以太網(wǎng)的幀頭、ARP 數(shù)據(jù),在復(fù)位時初始化數(shù)組的值,部分源代碼如下。

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip
省略部分代碼…(完整代碼見本文開頭提供的開源地址)

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip

以上代碼在復(fù)位時對數(shù)組進(jìn)行初始化。

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip

以上程序的第 5 行至 26 行代碼,根據(jù)輸入的發(fā)送類型目的 MAC 地址IP 地址,重新更新數(shù)組里的值。

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip

以上程序第 1 行至第 18 行代碼為發(fā)送 ARP 數(shù)據(jù)的狀態(tài)。我前面講過以太網(wǎng)幀格式的數(shù)據(jù)部分最少是 46 個字節(jié),ARP 數(shù)據(jù)只有 28 個字節(jié),因此在發(fā)送完 ARP 數(shù)據(jù)之后補充發(fā)送 18 個字節(jié),填充的數(shù)據(jù)為 0

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip

以上程序的第 1 行至 23 行代碼為發(fā)送 CRC 校驗值狀態(tài),發(fā)送模塊的 CRC 校驗是由 crc32_d8 模塊完成的,發(fā)送模塊將輸入的 crc 的計算結(jié)果每 4 位高低位互換,按位取反發(fā)送出去,crc 計算部分在后面闡述。

ARP 發(fā)送過程中采集的波形圖如下圖所示,arp_tx_en 信號作為開始發(fā)送 ARP 數(shù)據(jù)包的觸發(fā)信號,arp_tx_type 為高電平,表示發(fā)送 ARP 應(yīng)答數(shù)據(jù)包。ARP 應(yīng)答數(shù)據(jù)包中的目的 MAC 地址和目的 IP 地址從 ARP 接收數(shù)據(jù)包中獲取,gmii_tx_en 拉高,表示 gmii_txd 數(shù)據(jù)有效,在發(fā)送完 ARP 數(shù)據(jù)包后,輸出一個脈沖信號(tx_done),表示發(fā)送完成。

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip

CRC 校驗?zāi)K主要完成對 ARP 發(fā)送模塊數(shù)據(jù)的校驗,由于代碼較長,這里不再貼出代碼。CRC32 校驗在 FPGA 實現(xiàn)的原理是線性反饋移位寄存器,其思想是各個寄存器儲存著上一次 CRC32 運算的結(jié)果,寄存器的輸出即為 CRC32 的值。

CRC32 的原理與公式推導(dǎo)較復(fù)雜,在此可不必深究。

CRC32 的生成多項式為:G(x)= x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x^1 +1,只需稍作修改就可以直接使用。

ARP 控制模塊的代碼如下:

module arp_ctrl(
    input                clk        , //輸入時鐘   
    input                rst_n      , //復(fù)位信號,低電平有效
    
    input                touch_key  , //觸摸按鍵,用于觸發(fā)開發(fā)板發(fā)出ARP請求
    input                arp_rx_done, //ARP接收完成信號
    input                arp_rx_type, //ARP接收類型 0:請求  1:應(yīng)答 
    output  reg          arp_tx_en  , //ARP發(fā)送使能信號
    output  reg          arp_tx_type  //ARP發(fā)送類型 0:請求  1:應(yīng)答
    );

//reg define
reg         touch_key_d0;
reg         touch_key_d1;

//wire define
wire        pos_touch_key;  //touch_key信號上升沿

//*****************************************************
//**                    main code
//*****************************************************

assign pos_touch_key = ~touch_key_d1 & touch_key_d0;

//對arp_tx_en信號延時打拍兩次,用于采touch_key的上升沿
always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        touch_key_d0 <= 1'b0;
        touch_key_d1 <= 1'b0;
    end
    else begin
        touch_key_d0 <= touch_key;
        touch_key_d1 <= touch_key_d0;
    end
end

//為arp_tx_en和arp_tx_type賦值
always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        arp_tx_en <= 1'b0;
        arp_tx_type <= 1'b0;
    end
    else begin
        if(pos_touch_key == 1'b1) begin  //檢測到輸入觸摸按鍵上升沿
            arp_tx_en <= 1'b1;           
            arp_tx_type <= 1'b0;
        end
        //接收到ARP請求,開始控制ARP發(fā)送模塊應(yīng)答
        else if((arp_rx_done == 1'b1) && (arp_rx_type == 1'b0)) begin
            arp_tx_en <= 1'b1;
            arp_tx_type <= 1'b1;
        end
        else
            arp_tx_en <= 1'b0;
    end
end

endmodule

ARP 控制模塊的代碼較簡單,首先檢測輸入觸摸按鍵的上升沿,當(dāng)檢測到上升沿之后,觸發(fā) ARP 頂層模塊發(fā)起 ARP 請求信號;同時檢測輸入的 arp_rx_donearp_rx_type 信號,當(dāng)接收上位機的 ARP 請求信號后,觸發(fā) ARP 頂層模塊發(fā)送 ARP 應(yīng)答信號,將開發(fā)板的 MAC 地址發(fā)送給上位機。



4 下載驗證

程序設(shè)計完成并仿真通過后,接下來我們就可以上板下載驗證了,下面會詳細(xì)講解如何進(jìn)行本實驗的驗證。

編譯工程并生成比特流 .sbit 文件后,此時將下載器一端連接電腦,另一端與開發(fā)板上的 JTAG 下載口連接,將網(wǎng)線一端連接開發(fā)板的網(wǎng)口,另一端連接電腦的網(wǎng)口或者路由器,接下來連接電源線,并打開開發(fā)板的電源開關(guān),將 PDS 生成好的 .sbit 流文件下載到開發(fā)板中去。

程序下載完成后,PHY 芯片會和電腦網(wǎng)卡進(jìn)行通信(自協(xié)商),如果程序下載正確并且硬件連接無誤的話,我們點擊電腦右下角的網(wǎng)絡(luò)圖標(biāo),會看到本地連接剛開始顯示的是正在識別,一段時間之后顯示未識別的網(wǎng)絡(luò),打開方式如下圖所示(不同的 Windows 版本操作可能存在差異,但基本相同)。

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip

點擊上圖中的 “未識別的網(wǎng)絡(luò)(無 Internet)”,彈出如下圖所示界面。

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip

點擊 “更改適配器” 選項,彈出如下圖所示界面。

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip

如果看到上圖 “以太網(wǎng)” 顯示未識別的網(wǎng)絡(luò)之后,說明硬件連接和程序都是沒有問題的,接下來設(shè)置以太網(wǎng)的 IP 地址,改成代碼中設(shè)置的目的 IP 地址,頂層模塊參數(shù)定義如下:

//目的 IP 地址 192.168.1.102
parameter DES_IP = {8'd192,8'd168,8'd1,8'd102};

因此接下來將電腦以太網(wǎng)的 IP 地址設(shè)置成 192.168.1.102。鼠標(biāo)右擊上圖中的以太網(wǎng),如下圖所示:

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip

點擊 “屬性”,彈出如下圖所示界面。

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip

鼠標(biāo)雙擊 “Internet 協(xié)議版本 4(TCP/IPv4)”,彈出如下圖所示界面。

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip

“Internet 協(xié)議版本 4(TCP/IPv4)” 屬性界面中,選擇使用下面的 IP 地址,IP 地址設(shè)置成 192.168.1.102,并點擊確定完成設(shè)置。

接下來以管理員身份打開電腦的命令的 DOS 命令窗口(注意必須以管理員身份打開),打開方式如下所示。

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip

打開 DOS 命令窗口后,在命令行中輸入 “arp -a”,如下圖所示。

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip

輸入完成后,按下鍵盤的回車鍵,此時會彈出電腦中所有網(wǎng)絡(luò)接口的 ARP 緩存表,我們只需要關(guān)注以太網(wǎng)接口的 ARP 緩存表(IP 地址為 192.168.1.102),如下圖所示。

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip

可以發(fā)現(xiàn),此時 ARP 緩存表中還沒有開發(fā)板的 MAC 地址和 IP 地址,此時我們按下開發(fā)板的觸摸按鍵(TPAD)。按下后,開發(fā)板會向電腦發(fā)起 ARP 請求,并且電腦會返回自己的 MAC 地址到開發(fā)板。

需要說明的是,在開發(fā)板發(fā)起 ARP 請求時,會將開發(fā)板的 MAC 地址和 IP 地址都發(fā)給電腦,此時電腦就已經(jīng)獲取到了開發(fā)板的 MAC 地址和 IP 地址,并更新至 ARP 的緩存表中,我們重新在 DOS 命令中輸入 “arp -a”,如下面兩張圖所示。

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip

由上圖可知,此時以太網(wǎng)接口的 ARP 緩存表中已經(jīng)添加了開發(fā)板的 IP 地址(192.168.1.10)和 MAC 地址(00-11-22-33-44-55),說明開發(fā)板發(fā)送 ARP 請求成功。如果大家操作失敗,請檢查開發(fā)板的網(wǎng)口是否通過網(wǎng)線連接電腦的網(wǎng)口,并且此時開發(fā)板已經(jīng)下載程序以及通過按下觸摸按鍵(TPAD)來觸發(fā) ARP 請求。另外,如果電腦網(wǎng)口不支持千兆網(wǎng)通信,那么也會導(dǎo)致 ARP 操作失敗。

接下來我們再來通過電腦發(fā)起 ARP 請求,驗證開發(fā)板有沒有正確返回 ARP 應(yīng)答。我們先從以太網(wǎng) ARP 緩存表中刪除開發(fā)板的 MAC 地址,刪除方法是在 DOS 命令中輸入 “arp -d”,并按下按鍵的回車鍵,如下圖所示。

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip

接下來重新在 DOS 命令中輸入 “arp -a”,來驗證是否刪除成功(如果沒有以管理員運行會導(dǎo)致刪除失?。斎胪瓿珊?,如下圖所示。

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip

此時我們之前獲取的開發(fā)板 MAC 地址已經(jīng)刪除成功,接下來在 DOS 命令中輸入 “ping 192.168.1.10”,來讓電腦發(fā)起 ARP 請求,如下圖所示。

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip

需要說明的是,ping 是一個十分強大的 TCP/IP 工具,它可以用來檢測網(wǎng)絡(luò)的連通情況和分析網(wǎng)絡(luò)速度。ping 命令是一個固定格式的 ICMPInternet 控制報文協(xié)議)請求數(shù)據(jù)包,之后會發(fā)起 ARP 請求命令,所以我們這里是通過 ping 命令來間接發(fā)起 ARP 請求。由于開發(fā)板并沒有實現(xiàn) ICMP 協(xié)議,因此在 ping 時會請求超時,但是在 ping 的過程中發(fā)起的 ARP 請求,開發(fā)板會響應(yīng)并返回 ARP 應(yīng)答數(shù)據(jù)。

接下來再次在 DOS 命令中輸入 “arp -a”,查詢是否成功獲取到開發(fā)板 MAC 地址,如下圖所示。

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip

由上圖可知,電腦正確獲取到開發(fā)板的 MAC 地址,并更新至 ARP 緩存表中。到這里,開發(fā)板實現(xiàn)的 ARP 協(xié)議就已經(jīng)全部驗證成功了。

接下來介紹一個以太網(wǎng)通信時經(jīng)常使用的抓包軟件 Wireshark,可以直接在網(wǎng)上搜索下載,我們現(xiàn)在打開 Wireshark,界面如下圖所示。

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip

雙擊上圖所示的以太網(wǎng)或者先選中以太網(wǎng),再點擊上方紅框選中的藍(lán)色按鈕,即可開始抓取本地連接的數(shù)據(jù)包,抓取界面如下圖所示。

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip

從上圖可以看到,已經(jīng)抓取到其它應(yīng)用程序使用以太網(wǎng)發(fā)送的數(shù)據(jù)包,但是這些數(shù)據(jù)包并不是開發(fā)板發(fā)送的數(shù)據(jù)包,我們這個時候按下開發(fā)板的觸摸按鍵 TPAD(根據(jù)自己開發(fā)板來按),就可以在 wireshark 中抓取到數(shù)據(jù)包了,抓取到的數(shù)據(jù)包如下圖所示。

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip

上圖中第 38 行數(shù)據(jù)包是開發(fā)板發(fā)送給電腦的 ARP 請求包,第 39 行數(shù)據(jù)包是電腦發(fā)送給開發(fā)板的 ARP 應(yīng)答包,此時雙擊第 38 行即可看到開發(fā)板發(fā)送的詳細(xì)數(shù)據(jù),如下圖所示。

FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹),紫光同創(chuàng)FPGA開發(fā)筆記,fpga開發(fā),tcp/ip

上圖中下方紅框為開發(fā)板發(fā)送的 16 進(jìn)制數(shù)據(jù)(去掉前導(dǎo)碼、SFDCRC 值),可以看到,后面的 180 就是我們在發(fā)送時填充的 18 個字節(jié)數(shù)據(jù)。需要說明的是,當(dāng)打開第 39 行電腦返回的 ARP 請求包時,看不到填充的 0,這是由于后面填充的數(shù)據(jù)是網(wǎng)卡自動填充的,因此 wireshark 中會看不到。



5 總結(jié)

至此,本專欄中關(guān)于 FPGA 以太網(wǎng)入門的第二篇 —— ARP測試實驗已經(jīng)全部講解完畢,全文篇幅較長,爆肝4萬字,建議收藏后精讀。

希望以上的內(nèi)容對您有所幫助,誠摯地歡迎各位讀者在評論區(qū)或者私信我交流!

微博:沂舟Ryan (@沂舟Ryan 的個人主頁 - 微博 )

GitHub:ChinaRyan666

微信公眾號:沂舟無限進(jìn)步(內(nèi)含精品資料及詳細(xì)教程)

如果對您有幫助的話請點贊支持下吧!

集中一點,登峰造極。文章來源地址http://www.zghlxwxcb.cn/news/detail-828478.html

到了這里,關(guān)于FPGA以太網(wǎng)入門(二)——ARP測試實驗(基于紫光同創(chuàng),含原語介紹)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 【車載以太網(wǎng)測試從入門到精通】——以太網(wǎng)TCP/IP協(xié)議自動化測試(含CAPL源碼)

    【車載以太網(wǎng)測試從入門到精通】系列文章目錄匯總 TCP/IP(Transmission Control Protocol/Internet Protocol,傳輸控制協(xié)議/網(wǎng)際協(xié)議)是指能夠在多個不同網(wǎng)絡(luò)間實現(xiàn)信息傳輸?shù)膮f(xié)議簇

    2024年02月05日
    瀏覽(109)
  • 基于光口的以太網(wǎng) udp 回環(huán)實驗

    基于光口的以太網(wǎng) udp 回環(huán)實驗

    本章實驗我們通過網(wǎng)絡(luò)調(diào)試助手發(fā)送數(shù)據(jù)給 FPGA,FPGA通過光口接收數(shù)據(jù)并將數(shù)據(jù)使用 UDP 協(xié)議發(fā)送給電腦。 提示:任何文章不要過度深思!萬事萬物都經(jīng)不起審視,因為世上沒有同樣的成長環(huán)境,也沒有同樣的認(rèn)知水平,更「沒有適用于所有人的解決方案」 ;不要急著評判文

    2024年01月19日
    瀏覽(24)
  • 【車載以太網(wǎng)測試從入門到精通】——傳輸層測試

    【車載以太網(wǎng)測試從入門到精通】系列文章目錄匯總

    2023年04月27日
    瀏覽(30)
  • 【車載以太網(wǎng)測試從入門到精通】——物理層測試

    【車載以太網(wǎng)測試從入門到精通】系列文章目錄匯總 車載以太網(wǎng)是一種用以太網(wǎng)連接車內(nèi)電子單元的新型局域網(wǎng)技術(shù)。與普通的以太網(wǎng)使用4對非屏蔽雙絞線(UTP)電纜不同,車載以太網(wǎng)在單對非屏蔽雙絞線上可實現(xiàn)100Mbit/s甚至1Gbit/s的數(shù)據(jù)傳輸速率,同時還應(yīng)滿足汽車行業(yè)對

    2023年04月24日
    瀏覽(44)
  • 基于FPGA的以太網(wǎng)傳輸圖片通過HDMI顯示(含源碼)

    基于FPGA的以太網(wǎng)傳輸圖片通過HDMI顯示(含源碼)

    ??在此之前,已經(jīng)講解過HDMI、UDP、DDR3等模塊的使用,前文在使用HDMI顯示圖片時,由于沒有講解DDR3,使用FPGA內(nèi)部的RAM存儲圖像數(shù)據(jù),因為FPGA片上RAM的資源有限,導(dǎo)致最終顯示放大的圖片失真嚴(yán)重。 ??本文通過DDR3存儲整張圖片的數(shù)據(jù),然后通過HDMI在顯示器上進(jìn)行顯示,

    2024年03月27日
    瀏覽(78)
  • 基于FPGA的百兆以太網(wǎng)通信(一)——MDIO配置PHY芯片

    基于FPGA的百兆以太網(wǎng)通信(一)——MDIO配置PHY芯片

    ?一、以太網(wǎng)簡介 ? 之前提了個引子,接下來我會分享一下基于FPGA的百兆以太網(wǎng)通信學(xué)習(xí)過程。第一部分是對于以太網(wǎng)PHY芯片的配置和狀態(tài)讀取。 ? 一般來說,F(xiàn)PGA以太網(wǎng)通信是需要外接的PHY芯片的,目前的很多FPGA出廠的底板上已經(jīng)焊好了PHY芯片,所以這一點是比較方便的。

    2024年04月10日
    瀏覽(21)
  • 以太網(wǎng)協(xié)議介紹(ARP、UDP、ICMP、IP)

    以太網(wǎng)協(xié)議介紹(ARP、UDP、ICMP、IP)

    請求: 應(yīng)答: ARP協(xié)議: 以太網(wǎng)ARP數(shù)據(jù)包格式: FCS:校驗 在以太網(wǎng)幀頭部分也包含了目的地址的mac和ip地址。 以太網(wǎng)通信是通過包的形式進(jìn)行傳輸?shù)模幌翊趨f(xié)議一樣單位是byte。 幀間隙: TCP和UDP的區(qū)別 ? osi 7層模型:實現(xiàn)通信的任務(wù) 對于fpga開發(fā),只需要關(guān)注傳輸層,

    2024年02月03日
    瀏覽(23)
  • 基于FPGA 以太網(wǎng)gmii_to_rgmii模塊編寫 附源碼

    基于FPGA 以太網(wǎng)gmii_to_rgmii模塊編寫 附源碼

    筆者使用的開發(fā)板是米聯(lián)客zynq UitraScale+ xczu4ev-sfvc784-2-i開發(fā)板進(jìn)行測試 由于米聯(lián)客協(xié)議族源碼不開源,自己寫了一個簡易的以太網(wǎng)接口轉(zhuǎn)換模塊只支持1000M速率。 (1)接收時序(PHYFPGA) RXC 的上下邊沿與 RXD 和 RX_CTL 信號對齊,相位相同。(非延時模式) RXC 的上下邊沿與

    2024年02月06日
    瀏覽(24)
  • 【車載以太網(wǎng)測試從入門到精通】——DoIP BootLoader刷寫測試(含CAPL源碼)

    【車載以太網(wǎng)測試從入門到精通】系列文章目錄匯總 DoIP概述: DoIP(Diagnostic communication over InternetProtocol),基于IP網(wǎng)絡(luò)的汽車診斷協(xié)議。DoIP技術(shù)可實現(xiàn)本地診斷、遠(yuǎn)程診斷、空中下載技術(shù)等功能。 DoIP協(xié)議用于UDS診斷的傳輸,ISO13400規(guī)定了DoIP的物理層、數(shù)據(jù)鏈路層、網(wǎng)絡(luò)層、

    2024年02月10日
    瀏覽(97)
  • 【網(wǎng)絡(luò)編程·數(shù)據(jù)鏈路層】MAC幀/以太網(wǎng)協(xié)議/ARP協(xié)議/RARP協(xié)議

    【網(wǎng)絡(luò)編程·數(shù)據(jù)鏈路層】MAC幀/以太網(wǎng)協(xié)議/ARP協(xié)議/RARP協(xié)議

    ?需要云服務(wù)器等云產(chǎn)品來學(xué)習(xí)Linux的同學(xué)可以移步/--騰訊云--/--阿里云--/--華為云--/官網(wǎng),輕量型云服務(wù)器低至112元/年,新用戶首次下單享超低折扣。 目錄 一、MAC幀 1、IP地址和MAC地址的區(qū)別 2、MAC幀協(xié)議 3、MTU對IP協(xié)議的影響 4、MTU對UDP協(xié)議的影響 5、MTU對TCP協(xié)議的影響 二、

    2024年02月07日
    瀏覽(22)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包