目录

银杏科技有限公司旗下技术文档发布平台
技术支持电话0379-69926675-801
技术支持邮件Gingko@vip.163.com
版本 日期 作者 修改内容
V1.0 2019-12-25 gingko 初次建立

实验三十二:千兆以太网传输

一、实验目的与意义

  1. 了解以太网帧结构和IP协议以及UDP协议的定义。
  2. 了解PHY芯片RTL8211EG的引脚设定和信号规范。
  3. 学习千兆以太网传输原理和物理层接口GMII的时序控制方法。
  4. 掌握GMII接口千兆以太网的UDP协议通信模块设计。

二、实验设备及平台

  1. iCore3 双核心板( FPGA型号为EP4CE10F17)点击购买
  2. 千兆网传输模块点击购买
  3. Blaster(或相同功能的)仿真器和USB线缆点击购买
  4. Micro USB线缆和千兆速率网线。
  5. QuartusII开发软件(本实验中使用的是13.1版本)、TCP&UDP测试工具软件、wireshark抓包软件。
  6. 一台带有千兆网卡的电脑。

图32-1_硬件连接实物图 注意事项1: 注意FPC转接板和千兆网卡模块下边缘对齐连接,如图30-1红圈内标注所示。
注意事项2: 确认PC端网卡和网线是千兆速率,网线的水晶头连接紧密稳定。
注意事项3: 下载前请确认绑定的引脚或者加载的pin.tcl文件和千兆网与核心板之间的连接引脚相对应。

三、实验原理

1、数据收发流程

图32-2_数据收发传输路径

2、PHY芯片RTL8211EG

图32-3_rtl8211eg引脚示意图

图32-4_gmii模式引脚命名及定义1 图32-5_gmii模式引脚命名及定义2

图32-6_phy芯片模式选择控制 图32-7_rtl8211eg电路原理图

3、GMII接口

图32-8_gmii接口的相关信号

图32-9_gmii接口时序定义

图32-10_时钟gtx_clk相位偏移量设置

四、以太网

1、以太网帧结构
前导码 SFD 目标地址 源地址 类型 数据(IP数据包) CRC
7byte 1byte 6byte 6byte 2byte 46-1500byte 4byte
字段名称 字段含义
前导码 7个字节的0x55,用于以太网前导
SFD 1个字节的帧起始符,0xD5,表示以太网数据帧的开始
目标地址 接收方MAC地址,6字节
源地址 发送方MAC地址,6字节
类型 网络协议类型,0x0800表示为IP协议,0x0806表示是ARP协议
数据 46-1500字节,不够最少字节的用0x00填充。
CRC CRC-32 校验,从目标地址到数据结束都为需校验内容
2、IP协议
版本(4bit) 首部长度(4 bit) 服务类型(1 byte) 总长度(2 byte)
标识(2 byte) 标识(3 bit) 片偏移(13 bit)
生存时间(1 byte) 协议(1 byte) 首部校验和(2byte)
源IP地址(4 byte)
目标IP地址(4 byte)
选项(如果有)
数据
字段名称 字段含义
版本 IP协议版本,IPv 4 的协议版本号为4
首部长度 IP包头的长度,单位为4byte,即首部长度字段的值为5时,包头长度为20byte
服务类型 只有在使区分服务时,本字段才起作用
总长度 IP包的总长度,包括包头和数据
标识 用于分包/拼包
标志 用于分包/拼包
片偏移 用于分包/拼包
生存时间 数据在网络中的寿命,每经过一个路由器 -1,减到0时数据无效
协议 指明数据字段中的数据包协议类型,UDP(17),TCP(6)
首部校验和 IP包头部检验,只检验数据报的首部,不包括数据部分
源IP地址 发送方IP地址
目标IP地址 接收方IP地址
选项 可选字段(长度可变)
数据 IP数据包的数据部分(既UDP包)
3、UDP协议
源端口号(2 byte) 目标端口号(2 byte)
UDP长度(2 byte) UDP长度(2 byte)
数据(x byte) (如果有)
字段名称 字段含义
源端口号(2 byte) 发送方端口
目标端口号(2 byte) 接收方端口
UDP长度(2 byte) UDP数据包长度,包括包头和数据
UDP长度(2 byte) UDP包头部检验,只检验数据报的首部,不包括数据部分
数据(x byte) UDP数据包中的数据(也是帧结构的有效数据)
4、CRC校验

五、代码讲解

图32-11_数据接收流程图

图32-12_数据发送流程图

