第五章 外設(shè)接口通信,舉一反三
12.千兆網(wǎng)口實(shí)現(xiàn)MDIO接口讀寫
? ? ? ?千兆網(wǎng)口是我們?nèi)粘I钪薪?jīng)常見到的外設(shè)接口,在后面三個(gè)例程中,我們將會(huì)一起去動(dòng)手實(shí)現(xiàn)千兆網(wǎng)口實(shí)現(xiàn)MDIO接口讀寫、ARP通信協(xié)議、ICMP和UDP通信協(xié)議等,這三個(gè)例程有一定的難度,通過實(shí)際分析、動(dòng)手編碼、模塊劃分、上板調(diào)試大家可以學(xué)到很多內(nèi)容,涵蓋了MDIO協(xié)議、報(bào)文層層解析、層層組報(bào)、時(shí)鐘上下邊沿采樣數(shù)據(jù)、千兆網(wǎng)口報(bào)文CRC32校驗(yàn)、IP首部校驗(yàn)、UDP首部校驗(yàn)、ARP首部校驗(yàn)等,相信系統(tǒng)性學(xué)習(xí)實(shí)踐后,大家的模塊劃分和編碼調(diào)試能力又會(huì)提高一大步。
? ? ? 如圖1所示是豌豆開發(fā)板Artix7上千兆LAN口電路,這里選取了經(jīng)典的KSZ9031RN而作為PHY的主控芯片,KSZ9031RN相比于傳統(tǒng)的PHY芯片例如RTL8211E,既可以支持10/100/1000 Mbps網(wǎng)絡(luò)傳輸速率,又通過RGMII接口和FPGA相連進(jìn)行數(shù)據(jù)通信,RGMII是GMII的精簡版,相比于GMII接口,RGMII在硬件上極大地節(jié)約了引腳數(shù)量,數(shù)據(jù)的收發(fā)引腳由8根變成4根,所以在1000Mbps的傳輸速率下,即時(shí)鐘頻率是125Mhz時(shí),在時(shí)鐘的上下沿同時(shí)采樣數(shù)據(jù)。
?圖1 豌豆開發(fā)板Artix7上KSZ9031RN電路
? ? ? ?在以太網(wǎng)通信中設(shè)備之間的物理層鏈路均由PHY芯片即物理層芯片建立。PHY芯片都有一個(gè)配置接口即MDIO接口,通過這個(gè)接口可以配置PHY芯片的工作模式并且獲取PHY芯片的若干狀態(tài)信息,這個(gè)過程一般性地稱為以太網(wǎng)的自協(xié)商,在這個(gè)例程中我們實(shí)現(xiàn)對(duì)PHY芯片的 MDIO接口的初始化。
? ? ? ?僅僅從硬件的角度來說,以太網(wǎng)接口電路主要由MAC控制器和物理層接口PHY兩大部分所組成,在這個(gè)例程中MAC控制器由FPGA實(shí)現(xiàn),PHY芯片則指豌豆開發(fā)板上板載的以太網(wǎng)芯片。
? ? ? ?PHY在發(fā)送數(shù)據(jù)時(shí),接收MAC發(fā)過來的數(shù)據(jù)(對(duì)PHY來說已經(jīng)沒有幀的概念,不管是地址、報(bào)文、校驗(yàn)都看成數(shù)據(jù)),把并行數(shù)據(jù)轉(zhuǎn)化為串行流數(shù)據(jù),按照物理層的編碼規(guī)則把數(shù)據(jù)編碼轉(zhuǎn)換為模擬信號(hào)發(fā)送出去,而接收數(shù)據(jù)時(shí)的流程則相反。
? ? ? ? ?同時(shí)PHY還提供了和兩端設(shè)備連接的重要功能,并通過LED燈顯示出自己目前的連接狀態(tài)和工作狀態(tài)。當(dāng)我們將網(wǎng)口RJ45座子接入網(wǎng)線的時(shí)候,PHY芯片不斷發(fā)出脈沖信號(hào)來檢測相連端口是否有設(shè)備,它們通過標(biāo)準(zhǔn)的“語言”來交流,互相協(xié)商并確定連接速度、雙工模式、是否采用流控等,一般情況下,自協(xié)商的結(jié)果是兩個(gè)設(shè)備中能同時(shí)支持的最大速度和最好的雙工模式。
? ? ? ?MAC控制器和PHY物理芯片之間有一個(gè)配置接口即MDIO接口,可以配置PHY芯片的工作模式以及獲取PHY芯片的若干狀態(tài)信息。PHY芯片內(nèi)包含一系列寄存器,用戶可以通過這些寄存器配置PHY芯片的工作模式,并獲取PHY芯片的若干狀態(tài)信息,例如連接速率、雙工模式、自協(xié)商狀態(tài)等。
? ? ? ? FPGA通過MDIO接口對(duì) PHY芯片內(nèi)部的寄存器進(jìn)行配置,實(shí)際上在一般地情況下,PHY芯片在默認(rèn)狀態(tài)下也可以正常工作,當(dāng)然下結(jié)論之前筆者也都動(dòng)手測試過,在FPGA作為MAC控制器時(shí),只需要硬件上拉低一段時(shí)間的MDIO復(fù)位引腳,再通過MDIO接口通信協(xié)議即可讀出相關(guān)寄存器,從而判斷是否自協(xié)商正常。
? ? ? ? 在這個(gè)例程中我們即去實(shí)現(xiàn)這個(gè)過程,大家可以把它看成對(duì)千兆網(wǎng)口的初始化,只有在PC端和FPGA端進(jìn)行自協(xié)商完成后,彼此間才可以建立以太網(wǎng)通信,如圖2所示是MDIO接口示意圖,在這個(gè)例程中我們用到了MDC、MDIO、RESET三個(gè)引腳。
圖2 MDIO接口示意圖
? ? ? ? MDIO接口也稱之為SMI接口即串行管理接口,包括數(shù)據(jù)管理時(shí)鐘LAN_MDC和數(shù)據(jù)管理輸入輸出LAN_MDIO兩根信號(hào)線。而LAN_MDC為LAN_MDIO提供時(shí)鐘,LAN_MDIO為雙向數(shù)據(jù)引腳,既用于發(fā)送數(shù)據(jù),也用于接收數(shù)據(jù)。如圖3所示LAN_MDC的最大時(shí)鐘不能超過400ns即最大時(shí)鐘為2.5Mhz。
圖3 MDIO中MDC的配置說明
? ? ? ?如下圖4所示是MDIO接口通信協(xié)議,在這個(gè)例程中需要按照?qǐng)D中所示的協(xié)議格式去實(shí)現(xiàn)MDIO底層驅(qū)動(dòng)的開發(fā),再在上游模塊中實(shí)現(xiàn)控制層邏輯,讓其控制驅(qū)動(dòng)模塊工作,也類似于前面例程中FLASH的driver和control兩層分離模式,其中MDIO協(xié)議的幀格式具體說明如下:
1. Preamble:32位前導(dǎo)碼,由MAC控制器發(fā)送32位邏輯"1",用來同步 PHY 芯片;
2. ST:2位幀開始信號(hào),規(guī)定用01表示;
3. OP:2位操作碼,其中讀命令是10,寫命令是01;
4. PHYAD:5位PHY地址,用來表示MAC控制器與哪個(gè)PHY芯片通信,所以從這里能看出一個(gè) MAC控制器硬件上可以連接多個(gè)PHY芯片;
5. REGAD:5位寄存器地址,這里一共可以表示32種寄存器;
6. TA:2位轉(zhuǎn)向,在讀命令中,MDIO在此時(shí)將由MAC驅(qū)動(dòng)改為PHY驅(qū)動(dòng),在第一個(gè)TA位,MDIO引腳為高阻狀態(tài),第二個(gè)TA位,PHY將MDIO引腳拉低,準(zhǔn)備發(fā)送數(shù)據(jù);而在寫命令中,則不需要MDIO方向發(fā)生變化,MAC固定輸出 2'b10即可,隨后開始寫入數(shù)據(jù);
7. DATA:16位數(shù)據(jù),在讀命令中,PHY芯片將讀到的對(duì)應(yīng)PHYAD的REGAD寄存器的數(shù)據(jù)寫到DATA中;在寫命令中,MAC將要寫入對(duì)應(yīng)PHYAD的REGAD寄存器的值寫入DATA中;
8. IDLE:空閑狀態(tài),這時(shí)候MDIO為無源驅(qū)動(dòng),處于高阻狀態(tài),通常硬件通過上拉電阻使其上拉至高電平。
圖4 MDIO接口通信協(xié)議
? ? ? ? 如下圖5所示是MDIO接口讀時(shí)序圖,圖中以PHY地址為0x01,從寄存器地址0x00讀出數(shù)據(jù)舉例說明。整個(gè)讀操作過程的MDC時(shí)鐘由MAC驅(qū)動(dòng),同時(shí)MAC也驅(qū)動(dòng)MDIO引腳輸出前導(dǎo)碼+幀開始+操作碼+PHY 地址+寄存器地址,隨后MDIO引腳切換至PHY驅(qū)動(dòng)。在第一個(gè)TA位,MDIO引腳為高阻狀態(tài),第二個(gè)TA位為低電平,表示PHY芯片成功響應(yīng),并且接下來會(huì)輸出16位寄存器數(shù)據(jù);而如果第二個(gè)TA位處于高電平,PHY芯片響應(yīng)失敗。
? ? ? ? 讀操作中需要注意的是,PHY在MDC時(shí)鐘的上升沿采集數(shù)據(jù),為保證數(shù)據(jù)的穩(wěn)定傳輸,MAC在MDC的下降沿更新MDIO引腳的數(shù)據(jù)。而當(dāng)MDIO引腳切換至PHY驅(qū)動(dòng)時(shí),MDIO數(shù)據(jù)MDC時(shí)鐘的下降沿更新,MAC在MDC時(shí)鐘的上升沿采集數(shù)據(jù)。同時(shí)在讀操作結(jié)束后,MAC將MDIO引腳輸出高阻,此時(shí)MDIO引腳的外部上拉電阻會(huì)將MDIO引腳拉高,MDIO接口重新處于空閑狀態(tài)。
圖5 MDIO接口讀時(shí)序圖
? ? ? ? 如下圖6所示是MDIO接口寫時(shí)序圖,以PHY地址為0x01,向寄存器地址0x00寫入0x1340舉例說明,在整個(gè)寫操作過程中, MDC時(shí)鐘和MDIO引腳一直由MAC端驅(qū)動(dòng),按照MDIO接口寫通信協(xié)議開始傳輸數(shù)據(jù)。
? ? ? ? 寫操作中需要注意的是,PHY在MDC 時(shí)鐘的上升沿采集數(shù)據(jù),為保證數(shù)據(jù)的穩(wěn)定傳輸,MAC在MDC的下降沿將數(shù)據(jù)更新至MDIO引腳。在寫操作結(jié)束后,MAC將MDIO引腳輸出高阻,此時(shí)MDIO引腳的外部上拉電阻會(huì)將MDIO引腳拉高,MDIO接口重新處于空閑狀態(tài)。
圖6 MDIO接口寫時(shí)序圖
? ? ? ? 細(xì)心的同學(xué)一定會(huì)發(fā)現(xiàn)MDIO協(xié)議非常類似于IIC和SPI協(xié)議兩者的結(jié)合體,也非常有趣,一方面在工作模式上和IIC協(xié)議相似,即MDIO引腳對(duì)于FPGA端是輸入輸出引腳,既通過該引腳發(fā)送數(shù)據(jù)給PHY,也通過該引腳從PHY接收數(shù)據(jù),且包含有兩個(gè)引腳,一個(gè)做輸入輸出總線,一個(gè)做參考時(shí)鐘;另一方面在數(shù)據(jù)讀寫上和SPI協(xié)議相似,即在時(shí)鐘上升沿采集數(shù)據(jù),在時(shí)鐘下降沿更新數(shù)據(jù),所以大家可以通過這個(gè)例程把前面IIC和SPI協(xié)議的知識(shí)再復(fù)習(xí)下,如圖7所示是KSZ9031RN芯片在MDIO協(xié)議下的32位寄存器說明。
圖7 KSZ9031RN芯片在MDIO協(xié)議下的32位寄存器說明
? ? ? 下面我們來一起讀一讀KSZ9031RN芯片手冊(cè),并提取一些程序設(shè)計(jì)中的核心要點(diǎn),其中有些寄存器是僅可讀的,有些寄存器是僅可寫的,還有些寄存器是可讀可寫的,當(dāng)然在程序設(shè)計(jì)中我們不需要把這32個(gè)寄存器全部都用上,一般來說寄存器0x00、0x01、0x1F是3個(gè)最常用的寄存器,即基本控制寄存器、基本狀態(tài)寄存器、PHY控制寄存器。
? ? ? 如圖8所示是基本控制寄存器說明,這里主要有個(gè)軟復(fù)位操作,即MAC控制器可以通過MDIO協(xié)議向PHY發(fā)送軟復(fù)位請(qǐng)求,但遺憾的是筆者在兩款PHY芯片RTL8211FD和KSZ9031RN分別實(shí)驗(yàn)軟復(fù)位請(qǐng)求,經(jīng)測試發(fā)現(xiàn)RTL8211FD在大多數(shù)情況下軟復(fù)位一次后,即可讀取到正確的自協(xié)商結(jié)果,然而KSZ9031RN在大多數(shù)情況下軟復(fù)位一次后,總是讀取到錯(cuò)誤的自協(xié)商結(jié)果。
? ? ?于是第一反應(yīng)就是想在控制模塊做一個(gè)狀態(tài)機(jī)如果軟復(fù)位一次不正常再復(fù)位一次直到正常為止,但個(gè)人覺得太麻煩了且沒有必要,既然軟復(fù)位不一定可靠,那么我們就索性用硬件復(fù)位的方法即用拉低RESET復(fù)位引腳,經(jīng)過實(shí)際測試發(fā)現(xiàn)硬件復(fù)位的方法可以保證每次PHY芯片都復(fù)位正常。
? ? ? ?如圖9所示是基本狀態(tài)寄存器說明,用戶通過MDIO協(xié)議從PHY中讀取該寄存器的值,即可從16位的寄存器值中判斷目前自協(xié)商狀態(tài),注意到寄存器的第5位為1時(shí),代表自協(xié)商完成,為0時(shí)代表自協(xié)商未完成;寄存器的第5位為1時(shí),代表網(wǎng)線的物理層連接成功,為0時(shí)代表連接失敗。
? ? ? ?如圖10所示是PHY控制寄存器說明,同樣地用戶通過MDIO協(xié)議從PHY中讀取該寄存器的值,即可從16位的寄存器值中判斷自協(xié)商后連接速度,注意到寄存器的第6位為1時(shí),代表千兆速度;寄存器的第5位為1時(shí),代表百兆速度;而寄存器的第4位為1時(shí),代表十兆速度。
圖8 基本控制寄存器說明
圖9 基本狀態(tài)寄存器說明
圖10 PHY控制寄存器說明
? ? ? ?如表1所示是mdio_driver模塊信號(hào)列表,類似于前面讀寫FLASH例程,把整個(gè)邏輯細(xì)化成驅(qū)動(dòng)層和控制層,在這個(gè)模塊中主要去實(shí)現(xiàn)MDIO驅(qū)動(dòng)層的邏輯,大家可以再回顧下前面如圖11所示的MDIO接口通信協(xié)議。如圖5-26所示是MDIO接口驅(qū)動(dòng)層的代碼設(shè)計(jì),這里實(shí)現(xiàn)了MDIO接口的底層驅(qū)動(dòng),其實(shí)難度不大,但需要說明幾點(diǎn)應(yīng)該注意的地方:
? ? 1. 提到過MDIO的時(shí)鐘頻率不超過2.5Mhz,模塊中對(duì)50Mhz時(shí)鐘進(jìn)行了50分頻即為1Mhz;
? ? ?2. 在MDIO接口通信協(xié)議中TA是2位轉(zhuǎn)向位,所以注意在讀操作時(shí)候進(jìn)行MDIO的切換,把MDIO的控制端從MAC控制器交給PHY芯片。在進(jìn)行讀操作時(shí),轉(zhuǎn)向位的第2位讀到PHY芯片發(fā)送的低電平才確定PHY端響應(yīng),讀取到16位寄存器值才是有效的;
? ? ?3. 在MDIO接口中,時(shí)鐘上升沿采集數(shù)據(jù),在時(shí)鐘下降沿更新數(shù)據(jù),也非常類似于SPI接口的時(shí)序邏輯;
信號(hào)列表 | ||
信號(hào)名 |
I/O |
位寬 |
clk |
I |
1 |
rst_n |
I |
1 |
mdio_driver_en |
I |
1 |
phy_addr |
I |
5 |
reg_addr |
I |
5 |
wrl_rdh_mode |
I |
1 |
mdio_wr_data |
I |
16 |
mdio_rd_data |
O |
16 |
mdio_rd_ack |
O |
1 |
eth_mdc |
O |
1 |
eth_mdio |
I/O |
1 |
mdio_done |
O |
1 |
表1 mdio_driver模塊信號(hào)列表
圖11 MDIO接口驅(qū)動(dòng)模塊的代碼設(shè)計(jì)
? ? ? ? 如表2所示是mdio_control模塊信號(hào)列表,在這個(gè)模塊里實(shí)現(xiàn)了對(duì)MDIO接口協(xié)議的控制層邏輯,在控制模塊中我們先后讀取基本狀態(tài)寄存器和PHY控制寄存器,再通過兩個(gè)寄存器的值判斷出目前自協(xié)商后的結(jié)果,通過讀取基本狀態(tài)寄存器,即可判斷出自協(xié)商是否完成,以太網(wǎng)物理層是否連接成功;通過讀取PHY控制寄存器,即可判斷出自協(xié)商后的連接速度是否是默認(rèn)的千兆網(wǎng)速,整個(gè)模塊用一個(gè)基本狀態(tài)機(jī)即可實(shí)現(xiàn)。
? ? ? ?如圖12所示是MDIO接口控制模塊的代碼設(shè)計(jì),在這個(gè)模塊中向驅(qū)動(dòng)模塊發(fā)送使能信號(hào),并發(fā)送讀操作指令和讀寄存器地址,依次讀取從寄存器地址0x01和0x1F讀出數(shù)據(jù),判斷自協(xié)商過程是否完成,其結(jié)果是否為默認(rèn)的千兆網(wǎng)速,如果自協(xié)商錯(cuò)誤則置位錯(cuò)誤標(biāo)志位rd_mdio_err為1,這個(gè)讀取狀態(tài)結(jié)束后結(jié)束標(biāo)志位rd_mdio_done也置1,上游模塊直接在結(jié)束標(biāo)志位時(shí)判斷錯(cuò)誤標(biāo)志位即可,如果自協(xié)商正確,和初始化SD卡類似通過豌豆開發(fā)板上的一顆LED二極管點(diǎn)亮指示。
信號(hào)列表 | ||
信號(hào)名 |
I/O |
位寬 |
clk |
I |
1 |
rst_n |
I |
1 |
rd_mdio_en |
I |
1 |
eth_mdc |
O |
1 |
eth_mdio |
I/O |
1 |
rd_mdio_err |
O |
1 |
rd_mdio_done |
O |
1 |
表2 mdio_control模塊信號(hào)列表
圖12 MDIO接口控制模塊的代碼設(shè)計(jì)
? ? ?? 如圖13所示是整個(gè)例程的頂層例化文件,豌豆開發(fā)板上電后立刻拉低一秒鐘的PHY芯片復(fù)位引腳,用戶按下按鍵即觸發(fā)一次讀取自協(xié)商寄存器操作,開發(fā)板在讀取寄存器并判斷自協(xié)商正確后即把板載的LED二極管點(diǎn)亮,此時(shí)開發(fā)板和PC端的網(wǎng)口可以正常通信,且RJ45網(wǎng)口自帶的LED也在閃爍。
圖13 千兆網(wǎng)口實(shí)現(xiàn)MDIO接口讀寫頂層文件的例化
? ? ?? ?如圖14和15所示是在線調(diào)試ILA波形圖,朋友們可以看到從MDIO接口中讀取基本狀態(tài)寄存器值為796d,讀取PHY控制寄存器值為0348,對(duì)照相應(yīng)寄存器標(biāo)志位是滿足自協(xié)商千兆網(wǎng)速要求的。
圖14 MDIO接口讀取基本狀態(tài)寄存器ILA波形圖
文章來源:http://www.zghlxwxcb.cn/news/detail-429560.html
圖15 MDIO接口讀取PHY控制寄存器ILA波形圖文章來源地址http://www.zghlxwxcb.cn/news/detail-429560.html
到了這里,關(guān)于FPGA 20個(gè)例程篇:12.千兆網(wǎng)口實(shí)現(xiàn)MDIO接口讀寫的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!