基于FPGA的UDP网络通信

目录

1.协议栈层次结构

2.核心模块原理与数学建模

2.1 以太网MAC层:帧结构与CRC校验

2.2 IP层:地址解析与校验和计算

2.3UDP层:端口匹配与数据封装

3.FPGA实现与数学映射


1.协议栈层次结构

        系统遵循TCP/IP协议栈的分层模型,FPGA主要实现数据链路层(以太网MAC)网络层(IP)传输层(UDP)的核心功能,架构如图1所示:

各层核心功能:

MAC层:实现以太网帧的封装与解析,包括前导码、帧起始符(SFD)、目的MAC地址、源MAC地址、类型字段、数据域和CRC校验;

IP层:处理IP数据包的路由选择(简化为本地子网校验)、IP地址过滤和头部校验和计算;

UDP层:实现端口号匹配、UDP长度计算和校验和验证,提供无连接的数据报服务。

2.核心模块原理与数学建模

2.1 以太网MAC层:帧结构与CRC校验

       MAC层是FPGA与物理层(PHY)的接口,负责将IP数据包封装为以太网帧格式(IEEE802.3标准),并通过GMII/RGMII接口与PHY芯片通信。标准以太网帧结构(不包含前导码)的字段定义与长度(字节)如下:

字段目的 MAC源 MAC类型 / 长度数据域CRC 校验
长度(字节)66246~15004

MAC层采用CRC32校验算法检测帧传输错误,生成多项式为:

2.2 IP层:地址解析与校验和计算

       IP层负责数据包的路由和转发,FPGA实现时简化为本地子网内的通信,核心功能包括IP地址过滤、版本校验和头部校验和计算。IPv4 数据包头部(最小20字节)的关键字段定义:

字段长度(比特)含义约束条件
版本(Version)4IP 协议版本必须为 4(01002​)
头部长度(IHL)4头部字节数 / 4最小值 5(01012​,20 字节)
总长度16包总长(字节)20≤Ltotal​≤65535
源 IP 地址32发送端 IP32 位二进制表示(如192.168.1.1)
目的 IP 地址32接收端 IP同上
头部校验和16头部错误检测反码求和结果

2.3UDP层:端口匹配与数据封装

       UDP协议提供无连接的数据传输服务,FPGA实现的核心功能包括端口号过滤、UDP长度计算和校验和验证。UDP 数据报结构(8字节固定头部+数据域):

字段长度(比特)含义数学约束
源端口16发送端端口号0≤Port≤65535
目的端口16接收端端口号同上
长度16UDP 总长度(字节)8≤LUDP​≤65507
校验和16错误检测(可选)反码求和(含伪首部)

3.FPGA实现与数学映射

verilog程序如下:

................................................................
            else begin                                     //发送其它的数据包(第一个字节到倒数第二个字节)
               tx_data_counter<=tx_data_counter+1'b1;			
					if(i==0) begin    
					  dataout[7:0]<=datain_reg[31:24];	       //发送高8位(31:24)数据
					  i<=i+1'b1;
					  ram_rd_addr<=ram_rd_addr+1'b1;           //RAM地址加1, 提前让RAM输出数据	
					end
					else if(i==1) begin
					  dataout[7:0]<=datain_reg[23:16];         //发送次高8位(23:16)数据
					  i<=i+1'b1;
					end
					else if(i==2) begin
					  dataout[7:0]<=datain_reg[15:8];          //发送次低8位(15:8)数据
					  i<=i+1'b1;
					end
					else if(i==3) begin
			        dataout[7:0]<=datain_reg[7:0];           //发送低8位(7:0)数据
					  datain_reg<=datain;                      //准备数据					  
					  i<=0; 				  
					end
				end
			end					
			default:tx_state<=idle;		
       endcase	  
end 
 
 
 

alt_25 alt_25_u(enetclk,MDC);



assign ENET1_MDC=MDC;
assign GTX_CLK=0;


//产生发送的控制使能信号和地址信息
TXcontrol TXcontrol_u(
                 .TX_CLK (TX_CLK),//网口时钟
					  .SW4    (dataout[3:0]),
					  .flag   (flag),//发送接收周期性标志信号
					  .addr   (ADDR),//地址
					  .TX_EN  (TX_EN),//控制网口的EN信号
					  .TX_ER  (TX_ER),//控制网口的ER信号
					  .TX_DATA(TX_DATA)
                );

			 