1、数据接收模块
//-------------------接收数据-------------------//		
	parameter 		
						PRE_R  = 4'd0,
						SFD_R  = 4'd1,
						DA_R   = 4'd2,
						SA_R   = 4'd3,
						TYPE_R = 4'd4,
						ARP_R  = 4'd5,
						IP_R   = 4'd6,
						UDP_R  = 4'd7,
						APP_R  = 4'd8,
						END_R  = 4'd9;
 
		reg [3:0] STATE_R;//接收状态
		reg [7:0] cnt_R;//接收使用的计数器
		reg [47:0]dest_mac;//目标MAC地址
		reg [47:0]source_mac;//源MAC地址
		reg [15:0]type;//接收数据的协议类型
		reg [223:0]arp_data;//ARP中的数据
		reg [159:0]ip_head;//IP报头
		reg [63:0]udp_head;//UDP数据报头
		reg [7:0]buffer[63:0];//数据缓存区
		reg [15:0]data_lenght;//数据长度
		reg [11:0] i;//数据计数器
		reg [7:0]data1;
		reg UDP_SD_EN;
    UDP_R:// 接收UDP包头 8 byte
        begin
	    if(cnt_R == 8'd7)
	        begin
		    udp_head <= {udp_head[55:0],data1};
		    cnt_R <= 8'd0;	
		    if(udp_head[39:24] == 16'h7530)//16进制的7530是十进制的30000,即设定的端口号
		        begin
			    data_lenght <= udp_head[23:8] - 16'd8;//提取数据长度,udp_head的[23:8]定义了UDP包的数据长度,包括了UDP头部,所以这里要减去UDP头部的数据长度8	
			    STATE_R <= APP_R;
			end
		    else
			begin
			    STATE_R <= PRE_R; //如果端口不匹配,则返回PRE_R状态
			end
		end
	   else
	        begin
		    udp_head <= {udp_head[55:0],data1};
		    cnt_R <= cnt_R +1'd1;			
		end									
     end
2、数据发送模块
reg flag;//连发模式标志位	
reg flag_h;//连发开始位标志
reg flag_l;//连发停止位标志
 
always@(posedge RX_CLK or negedge rst_N )
		if(rst_N==1'b0)
		    flag_h<=1'b0;
		else if((buffer[0]==8'h33)&&(STATE_UT==APP_R))//连发开始位标志3
			flag_h<=1'b1;
		     else 
			flag_h<=1'b0;
always@(posedge RX_CLK or negedge rst_N )
		if(rst_N==1'b0)
		    flag_l<=1'b0;
		else if((buffer[0]==8'h73)&&(STATE_UT==APP_R))//连发停止位标志s
			flag_l<=1'b1;
		     else
			flag_l<=1'b0;
 
always@(posedge RX_CLK or negedge rst_N )
		if(rst_N==1'b0)
		    flag<=1'b0;
		else if(flag_l)	//连发状态停止
			flag<=1'b0;
		     else if(flag_h==1'b1)//连发状态开始
			      flag<=1'b1;
	reg SD_EN;	
	always@(posedge	clk_125M or negedge rst_N)
		if(!rst_N)
		    SD_EN<=1'b0;
		else if(flag)
			SD_EN<=1'b1;
		     else if(!flag)
			      SD_EN<=UDP_SD_EN;
check1:
	begin
	    if(cnt == 8'd6)
		begin//IP计算首部校验和:以16位相加方式加到32位校验和中
		    ip_check_sum <= {ip_send[0],ip_send[1]} + {ip_send[2],ip_send[3]}+{ip_send[4],ip_send[5]} + {ip_send[6],ip_send[7]} + {ip_send[8],ip_send[9]}+{ip_send[12],ip_send[13]}+{ip_send[14],ip_send[15]}+{ip_send[16],ip_send[17]}+{ip_send[18],ip_send[19]};
		    crc_reset <= 1'd1;
		    cnt <= 8'd0;
		    STATE_UT <= check2;
		end
	    else
		begin
		    cnt <= cnt  + 1'd1;
		end
	end
check2:
	begin//IP计算首部校验和:16位相加取反
	    {ip_send[10],ip_send[11]} = ~(ip_check_sum[15:0] + ip_check_sum[31:16]);
	    STATE_UT <= send55;
	end
	send_udp://发送UDP包头
	    begin
		if(cnt == 8'd7)
		    begin
			data_out <= udp_send[cnt];
			cnt <= 8'd0;
		        data_counter <= 16'd0;
			if(flag) //控制发送状态跳转至send_data1
			    STATE_UT<=send_data1;
		        else
			    STATE_UT <= send_data;
		    end
		else
		    begin
			data_out <= udp_send[cnt];
		        cnt <= cnt +1'd1;
		    end
		end
send_data://发送数据
     begin		
	if(data_lenght < 16'd19)
	    begin
	        if(data_counter == 16'd20)
                    begin
		        data_out <= buffer[data_counter];
			data_counter <= 16'd0;
			STATE_UT <= send_crc;
		    end
		else
		    begin									
			data_out <= buffer[data_counter];							                data_counter <= data_counter + 1'd1;
		    end
	    end
	else										
            begin
		if(data_counter == data_lenght - 16'd1)
		    begin
			data_out <= buffer[data_counter];
			data_counter <= 16'd0;
			STATE_UT <= send_crc;
	            end
		else
		    begin										
			data_out <= buffer[data_counter];										data_counter <= data_counter + 1'd1;
	            end
	    end
	end
 
send_data1:
       begin
	if(cnt_l==1200)
		begin
		STATE_UT <=send_crc;
		cnt_l<=12'd0;
		end
	else
	    begin
		data_out<=8'h38;//输出数值随便定义,这里设定的“8”
		cnt_l<=cnt_l+1'b1;
	    end
	end

六、操作流程和测试结果

1、操作步骤:

图32-13_设置ip地址

图32-14_wireshark界面

图32-15	TCP&UDP测试工具创建连接

图32-16	TCP&UDP测试工具参数设置

图32-17	TCP&UDP测试工具测试界面

2、测试结果:

图32-18  TCP&UDP测试工具和wireshark软件联合调试

图32-19  测试结果

七、拓展实验: