以太网UDP帧发包设计

以太网UDP帧发包设计

RTL8211 是一片 10M/100M/1000M 自适应以太网收发器,提供 MII/GMII/RGMII 接口的
MAC 连接。
下图为 RTL8211 与 FPGA 的连接关系。
在这里插入图片描述
在这里插入图片描述

以太网MAC层(媒体介入控制层)接口介绍
在这里插入图片描述

MII 接口

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

PHY是物理接口收发器,它实现物理层。包括MII/GMII(介质独立接口)子层、PCS(物理编码子层)、PMA(物理介质附加)子层、PMD(物理介质相关)子层、MDI子层。

MAC 侧向 PHY 侧传输数据的时序图如下。发送数据信号 TXD 和发送使能信号需要在时钟上升沿保持稳定。
在这里插入图片描述
PHY 侧向 MAC 侧传输数据(也就是 MAC 侧接收 PHY 侧传过来的数据)的时序图如下。 PHY 芯片传出(也就是 MAC 接收)数据信号 RXD 和数据有效信号在时钟上升沿保持稳定。在 MAC 接收数据时,需要根据传过来数据信号的时序特点进行正确的
接收。
在这里插入图片描述

GMII 接口

在这里插入图片描述
在这里插入图片描述
从波形图可以看出,发送数据信号 TXD 和发送使能信号需要在时钟 GTX_CLK 的上升沿保持稳定;同样的 PHY 芯片传出(也就是 MAC 接收)数据信号 RXD 和数据有效信号在时钟RX_CLK 上升沿保持稳定。在 MAC 发送/接收数据时,需要满足这些时序要求才能让 PHY 正确收到数据和正确接收到 PHY 传过来数据。
在这里插入图片描述

RGMII 接口

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
RGMII 接口为了保持 1000Mbps 的传输速率不变, RGMII 接口在时钟的上升沿和下降沿都采样数据。在参考时钟的上升沿发送 GMII 接口中的 TXD[3:0]/RXD[3:0],在参考时钟的下降沿发送 GMII 接口中的 TXD[7:4]/RXD[7:4]。 RGMII 同时也兼容 100Mbps 和 10Mbps 两种速率,此时参考时钟速率分别为 25MHz 和 2.5MHz。 TX_EN 信号线上传送 TX_EN 和 TX_ER 两种信息,在 TX_CLK 的上升沿发送TX_EN,下降沿发送 TX_ER; 同样的, RX_DV 信号线上也传送 RX_DV 和RX_ER 两种信息,在 RX_CLK 的上升沿传输 RX_DV,下降沿传输 RX_ER。
在这里插入图片描述

以太网(MAC) 帧协议介绍

以太网技术的正式标准是 IEEE 802.3 标准,它规定了在以太网中传输的数据帧结构,如下图所示。
在这里插入图片描述
在物理层上看,一个完整的以太网帧有 7 个字段,事实上,前两个字段并不能算是真正意义上的以太网数据帧,它们是以太网在物理层上发送以太网数据时添加上去的。
为了实现底层数据的正确阐述,物理层使用 7 个字节前同步码(0 和 1 交替的 56 位(55-55-55-55-55-55-55))实现物理层帧输入/输出同步;使用 1 个字节的 SFD(帧首定界符,固定为 10101011)标识帧的开始。
上图中剩下的 5 个字段是真正的以太网数据,其中包含了目的地址和源地址,它们都是 6 字节长度(通常每个网卡都有 1 个 6 个字节 MAC 地址,以在以太网中唯一地标识自己)。网卡接收数据时,通过将目的地址字段和自身的 MAC 地址做比较,判断是否
接收该数据包。通常,将这里的 6 字节目的地址按照下面的格式来书写,如: 00-01-02-03-04-05。这 6 个字节在以太网中是按照从左到右(先发该字段的高字节后发字段的低字节)的顺序发送的,同时对每个字节来说,最先发送的是最低位 bit0,最后是最高位 bit7。
在这里插入图片描述
在以太网帧中,目的 MAC 地址可以分为三类:单播地址、多播地址和广播地址。单播地址通常与一个具体网卡的 MAC 地址相对应,它要求第一个字节的 bit0(即最先发出去的位)必须是 0;多播地址则要求第一个字节的 bit0 为 1,这样,在网络中多播地址不会与任何网卡的 MAC 相同,多播数据可以被很多个网卡同时接收;广播地址的所有 48 位全为 1(即 FF-FF-FF-FF-FF-FF),同一局域网中的所有网卡可以接收广播数据包。

