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

FPGA千兆網(wǎng)口數(shù)據(jù)傳輸MDIO接口——FPGA學習筆記3

這篇具有很好參考價值的文章主要介紹了FPGA千兆網(wǎng)口數(shù)據(jù)傳輸MDIO接口——FPGA學習筆記3。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

一、以太網(wǎng)簡介

????????是當今現(xiàn)有局域網(wǎng)采用的最通用的通信協(xié)議標準,它規(guī)定了包括物理層的連線、電子信號和介質(zhì)訪問層協(xié)議的內(nèi)容。成本低,通信速率高,抗干擾能力強。

? ? ? ? 1、分類

標準以太網(wǎng):10Mbit/s

快速以太網(wǎng):100Mbit/s

千兆以太網(wǎng):1000Mbit/s

.........

以太網(wǎng)和千兆網(wǎng)口其實不完全相同。以太網(wǎng)是一種局域網(wǎng)技術標準,而千兆網(wǎng)口通常指的是支持1Gb/s(即千兆位每秒)速度的網(wǎng)絡接口。

以太網(wǎng)是一種通用的局域網(wǎng)技術標準,定義了數(shù)據(jù)傳輸?shù)囊?guī)范和硬件設備之間的通信方式。而千兆網(wǎng)口是一種物理接口標準,用于連接計算機或其他網(wǎng)絡設備到網(wǎng)絡中,支持更高的數(shù)據(jù)傳輸速度。

因此,可以說千兆網(wǎng)口是以太網(wǎng)的一種實現(xiàn)方式,它提供了更快的數(shù)據(jù)傳輸速度,但并不等同于以太網(wǎng)。在實際應用中,通常會使用以太網(wǎng)技術,并通過千兆網(wǎng)口進行連接,以實現(xiàn)更快的網(wǎng)絡通信速度。

? ? ? ? 2、以太網(wǎng)接口

????????以太網(wǎng)通信離不開連接端口的支持,網(wǎng)絡數(shù)據(jù)連接的端口就是以太網(wǎng)接口。以太網(wǎng)接口類型有RJ45接口,RJ11接口(電話線接口),SC光纖接口等其中RJ45接口是我們現(xiàn)在最常見的網(wǎng)絡設備接口(如:電腦網(wǎng)口)

基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記

基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記

基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記

3、6一對是為了向下兼容10/100M

基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記

上圖為RGMII接口,時鐘為雙沿2.5MHz、25MHz、250MHz。位寬為4位。(節(jié)省引腳)

GMII接口,時鐘為單沿1.25MHz、12.5MHz、125MHz。位寬為8位。

MAC側完成對報文的封包和解包過程

PHY芯片:實現(xiàn)模數(shù)轉換

ETH_RXC 接收端時鐘
ETH_RXCTL 接收端數(shù)據(jù)使能(接受報文有效,該引腳拉高)
ETH_RXD[3:0] 接收數(shù)據(jù)
ETH_TXC 發(fā)送端時鐘
ETH_TXCTL 發(fā)送端數(shù)據(jù)使能(發(fā)送報文有效,該引腳拉高)
ETH_TXD[3:0] 發(fā)送數(shù)據(jù)
ETH_RST_N 復位腳
ETH_MDC
ETH_MDIO

MDIO接口:(默認即可實現(xiàn)功能)

? ? ? ? 3、UDP網(wǎng)絡協(xié)議簡介

UDP(User Datagram Protocol,用戶數(shù)據(jù)報協(xié)議)是一種無連接的網(wǎng)絡傳輸協(xié)議,位于OSI模型的傳輸層。以下是UDP網(wǎng)絡協(xié)議的簡介:

? ? ? ? ? ? ? ? (1)無連接性:UDP是一種無連接的協(xié)議,發(fā)送端在發(fā)送數(shù)據(jù)之前不需要與接收端建立連接,也不會維護連接狀態(tài)。

? ? ? ? ? ? ? ? (2)面向數(shù)據(jù)報:UDP以數(shù)據(jù)報(Datagram)的形式傳輸數(shù)據(jù),每個數(shù)據(jù)報都是獨立的,互相之間沒有關聯(lián)。

? ? ? ? ? ? ? ? (3)不可靠性:UDP不提供數(shù)據(jù)可靠性保證,數(shù)據(jù)報可能會丟失、重復或無序到達。也不會進行數(shù)據(jù)校驗和重傳。

? ? ? ? ? ? ? ? (4)高效性:由于沒有連接建立和維護的開銷,以及簡化的功能,UDP比TCP更輕量級,傳輸效率更高。

? ? ? ? ? ? ? ? (5)適用場景:UDP適用于對實時性要求高、數(shù)據(jù)傳輸完整性要求不高的應用場景,如音頻、視頻流媒體傳輸、在線游戲等。

????????????????總的來說,UDP是一種簡單、高效但不可靠的網(wǎng)絡傳輸協(xié)議,適用于對實時性要求高、能容忍少量數(shù)據(jù)丟失的應用場景。

? ? ? ? 4、數(shù)據(jù)鏈路

????????數(shù)據(jù)通過FPGA進行數(shù)據(jù)協(xié)議的打包和MAC協(xié)議處理,通過RGMII總線協(xié)議傳輸將數(shù)據(jù)傳送至PHY芯片,PHY芯片將數(shù)據(jù)進行處理后發(fā)送至RJ45接口進行數(shù)據(jù)發(fā)送。

基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記

????????物理層(RJ45網(wǎng)口接口)、數(shù)據(jù)鏈路層(PHY芯片和MAC協(xié)議)、網(wǎng)絡層(在FPGA中處理的MAC協(xié)議)、傳輸層(在FPGA中處理的數(shù)據(jù)協(xié)議打包,用UDP或者TCP協(xié)議就是說的這一層)

二、以太網(wǎng)PHY芯片簡介RTL8211

? ? ? ? 1、PHY芯片:物理層芯片(物理接口收發(fā)器)

????????????????自動協(xié)商通信速率,或自行配置

基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記

? ? ? ? 2、BMCI寄存器配置(RTL8211為例)

基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記

基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記

? ? ? ? ? ? ? ? BMCI寄存器addr為:0x00

? ? ? ? ? ? ? ? (1)0.15:軟件復位,1復位,0工作。結束復位后,無需手動寫0,結束復位會自動歸0,基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記

? ? ? ? ? ? ? ? (2)0.14:環(huán)回,主要用于檢測,1使能,0失能。

? ? ? ? ? ? ? ? (3)0.13,0.6:Speed配置,配置不同速率(先失能自協(xié)商)?

? ? ? ? ? ? ? ? (4)0.12:自協(xié)商配置,默認使能,1使能,0失能。

? ? ? ? ? ? ? ? (5)0.11:掉電模式配置,1掉電模式,0正常工作模式。

? ? ? ? ? ? ? ? (6)0.10:隔離配置,RGMII接口隔離,引腳失能,只有MDIO,MDC配置有效

? ? ? ? ? ? ? ? (7)0.9:重新開始自協(xié)商配置。

? ? ? ? ? ? ? ? (8)0.8:雙工模式配置

? ? ? ? ? ? ? ? (9)0.7:沖突測試

? ? ? ? ? ? ? ? (10)0.5:單向使能:1雙方建立連接成功后通信,0直接通信

? ? ? ? 3、BMSR寄存器配置

? ? ? ? ? ? ? ? BMCI寄存器addr為:0x01

基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記

基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記