always@(posedge MDC)// 命令
begin
    if(flag==1'b1) 
	 begin 
			case(cnt1)
					 0:begin 	
					     RST_N    <= 1'b0;
						  men_MDIO <= men_MDIO+1;
						  if(men_MDIO&32'hffffffff==32'hffffffff) 
						  begin  
					       RST_N <= 1'b1; 
					       cnt1  <= 1'b1;
						  end else 
						    cnt1  <= 5'd0;
					   end
						
					 1:begin 
					      men_MDIO <= TIME_SEQ1;//产生MDIO控制时序
							cnt1     <= 5'd2;
					   end 
							
					 2:begin 
					      cnt2 <= cnt2 + 7'd1;
							if(cnt2 < 7'd96)
							begin 
								mdio     <= men_MDIO[95]; 
								wr_rd    <= 1'b1;
								men_MDIO <= men_MDIO<<1;
								cnt1     <= 5'd2;
							end else 
							begin  
					         cnt1 <= 5'd5;
					         cnt2 <= 7'd0;
							end 
						end  
 
					 5:begin 
					     men_MDIO <= TIME_SEQ2;
						  cnt1     <= 5'd6;
						end
					 
					 6:begin 
					     cnt2 <= cnt2 + 7'd1;
						  
						  if(cnt2<96)
						  begin 
						     mdio     <= men_MDIO[95]; 
						     wr_rd    <= 1'b1;
						     men_MDIO <= men_MDIO<<1;
						     cnt1     <= 5'd6;
						  end else 
						  begin   
						     cnt1 <= 5'd9;
						     cnt2 <= 7'd0;
						  end 
					   end  	
									 
						
									 
					 9:begin 
					      men_MDIO <= TIME_SEQ3;
							cnt1     <= 5'd10;
						end 
						 
					 10:begin 
					      cnt2 <= cnt2 + 7'd1;
							if(cnt2 < 7'd96)
							begin 
								mdio     <= men_MDIO[95]; 
								wr_rd    <= 1'b1;
								men_MDIO <= men_MDIO<<1;
								cnt1     <= 5'd10;
							end else 
							begin  
							  cnt1 <= 5'd13;
							  cnt2 <= 7'd0;
							end 
						 end  
			
									 
					 13:begin 
					      men_MDIO <= TIME_SEQ4;
							cnt1     <= 5'd14;
						 end  
 
					 14:begin 
					      cnt2<=cnt2+1;
						   if(cnt2<96)
							begin 
							   mdio     <= men_MDIO[95]; 
								wr_rd    <= 1'b1;
								men_MDIO <= men_MDIO<<1;
								cnt1     <= 5'd14;
							end else 
							begin  
							  cnt1 <= 5'd17;
							  cnt2 <= 7'd0;
							end 
						 end  	
					
									 
					 17:begin 
					      men_MDIO <= TIME_SEQ5;
							cnt1     <= 5'd18;
						 end 
 
					 18:begin 
					      cnt2<=cnt2+7'd1;
							if(cnt2 < 7'd96)
							begin 
								mdio     <= men_MDIO[95]; 
								wr_rd    <= 1;
								men_MDIO <= men_MDIO<<1;
								cnt1     <= 5'd18;
							end else 
							begin   
								cnt1 <= 5'd19;
								cnt2 <= 7'd0;
							end 
						 end  
									 
									 
									 
					19:begin 
					     men_MDIO <= TIME_SEQ6;
						  cnt1     <= 5'd20;
						end 
					

					20:begin 
					     cnt2<=cnt2+7'd1;
						  if(cnt2<7'd96)
						  begin 
						    mdio     <= men_MDIO[95]; 
						    wr_rd    <= 1'b1;
						    men_MDIO <= men_MDIO<<1;
						    cnt1     <= 5'd20;
						  end else 
						  begin 
						    cnt1 <= 5'd21;
						    cnt2 <= 7'd0;
						  end  
					   end
									 

				  21:begin 
				       cnt2<=cnt2+7'd1;
						 if(cnt2<7'd32)
						 begin 
							 mdio  <= 1'b1; 
							 wr_rd <= 1'b1;
							 cnt1  <= 5'd21;
						 end else 
						 begin 
						   flag  <= 1'b0;
						   wr_rd <= 1'b0;
						 end  
					  end  
			endcase 
	 end 
    else begin
				case(UDP_states)
					0:begin 
					    men_MDIO   <=TIME_SEQ7;
						 UDP_states <= 1;
						 wr_rd      <= 1;
						 cnt2       <= 0;
					  end 
					1:begin 
					    cnt2 <= cnt2 + 1; 
						 if(cnt2<48)
						 begin 
							 mdio       <= men_MDIO[95]; 
							 men_MDIO   <= men_MDIO<<1;
							 UDP_states <= 1;
						 end else 
						 begin 
						   wr_rd      <=0;
						   UDP_states <=2;
						 end 
					  end 
					  
			  	   2: UDP_states<=5'd3;
				   3: UDP_states<=5'd4;
				   4: UDP_states<=5'd5;
				   5: UDP_states<=5'd6;
				   6: UDP_states<=5'd7;
				   7: UDP_states<=5'd8;
				   8: UDP_states<=5'd9;
				   9: UDP_states<=5'd10;
				   10:UDP_states<=5'd11;
				   11:UDP_states<=5'd12;
				   12:UDP_states<=5'd13;
				   13:UDP_states<=5'd14;
				   14:UDP_states<=5'd15;
				   15:UDP_states<=5'd16;
				   16:UDP_states<=5'd17;
					
					
				   17:begin 
				      cnt2      <= 7'd1;
						UDP_states<= 5'd18;
					 end
					
				   18:begin 
				       cnt2  <= cnt2+7'd1;
					    wr_rd <= 1'b1;
					    mdio  <= 1'b1;
					    if(cnt2==7'h3f)
					    cnt2  <= 7'd0;
					    UDP_states <= 5'd0;  
				     end 
				endcase 	
     end 				
end
						

assign MDIO=wr_rd?mdio:1'bz;
assign mdio_in=MDIO;
				
endmodule

其中Tx端有三个信号:

Txd_RGM,

Tx_ctrl,

Tx_clk,

其中Tx_clk是由FPGA提供的125MHz的时钟,

Tx_RGM是发送的数据,

Tx_ctrl在Tx_clk时钟上升沿发送的是Tx_en,在下降沿发送的是Tx_en和Tx_er的异或值。

Rx端也有三个信号:Rxd_RGM,Rx_ctrl,Rx_clk,其中Rx_clk是由88E1111提供的125MHz的时钟,Rx_RGM表示接收到的数据,Rx_ctrl在Rx_clk的上升沿收到的是Rx_en,在下降沿收到的是Rx_en和Rx_er的异或值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

fpga和matlab

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

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

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

打赏作者

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

抵扣说明:

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

余额充值