01.以太网-FPGA
01.以太网-FPGA
以下均来自正点原子,仅个人学习,记录使用。
一、(PHY)MDIO与以太网连接
以太网(Ethernet)是当今现有局域网采用的最通用的通信协议标准, 该标准定义了在局域网中采用的电缆类型和信号处理方法。
**分类: **有标准以太网(10Mbit/s)、 快速以太网(100Mbit/s)和千兆以太网( 1000Mbit/s),万兆以太网(10Gbit/s)。
**端口:**RJ45 接口、 RJ11 接口(电话线接口)、 SC 光纤接口 等
硬件角度:
MAC(Media Access Control)控制器 -- FPGA实现
FPGA 通过 MDIO 接口对 PHY 芯片内部的寄存器进行配置
物理层接口PHY(Physical Layer) -- 板载PHY芯片
PHY 芯片内部包含一系列寄存器,用户通过这些寄存器来配置 PHY 芯片的工作模式以及获取 PHY 芯片的若干状态信息,如连接速率、双工模式、自协商状态等。
1. MDIO接口
1.1 帧格式及时序
MDIO,又称SMI接口(Serial Management Interface,串行管理接口)
信号名 | 作用 |
---|---|
ETH_MDC(数据管理时钟) | 为ETH_MDIO提供时钟,速率不能大于12.5MHz |
ETH_MDIO(数据管理输入输出) | 双向数据引脚,既用于发送数据,也接收数据 |

字段名 | 位宽 | 作用 |
---|---|---|
Preamble | 32 | 由 MAC 端发送 32 位逻辑“1”,用于同步 PHY 芯片 |
ST(Start of Frame) | 2 | 帧开始信号,用 01 表示 |
OP(Operation Code) | 2 | 操作码,读: 10 写: 01 |
PHYAD(PHY Address) | 5 | PHY 地址,用于表示与哪个 PHY 芯片通信,一个 MAC 上可以连接多个 PHY 芯片 |
REGAD(Register Address) | 5 | 寄存器地址,可以表示 32 个寄存器 |
TA(Turnaround) | 2 | 转向, 1.在读命令中, MDIO 在此时由 MAC 驱动改为 PHY 驱动,在第一个 TA位, MDIO 引脚为高阻状态,第二个 TA 位, PHY 将 MDIO 引脚拉低,准备发送数据; 2.在写命令中,不需要 MDIO 方向发生变化, MAC 固定输出 2’b10,随后开始写入数据 |
DATA | 16 | 1.在读命令中, PHY 芯片将对应的 PHYAD 的 REGAD 寄存器的数据写到 DATA 中; 2.在写命令中, PHY 芯片将接收到的 DATA 写入 REGAD 寄存器中。 注意:MSB优先 |
IDLE | -- | 空闲状态,此时 MDIO 为无源驱动,处于高阻状态,但一般用上拉电阻使其上拉至高电平 |
具体读写时序
读例子:以 PHY 地址为 0x01,从寄存器地址 0x00 读出数据

解释:整个读操作过程的 MDC 时钟由 MAC驱动,同时 MAC 驱动 MDIO 引脚输出前导码+帧开始+操作码+PHY 地址+寄存器地址,随后 MDIO 引脚切换至 PHY 驱动。在第一个 TA 位, MDIO 引脚为高阻状态,第二个 TA 位为低电平,表示 PHY 芯片成功响应,并且接下来会输出 16 位寄存器数据;而如果第二个 TA 位处于高电平,则 PHY 芯片响应失败,有可能PHY 地址不正确或者其它时序的错误。
注意:
PHY 在 MDC 时钟的上升沿采集数据,为保证数据的稳定传输, MAC 在 MDC 的下降沿更新 MDIO 引脚的数据。
当 MDIO 引脚切换至 PHY 驱动时, MDIO 数据在 MDC 时钟的下降沿更新,因此 MAC 在 MDC 时钟的上升沿采集数据。
在读操作结束后, MAC 将 MDIO 引脚输出高阻,此时 MDIO 引脚的外部上拉电阻会将 MDIO 引脚拉高,此时 MDIO 接口处于空闲状态。
写例子: 以 PHY 地址为 0x01,向寄存器地址 0x00 写入 0x1340

**解释:**在整个写操作过程中, MDC 时钟和 MDIO 引脚一直由 MAC 端驱动,按照 MDIO 接口写通信协议开始传输数据。
1.2 以太网芯片(YT8531)
1.PHY地址