UDP 协议介绍

UDP 是 User Datagram Protocol 的简称, 中文名是用户数据报协议,是 OSI(Open SystemInterconnection,开放式系统互联)参考模型中一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务, IETF RFC 768 是 UDP 的正式规范。
UDP 协议的主要作用是将网络数据流量压缩成数据包的形式。一个典型的数据包就是一个二进制数据的传输单位。每一个数据包的前 8 个字节用来包含报头信息,剩余字节则用来包含具体的传输数据。

IP 数据报格式
IP 是 TCP/IP 协议族中最核心的协议,所有的 TCP、 UDP、 ICMP、 IGMP 数据都以 IP 数据报的格式传输。 IP 仅提供尽力而为的传输服务,如果发生某种错误, IP 会丢失该数据,然后发送 ICMP 消息给信源端。另外, IP 数据报可以不按发送顺序接受。

IP 数据报的格式如下, IP 数据报的长度/类型段的数值为 0x0800,数据和填充段包括IP 头部数据和 IP 数据两个部分。
在这里插入图片描述
在这里插入图片描述
首部的每一行是一个以 32bit 为单位的数据,最高位在左边,为 0bit,最低位在右边,为 31bit。
首部长度是指首部占 32bit 字(4 字节) 的数目,因为 4 位的最大值为 15,因此首部最长为 60(4*15=60) 字节,也即是说选项部分的最大值为 40 字节,不够 4 的倍数,要用 0 填充,使数据部分的起始地址为 4 的倍数。
在这里插入图片描述

UDP 数据报格式

UDP 数据报分为首部和用户数据部分,整个 UDP 数据报作为 IP 数据报的数据部分封装在 IP 数据报中, UDP 报文的以太网帧结构如图所示。
在这里插入图片描述
UDP 报文包括 UDP 报文首部数据和 UDP 报文数据(数据负载),其中 UDP 首部有 8 个字节,由 4 个字段构成,每个字段都是两个字节。
在这里插入图片描述
例如本机端口号为 5000(0x1388), 要给端口号为 6000(0x1770)的目标主机发送“Hello, welcome to FPGA!”,数据为 23 个字节, UDP 首部 8 个字节,合计 31 个字节,则 UDP 报文组包如下。
在这里插入图片描述

以太网 UDP 帧发包接口 FPGA 实现

在这里插入图片描述
在这里插入图片描述
UDP 以太网帧里面包括 3 个校验字段, IP 报文头部检验字段、UDP 头部校验字段和以太网报文的校验字段 FCS。 IP 头部检验 IPchecksun 与 IP 头部的数据有关,在 IP 头部数据改变(比如目的 IP 等数据改变)的时候,这个校验和也是需要重新进行计算的。 UDP 头部校验是可选字段, 该字段可以直接填充全零,表示不进行校验,考虑设计的简单性,后面的设计就直接忽略 UDP 头部检验,直接将该字段填充全零。以太网报文最后字段 FCS 与整个报文的数据都有关系,不管报文哪个数据发生变化,这个校验和 FCS 字段都需要重新进行计算。

IP 头部检验 IPchecksun 的计算
IP 头部检验 IPchecksun 仅与 IP 头部的数据有关。
在这里插入图片描述
发送端发送数据时具体 checksum 计算步骤如下。

  1. 把校验和字段(check sum) 置为 0;
  2. 对 IP 头部中的每 16bit 进行二进制求和;
  3. 如果和的高 16bit 不为 0,则将和的高 16bit 和低 16bit 反复相加,直到和的高 16bit为 0,从而获得一个 16bit 的值;
  4. 将该 16bit 的值取反, 即为最终计算的 check sum 值, 存入校验和字段。

以上面数据举例对 check sum 进行计算, 我们使用 IP 协议发送一个数据长度为 31 个字节的数据包,发送端 IP 为 192.168.0.2, 接收端 IP 为 192.168.0.3。 根据 check sum 计算的步骤,对需要计算的 check sum 字段置为 0,然后以每 16bit 进行求和, 即:

