赞
踩
目录
RGMII接口是FPGA芯片与PHY芯片进行通信的接口,全称Reduced Gigabit Media Independent Interface(吉比特介质独立接口),支持10 Mbps,100 Mbps和1000 Mbps的PHY层连接速度。
序号 | 引脚 | 方向 | 描述 |
1 | TXC | MAC → PHY | 发送时钟 |
2 | TX_CTL | MAC → PHY | 发送使能 |
3 | TXD | MAC → PHY | |
4 | RXC | PHY → MAC | 接收时钟 |
5 | RX_CTL | PHY → MAC | 接收使能 |
6 | RXD | PHY → MAC | 接收数据 |
7 | MDC | MAC → PHY | PHY配置时钟 |
8 | MDIO | MAC ←→ PHY | PHY配置读写 |
在1000 Mbps模式下,TXC和RXC为125 MHz,时钟的上升沿和下降沿同时传输数据,每次传输4bit数据。所以总速率为:125M*2*4bit / 1s = 1000Mbps。
本次实验FPGA开发板配套PHY芯片引脚定义如下:除去数据收发引脚,还有ETH_INT及PHYRSTB引脚, 用于初始化和复位,没有特殊需求一直给高电平芯片就能正常运行。
PHY芯片发送数据时,在时钟的上升沿发送字节的低4位,在下降沿发送字节的高4位。
当RX_CTL上升沿和下降沿均为1时,表示数据有效,无何何错误。
当RX_CTL上升沿为1,下降沿为0时,表示当前时钟周期的数据错误。
开发板卡在设计时通常会通过在PCB走线、在控制器端或在PHY芯片内部添加时钟偏移,让其工作在延时模式。
简言之就是PHY芯片发送的数据是在时钟的上升沿以及下降沿变化的,如下图。
然后通过时钟偏移,偏移90度,让FPGA收到的时钟沿和数据的中心对齐,如下图。
如果不做任何处理,FPGA是无法在时钟沿上正确的采集到每个数据。
本次实验所采用芯片为RTL8211E,如图2,根据芯片手册,如下表,16及32引脚均通过上拉电阻拉高,PHY芯片已经工作于延时模式。
PIN | PIN_NAME | DESCRIPTION |
16 | TXDLY | 1: Add 2ns delay to TXC for TXD latching |
32 | RXDLY | 1: Add 2ns delay to RXC for RXD latching |
FPGA芯片发送数据时,在时钟的上升沿发送字节的低4位,在下降沿发送字节的高4位。
根据PHY芯片是否工作在延时模式,FPGA芯片对发送时钟进行调整。
如果PHY芯片是在延时模式,则发送时钟不做处理。
如果未在延时模式,则发送时钟偏移90度相位。
本次实验RTL8211芯片工作于延时模式,发送时钟不做处理。
主模块:rgmii_to_gmii模块
包含2个子模块:rgmii_rxd 模块, rgmii_txd 模块
顶层按照原理图引入相关接口,MDC以及MDIO接口此处对PHY芯片无配置需求,暂不引入,引入clk_wiz IP核输出复位接口,引入ila IP核观测接口。
- `timescale 1ns / 1ps
-
- module top(
- input sysclk ,
- output eth_rst_n ,
- input rgmii_rx_clk ,
- input [3:0] rgmii_rxd ,
- input rgmii_rx_dv ,
- output rgmii_tx_clk ,
- output [3:0] rgmii_txd ,
- output rgmii_tx_en
- );
-
- wire clk_50M,rst_n;
- assign eth_rst_n = rst_n;
- clk_wiz_0 u0_clk_wiz_0
- (
- .clk_50M (clk_50M ), // output clk_200M
- .reset (1'd0 ), // input reset
- .locked (rst_n ),
- .clk_in1 (sysclk )
- );
-
- wire gmii_rx_clk ;
- wire gmii_rx_dv ;
- wire [7:0] gmii_rxd ;
- wire gmii_tx_clk ;
- wire gmii_tx_en ;
- wire [7:0] gmii_txd ;
- rgmii_to_gmii u1_rgmii_to_gmii(
- .gmii_rxc (gmii_rx_clk ),
- .gmii_rxdv (gmii_rx_dv ),
- .gmii_rxd (gmii_rxd ),
- .gmii_txc (gmii_tx_clk ),
- .gmii_txen (gmii_tx_en ),
- .gmii_txd (gmii_txd ),
- .rgmii_rxc (rgmii_rx_clk ),
- .rgmii_rx_ctrl (rgmii_rx_dv ),
- .rgmii_rxd (rgmii_rxd ),
- .rgmii_txc (rgmii_tx_clk ),
- .rgmii_tx_ctrl (rgmii_tx_en ),
- .rgmii_txd (rgmii_txd )
- );
-
- ila_16 ila_u (
- .clk(gmii_rx_clk), // input wire clk
- .probe0({gmii_rx_dv,gmii_rxd}) // input wire [15:0] probe0
- );
- endmodule
例化rgmii接口的收发模块
- module rgmii_to_gmii(
- output gmii_rxc ,
- output gmii_rxdv ,
- output [7:0] gmii_rxd ,
- output gmii_txc ,
- input gmii_txen ,
- input [7:0] gmii_txd ,
- input rgmii_rxc ,
- input rgmii_rx_ctrl ,
- input [3:0] rgmii_rxd ,
- output rgmii_txc ,
- output rgmii_tx_ctrl ,
- output [3:0] rgmii_txd
- );
-
- assign gmii_txc = gmii_rxc;
-
- rgmii_rxd rgmii_rxd_inst(
- .rgmii_rxc (rgmii_rxc ),
- .rgmii_rx_ctrl (rgmii_rx_ctrl ),
- .rgmii_rxd (rgmii_rxd ),
- .gmii_rxc (gmii_rxc ),
- .gmii_rxdv (gmii_rxdv ),
- .gmii_rxd (gmii_rxd )
- );
-
- rgmii_txd rgmii_txd_inst(
- .gmii_txc (gmii_txc ),
- .gmii_txen (gmii_txen ),
- .gmii_txd (gmii_txd ),
- .rgmii_txc (rgmii_txc ),
- .rgmii_tx_ctrl (rgmii_tx_ctrl ),
- .rgmii_txd (rgmii_txd )
- );
-
- endmodule
通过IDDR原语,对PHY芯片输入的双沿信号处理成单沿信号,包含使能信号以及4bit数据信号。
使能信号处理方式为:时钟的上下沿使能信号同时为高电平时,在下一个时钟输出高电平,只要有一个沿为低电平,最终就不会输出高电平。
数据信号处理方式为:时钟的上沿数据作为低4bit,下沿数据作为高4bit,在下一个时钟组合输出一个8bit数据。
- module rgmii_rxd(
- input rgmii_rxc ,
- input rgmii_rx_ctrl ,
- input [3:0] rgmii_rxd ,
- output gmii_rxc ,
- output gmii_rxdv ,
- output [7:0] gmii_rxd
- );
-
-
- wire rgmii_rxc_bufio; //全局时钟IO缓存
- wire [1:0] gmii_rxdv_t; //上下沿有效信号
-
- BUFG BUFG_inst (
- .I (rgmii_rxc), // 1-bit input: Clock input
- .O (gmii_rxc) // 1-bit output: Clock output
- );
-
- BUFIO BUFIO_inst (
- .I (rgmii_rxc), // 1-bit input: Clock input
- .O (rgmii_rxc_bufio) // 1-bit output: Clock output
- );
-
- IDDR #(
- .DDR_CLK_EDGE("SAME_EDGE_PIPELINED"),// "OPPOSITE_EDGE", "SAME_EDGE"
- // or "SAME_EDGE_PIPELINED"
- .INIT_Q1 (1'b0), // Initial value of Q1: 1'b0 or 1'b1
- .INIT_Q2 (1'b0), // Initial value of Q2: 1'b0 or 1'b1
- .SRTYPE ("SYNC") // Set/Reset type: "SYNC" or "ASYNC"
- ) IDDR_inst (
- .Q1 (gmii_rxdv_t[0]), // 1-bit output for positive edge of clock
- .Q2 (gmii_rxdv_t[1]), // 1-bit output for negative edge of clock
- .C (rgmii_rxc_bufio), // 1-bit clock input
- .CE (1'b1), // 1-bit clock enable input
- .D (rgmii_rx_ctrl), // 1-bit DDR data input
- .R (1'b0), // 1-bit reset
- .S (1'b0) // 1-bit set
- );
- assign gmii_rxdv = gmii_rxdv_t[0]&gmii_rxdv_t[1];
-
- genvar i;
- generate for (i=0; i<4; i=i+1)
- begin : rxdata_bus
- IDDR #(
- .DDR_CLK_EDGE("SAME_EDGE_PIPELINED"),// "OPPOSITE_EDGE", "SAME_EDGE"
- // or "SAME_EDGE_PIPELINED"
- .INIT_Q1 (1'b0), // Initial value of Q1: 1'b0 or 1'b1
- .INIT_Q2 (1'b0), // Initial value of Q2: 1'b0 or 1'b1
- .SRTYPE ("SYNC") // Set/Reset type: "SYNC" or "ASYNC"
- ) IDDR_inst (
- .Q1 (gmii_rxd[i]), // 1-bit output for positive edge of clock
- .Q2 (gmii_rxd[4+i]), // 1-bit output for negative edge of clock
- .C (rgmii_rxc_bufio), // 1-bit clock input rgmii_rxc_buf
- .CE (1'b1), // 1-bit clock enable input
- .D (rgmii_rxd[i]), // 1-bit DDR data input
- .R (1'b0), // 1-bit reset
- .S (1'b0) // 1-bit set
- );
- end
- endgenerate
-
- endmodule
仿真结果如下:
1.上下沿数据同时有效:
信号名称 | 信号定义 |
rgmii_rxc | PHY芯片输入的时钟 |
rgmii_rx_ctrl | PHY芯片输入的使能信号 |
rgmii_rxd | PHY芯片输入的4bit数据 |
gmii_rxdv | 模块输出的使能信号 |
gmii_rxdv | 模块输出的8bit数据 |
在112ns时上升沿采样到低4位4’b0001,在116ns时下降沿采样到高4位0010,在120ns时将前两次采样的结果组合成8’b00100001输出。
2.上下沿数据非同时有效:
在112ns时上升沿采样到低4位4’b0001,在116ns时使能信号消失,下降沿未采样高4位数据,在120ns时将不会有数据输出。
将输入的8bit信号以及使能信号处理成双沿信号,通过ODDR原语实现。
- module rgmii_txd(
- input gmii_txc ,
- input gmii_txen ,
- input [7:0] gmii_txd ,
- output rgmii_txc ,
- output rgmii_tx_ctrl ,
- output [3:0] rgmii_txd
- );
- assign rgmii_txc = gmii_txc;
-
- // TX CTRL DDR OUTPUT
- ODDR #(
- .DDR_CLK_EDGE ("SAME_EDGE"), // "OPPOSITE_EDGE" or "SAME_EDGE"
- .INIT (1'b0), // Initial value of Q: 1'b0 or 1'b1
- .SRTYPE ("SYNC") // Set/Reset type: "SYNC" or "ASYNC"
- ) ODDR_inst (
- .Q (rgmii_tx_ctrl), // 1-bit DDR output
- .C (gmii_txc), // 1-bit clock input
- .CE (1'b1), // 1-bit clock enable input
- .D1 (gmii_txen), // 1-bit data input (positive edge)
- .D2 (gmii_txen), // 1-bit data input (negative edge)
- .R (1'b0), // 1-bit reset
- .S (1'b0) // 1-bit set
- );
- genvar i;
- generate for (i=0; i<4; i=i+1) //TXD DDR OUTPUT
- begin : txd_ddr
- ODDR #(
- .DDR_CLK_EDGE ("SAME_EDGE"), // "OPPOSITE_EDGE" or "SAME_EDGE"
- .INIT (1'b0), // Initial value of Q: 1'b0 or 1'b1
- .SRTYPE ("SYNC") // Set/Reset type: "SYNC" or "ASYNC"
- ) ODDR_inst (
- .Q (rgmii_txd[i]), // 1-bit DDR output
- .C (gmii_txc), // 1-bit clock input
- .CE (1'b1), // 1-bit clock enable input
- .D1 (gmii_txd[i]), // 1-bit data input (positive edge)
- .D2 (gmii_txd[4+i]), // 1-bit data input (negative edge)
- .R (1'b0), // 1-bit reset
- .S (1'b0) // 1-bit set
- );
- end
- endgenerate
-
- endmodule
-
仿真结果如下:
信号名称 | 信号定义 |
gmii_txc | 模块输入的时钟 |
gmii_tx_en | 模块输入的使能信号 |
gmii_txd | 模块输入的8bit数据 |
rgmii_tx_ctrl | 向PHY芯片输出的使能信号 |
rgmii_txd | 向PHY芯片输出的4bit数据 |
在112ns时上升沿采样到数据8’b00100001,在120ns时上升沿输出低4位4’b0001,在124ns时下降沿输出高4位4’b0010。
1.将开发板与PC通过网线连接,烧录好bit文件。
2.进入控制面板,查看当前网卡是否工作在千兆模式。
3.配置网卡地址为192.168.10.49 ,掩码为255.255.255.0。
也可配置为其他地址,但后续为板卡分配地址时一定要和PC的网卡地址在同一网段。
4.键入win+R,输入cmd打开PC控制台。
5.输入ping 192.168.10.XXX 命令,PC网卡主动发出数据包。
6.PHY芯片正常收到数据后将数据传给FPGA,FPGA可以正常抓取到输入的信号。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。