YT8531 是一个千兆以太网物理层收发器,支持 1000/100/10Mbps 通信速率,该芯片内部的参数可以通过 MDIO 接口进行配置。
由上图可知,开发板上的以太网 PHY 芯片 PHYAD2 接上拉电阻, PHYAD1 和PHYAD0 接下拉电阻,因此 PHY 地址为 5’h04。
2.复位
YT8531 芯片复位后, PHY 内部寄存器的数据会恢复默认的状态,并且重新开始和 MAC 进行自协商。Y
T8531 支持两种复位方式,一种是硬件复位,另外一种是软件复位。
硬件复位时通过 PHY_RST_N 引脚实现对 PHY 芯片的复位,当 ETH_RST_N 引脚持续 10ms 的低电平时,即可实现对 PHY 芯片的复位。
软件复位通过向寄存器地址 0x00 的 Bit[15]写入 1 进行复位,并且在完成复位后,该位会自动清零。
3.寄存器
YT8531 共有 22 位寄存器,控制寄存器、状态寄存器以及PHY 芯片具体状态寄存器....
基本控制寄存器(Basic Control Register, Address 0x00), 用于芯片的复位和其它功能的控制
基本状态寄存器(Basic Status Register, Address 0x01)
PHY 特定状态寄存器(PHY Specific Status Register , Address 0x11)
位宽均为16位
1.3 RJ45 接口-原理图

- LED_1000 和 LED_ACT 是 PHY 输出的 LED 信号,用于控制 RJ45 接口上的 LED 灯
- MDP0/N0~ MDP3/N3 是 PHY 和 RJ45 接口间的差分信号线,用于传输数据
2.MDIO读写测试
2.1 MDIO驱动模块
信号名 | 位 宽 | 方向 | 端口说明 | 作用 |
---|---|---|---|---|
clk | 1 | 输入 | 系统时钟,50MHz | |
rst_n | 1 | 输入 | 系统复位按键, 低电平有效 | |
op_exec | 1 | 输入 | 触发开始信号 | 默认低电平,当触发信号时, op_exec 拉高,表示 PHY 芯片被触发 |
op_rh_wl | 1 | 输入 | 低电平写,高电平读 | 当 op_exec 被触发后,会根据读写信号 op_rh_wl 的高低电平判断读与写, 低电平进行写操作,高电平进行读操作 |
op_addr | 5 | 输入 | 寄存器地址 | 最大位宽为 5 |
op_wr_data | 16 | 输入 | 写入寄存器的数据 | |
op_done | 1 | 输出 | 读写完成 | 当写入完成或者读出完成后, op_done 读写完成会拉高一个时钟周期,表示读或者写操作完成 |
op_rd_data | 16 | 输出 | 读出的数据 | |
op_rd_ack | 1 | 输出 | 读应答信号 0:应答 1:未应答 | |
dri_clk | 1 | 输出 | 驱动时钟 | |
eth_mdc | 1 | 输出 | PHY管理接口的时钟信号 | eth_mdc 是在dri_clk 的基础上进行分频,一般频率不能超过 12.5Mhz |
eth_mdio | 1 | 输入/输出 | PHY管理接口的双向数据信号 |
状态转移图:

2.2 MDIO控制模块
信号名 | 位宽 | 方向 | 端口说明 | 作用 |
---|---|---|---|---|
clk | 1 | 输入 | 系统时钟,50MHz | |
rst_n | 1 | 输入 | 系统复位按键, 低电平有效 | |
soft_rst_trig | 1 | 输入 | 软复位触发开始信号 | 当 soft_rst_trig 被按下,会进行软件复位,在软复位完成后判断 MDIO 链路是否正常并且进行自协商 |
op_done | 1 | 输入 | 读写完成 | |
op_rd_data | 16 | 输入 | 读出的数据 | |
op_rd_alk | 1 | 输入 | 读应答信号 | 0: 应答 1:未应答 |
op_exec | 1 | 输出 | 触发开始信号 | 当 soft_rst_trig 被按下或者定时信号拉高, op_exec 则会被触发 |
op_rd_wl | 1 | 输出 | 读写控制信号 | 低电平写,高电平读 |
op_addr | 5 | 输出 | 寄存器地址 | |
op_wr_data | 16 | 输出 | 写入寄存器的数据 | |
led | 2 | 输出 | LED灯指示以太网连接状态 | led 为 LED 灯指示以太网连接状态, LED 会根据以太网连接的状态显示对应的通讯速率 |
主体功能:根据软复位信号对 MDIO 接口进行软复位,并定时读取以太网的连接状态 ,代码实现总结如下:

其中,定时用于一定间隔后获取以太网的速度信息
2.3 顶层模块