? ? ? ? ? ? ? ? ? ? ? ? (1)1.5:自協(xié)商完成

? ? ? ? ? ? ? ? ? ? ? ? (2)1.2:是否連接OK

????????4、PHYSR寄存器配置

? ? ? ? ? ? ? ? BMCI寄存器addr為:0x11

基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記

? ? ? ? ? ? ? ? (1)17.15:14? :連接速率(前提link ok,自協(xié)商完成)

三、以太網(wǎng)PHY芯片簡介YT8531

? ? ? ? 1、PHY芯片

基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記

網(wǎng)線差分模擬信號轉換數(shù)字信號,F(xiàn)PGA數(shù)字信號轉換網(wǎng)線差分模擬信號。

? ? ? ? 2、引腳復用

基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記

? ? ? ? 3、硬件原理圖(正點原子達芬奇開發(fā)板)

基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記

22R電阻做阻抗匹配。

? ? ? ? 4、PHY地址接口

一定會響應0x00??!

基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記

? ? ? ? 5、基本控制寄存器配置

寄存器地址0x00

基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記

? ? ? ? ? ? ? ? (1)?15:軟復位,帶自清0,默認為0 。0工作,1復位。

? ? ? ? ? ? ? ? (2) 14:內(nèi)部環(huán)回,默認為0。0失能,1使能。

? ? ? ? ? ? ? ? (3) 13:速率配置低位,關閉自協(xié)商才可以使用,bit6,13進行配置。

? ? ? ? ? ? ? ? (4) 12:自協(xié)商使能,默認支持。1使能,0失能。

? ? ? ? ? ? ? ? (5) 11:掉電模式,1掉電,0正常。

? ? ? ? ? ? ? ? (6) 10:隔離模式,一般為0正常模式

? ? ? ? ? ? ? ? (7) 9:重新自協(xié)商,自帶置1。

? ? ? ? ? ? ? ? (8) 8:配置雙工,關閉自協(xié)商才可以使用,1雙工,0半雙工。

? ? ? ? 6、基本狀態(tài)寄存器配置?

寄存器地址0x01

基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記

基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記

基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記

基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記

? ? ? ? ? ? ? ? (1) 13:雙工模式檢測。? ? ? ? 0:半雙工,? ? ? ? ?1:全雙工。

? ? ? ? ? ? ? ? (2) 15~14:傳輸速度等級檢測。10:1000M? ? ? 01:100M? ? ? ?00:10M

? ? ? ? ? ? ? ? (3) 2:連接狀態(tài)。? ? ? 1:連接已建立,? ? ? ? 0:鏈接未建立。

? ? ? ? ? ? ? ? (4) 3:自協(xié)商能力,? ? 1具有,? ? ? 0不具備。

? ? ? ? ? ? ? ? (5) 4:遠端錯誤指示位:讀取后自動清0? ? ? ? ?0:遠端設備正常? ? 1:遠端設備異常

? ? ? ? ? ? ? ? (6) 5:自協(xié)商完成標志,軟復位后自動清0? ? ? ?1:完成自協(xié)商? ? ? 0:未完成自協(xié)商。

? ? ? ? ? ? ? ? (7) 6:前導碼模式,1:不檢測前導碼直接接受? ? ? ? 0:檢測前導碼

? ? ? ? ? ? ? ? (8) 7:單項傳輸能力:0:當檢測到建立有效連接才開始傳輸? ? ?1:直接開始傳輸。

? ? ? ? 7、特定狀態(tài)寄存器

寄存器地址0x11

基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記

基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記

基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記

基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記

四、MDIO接口時序

????????MDIO: Management Data Input/Output

????????也被稱為SMI ( Serial Management Interface ) ,即串行管理接口。

????????MAC和 PHY芯片有一個配置接口,即MDIO接口,可以配置 PHY芯片的工作模式以及獲取 PHY芯片的若干狀態(tài)信息。?

????????1、MDIO接口連接圖

基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記

? ? ? ? 2、PHY幀格式

基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記

????????管理接口通過MDC和MDIO引腳提供對內(nèi)部寄存器的訪問,如IEEE802.3u第22節(jié)所述。MDC信號由MAC提供,是MDIO信號的管理數(shù)據(jù)時鐘參考。MDIO是管理數(shù)據(jù)的輸入/輸出,是一個雙向信號,與MDC同步運行。MDIO引腳需要一個1.5k歐姆的上拉電阻,以在空閑和周轉期間保持MDIO高電平。

基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記

前置抑制為RTL8211E/RTL8211EG上電后的默認設置。然而,在操作之間仍然必須至少有一個空閑位。RTL8211E/RTL8211EG可以共享同一條MDIO線。在交換機/路由器應用程序中,每個端口應該在硬件復位序列中分配一個唯一的地址,并且只能通過該唯一的PHY地址進行尋址。有關RTL8211E/RTL8211EG管理寄存器的詳細信息,請參見第30頁第8節(jié)寄存器描述。

基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記

寫狀態(tài)下,一直由FPGA輸出數(shù)據(jù)給到PHY芯片;讀狀態(tài)下,在TA位切換方向

? ? ? ? ? ? ? ? (1)Preamble:前導碼,32個邏輯1,同時給出時鐘。

? ? ? ? ? ? ? ? (2)ST:幀開始。固定01

? ? ? ? ? ? ? ? (3)OP:操作碼,指示當前讀寫

? ? ? ? ? ? ? ? (4)PHYAD:PHY地址

? ? ? ? ? ? ? ? (5)REGAD:寄存器地址

? ? ? ? ? ? ? ? (6)TA:2bit寬度,時間間隔,切換FPGA數(shù)據(jù)線方向。Z為高阻狀態(tài),0為應答。

? ? ? ? ? ? ? ? (7)DATA:數(shù)據(jù)?

? ? ? ? 3、PHY讀寫傳輸時序

? ? ? ? ? ? ? ? ? ? ? ? 上升沿采集數(shù)據(jù),下降沿更新數(shù)據(jù);MDC的最小周期為80ns對應時鐘最大為12.5MHz?

基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記

?基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記

五、MDIO讀寫測試實驗

? ? ? ? PHY芯片不進行配置也可以使用?

? ? ? ? 1、系統(tǒng)框圖

基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記

? ? ? ? 2、模塊原理圖

基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記

基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記

u_mdio_dri模塊:

op_addr:讀寫地址

op_exec:觸發(fā)信號↓↓↓↓↓↓↓↓↓↓↓

op_rh_wl:讀寫標志信號? ? 1讀? ? 0寫

op_wr_data:具體寫入數(shù)據(jù)

op_done:讀寫結束后,拉高該信號

op_rd_ack:讀應答信號? ? 0應答? ? ?1未應答(幀格式里面的AT)

op_rd_data:讀出的信號

dri_clk:驅動時鐘

?當op_exec信號拉高標志一次讀寫操作開始,根據(jù)op_rh_wl狀態(tài)判斷讀寫操作,同時給出讀寫操作地址op_addr(如果是寫操作要對應給出op_wr_data),讀寫操作結束后,拉高op_done信號,表示當前讀寫操作完成,控制模塊可以發(fā)起下一次操作(如果是寫讀操作,在op_done為高期間,如果是0表示應答,如果是1表示未應答)(如果讀操作,在op_done為高期間,會返回讀到的數(shù)據(jù))。

基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記

? ? ? ? 3、狀態(tài)機

基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記

基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記

? ? ? ? 4、用戶接口時序

