FPGA实现以太网UDP:从协议解析到详细设计(上)

230 阅读9分钟

引言:以太网在嵌入式系统中的重要性

以太网作为现代局域网的核心技术,凭借高可靠性、易扩展性和标准化优势,已成为工业控制、智能设备等领域的关键通信方案。本文将基于FPGA平台,深入解析以太网协议栈,并实现UDP数据回环的硬件设计。

一、网络协议栈核心模型

层级核心功能关键协议/组件
应用层提供用户接口及网络服务HTTP/DNS/DHCP
传输层端到端数据传输与流量控制(无连接、低延迟)UDP
网络层路由寻址与跨网络传输IP/ICMP
数据链路层帧封装、介质访问控制MAC/ARP
物理层比特流传输与电气特性定义PHY芯片/RJ45接口

注:相较于OSI七层模型,UDP合并了会话层、表示层与应用层

二、以太网协议分层定位

以太网协议分层定位.png

三、核心协议解析与实现要点

1. 物理层(PHY)关键设计

  • 接口标准选择

    • MII:16线制,独立收发时钟(25MHz@100Mbps) image.png

    • RMII:7线制,共用50MHz参考时钟(成本更低) image.png

    • 信号说明

    信号名称功能描述MII接口特性RMII接口特性
    TX_CLK数据发送时钟线10Mbit/s时2.5MHz,100Mbit/s时25MHz,由PHY提供无该线,时钟由外部50MHz参考时钟提供
    RX_CLK数据接收时钟线10Mbit/s时2.5MHz,100Mbit/s时25MHz,由PHY提供无该线,时钟由外部50MHz参考时钟提供
    TX_EN数据发送使能信号,数据发送期间保持有效有效时TXD数据有效有效时TXD数据有效
    TXD[3:0] / TXD[1:0]数据发送数据线4位数据线2位数据线
    CRS载波侦听信号,由PHY驱动,介质非空闲时有效有效(半双工模式)无独立CRS线,CRS与RX_DV合并为CRS_DV
    COL冲突检测信号,由PHY驱动,检测冲突时有效有效(半双工模式)无该线
    RXD[3:0] / RXD[1:0]数据接收数据线4位数据线,由PHY驱动2位数据线,由PHY驱动
    RX_DV接收数据有效信号,PHY驱动有效时RXD数据有效与CRS合并为CRS_DV信号
    RX_ER接收错误信号,由PHY驱动有效时报告接收错误有效时报告接收错误
    REF_CLK参考时钟一般由PHY提供25MHz时钟由外部提供50MHz参考时钟,供MAC和PHY使用

    备注:

    • MII接口数据线宽度为4位,RMII接口为2位,导致两者在时钟设计和数据传输方式上存在显著差异。
    • MII接口依赖PHY提供TX_CLK和RX_CLK时钟信号,而RMII接口取消了TX_CLK和RX_CLK,改为统一使用外部50MHz参考时钟。
    • RMII接口将CRS和RX_DV信号合并为CRS_DV,简化了信号线数量,适合资源受限的应用场景。
  • 编码方案

2. MAC层数据帧结构

| 前导码(7B) | SFD(1B) | 目的MAC(6B) | 源MAC(6B) | 类型(2B) | 数据(46-1500B) | 填充域 | FCS(4B) |
字段名称长度(Byte)功能描述详细说明
前导字段7时钟同步连续7个字节0x55的方波信号,用于收发节点时钟同步,MAC接收后自动过滤
帧起始定界符(SFD)1标识数据段开始1字节0xD5,用于区分前导字段和数据段,MAC接收后自动过滤
目标地址(DA)6目标MAC地址48位物理地址,标识数据包接收端,支持广播和多播
源地址(SA)6源MAC地址48位物理地址,标识数据包发送端,通常由网卡出厂设置或软件配置
QTag前缀4 (可选)VLAN标识及优先级IEEE 802.3扩展字段,位于SA和数据包类型之间,前2字节固定0x8100,后2字节包含用户优先级、CFI和VLAN ID
数据包类型2类型或长度字段大于0x0600表示协议类型(如IP、ARP、SNMP),否则表示数据段长度
数据段46~1500上层数据MAC包核心内容,长度可变,承载上层协议数据
填充域可变保证最小帧长当数据段长度<46字节时自动填充无效数据,确保整个帧长度≥64字节
校验和域(CRC)4差错检测保存CRC校验码,用于检测数据包传输错误
  • 核心规则

    1. 最小帧长64字节(含FCS)
    2. 数据不足46字节时自动填充
    3. FCS校验采用CRC32算法

3. IPv4协议关键字段