使用系统复位信号进行硬件复位
//硬件复位
assign eth_rst_n = sys_rst_n;
2.5 下载验证
引脚约束
信号名,方向,管脚,端口说明,电平标准
//xdc create_clock -period 20.000 -name sys_clk -waveform {0.000 10.000} [get_ports sys_clk] set_property -dict {PACKAGE_PIN U18 IOSTANDARD LVCMOS33} [get_ports sys_clk] set_property -dict {PACKAGE_PIN N16 IOSTANDARD LVCMOS33} [get_ports sys_rst_n] set_property -dict {PACKAGE_PIN F20 IOSTANDARD LVCMOS33} [get_ports eth_mdc] set_property -dict {PACKAGE_PIN F19 IOSTANDARD LVCMOS33} [get_ports eth_mdio] set_property -dict {PACKAGE_PIN G15 IOSTANDARD LVCMOS33} [get_ports eth_rst_n] set_property -dict {PACKAGE_PIN F16 IOSTANDARD LVCMOS33} [get_ports touch_key] set_property -dict {PACKAGE_PIN H15 IOSTANDARD LVCMOS33} [get_ports {led[0]}] set_property -dict {PACKAGE_PIN L15 IOSTANDARD LVCMOS33} [get_ports {led[1]}]
3.网速调整

对于YT8351以太网PHY芯片,基本寄存器地址为0x00,基本状态寄存器为0x01,特殊状态寄存器为0x11
网速控制只有在非自协商模式下有效

16‘9140 = 1001 0001 0100 0000
// 启用了 复位(15),自协商(12), Duplex_Mode(双工模式-8) 速度为 1000 Mb/s (6:13) 10
Q1:当使用100M的网速时,需要使用双工模式吗?
2.对以太网 10/100/1000Mb 半/全双工自动协商进行配置和验证
16‘9140 = 1011 0001 0000 0000
// 启用了 复位(15),自协商(12), Duplex_Mode(双工模式-8) 速度为 1000 Mb/s (6:13) 01
二、ARP
1.概念
1.1 ARP与以太网帧格式
ARP(Address Resolution Protocol),即地址解析协议,是根据 IP 地址(逻辑地址)获取 MAC 地址的一种 TCP/IP 协议。
MAC 地址在网络中表示网卡的 ID,每个网卡都需要并有且仅有一个 MAC 地址。在获取到目的 MAC 地址之后,将目的 MAC 地址更新至 ARP 缓存表中,称为 ARP 映射,下次通信时,可以直接从 ARP 缓存表中获取,而不用重新通过 ARP 获取 MAC 地址。但一般 ARP 缓存表会有过期时间,过期后需要重新通过 ARP协议进行获取。
以太网MAC --- IEEE 802.3

NOTE:以太网相邻两帧之间的时间间隔, 即帧间隙(IFG, Interpacket Gap) 。
帧间隙的时间就是网络设备和组件在接收一帧之后,需要短暂的时间来恢复并为接收下一帧做准备的时间, IFG 的最小值是 96 bit time,即在媒介中发送 96 位原始数据所需要的时间,在不同媒介中 IFG 的最小值是不一样的。 不管 10M/100M/1000M 的以太网,两帧之间最少要有 96bit time,
IFG 的最少间隔时间计算方法如下:
10Mbit/s 最小时间为:
100Mbit/s 最小时间为:
1000Mbit/s 最小时间为:
TCP/IP 协议不仅可以运行在以太网上,也可以运行在 FDDI(光纤分布式数据接口)和 WLAN(无线局域网)上。反过来, 以太网的高层协议不仅可以是 TCP/IP 协议,也可以是 IPX 协议(互联网分组交换协议)等
字段名 | 长度(字节) | 作用 |
---|---|---|
前导码(Preamble) | 7 | 0,1交替同步码, 8'h55_55_55_55_55_55_55 |
帧起始界定符 | 1 | 固定值 8'd5 |
目的MAC地址 | 6 | 接收端物理MAC地址,MAC 地址从应用上可分为单播地址、组播地址和广播地址。 单播地址:第一个字节的最低位为 0,比如 00-00-00-11-11-11,一般用于标志唯一的设备 组播地址:第一个字节的最低位为 1,比如 01-00-00-11-11-11,一般用于标志同属一组的多个设备 广播地址:所有 48bit 全为 1,即 FF-FF-FF-FF-FF-FF,它用于标志同一网段中的所有设备 单播地址示例:00:1A:2B:3C:4D:5E(最低有效位为0) 组播地址示例:01:1A:2B:3C:4D:5E(最低有效位为1) |
源MAC地址 | 6 | 发送端物理 MAC 地址 |
长度/类型 | 2 | 当这两个字节的值小于 1536(十六进制为 0x0600)时,代表该以太网中数据段的长度; 如果这两个字节的值大于 1536,则表示该以太网中的数据属于哪个上层协议,例如 0x0800 代表 IP 协议(网际协议) 、 0x0806 代表 ARP 协议(地址解析协议)等。 |
数据 | 46~1500 | 以太网中的数据段长度最小 46 个字节, 最大 1500 个字节 (称 MTU,最大传输单元) |
帧检验序列 | 4 | 通用的 CRC 标准有 CRC-8、 CRC-16、 CRC-32、 CRC-CCIT,其中在网络通信系统中应用最广泛的是 CRC-32 标准 |
1.2 ARP协议
ARP 协议分为 ARP 请求和 ARP 应答:
源主机发起查询目的 MAC 地址的报文称为 ARP 请求
目的主机响应源主机并发送包含本地 MAC 地址的报文称为 ARP 应答。