基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記

? ? ? ? 5、程序設計

? ? ? ? ? ? ? ? (1)mdio_dri模塊

基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記

module mdio_dri #(
    parameter  PHY_ADDR = 5'b00100,//PHY地址
    parameter  CLK_DIV  = 6'd10    //分頻系數(shù)
   )

    (
    input                clk       , //時鐘信號
    input                rst_n     , //復位信號,低電平有效
    input                op_exec   , //觸發(fā)開始信號
    input                op_rh_wl  , //低電平寫,高電平讀
    input        [4:0]   op_addr   , //寄存器地址
    input        [15:0]  op_wr_data, //寫入寄存器的數(shù)據(jù)
    output  reg          op_done   , //讀寫完成
    output  reg  [15:0]  op_rd_data, //讀出的數(shù)據(jù)
    output  reg          op_rd_ack , //讀應答信號 0:應答 1:未應答
    output  reg          dri_clk   , //驅動時鐘
    
    output  reg          eth_mdc   , //PHY管理接口的時鐘信號 
    inout                eth_mdio    //PHY管理接口的雙向數(shù)據(jù)信號
    );

//parameter define
localparam st_idle    = 6'b00_0001;  //空閑狀態(tài)
localparam st_pre     = 6'b00_0010;  //發(fā)送PRE(前導碼)
localparam st_start   = 6'b00_0100;  //開始狀態(tài),發(fā)送ST(開始)+OP(操作碼)
localparam st_addr    = 6'b00_1000;  //寫地址,發(fā)送PHY地址+寄存器地址
localparam st_wr_data = 6'b01_0000;  //TA+寫數(shù)據(jù)
localparam st_rd_data = 6'b10_0000;  //TA+讀數(shù)據(jù)

//reg define
reg    [5:0]  cur_state ;
reg    [5:0]  next_state;

reg    [5:0]  clk_cnt   ;  //分頻計數(shù)                      
reg   [15:0]  wr_data_t ;  //緩存寫寄存器的數(shù)據(jù)
reg    [4:0]  addr_t    ;  //緩存寄存器地址
reg    [6:0]  cnt       ;  //計數(shù)器
reg           st_done   ;  //狀態(tài)開始跳轉信號
reg    [1:0]  op_code   ;  //操作碼  2'b01(寫)  2'b10(讀)                  
reg           mdio_dir  ;  //MDIO數(shù)據(jù)(SDA)方向控制
reg           mdio_out  ;  //MDIO輸出信號
reg   [15:0]  rd_data_t ;  //緩存讀寄存器數(shù)據(jù)

//wire define
wire          mdio_in    ; //MDIO數(shù)據(jù)輸入
wire   [5:0]  clk_divide ; //PHY_CLK的分頻系數(shù)

assign eth_mdio = mdio_dir ? mdio_out : 1'bz; //控制雙向io方向
assign mdio_in = eth_mdio;                    //MDIO數(shù)據(jù)輸入
//將PHY_CLK的分頻系數(shù)除以2,得到dri_clk的分頻系數(shù),方便對MDC和MDIO信號操作
assign clk_divide = CLK_DIV >> 1;