|版本+首部长度(1B) | 服务类型(1B) | 总长度(2B) | 标识(2B) | 标记+分段偏移(2B) | 生存时间(1B) | 协议(1B) | 首部校验和(2B) | 源地址(4B) | 目的地址(4B) | 选项(0~40B,可选) | 数据(可变)|
字段名称长度(bit)长度(Byte)功能描述详细说明
版本40.5指明IP协议版本IPv4版本号,固定为4,指示数据报格式
首部长度40.5IP首部长度以32位字(4字节)为单位,最小值5(20字节),最大15(60字节)
服务类型81服务质量指示包含优先级(3位)、服务类型(4位)、1位未定义
总长度162整个IP数据报长度包括首部和数据,最大65535字节
标识162数据报标识符用于分段时标识数据报,所有分段共享此值
标记30.375分段控制标志MF(更多分段)、DF(不分段)、保留位(0)
分段偏移131.625分段相对偏移指示该分段在原始数据报中的位置
生存时间(TTL)81限制数据报寿命每经过一个路由器减1,减到0时丢弃
协议81上层协议标识指示数据报承载的上层协议类型,如TCP、UDP等
首部校验和162IP首部完整性校验对IP首部进行校验,确保传输过程中无误
源地址324源主机IP地址数据报发送方IP地址,传输过程中不变
目的地址324目的主机IP地址数据报接收方IP地址,传输过程中不变

4. IP首部校验和(Checksum)计算方法

  • 计算步骤

    1. 校验和字段强制置0,即将IP首部中的校验和字段(2字节)清零。
    2. 将IP首部(通常20字节)按2字节(16位)为单位拆分,逐个相加。
    3. 若相加结果超过16位(大于0xFFFF),将高16位与低16位相加,直到结果为16位。
    4. 对最终结果取反(按位取反),得到校验和字段的值。
  • 示例

    • 抓取的IP首部20字节数据(十六进制):
    45 00 00 30 80 4c 40 00 80 06 b5 2e d3 43 11 7b cb 51 15 3d
    
    • 将校验和字段 b5 2e 置为 00 00,变为:
    45 00 00 30 80 4c 40 00 80 06 00 00 d3 43 11 7b cb 51 15 3d
    
    • 按2字节拆分并求和(十六进制):
    4500 + 0030 + 804c + 4000 + 8006 + 0000 + d343 + 117b + cb51 + 153d = 34ace
    
    • 处理进位(高16位3)加到低16位:
    0003 + 4ace = 4ad1
    
    • 取反得到校验和:
    ~4ad1 = b52e
    

5. 校验和验证方法

  • 对完整IP首部(含校验和字段)按2字节反码求和。

  • 结果取反后应为0,表示校验通过。

  • 示例验证

    4500 + 0030 + 804c + 4000 + 8006 + b52e + d343 + 117b + cb51 + 153d = 3fffc
    
    • 进位加法:
    0003 + fffc = ffff
    
    • 取反:
    ~ffff = 0000
    

    校验正确

6. UDP协议及校验和计算

  • UDP数据包格式
字段长度(Byte)说明
源端口号2发送端口号
目的端口号2接收端口号
UDP长度2UDP头部和数据总长度
UDP校验和2校验和字段(可选)
数据可变UDP有效载荷
  • UDP校验和计算方法

    • 计算时需要三部分数据:

      1. UDP伪首部(包含IP源地址、目的地址、协议号、UDP长度)
      2. UDP首部
      3. UDP数据
    • 计算步骤:

      1. 将UDP校验和字段置0。
      2. 将伪首部、UDP首部和数据按2字节拆分,逐个相加。
      3. 若结果超过16位,进位加到低16位。
      4. 取反得到UDP校验和。
    • 示例:

      相关数据(十六进制):

      a9 fe bf 1f a9 fe 01 17 00 11 00 28 04 d2 04 d2 00 28 00 00 68 74 74 70 3a 2f 2f 77 77 77 2e 63 6d 73 6f 66 74 2e 63 6e 20 51 51 3a 31 30 38 36 35 36 30 30
      
      • 将校验和字段 00 92 置为 00 00
      • 按2字节拆分求和:
      a9fe + bf1f + a9fe + 0117 + 0011 + 0028 + 04d2 + 04d2 + 0028 + 0000 + 6874 + 7470 + 3a2f + 2f77 + 7777 + 2e63 + 6d73 + 6f66 + 742e + 636e + 2051 + 513a + 3130 + 3836 + 3536 + 3030 = 6ff67
      
      • 进位加法:
      6 + ff67 = ff6d
      
      • 取反得到校验和:
      ~ff6d = 0092
      

7. 总结

校验和类型计算范围计算步骤简述备注
IP首部校验和IP首部(通常20字节)校验和字段置0,16位分段求和,进位加,取反确保IP首部完整性
UDP校验和UDP伪首部 + UDP首部 + UDP数据校验和字段置0,16位分段求和,进位加,取反可选字段,保证UDP数据完整性