字段名 | 长度(字节) | 作用 |
---|---|---|
硬件类型 | 2 | 1 表示以太网地址 |
协议类型 | 2 | ARP 协议的上层协议为 IP 协议,因此该协议类型为 IP 协议,其值为 0x0800 |
硬件地址长度 | 1 | 对于以太网上 IP 地址的 ARP 请求或者应答来说,该值为 6 |
协议地址长度 | 1 | 对于以太网上 IP 地址的 ARP 请求或者应答来说,该值为 4 |
OP(Opcode) | 2 | 操作码,用于表示该数据包为 ARP 请求或者 ARP 应答。 1 表示 ARP 请求, 2 表示 ARP应答 |
源 MAC 地址 | 6 | 发送端的硬件地址 |
源 IP 地址 | 4 | 发送端的协议(IP)地址 |
目的 MAC 地址 | 6 | 接收端的硬件地址,在 ARP 请求时由于不知道接收端 MAC 地址,因此该字段为广播地址,即 48’hff_ff_ff_ff_ff_ff |
目的 IP 地址 | 4 | 接收端的协议(IP)地址 |

28 字节的 ARP 数据位于以太网帧格式的数据段。由于以太网数据段最少为 46 个字节,而 ARP 数据包总长度为 28 个字节,因此在 ARP 数据段后面需要填充 18 个字节的数据,以满足以太网传输格式的要求。这个填充的过程称为 Padding(填充),填充的数据可以为任意值,但一般为 0。
2.以太网MAC和PHY间的接口
以太网 MAC 和 PHY 之间常用的接口有MII、 RMII、 GMII、 RGMII 等
Mbps(Mb/s)的含义是兆比特每秒,指每秒传输的位数量(小写b代表bit);
MB/s的含义是兆字节每秒,指每秒传输的字节数量(大写B代表Byte);
1Mbps=125000字节/秒=122.070KB/秒=0.119MB/秒。
IEC标准规定如下:
1Byte=8bit;
1 KB = 1,024 Bytes;
1 MB = 1,024 KB= 1,048,576 Bytes;
1 GB = 1,024 MB= 1,048,576 KB= 1,073,741,824 Bytes;
1 TB = 1,024 GB= 1,048,576 MB= 1,073,741,824 KB= 1,099,511,627,776 Bytes;
接口名 | 说明 | 位宽 | 支持速率(Mbps) | 时钟频率 |
---|---|---|---|---|
MII(Medium Independent Interface) | 媒体独立接口 | 4 | 10/100 | 25 MHz(100 Mpbs 传输下) |
RMII(Reduced MII) | 是 MII 的简化版 | 2 | 50 MHz(100 Mpbs 传输下) | |
GMII(Gigabit MII) | 向下兼容 MII 接口 | 8 | 10/100/1000 | 125 MHz(1000 Mpbs 传输下) |
RGMII(Reduced GMII) | 是 GMII 的简化版 | 4 | 10/100/1000 | 在 1000Mbps 传输速率下,时钟频率为 125Mhz,在时钟的上下沿同时采样数据。 在 100Mbps 和 10Mbps 通信速率下,为单个时钟沿采样。 |
在 千 兆 以太 网 中 ,常 用 的接 口 为 RGMII 和 GMII 接 口。 RGMII 接口的 优 势 是同 时 适 用 于10M/100M/1000Mbps 通信速率,同时占用的引脚数较少。
但 RGMII 接口也有其缺点,就是在 PCB 布线时需要尽可能对时钟、控制和数据线进行等长处理,且时序约束相对也更为严格。
3. RGMII 接口