//分頻得到dri_clk時鐘
always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        dri_clk <=  1'b0;
        clk_cnt <= 1'b0;
    end
    else if(clk_cnt == clk_divide[5:1] - 1'd1) begin
        clk_cnt <= 1'b0;
        dri_clk <= ~dri_clk;
    end
    else
        clk_cnt <= clk_cnt + 1'b1;
end

//產(chǎn)生PHY_MDC時鐘
always @(posedge dri_clk or negedge rst_n) begin
    if(!rst_n)
        eth_mdc <= 1'b1;
    else if(cnt[0] == 1'b0)
        eth_mdc <= 1'b1;
    else    
        eth_mdc <= 1'b0;  
end

//(三段式狀態(tài)機)同步時序描述狀態(tài)轉移
always @(posedge dri_clk or negedge rst_n) begin
    if(!rst_n)
        cur_state <= st_idle;
    else
        cur_state <= next_state;
end  

//組合邏輯判斷狀態(tài)轉移條件
always @(*) begin
    next_state = st_idle;
    case(cur_state)
        st_idle : begin
            if(op_exec)
                next_state = st_pre;
            else 
                next_state = st_idle;   
        end  
        st_pre : begin
            if(st_done)
                next_state = st_start;
            else
                next_state = st_pre;
        end
        st_start : begin
            if(st_done)
                next_state = st_addr;
            else
                next_state = st_start;
        end
        st_addr : begin
            if(st_done) begin
                if(op_code == 2'b01)                //MDIO接口寫操作  
                    next_state = st_wr_data;
                else
                    next_state = st_rd_data;        //MDIO接口讀操作  
            end
            else
                next_state = st_addr;
        end
        st_wr_data : begin
            if(st_done)
                next_state = st_idle;
            else
                next_state = st_wr_data;
        end        
        st_rd_data : begin
            if(st_done)
                next_state = st_idle;
            else
                next_state = st_rd_data;
        end                                                                          
        default : next_state = st_idle;
    endcase
  end

//時序電路描述狀態(tài)輸出
always @(posedge dri_clk or negedge rst_n) begin
    if(!rst_n) begin
        cnt <= 5'd0;
        op_code <= 1'b0;
        addr_t <= 1'b0;
        wr_data_t <= 1'b0;
        rd_data_t <= 1'b0;
        op_done <= 1'b0;
        st_done <= 1'b0; 
        op_rd_data <= 1'b0;
        op_rd_ack <= 1'b1;
        mdio_dir <= 1'b0;
        mdio_out <= 1'b1;
    end
    else begin
        st_done <= 1'b0 ;                            
        cnt     <= cnt +1'b1 ;          
        case(cur_state)
            st_idle : begin
                mdio_out <= 1'b1;                     
                mdio_dir <= 1'b0;                     
                op_done <= 1'b0;                     
                cnt <= 7'b0;  
                if(op_exec) begin
                    op_code <= {op_rh_wl,~op_rh_wl}; //OP_CODE: 2'b01(寫)  2'b10(讀) 
                    addr_t <= op_addr;
                    wr_data_t <= op_wr_data;
                    op_rd_ack <= 1'b1;
                end     
            end 
            st_pre : begin                          //發(fā)送前導碼:32個1bit 
                mdio_dir <= 1'b1;                   //切換MDIO引腳方向:輸出
                mdio_out <= 1'b1;                   //MDIO引腳輸出高電平
                if(cnt == 7'd62) 
                    st_done <= 1'b1;
                else if(cnt == 7'd63)
                    cnt <= 7'b0;
            end            
            st_start  : begin
                case(cnt)
                    7'd1 : mdio_out <= 1'b0;        //發(fā)送開始信號 2'b01
                    7'd3 : mdio_out <= 1'b1; 
                    7'd5 : mdio_out <= op_code[1];  //發(fā)送操作碼
                    7'd6 : st_done <= 1'b1;
                    7'd7 : begin
                               mdio_out <= op_code[0];
                               cnt <= 7'b0;  
                           end    
                    default : ;
                endcase
            end    
            st_addr : begin
                case(cnt)
                    7'd1 : mdio_out <= PHY_ADDR[4]; //發(fā)送PHY地址
                    7'd3 : mdio_out <= PHY_ADDR[3];
                    7'd5 : mdio_out <= PHY_ADDR[2];
                    7'd7 : mdio_out <= PHY_ADDR[1];  
                    7'd9 : mdio_out <= PHY_ADDR[0];
                    7'd11: mdio_out <= addr_t[4];  //發(fā)送寄存器地址
                    7'd13: mdio_out <= addr_t[3];
                    7'd15: mdio_out <= addr_t[2];
                    7'd17: mdio_out <= addr_t[1];  
                    7'd18: st_done <= 1'b1;
                    7'd19: begin
                               mdio_out <= addr_t[0]; 
                               cnt <= 7'd0;
                           end    
                    default : ;
                endcase                
            end    
            st_wr_data : begin
                case(cnt)
                    7'd1 : mdio_out <= 1'b1;         //發(fā)送TA,寫操作(2'b10)
                    7'd3 : mdio_out <= 1'b0;
                    7'd5 : mdio_out <= wr_data_t[15];//發(fā)送寫寄存器數(shù)據(jù)
                    7'd7 : mdio_out <= wr_data_t[14];
                    7'd9 : mdio_out <= wr_data_t[13];
                    7'd11: mdio_out <= wr_data_t[12];
                    7'd13: mdio_out <= wr_data_t[11];
                    7'd15: mdio_out <= wr_data_t[10];
                    7'd17: mdio_out <= wr_data_t[9];
                    7'd19: mdio_out <= wr_data_t[8];
                    7'd21: mdio_out <= wr_data_t[7];
                    7'd23: mdio_out <= wr_data_t[6];
                    7'd25: mdio_out <= wr_data_t[5];
                    7'd27: mdio_out <= wr_data_t[4];
                    7'd29: mdio_out <= wr_data_t[3];
                    7'd31: mdio_out <= wr_data_t[2];
                    7'd33: mdio_out <= wr_data_t[1];
                    7'd35: mdio_out <= wr_data_t[0];
                    7'd37: begin
                        mdio_dir <= 1'b0;
                        mdio_out <= 1'b1;
                    end
                    7'd39: st_done <= 1'b1;           
                    7'd40: begin
                               cnt <= 7'b0;
                               op_done <= 1'b1;      //寫操作完成,拉高op_done信號 
                           end    
                    default : ;
                endcase    
            end
            st_rd_data : begin
                case(cnt)
                    7'd1 : begin
                        mdio_dir <= 1'b0;            //MDIO引腳切換至輸入狀態(tài)
                        mdio_out <= 1'b1;
                    end
                    7'd2 : ;                         //TA[1]位,該位為高阻狀態(tài),不操作             
                    7'd4 : op_rd_ack <= mdio_in;     //TA[0]位,0(應答) 1(未應答)
                    7'd6 : rd_data_t[15] <= mdio_in; //接收寄存器數(shù)據(jù)
                    7'd8 : rd_data_t[14] <= mdio_in;
                    7'd10: rd_data_t[13] <= mdio_in;
                    7'd12: rd_data_t[12] <= mdio_in;
                    7'd14: rd_data_t[11] <= mdio_in;
                    7'd16: rd_data_t[10] <= mdio_in;
                    7'd18: rd_data_t[9] <= mdio_in;
                    7'd20: rd_data_t[8] <= mdio_in;
                    7'd22: rd_data_t[7] <= mdio_in;
                    7'd24: rd_data_t[6] <= mdio_in;
                    7'd26: rd_data_t[5] <= mdio_in;
                    7'd28: rd_data_t[4] <= mdio_in;
                    7'd30: rd_data_t[3] <= mdio_in;
                    7'd32: rd_data_t[2] <= mdio_in;
                    7'd34: rd_data_t[1] <= mdio_in;
                    7'd36: rd_data_t[0] <= mdio_in;
                    7'd39: st_done <= 1'b1;
                    7'd40: begin
                        op_done <= 1'b1;             //讀操作完成,拉高op_done信號          
                        op_rd_data <= rd_data_t;
                        rd_data_t <= 16'd0;
                        cnt <= 7'd0;
                    end
                    default : ;
                endcase   
            end                
            default : ;
        endcase               
    end
end                    

endmodule
? ? ? ? ? ? ? ? ????????①控制雙向io方向

基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記

? ? ? ? ? ? ? ? ? ? ? ? ②分頻得到dri_clk時鐘

?????????????????基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記

? ? ? ? ? ? ? ? 首先對CLK_DIV進行除2,目的是得到2倍的CLK_DIV時鐘分頻,再利用clk_cnt計數(shù)器產(chǎn)生dri_clk時鐘。clk_divide[5:1] - 1'd1? ? ?取clk_divide的第5到第1位(實際作用除2取整,記滿進行信號反轉),再減掉1位作為計數(shù)器最大值、dri_clk信號跳轉標志。(對時鐘信號進行二分頻)

基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記

? ? ? ?? ? ? ? ?????????③產(chǎn)生PHY_MDC時鐘

基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記

? ? ? ? ? ? ? ?cnt計數(shù)器最低位,實際只在0.1互相切換,?實際是對dri_clk進行二分頻。(也就是dri_clk是MDC的兩倍,此時eth_mdc是時鐘頻率四分頻)

基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記

? ? ? ? ? ? ? ? ????????④狀態(tài)機——狀態(tài)轉移
//parameter define
localparam st_idle    = 6'b00_0001;  //空閑狀態(tài)
localparam st_pre     = 6'b00_0010;  //發(fā)送PRE(前導碼)
localparam st_start   = 6'b00_0100;  //開始狀態(tài),發(fā)送ST(開始)+OP(操作碼)
localparam st_addr    = 6'b00_1000;  //寫地址,發(fā)送PHY地址+寄存器地址
localparam st_wr_data = 6'b01_0000;  //TA+寫數(shù)據(jù)
localparam st_rd_data = 6'b10_0000;  //TA+讀數(shù)據(jù)
//(三段式狀態(tài)機)同步時序描述狀態(tài)轉移
always @(posedge dri_clk or negedge rst_n) begin
    if(!rst_n)
        cur_state <= st_idle;
    else
        cur_state <= next_state;
end  

? ? ? ? ? ? ? ? 狀態(tài)轉移,當前狀態(tài)等于下一狀態(tài)

? ? ? ? ? ? ? ? ? ? ? ? ⑤狀態(tài)機——狀態(tài)轉移條件
//組合邏輯判斷狀態(tài)轉移條件
always @(*) begin
    next_state = st_idle;
    case(cur_state)
        st_idle : begin
            if(op_exec)
                next_state = st_pre;
            else 
                next_state = st_idle;   
        end  
        st_pre : begin
            if(st_done)
                next_state = st_start;
            else
                next_state = st_pre;
        end
        st_start : begin
            if(st_done)
                next_state = st_addr;
            else
                next_state = st_start;
        end
        st_addr : begin
            if(st_done) begin
                if(op_code == 2'b01)                //MDIO接口寫操作  
                    next_state = st_wr_data;
                else
                    next_state = st_rd_data;        //MDIO接口讀操作  
            end
            else
                next_state = st_addr;
        end
        st_wr_data : begin
            if(st_done)
                next_state = st_idle;
            else
                next_state = st_wr_data;
        end        
        st_rd_data : begin
            if(st_done)
                next_state = st_idle;
            else
                next_state = st_rd_data;
        end                                                                          
        default : next_state = st_idle;
    endcase
  end

? ? ? ? 在?st_idle(空閑狀態(tài))模式下:op_exec(觸發(fā)開始信號)拉高,下一狀態(tài)進入st_pre,否則保持。

? ? ? ? 在st_pre(發(fā)送PRE(前導碼))模式下:st_done(狀態(tài)開始跳轉信號)拉高,下一狀態(tài)進入st_start,否則保持

? ? ? ? 在st_start(開始狀態(tài),發(fā)送ST(開始)+OP(操作碼))模式下:st_done(狀態(tài)開始跳轉信號)拉高,下一狀態(tài)進入st_addr,否則保持

? ? ? ? 在st_addr(寫地址,發(fā)送PHY地址+寄存器地址)模式下:如果op_code (操作碼)== 2'b01,下一狀態(tài)進入st_wr_data,否則進入st_rd_data

? ? ? ? 在st_wr_data(TA+寫數(shù)據(jù))模式下:st_done(狀態(tài)開始跳轉信號)拉高,下一狀態(tài)進入st_idle,否則保持

? ? ? ? 在st_rd_data(TA+讀數(shù)據(jù))模式下:st_done(狀態(tài)開始跳轉信號)拉高,下一狀態(tài)進入st_idle,否則保持

基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記

? ? ? ? ? ? ? ? ? ? ? ? ⑥狀態(tài)機——狀態(tài)輸出
//時序電路描述狀態(tài)輸出
always @(posedge dri_clk or negedge rst_n) begin
    if(!rst_n) begin
        cnt <= 5'd0;
        op_code <= 1'b0;
        addr_t <= 1'b0;
        wr_data_t <= 1'b0;
        rd_data_t <= 1'b0;
        op_done <= 1'b0;
        st_done <= 1'b0; 
        op_rd_data <= 1'b0;
        op_rd_ack <= 1'b1;
        mdio_dir <= 1'b0;
        mdio_out <= 1'b1;
    end
    else begin
        st_done <= 1'b0 ;                            
        cnt     <= cnt +1'b1 ;          
        case(cur_state)
            st_idle : begin
                mdio_out <= 1'b1;                     
                mdio_dir <= 1'b0;                     
                op_done <= 1'b0;                     
                cnt <= 7'b0;  
                if(op_exec) begin
                    op_code <= {op_rh_wl,~op_rh_wl}; //OP_CODE: 2'b01(寫)  2'b10(讀) 
                    addr_t <= op_addr;
                    wr_data_t <= op_wr_data;
                    op_rd_ack <= 1'b1;
                end     
            end 
            st_pre : begin                          //發(fā)送前導碼:32個1bit 
                mdio_dir <= 1'b1;                   //切換MDIO引腳方向:輸出
                mdio_out <= 1'b1;                   //MDIO引腳輸出高電平
                if(cnt == 7'd62) 
                    st_done <= 1'b1;
                else if(cnt == 7'd63)
                    cnt <= 7'b0;
            end            
            st_start  : begin
                case(cnt)
                    7'd1 : mdio_out <= 1'b0;        //發(fā)送開始信號 2'b01
                    7'd3 : mdio_out <= 1'b1; 
                    7'd5 : mdio_out <= op_code[1];  //發(fā)送操作碼
                    7'd6 : st_done <= 1'b1;
                    7'd7 : begin
                               mdio_out <= op_code[0];
                               cnt <= 7'b0;  
                           end    
                    default : ;
                endcase
            end    
            st_addr : begin
                case(cnt)
                    7'd1 : mdio_out <= PHY_ADDR[4]; //發(fā)送PHY地址
                    7'd3 : mdio_out <= PHY_ADDR[3];
                    7'd5 : mdio_out <= PHY_ADDR[2];
                    7'd7 : mdio_out <= PHY_ADDR[1];  
                    7'd9 : mdio_out <= PHY_ADDR[0];
                    7'd11: mdio_out <= addr_t[4];  //發(fā)送寄存器地址
                    7'd13: mdio_out <= addr_t[3];
                    7'd15: mdio_out <= addr_t[2];
                    7'd17: mdio_out <= addr_t[1];  
                    7'd18: st_done <= 1'b1;
                    7'd19: begin
                               mdio_out <= addr_t[0]; 
                               cnt <= 7'd0;
                           end    
                    default : ;
                endcase                
            end    
            st_wr_data : begin
                case(cnt)
                    7'd1 : mdio_out <= 1'b1;         //發(fā)送TA,寫操作(2'b10)
                    7'd3 : mdio_out <= 1'b0;
                    7'd5 : mdio_out <= wr_data_t[15];//發(fā)送寫寄存器數(shù)據(jù)
                    7'd7 : mdio_out <= wr_data_t[14];
                    7'd9 : mdio_out <= wr_data_t[13];
                    7'd11: mdio_out <= wr_data_t[12];
                    7'd13: mdio_out <= wr_data_t[11];
                    7'd15: mdio_out <= wr_data_t[10];
                    7'd17: mdio_out <= wr_data_t[9];
                    7'd19: mdio_out <= wr_data_t[8];
                    7'd21: mdio_out <= wr_data_t[7];
                    7'd23: mdio_out <= wr_data_t[6];
                    7'd25: mdio_out <= wr_data_t[5];
                    7'd27: mdio_out <= wr_data_t[4];
                    7'd29: mdio_out <= wr_data_t[3];
                    7'd31: mdio_out <= wr_data_t[2];
                    7'd33: mdio_out <= wr_data_t[1];
                    7'd35: mdio_out <= wr_data_t[0];
                    7'd37: begin
                        mdio_dir <= 1'b0;
                        mdio_out <= 1'b1;
                    end
                    7'd39: st_done <= 1'b1;           
                    7'd40: begin
                               cnt <= 7'b0;
                               op_done <= 1'b1;      //寫操作完成,拉高op_done信號 
                           end    
                    default : ;
                endcase    
            end
            st_rd_data : begin
                case(cnt)
                    7'd1 : begin
                        mdio_dir <= 1'b0;            //MDIO引腳切換至輸入狀態(tài)
                        mdio_out <= 1'b1;
                    end
                    7'd2 : ;                         //TA[1]位,該位為高阻狀態(tài),不操作             
                    7'd4 : op_rd_ack <= mdio_in;     //TA[0]位,0(應答) 1(未應答)
                    7'd6 : rd_data_t[15] <= mdio_in; //接收寄存器數(shù)據(jù)
                    7'd8 : rd_data_t[14] <= mdio_in;
                    7'd10: rd_data_t[13] <= mdio_in;
                    7'd12: rd_data_t[12] <= mdio_in;
                    7'd14: rd_data_t[11] <= mdio_in;
                    7'd16: rd_data_t[10] <= mdio_in;
                    7'd18: rd_data_t[9] <= mdio_in;
                    7'd20: rd_data_t[8] <= mdio_in;
                    7'd22: rd_data_t[7] <= mdio_in;
                    7'd24: rd_data_t[6] <= mdio_in;
                    7'd26: rd_data_t[5] <= mdio_in;
                    7'd28: rd_data_t[4] <= mdio_in;
                    7'd30: rd_data_t[3] <= mdio_in;
                    7'd32: rd_data_t[2] <= mdio_in;
                    7'd34: rd_data_t[1] <= mdio_in;
                    7'd36: rd_data_t[0] <= mdio_in;
                    7'd39: st_done <= 1'b1;
                    7'd40: begin
                        op_done <= 1'b1;             //讀操作完成,拉高op_done信號          
                        op_rd_data <= rd_data_t;
                        rd_data_t <= 16'd0;
                        cnt <= 7'd0;
                    end
                    default : ;
                endcase   
            end                
            default : ;
        endcase               
    end
end                    

endmodule

? ? ? ? ? ? ? ? 復位后:cnt(計數(shù)器)、op_code(操作碼 ?2'b01(寫) ?2'b10(讀))、addr_t(緩存寄存器地址)、wr_data_t(緩存寫寄存器的數(shù)據(jù))、rd_data_t(緩存讀寄存器數(shù)據(jù))、op_done(讀寫完成)、st_done(狀態(tài)開始跳轉信號)、op_rd_data(讀出的數(shù)據(jù))、mdio_dir(MDIO數(shù)據(jù)(SDA)方向控制)清零。op_rd_ack(讀應答信號 0:應答 1:未應答)、mdio_out(MDIO輸出信號)置1。

基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記

????????mdio_out(MDIO輸出信號)置1、mdio_dir(MDIO數(shù)據(jù)(SDA)方向控制):輸入、op_done(讀寫完成)置0。

? ? ? ? 如果op_exec(觸發(fā)信號)拉高,對op_code進行為拼接賦值,op_addr、op_wr_data進行寄存,op_rd_ack(讀應答信號 0:應答 1:未應答)置1。

基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記

????????dri_clk下計數(shù)63個上升沿,對應MDC時鐘31個上升沿,即為發(fā)送32個前導碼1。記滿cnt清零

基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記

? ? ? ? 發(fā)送起始信號ST01,發(fā)送讀寫操作碼低電平寫,op_code[1],op_code[0]低電平寫,高電平讀。st_done(狀態(tài)開始跳轉信號)置為1。????????

? ? ? ? 為什么cnt計數(shù)為奇數(shù)時改變數(shù)據(jù):dri_clk為MDC的2倍,奇數(shù)剛好在MDC下降沿改變數(shù)據(jù)。

基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記

? ? ? ? 依次發(fā)送PHY地址、寄存器地址,期間st_done(狀態(tài)開始跳轉信號)置為1

基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記

? ? ? ? 發(fā)送TA寫指令后,開始發(fā)送寫入數(shù)據(jù)。之后將mdio_dir(MDIO數(shù)據(jù)(SDA)方向控制)置0釋放總線進入高阻,mdio_out(MDIO輸出信號)置1,op_done(讀寫完成)拉高標志一次讀寫造作結束。

?基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記

???????? 發(fā)送TA讀指令后,TA[1]位無需操作保持高阻狀態(tài),由PHY側控制總線。檢測TA[0]位,如有應答,PHY側會拉低mdio_in引腳,作為應答信號。依次接受16位讀出數(shù)據(jù)寄存到rd_data_t下。之后op_done(讀寫完成)拉高標志一次讀寫造作結束,op_rd_data <= rd_data_t;進行輸出其他新信號清零。

? ? ? ? ? ? ? ? (2)mdio_ctrl模塊

基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記

module mdio_ctrl(
    input                clk           ,
    input                rst_n         ,
    input                soft_rst_trig , //軟復位觸發(fā)信號
    input                op_done       , //讀寫完成
    input        [15:0]  op_rd_data    , //讀出的數(shù)據(jù)
    input                op_rd_ack     , //讀應答信號 0:應答 1:未應答
    output  reg          op_exec       , //觸發(fā)開始信號
    output  reg          op_rh_wl      , //低電平寫,高電平讀
    output  reg  [4:0]   op_addr       , //寄存器地址
    output  reg  [15:0]  op_wr_data    , //寫入寄存器的數(shù)據(jù)
    output       [1:0]   led             //LED燈指示以太網(wǎng)連接狀態(tài)
    );

//reg define
reg          rst_trig_d0;    
reg          rst_trig_d1;    
reg          rst_trig_flag;   //soft_rst_trig信號觸發(fā)標志
reg  [23:0]  timer_cnt;       //定時計數(shù)器 
reg          timer_done;      //定時完成信號
reg          start_next;      //開始讀下一個寄存器標致
reg          read_next;       //處于讀下一個寄存器的過程
reg          link_error;      //鏈路斷開或者自協(xié)商未完成
reg  [2:0]   flow_cnt;        //流程控制計數(shù)器 
reg  [1:0]   speed_status;    //連接速率 

//wire define
wire         pos_rst_trig;    //soft_rst_trig信號上升沿

//采soft_rst_trig信號上升沿
assign pos_rst_trig = ~rst_trig_d1 & rst_trig_d0;
//未連接或連接失敗時led賦值00
// 01:10Mbps  10:100Mbps  11:1000Mbps 00:其他情況
assign led = link_error ? 2'b00: speed_status;
//對soft_rst_trig信號延時打拍
always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        rst_trig_d0 <= 1'b0;
        rst_trig_d1 <= 1'b0;
    end
    else begin
        rst_trig_d0 <= soft_rst_trig;
        rst_trig_d1 <= rst_trig_d0;
    end
end

//定時計數(shù)
always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        timer_cnt <= 1'b0;
        timer_done <= 1'b0;
    end
    else begin
        if(timer_cnt == 24'd1_000_000 - 1'b1) begin
            timer_done <= 1'b1;
            timer_cnt <= 1'b0;
        end
        else begin
            timer_done <= 1'b0;
            timer_cnt <= timer_cnt + 1'b1;
        end
    end
end    

//根據(jù)軟復位信號對MDIO接口進行軟復位,并定時讀取以太網(wǎng)的連接狀態(tài)
always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        flow_cnt <= 3'd0;
        rst_trig_flag <= 1'b0;
        speed_status <= 2'b00;
        op_exec <= 1'b0; 
        op_rh_wl <= 1'b0; 
        op_addr <= 1'b0;       
        op_wr_data <= 1'b0; 
        start_next <= 1'b0; 
        read_next <= 1'b0; 
        link_error <= 1'b0;
    end
    else begin
        op_exec <= 1'b0; 
        if(pos_rst_trig)                      
            rst_trig_flag <= 1'b1;             //拉高軟復位觸發(fā)標志
        case(flow_cnt)
            2'd0 : begin
                if(rst_trig_flag) begin        //開始對MDIO接口進行軟復位
                    op_exec <= 1'b1; 
                    op_rh_wl <= 1'b0; 
                    op_addr <= 5'h00; 
                    op_wr_data <= 16'h9140;    //Bit[15]=1'b1,表示軟復位
                    flow_cnt <= 3'd1;
                end
                else if(timer_done) begin      //定時完成,獲取以太網(wǎng)連接狀態(tài)
                    op_exec <= 1'b1; 
                    op_rh_wl <= 1'b1; 
                    op_addr <= 5'h01; 
                    flow_cnt <= 3'd2;
                end
                else if(start_next) begin       //開始讀下一個寄存器,獲取以太網(wǎng)通信速度
                    op_exec <= 1'b1; 
                    op_rh_wl <= 1'b1; 
                    op_addr <= 5'h11;
                    flow_cnt <= 3'd2;
                    start_next <= 1'b0; 
                    read_next <= 1'b1; 
                end
            end    
            2'd1 : begin
                if(op_done) begin              //MDIO接口軟復位完成
                    flow_cnt <= 3'd0;
                    rst_trig_flag <= 1'b0;
                end
            end
            2'd2 : begin                       
                if(op_done) begin              //MDIO接口讀操作完成
                    if(op_rd_ack == 1'b0 && read_next == 1'b0) //讀第一個寄存器,接口成功應答,
                        flow_cnt <= 3'd3;                      //讀第下一個寄存器,接口成功應答
                    else if(op_rd_ack == 1'b0 && read_next == 1'b1)begin 
                        read_next <= 1'b0;
                        flow_cnt <= 3'd4;
                    end
                    else begin
                        flow_cnt <= 3'd0;
                     end
                end    
            end
            2'd3 : begin                     
                flow_cnt <= 3'd0;          //鏈路正常并且自協(xié)商完成
                if(op_rd_data[5] == 1'b1 && op_rd_data[2] == 1'b1)begin
                    start_next <= 1;
                    link_error <= 0;
                end
                else begin
                    link_error <= 1'b1;  
               end           
            end
            3'd4: begin
                flow_cnt <= 3'd0;
                if(op_rd_data[15:14] == 2'b10)
                    speed_status <= 2'b11; //1000Mbps
                else if(op_rd_data[15:14] == 2'b01) 
                    speed_status <= 2'b10; //100Mbps 
                else if(op_rd_data[15:14] == 2'b00) 
                    speed_status <= 2'b01; //10Mbps
                else
                    speed_status <= 2'b00; //其他情況  
            end
        endcase
    end    
end    

endmodule
? ? ? ? ? ? ? ? ? ? ? ? ①?對soft_rst_trig信號延時打兩拍

基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記

基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記

????????對soft_rst_trig?軟復位觸發(fā)信號進行打兩拍,抓取soft_rst_trig上升沿信號

? ? ? ? ? ? ? ? ? ? ? ? ?②定時計數(shù)

基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記

? ? ? ? ? ? ? ? ? ? ? ? ?③流程控制

基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記

?????????如果檢測到soft_rst_trig 上升沿,將rst_trig_flag信號拉高

? ? ? ? ?不拉高op_exec原因:觸摸按鍵按下實踐不確定,如果在讀寫期間按下,拉高op_exec沒有意義,無法達到復位效果。

? ? ? ? 0狀態(tài):

基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記

? ? ? ? 如果rst_trig_flag信號拉高,進行軟復位,op_exec(觸發(fā)開始信號)置1,op_rh_wl(低電平寫,高電平讀)置0。op_addr(寄存器地址)給出寄存器地址0x00,op_wr_data(寫入寄存器的數(shù)據(jù))對PHY芯片寄存器給出配置。flow_cnt下一狀態(tài)進入1狀態(tài)。

????????????????16'h9140? ?=? ? 2'b1001_0001_0100_0000?

回看0x00寄存器,

基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記

基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記

基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記

? ? ? ? ? ? ? ? 如果復位沒有按下,則會等待計數(shù)器記滿后,讀取當前通信速率。op_exec(觸發(fā)開始信號)置1,op_rh_wl(低電平寫,高電平讀)置1,op_addr(寄存器地址)給出寄存器地址0x01。flow_cnt下一狀態(tài)進入2狀態(tài)。

????????????????16'h9140? ?=? ? 2'b1001_0001_0100_0000?

? ? ? ? ? ? ? ? 如果計數(shù)器沒有記滿,start_next拉高時,op_exec(觸發(fā)開始信號)置1,op_rh_wl(低電平寫,高電平讀)置1,op_addr(寄存器地址)給出寄存器地址0x11。flow_cnt下一狀態(tài)進入2狀態(tài)。start_next <= 1'b0;read_next <= 1'b1;?

? ? ? ? 1狀態(tài):

基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記

? ? ? ? 等待op_done讀寫結束標志拉高,下一狀態(tài)為0狀態(tài),rst_trig_flag標志位拉低。

? ? ? ? 2狀態(tài):

基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記

? ? ? ? 如果應答信號op_rd_ack為0,read_next(寄存器讀取標志)為0,跳轉到3狀態(tài)。

? ? ? ? 如果read_next(寄存器讀取標志)為1,重置read_next為0,下一狀態(tài)為4狀態(tài)。

? ? ? ? 如果沒有應答信號op_rd_ack為1時,下一狀態(tài)進入0狀態(tài)。

? ? ? ? 3狀態(tài):

基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記

下一狀態(tài)進入0狀態(tài)。讀出0x01寄存器的第5位和第2位,進行判斷。符合條件(遠端連接成功)start_next拉高。

基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記

基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記

? ? ? ? ?4狀態(tài):

基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記

? ? ? ? 下一狀態(tài)進入0狀態(tài),讀取寄存器0x11的15、14位,的出對應的通信速率,賦值給speed_status。

基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記

基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記

? ? ? ? 利用三目運算為led進行賦值。

? ? ? ? ????????(3)mdio_rw_test頂層

module mdio_rw_test(
    input          sys_clk  ,
    input          sys_rst_n,
    //MDIO接口
    output         eth_mdc  , //PHY管理接口的時鐘信號
    inout          eth_mdio , //PHY管理接口的雙向數(shù)據(jù)信號
    output         eth_rst_n, //以太網(wǎng)復位信號
    
    input          touch_key, //觸摸按鍵
    output  [1:0]  led        //LED連接速率指示
    );
    
//wire define
wire          op_exec    ;  //觸發(fā)開始信號
wire          op_rh_wl   ;  //低電平寫,高電平讀
wire  [4:0]   op_addr    ;  //寄存器地址
wire  [15:0]  op_wr_data ;  //寫入寄存器的數(shù)據(jù)
wire          op_done    ;  //讀寫完成
wire  [15:0]  op_rd_data ;  //讀出的數(shù)據(jù)
wire          op_rd_ack  ;  //讀應答信號 0:應答   1:未應答
wire          dri_clk    ;  //驅動時鐘

//硬件復位
assign eth_rst_n = sys_rst_n;

//MDIO接口驅動
mdio_dri #(
    .PHY_ADDR    (5'h04),   //PHY地址
    .CLK_DIV     (6'd10)    //分頻系數(shù)
    )
    u_mdio_dri(
    .clk        (sys_clk),
    .rst_n      (sys_rst_n),
    .op_exec    (op_exec   ),
    .op_rh_wl   (op_rh_wl  ),   
    .op_addr    (op_addr   ),   
    .op_wr_data (op_wr_data),   
    .op_done    (op_done   ),   
    .op_rd_data (op_rd_data),   
    .op_rd_ack  (op_rd_ack ),   
    .dri_clk    (dri_clk   ),  
                 
    .eth_mdc    (eth_mdc   ),   
    .eth_mdio   (eth_mdio  )   
);      

//MDIO接口讀寫控制    
mdio_ctrl  u_mdio_ctrl(
    .clk           (dri_clk),  
    .rst_n         (sys_rst_n ),  
    .soft_rst_trig (touch_key ),  
    .op_done       (op_done   ),  
    .op_rd_data    (op_rd_data),  
    .op_rd_ack     (op_rd_ack ),  
    .op_exec       (op_exec   ),  
    .op_rh_wl      (op_rh_wl  ),  
    .op_addr       (op_addr   ),  
    .op_wr_data    (op_wr_data),  
    .led           (led       )
);      

endmodule

六、下載驗證

基于fpga的rtl8211fd以太網(wǎng)接收程序,FPGA學習筆記,fpga開發(fā),學習,筆記文章來源地址http://www.zghlxwxcb.cn/news/detail-842838.html

到了這里,關于FPGA千兆網(wǎng)口數(shù)據(jù)傳輸MDIO接口——FPGA學習筆記3的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

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

領支付寶紅包贊助服務器費用

相關文章

  • 千兆以太網(wǎng)(二)——MDIO接口協(xié)議

    千兆以太網(wǎng)(二)——MDIO接口協(xié)議

    ??MAC和PHY芯片有一個配置接口,即MDIO接口??梢耘渲肞HY芯片的工作模式以及獲取PHY芯片的狀態(tài)信息。PHY芯片內(nèi)部有一系列寄存器。用戶通過配置寄存器來配置PHY芯片的工作模式。 ??FPGA通過MDIO接口對PHY芯片的內(nèi)部寄存器進行配置。通常情況下芯片在默認情況下也可以工作

    2024年01月20日
    瀏覽(27)
  • FPGA學習筆記:數(shù)據(jù)采集傳輸系統(tǒng)設計(三):AD采集驅動ADC128S052

    FPGA學習筆記:數(shù)據(jù)采集傳輸系統(tǒng)設計(三):AD采集驅動ADC128S052

    ADC128S052為 12 位、8通道 的模數(shù)轉換器 (ADC),轉換速度高達 10 MSPS,采用SPI串行通信。 (1)工作時序圖 應注意DIN中配置好的通道地址ADD在下一次采樣時才生效 。 從時序圖中可得出,ADC芯片在上升沿時采樣,讀取DIN數(shù)據(jù);DOUT在下降沿時改變數(shù)據(jù)。 (2)串行時序圖 片選信號在

    2024年02月07日
    瀏覽(16)
  • E9—TEMAC IP實現(xiàn)千兆網(wǎng)口UDP傳輸2023-08-28

    E9—TEMAC IP實現(xiàn)千兆網(wǎng)口UDP傳輸2023-08-28

    Tri Mode Ethernet MAC是收費IP,打開IP后,當左下角顯示Bought IP license available則IP可用。 應用搭建的場景是,上位機發(fā)送數(shù)據(jù),首先發(fā)起arp請求,隨后下位機給出arp應答響應,上位機get到下位機的mac地址之后,將發(fā)送框中的數(shù)據(jù)打包成udp數(shù)據(jù)包下發(fā)到下位機中,下位機收到udp包,將

    2024年02月10日
    瀏覽(20)
  • FPGA(Verilog)實現(xiàn)uart傳輸協(xié)議傳輸數(shù)據(jù)(含仿真)

    FPGA(Verilog)實現(xiàn)uart傳輸協(xié)議傳輸數(shù)據(jù)(含仿真)

    目錄 實現(xiàn)功能: 1.接收uart串行數(shù)據(jù),輸出并行數(shù)據(jù)(1byte)。 2.輸入并行數(shù)據(jù)(1byte),輸出uart串行數(shù)據(jù)。 3.完成uart傳輸?shù)?次環(huán)回。 uart協(xié)議的1幀數(shù)據(jù)傳輸 模塊封裝-port設置 Verilog代碼實現(xiàn) 1.uart接收模塊:接收串行數(shù)據(jù),輸出并行數(shù)據(jù)和其有效標志。 仿真結果: 2.uart發(fā)送模塊:接收

    2024年04月16日
    瀏覽(21)
  • FPGA 20個例程篇:13.千兆網(wǎng)口實現(xiàn)ARP通信協(xié)議(下)

    FPGA 20個例程篇:13.千兆網(wǎng)口實現(xiàn)ARP通信協(xié)議(下)

    ? ? ? ? 完成了RGMII接口和GMII接口轉換的代碼設計,接下來我們來設計以太網(wǎng)幀的報文解析模塊,為了兼顧下一個例程中ICMP和UDP報文的解析,我們把ARP報文解析分成以太網(wǎng)首部解析和ARP數(shù)據(jù)解析兩部分,這樣以太網(wǎng)首部解析模塊還可以再用到下一個例程當中提高了代碼的復用

    2024年02月13日
    瀏覽(25)
  • FPGA 20個例程篇:14.千兆網(wǎng)口實現(xiàn)ICMP、UDP通信協(xié)議(上)

    FPGA 20個例程篇:14.千兆網(wǎng)口實現(xiàn)ICMP、UDP通信協(xié)議(上)

    ? ? ? ?UDP是一種面向無連接的傳輸層協(xié)議,屬于TCP/IP協(xié)議族的一種,UDP具有消耗資源少、通信效率高等優(yōu)點,一般性地用來傳輸音頻或者視頻等對實時性要求高的場合。 ? ? ? ? ICMP是TCP/IP協(xié)議族的一個IP層子協(xié)議,包含在IP數(shù)據(jù)報里,主要用于IP主機、路由器之間傳遞控制消

    2024年02月03日
    瀏覽(26)
  • FPGA 高速數(shù)據(jù)采集傳輸畢業(yè)論文【附仿真】

    FPGA 高速數(shù)據(jù)采集傳輸畢業(yè)論文【附仿真】

    以 FIFO IP 核以及 Verilog 編程設計的數(shù)字邏輯模塊對JESD204B IP 核輸出數(shù)據(jù)完成接收,處理成驅動設備可讀取的數(shù)據(jù)格式后,送入設計的數(shù)字邏輯緩存部分中,通過AXI 總線送入DDR3 SDRAM 中緩存,并由傳輸部分數(shù)字邏輯模塊完成緩存深度配置。? 介紹設計的具體實現(xiàn)。在數(shù)字采集功

    2024年04月25日
    瀏覽(36)
  • FPGA中光纖,ddr3,srio數(shù)據(jù)傳輸速率、帶寬分析

    需求分析:FPGA通過光纖接收數(shù)據(jù),將接受的數(shù)據(jù)寫入ddr中,再通過srio將數(shù)據(jù)傳遞給dsp。光纖傳輸?shù)臄?shù)據(jù)量為17萬個32bit數(shù)據(jù)。 光纖速率分析:由于在光纖IP核中設置的速率為3.125G,單位bit。數(shù)據(jù)位寬為16bit。又由于光纖傳輸數(shù)據(jù)會進行8b/10b編碼。因此單根光纖本地的傳輸速率

    2024年02月13日
    瀏覽(12)
  • SpringBoot案例 調(diào)用第三方接口傳輸數(shù)據(jù)

    SpringBoot案例 調(diào)用第三方接口傳輸數(shù)據(jù)

    最近再寫調(diào)用三方接口傳輸數(shù)據(jù)的項目,這篇博客記錄項目完成的過程,方便后續(xù)再碰到類似的項目可以快速上手 項目結構: 這里主要介紹HttpClient發(fā)送POST請求工具類和定時器的使用,mvc三層架構編碼不做探究 pom.xml application-dev.yml Constast utils scheduled 該定時任務每10秒執(zhí)行一

    2024年02月12日
    瀏覽(29)
  • 基于FPGA的EMAC模塊與FIFO模塊:高速數(shù)據(jù)傳輸與存儲

    基于FPGA的EMAC模塊與FIFO模塊:高速數(shù)據(jù)傳輸與存儲 在現(xiàn)代社會,高速數(shù)據(jù)傳輸和存儲是信息技術領域的關鍵問題之一。而基于FPGA的EMAC模塊與FIFO模塊則成為了解決這些問題的重要途徑。本文將介紹這兩個模塊的原理、實現(xiàn)方法以及如何在FPGA中應用它們。 EMAC模塊是以太網(wǎng)MA

    2024年02月03日
    瀏覽(21)

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

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

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

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

二維碼1

領取紅包

二維碼2

領紅包