0x4500 + 0x0033 + 0x0000 + 0x0000 + 0x4011 + 0x0000(check sum 计算时置为 0) +0xc0a8 + 0x0002 + 0xc0a8 + 0x0003 = 0x20699

上面计算的结果 0x20699 的高 16bit 不为 0,将高 16bit 和低 16bit 相加,计算如下。
0x0002 + 0x0699 = 0x069b

上面计算结果的高 16bit 为 0,进行步骤的第 4 步,则 check sum 最终计算的值为
checksum = ~0x069b = 0xf964

module ip_checksum(
input clk ,
input reset_n ,
input cal_en ,
input [3:0] IP_ver ,
input [3:0] IP_hdr_len ,
input [7:0] IP_tos ,
input [15:0] IP_total_len ,
input [15:0] IP_id ,
input IP_rsv ,
input IP_df ,
input IP_mf ,
input [12:0] IP_frag_offset ,
input [7:0] IP_ttl ,
input [7:0] IP_protocol ,
input [31:0] src_ip ,
input [31:0] dst_ip ,
output [15:0] checksum
);
	reg [31:0]suma;
	wire [16:0]sumb;
	wire [15:0]sumc;
	
	always@(posedge clk or negedge reset_n)
		if(!reset_n)
			suma <= 32'd0;
		else if(cal_en)
			suma <= {IP_ver,IP_hdr_len,IP_tos}+IP_total_len+IP_id+{IP_rsv,IP_df,IP_mf,IP_frag_offset}
			+{IP_ttl,IP_protocol}+src_ip[31:16]+src_ip[15:0]+dst_ip[31:16]+dst_ip[15:0];
		else
			suma <= suma;
			
	assign sumb = suma[31:16]+suma[15:0];
	assign sumc = sumb[16]+sumb[15:0];
	assign checksum = ~sumc;
endmodule

该模块仿真测试的 testbench 代码如下。

`timescale 1ns/1ns
`define CLK_PERIOD 8
module ip_checksum_tb();
	reg clk ;
	reg reset_n ;
	reg cal_en ;
	reg [15:0] IP_total_len ;
	reg [31:0] src_ip ;
	reg [31:0] dst_ip ;
	wire [15:0] checksum ;
	
	initial clk = 1;
	always#(`CLK_PERIOD/2)clk = ~clk;
	
	initial begin
		reset_n = 1'b0;
		cal_en = 1'b0;
		IP_total_len = 16'd0;
		src_ip = 32'hc0a80002;
		dst_ip = 32'hc0a80003;
		#(`CLK_PERIOD*20 + 1 );
		reset_n = 1'b1;
		#(`CLK_PERIOD*50);
		
		cal_en = 1'b1;
		IP_total_len = 16'h33;
		src_ip = 32'hc0a80002;
		dst_ip = 32'hc0a80003;
		#(`CLK_PERIOD)
		cal_en = 1'b0;
		
		#200;
		cal_en = 1'b1;
		IP_total_len = 16'h44;
		src_ip = 32'hc0a80004;
		dst_ip = 32'hc0a80005;
		#(`CLK_PERIOD)
		cal_en = 1'b0;
		#200;
		$stop;
end

ip_checksum ip_checksum(
		.clk(clk),
		.reset_n(reset_n),
		.cal_en(cal_en),
		.IP_ver(4'h4),
		.IP_hdr_len(4'h5),
		.IP_tos(8'h00),
		.IP_total_len(IP_total_len),
		.IP_id(16'h0000),
		.IP_rsv(1'b0),
		.IP_df(1'b0),
		.IP_mf(1'b0),
		.IP_frag_offset(13'h0000),
		.IP_ttl(8'h40),
		.IP_protocol(8'h11),
		.src_ip(src_ip),
		.dst_ip(dst_ip),
		.checksum(checksum)
);

endmodule

以太网报文的校验字段 FCS 的计算
以太网报文校验字段 FCS 采用的是 CRC32 计算,关于 CRC 计算的 Verilog 代码实现已经做的很成熟,网上也有可直接生成 CRC 计算 Verilog 代码的网站。

以太网报文发送模块实现
UDP 帧根据格式包括前导码+帧界定符、以太网头部数据、 IP 头部数据、 UDP 头部数据、 UDP 数据、 FCS 数据。根据格式对 UDP 帧发送的设计的状态机转移图如下。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

傻童:CPU

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值