信号名 | 位宽 | 针对MAC侧 | 端口说明 | 作用 |
---|---|---|---|---|
ETH_RXC | 1 | 输入 | 接收数据参考时钟 | 1000Mbps 速率下,时钟频率为 125MHz,时钟为上下沿同时采样; 100Mbps 速率下,时钟频率为 25MHz; 10Mbps 速率下,时钟频率为 2.5MHz, ETH_RXC 由 PHY 侧提供 |
ETH_RXCTL | 1 | 输入 | 接收数据控制信号 | |
ETH_RXD | 4 | 输入 | 四位并行的接收数据线 | |
ETH_TXC | 1 | 输出 | 发送参考时钟 | 1000Mbps 速率下,时钟频率为 125MHz,时钟为上下沿同时采样: 100Mbps速率下,时钟频率为 25MHz; 10Mbps 速率下,时钟频率为 2.5MHz, ETH_TXC 由 MAC 侧提供 |
ETH_TXCTL(ETH_TXEN) | 1 | 输出 | 发送数据控制信号 | |
ETH_TXD | 4 | 输出 | 四位并行的发送数据线 | |
ETH_RESET_N | 1 | 输出 | PHY 芯片硬件复位信号 | 低电平有效 |
ETH_MDC | 1 | 输出 | 数据管理时钟(Management Data Clock) | 该引脚对 ETH_MDIO 信号提供了一个同步的时钟 |
ETH_MDIO | 1 | 输出 | 数据输入/输出管理(Management Data Input/Output) | 该引脚提供了一个双向信号用于传递管理信息 |
- 由于 PHY 芯片的内部寄存器在默认配置下(自动协商模式)也可以正常工作,因此本次实验没有对 MDIO 接口进行读写操作,只用到了以太网的 RGMII 接口信号和复位信号
- ETH_TXC 和 ETH_RXC 的时钟频率为 125Mhz,采用上下沿 DDR(Double Data Rate)的方式在一个时钟周期内传输 8 位数据信号,即上升沿发送/接收低 4位数据,下降沿发送/接收高 4 位数据
- ETH_TXCTL 和 ETH_RXCTL 控制信号
- 采用 DDR 的方式在一个时钟周期内传输两位控制信号,即上升沿发送/接收数据使能(TX_EN/RX_ DV)信号,下降沿发送/接收使能信号与错误信号的异或值(TX_ERR xor TX_EN、 RX_ERR xor RX_DV)
- 当 RX_DV 为高电平(表示数据有效), RX_ERR 为低电平(表示数据无错误),则异或的结果值为高电平,因此只有当 ETH_RXCTL和 ETH_TXCTL 信号的上下沿同时为高电平时,发送和接收的数据有效且正确。
3.1 时序


3.2 Xilinx原语
原语是 Xilinx 器件底层硬件中的功能模块,它使用专用的资源来实现一系列的功能。相比于 IP 核,原语的调用方法更简单,但是一般只用于实现一些简单的功能
**BUFG : **全局缓冲, BUFG 的输出到达 FPGA 内部的 IOB、 CLB、块 RAM 的时钟延迟和抖动最小
BUFG BUFG_inst (
.O(O), // 1-bit output: Clock output
.I(I) // 1-bit input: Clock input
);
**BUFR : **BUFR 是 regional 时钟网络,它的驱动范围只能局限在一个 clock region 的逻辑。 BUFR 相比 BUFG 的最大优势是偏斜和功耗都比较小。
BUFIO: BUFIO 是 IO 时钟网络,其独立于全局时钟资源,适合采集源同步数据。它只能驱动 IO Block里面的逻辑,不能驱动 CLB 里面的 LUT, REG 等逻辑。 BUFIO 原语模板如下:
BUFIO BUFIO_inst (
.O(O), // 1-bit output: Clock output (connect to I/O clock loads)
.I(I) // 1-bit input: Clock input (connect to an IBUF or BUFMR).
);
BUFIO 在采集源同步 IO 数据时,提供非常小的延时,因此非常适合采集比如 RGMII 接收侧的数据,但是由于其不能驱动 FPGA 的内部逻辑,因此需要 BUFIO 和 BUFG 配合使用,以达到最佳性能。
ETH_RXC的时钟经过 BUFIO,用来采集端口数据; ETH_RXC 经过 BUFG,用来作为除端口采集外的其他模块的操作时钟。
单边沿取样(Single-Duty Ratio , SDR)
**IDDR : **在 7 系列设备的 ILOGIC block 中有专属的 registers 来实现 input double-data-rate(IDDR) registers,将输入的上下边沿 DDR 信号,转换成两位单边沿 SDR 信号

C:输入的同步时钟;
D:输入的 1 位 DDR 数据;
Q1 和 Q2:分别是“C”时钟上升沿和下降沿同步输出的 SDR 数据。
CE:时钟使能信号;
S/R:置位/复位信号,这两个信号不能同时拉高。
IDDR #(
.DDR_CLK_EDGE("OPPOSITE_EDGE"), // "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(Q1), // 1-bit output for positive edge of clock
.Q2(Q2), // 1-bit output for negative edge of clock
.C(C), // 1-bit clock input
.CE(CE), // 1-bit clock enable input
.D(D), // 1-bit DDR data input
.R(R), // 1-bit reset
.S(S) // 1-bit set
);

SAME_EDGE_PIPELINED 模式下,在时钟的上升沿输出 Q1 和 Q2, Q1 和 Q2 虽然在同一个 cycle 输出,但整体延时了一个时钟周期。在使用 IDDR 时,一般采用此种模式 。
**ODDR : **通过 ODDR 把两路单端的数据合并到一路上输出,上下沿同时输出数据,上升沿输出 a 路,下降沿输出 b 路;如果两路输入信号一路固定为 1,另外一路固定为 0,那么输出的信号实际上是时钟信号。

C:输入的同步时钟;
Q:输出的 1 位 DDR 数据;
D1 和 D2:分别是“C”时钟上升沿和下降沿同步输入的 SDR 数据。
CE:时钟使能信号;
S/R:置位/复位信号,这两个信号不能同时拉高。
ODDR #(
.DDR_CLK_EDGE("OPPOSITE_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(Q), // 1-bit DDR output
.C(C), // 1-bit clock input
.CE(CE), // 1-bit clock enable input
.D1(D1), // 1-bit data input (positive edge)
.D2(D2), // 1-bit data input (negative edge)
.R(R), // 1-bit reset
.S(S) // 1-bit set
);

此种模式下,数据可以在相同的时钟边沿输出到 Q,一般采用此种模式。
**IDELAYE2 :**IO 延时原语,用于在信号通过引脚进入芯片内部之前,进行延时调节,一般高速端口信号由于走线延时等原因,需要通过 IDELAYE2 原语对数据做微调。
ug471_7Series_SelectIO.pdf


3. ARP测试
使用领航者 ZYNQ 开发板上的 PL 端以太网接口,和上位机实现 ARP 请求和应答的功能。当上位机发送 ARP 请求时,开发板返回 ARP 应答数据。当按下开发板的触摸按键时,开发板发送 ARP请求,此时上位机返回应答数据。
3.1 整体模块

系统时钟经过 PLL 时钟模块后,输出 200Mhz 的时钟,用于 IDELAYCTRL 原语的参考时钟;
GMII TO RGMII 模块负责双沿( DDR)数据和单沿(SDR)数据之间的转换;
ARP 顶层模块实现了以太网 ARP 数据包的接收、发送以及 CRC 校验的功能;
ARP 控制模块根据输入的按键触摸信号和接收到的 ARP 请求信号,控制 ARP 顶层模块发送 ARP 请求或者 ARP 应答。
3.2 gmii_to_rgmii
通过调用 BUFG、 BUFIO、 IDDR、 IDELAYCTRL 和 IDELAY2 原语,实现了 RGMII接口输入的 DDR 数据(双边沿)到 SDR 数据(单边沿)的转换
GMII(Gigabit MII) | 向下兼容 MII 接口 | 8 | 10/100/1000 | 125 MHz(1000 Mpbs 传输下) |
---|---|---|---|---|
RGMII(Reduced GMII) | 是 GMII 的简化版 | 4 | 10/100/1000 | 在 1000Mbps 传输速率下,时钟频率为 125Mhz,在时钟的上下沿同时采样数据。 在 100Mbps 和 10Mbps 通信速率下,为单个时钟沿采样。 |

rgmii_rx模块:

时钟专用引脚输入的 rgmii_rxc 时钟 经过 BUFG 后,得到 rgmii_rxc_bufg(gmii_rx_clk),该时钟为全局缓冲时钟,其到达 FPGA 内部的 IOB、 CLB、块 RAM 的时钟延迟和抖动非常小,为其他模块提供操作时钟;
rgmii_rxc 时钟也经过 BUFIO,专门用于采集 IO 端口的数据;
rgmii_rx_ctl 控制信号和 4 位 rgmii_rxd 数据先经过 IDELAY2 进行延时,再经过 IDDR 将双沿 1 位数据转换成单沿两位数据。
rgmii_tx模块 :

- gmii_tx_en 数据使能信号和 8 位 gmii_txd 数据经过 ODDR 将单沿 2 位数据转换成双沿 1 位数据
3.3 arp模块

仅对发送arp请求进行了校验
关于发送接收模块
ARP 的数据包格式包括前导码+SFD、以太网帧头、 ARP 数据(包括填充部分数据)和 CRC 校验。在接收以太网数据的过程中,这些不同部分的数据可以刚好对应状态机的不同状态位,因此我们可以通过状态机来解析以太网的数据 。

关于CRC冗余校验
CRC32 校验在 FPGA 实现的原理是线性反馈移位寄存器,其思想是各个寄存器储存着上一次 CRC32 运算的结果,寄存器的输出即为 CRC32 的值
CRC 校验的源代码可直接通过网页生成工具直接下载,网址: http://www.easics.com/webtools/crctool
发送模块的 CRC 校验是由 crc32_d8 模块完成的, 发送模块将输入的crc 的计算结果每 4 位高低位互换,按位取反发送出去
st_crc : begin //发送CRC校验值
gmii_tx_en <= 1'b1;
cnt <= cnt + 1'b1;
if(cnt == 6'd0)
gmii_txd <= {~crc_next[0], ~crc_next[1], ~crc_next[2],~crc_next[3],
~crc_next[4], ~crc_next[5], ~crc_next[6],~crc_next[7]};
else if(cnt == 6'd1)
gmii_txd <= {~crc_data[16], ~crc_data[17], ~crc_data[18],
~crc_data[19], ~crc_data[20], ~crc_data[21],
~crc_data[22],~crc_data[23]};
else if(cnt == 6'd2) begin
gmii_txd <= {~crc_data[8], ~crc_data[9], ~crc_data[10],
~crc_data[11],~crc_data[12], ~crc_data[13],
~crc_data[14],~crc_data[15]};
end
else if(cnt == 6'd3) begin
gmii_txd <= {~crc_data[0], ~crc_data[1], ~crc_data[2],~crc_data[3],
~crc_data[4], ~crc_data[5], ~crc_data[6],~crc_data[7]};
tx_done_t <= 1'b1;
skip_en <= 1'b1;
cnt <= 1'b0;
end
else;
end
三、ICMP
ICMP 协议是一种面向无连接的协议,用于传输出错报告控制信息, 它是一个非常重要的协议,它对于网络安全具有极其重要的意义。
它属于网络层协议,主要用于在主机与路由器之间传递控制信息,包括报告错误、交换受限控制和状态信息等。当遇到 IP 数据无法访问目标、 IP 路由器无法按当前的传输速率转发数据包等情况时,会自动发送 ICMP 消息。
ping 和 tracert 是两个常用网络管理命令, ping 用来测试网络可达性, tracert 用来显示到达目的主机的路径。 ping 和 tracert 都利用 ICMP 协议来实现网络功能,它们是把网络协议应用到日常网络管理的典型实例。
ICMP是一个“错误侦测与回报机制” ,其目的就是让我们能够检测网路的连线状况, 也能确保连线的准确性。
当路由器在处理一个数据包的过程中发生了意外,可以通过 ICMP 向数据包的源端报告有关事件。
其功能主要有:侦测远端主机是否存在,建立及维护路由资料,重导资料传送路径( ICMP 重定向),资料流量控制。 ICMP 在沟通之中,主要是透过不同的类别(Type)与代码(Code)让机器来识别不同的连线状况。

1.概念
1.1 IP协议
IP 协议是 TCP/IP 协议簇中的核心协议,也是 TCP/IP 协议的载体, IP 协议规定了数据传输时的基本单元和格式

字段名 | 作用 |
---|---|
版本 | 4 位 IP 版本号(Version),这个值设置为二进制的 0100 时表示 IPv4,设置为 0110 时表示 IPv6,目前使用比较多的 IP 协议版本号是 4 |
首部长度 | 表示 IP 首部一共有多少个 32 位(4 个字节) 。在没有可选字段时, IP 首部长度为 20 个字节, 因此首部长度的值为 5 |
服务类型 | 8 位服务类型(TOS, Type of service),该字段被划分成两个子字段: 3 位优先级字段(现在已经基本忽略掉了)和 4 位 TOS 字段,最后一位固定为 0。服务类型为 0 时表示一般服务 |
总长度 | 16 位 IP 数据报总长度(Total Length),包括 IP 首部和 IP 数据部分,以字节为单位。我们利用 IP 首部长度和 IP 数据报总长度,就可以知道 IP 数据报中数据内容的起始位置和长度。由于该字段长16bit,所以 IP 数据报最长可达 65535 字节 |
标识 | 16 位标识(Identification)字段,用来标识主机发送的每一份数据报。通常每发送一份报文它的值就会加 1 |
标志 | 3 位标志(Flags)字段,第 1 位为保留位;第 2 位表示禁止分片(1 表示不分片 0:允许分片);第 3 位标识更多分片(除了数据报的最后一个分片外,其它分片都为 1) |
片偏移 | 13 位片偏移(Fragment Offset),在接收方进行数据报重组时用来标识分片的顺序 |
生存时间 | 8 位生存时间字段, TTL(Time To Live)域防止丢失的数据包在无休止的传播,一般被设置为 64 或者 128 |
协议 | 8 位协议(Protocol)类型,表示此数据报所携带上层数据使用的协议类型, ICMP 为 1, TCP 为6, UDP 为 17 |
首部校验和 | 16 位首部校验和(Header Checksum),该字段只校验数据报的首部,不包含数据部分;校验 IP 数据报头部是否被破坏、篡改和丢失等 |
源 IP 地址 | 32 位源 IP 地址(Source Address),即发送端的 IP 地址, 如 192.168.1.123 |
目的 IP 地址 | 32 位目的 IP 地址(Destination Address),即接收端的 IP 地址, 如 192.168.1.102 |
可选字段 | 数据报中的一个可变长度的可选信息,选项字段以 32bit 为界,不足时插入值为 0 的填充字节,保证 IP 首部始终是 32bit 的整数倍 |
IP首部校验和的计算方法 :
详见 > https://www.cnblogs.com/colourfire/p/15149347.html
使用 IP 协议发送一个 IP 数据报总长度为 60 个字节(有效数据为 40 个字节)的数据包,发送端 IP 地址为 192.168.1.10,接收端 IP 地址为 192.168.1.102,则 IP 首部数据如下:

1.2 ICMP协议
ICMP 报文包含在 IP 数据报中,属于 IP 的一个用户, IP 头部就在 ICMP 报文的前面,所以一个 ICMP报文包括 IP 头部、 ICMP 头部和 ICMP 报文, IP 头部的 Protocol 值为 1 就说明这是一个 ICMP 报文


字段名 | 说明 | 常用值 |
---|---|---|
类型(type) | 用于标识错误类型的差错报文或者查询类型的报告报文 | 类型 0,代码 0:表示回显应答(ping 应答); 类型 8,代码 0:表示回显请求(ping 请求); 类型 11,代码 0:超时; |
代码(code) | 根据 ICMP 差错报文的类型,进一步分析错误的原因,代码值不同对应的错误也不同, | 类型 3,代码 0:网络不可达; 类型 3,代码 1:主机不可达; 类型 5,代码 0:重 定向 .....(还有很多) |
校验和(checksum) | 校验的方法同上述 IP 首部校验和的方法一致 | |
标识符 (Identifier) | 对于每一个发送的数据报进行标识 | |
序列号(Sequence number) | 对于发送的每一个数据报文进行编号,比如:发送的第一个数据报序列号为 1,第二个序列号为 2 | |
数据(Data) | 具体的ICMP 数据 |


2. 硬件实现
2.1 总体模块

GMII 接收侧的引脚同时连接至 ARP 顶层模块和 ICMP顶层模块,这个两个模块会分别根据 ARP 协议和 ICMP 协议解析数据。
而 GMII 发送侧引脚只能和 ARP 顶层模块和 ICMP 顶层模块的其中一个连接,因此以太网控制模块会根据当前接收到的协议类型,选择切换GMII 发送侧引脚和 ARP 顶层模块或者 ICMP 顶层模块连接。
除此之外,以太网控制模块根据输入的 ARP接收的类型,控制 ARP 顶层模块返回 ARP 应答信号。以太网单次会接收到大量数据, 因此本次实验需要一个 FIFO 模块用来缓存数据,由于本次实验所使用的 GMII 接收时钟和 GMII 发送时钟实际上为同一个时钟,因此这里使用的是同步 FIFO。
2.2 ICMP模块
对于接收模块:
解析顺序: 前导码+帧起始界定符→以太网帧头→IP 首部→ICMP 首部→ICMP 数据(有效数据) →接收结束
- 三段式状态机完成数据读取外,注意在在 中间状态如前导码错误、 MAC 地址错误、协议类型错误、 ICMP 协议错误以及 IP 地址错误时,需要等待一个单包数据发送完毕结束,再开启新的接收。
对于发送模块:
发送顺序:前导码+帧起始界定符→以太网帧头→IP 首部→ICMP 首部→ICMP 数据(有效数据) →CRC 校验
2.3 控制模块
实现以太网协议的的一个切换,我们可以定义一个寄存器来进行 ARP 以及 ICMP协议的一个切换
四、UDP
概述


内容 | 说明 |
---|---|
源端口号 | 16 位发送端端口号,用于区分不同服务的端口,端口号的范围从 0 到 65535 |
目的端口号 | 16 位接收端端口号 |
UDP 长度 | 16 位 UDP 长度,包含 UDP 首部长度+数据长度, 单位是字节(byte) |
UDP 校验和 | 16 位 UDP 校验和 |
TCP 协议设计之初是根据软件灵活性设计的, 如果使用硬件逻辑实现,工程量会十分巨大,而且功能和性能无法得到保证, 因此, TCP 协议设计并不适合使用硬件逻辑实现。 UDP 协议是一种不可靠传输,发送方只负责数据发送出去,而不管接收方是否正确的接收。 在很多场合,是可以接受这种潜在的不可靠性的,例如视频实时传输显示等。
整体模块

通过以太网控制模块来控制 ICMP ,UDP,arp 协议的切换