m基于DE2-115开发板的网口UDP数据收发系统FPGA实现

目录

1.算法仿真效果

2.算法涉及理论知识概要

3.Verilog核心程序

4.完整算法代码文件


1.算法仿真效果

Quartusii18.0+DE2-115开发板测试结果如下:

一个DE2-115做发射,一个DE2-115做接收

发射0010

发射1001 

扫描二维码关注公众号,回复: 14946132 查看本文章

发射1011 

2.算法涉及理论知识概要

        UDP 是User Datagram Protocol的简称, 中文名是用户数据报协议,是OSI(Open System Interconnection,开放式系统互联) 参考模型中一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务,IETF RFC 768 [1]  是UDP的正式规范。UDP在IP报文的协议号是17。
       UDP协议与TCP协议一样用于处理数据包,在OSI模型中,两者都位于传输层,处于IP协议的上一层。UDP有不提供数据包分组、组装和不能对数据包进行排序的缺点,也就是说,当报文发送之后,是无法得知其是否安全完整到达的。UDP用来支持那些需要在计算机之间传输数据的网络应用。包括网络视频会议系统在内的众多的客户/服务器模式的网络应用都需要使用UDP协议。UDP协议从问世至今已经被使用了很多年,虽然其最初的光彩已经被一些类似协议所掩盖,但即使在今天UDP仍然不失为一项非常实用和可行的网络传输层协议。
       许多应用只支持UDP,如:多媒体数据流,不产生任何额外的数据,即使知道有破坏的包也不进行重发。当强调传输性能而不是传输的完整性时,如:音频和多媒体应用,UDP是最好的选择。在数据传输时间很短,以至于此前的连接过程成为整个流量主体的情况下,UDP也是一个好的选择。

     1.udp是无连接的,也就是不需要像TCP那样调用 connect(...)函数。正是因为UDP是不需要connect(...),所以UDP是不可靠的。是无应答消息的,即:发出去了就发出去了,也不知道有没有收到。UDP协议也是数据包无序号标识,即:可能先发的数据包,最后收到,也有可能后发的数据包,最先收到,是比较随机的。

      2.UDP是面向数据包的,即:UDP每次发送都是以一个一个数据包来进行发送的。正是因为如此,对应的应用层数据既不会合并也不会拆分(保留数据包的边界)。每次发送的数据都是一个独立的UDP数据包,即:第一次发送的UDP数据包 和 第二次发送的UDP数据包,不会有任何的联系,2次发送的数据,就需要2次接收。因此,不会产生TCP中,那种粘包的行为。

     3.UDP没有拥塞控制,UDP只知道不停的往外发送数据,网络出现的拥塞不会使源主机的发送速率降低。从某种意义上来看,UDP的效率更高。因为,UDP没有繁琐的握手机制、同步机制。

     4.UDP支持一对一、一对多、多对一和多对多的交互通信。因为UDP只需要知道目标主机ip地址,以及端口号 就可以进行通信。

    5.UDP消息头开销小,只有8个字节。TCP消息头工有20个字节。

     6.所以,我们知道 UDP更加高效,UDP的高效是通过可靠性来换取的。如果想要高效,那么就选UDP,如果想要可靠性,那么就选TCP。UDP he TCP 是互补的。 

3.Verilog核心程序

reg [15:0] myIP_Prtcl;
reg [159:0]myIP_layer;
reg [63:0] myUDP_layer;
reg [31:0] mydata; 
reg [2:0]  byte_counter;
reg [4:0]  state_counter;
reg [95:0] mymac;
reg [15:0] data_counter;
reg [3:0]  rx_state;
wire       e_rxdv;
wire[7:0  ]datain;
reg [159:0]IP_layer; 
reg [63:0] UDP_layer;
reg [15:0] rx_total_length;         //UDP frame的总长度
reg [15:0] rx_data_length;          //接收的UDP数据包的长度
reg [31:0] data_o;                  //UDP接收的数据 


assign e_rxdv=1'b1;


assign datain={ENET1_RX_DATA,ENET1_RX_DATA};


parameter idle=4'd0,
          six_55=4'd1,
			 spd_d5=4'd2,
			 rx_mac=4'd3,
			 rx_IP_Protocol=4'd4,
	       rx_IP_layer=4'd5,
			 rx_UDP_layer=4'd6,
			 rx_data=4'd7,
			 rx_finish=4'd8;

initial
begin
	 rx_state<=idle;
end

//UDP数据接收程序	 	
always@(posedge clk_50)
begin
data_o<={24'd0,datain};
case(rx_state)
  idle: begin
		  byte_counter<=3'd0;
		  data_counter<=10'd0;
		  mydata<=32'd0;
		  state_counter<=5'd0;	
		  if(e_rxdv==1'b1) begin                           //接收数据有效为高,开始接收数据
			  if(datain[7:0]==8'h55) begin                  //接收到第一个55//
				  rx_state<=six_55;
				  mydata<={mydata[23:0],datain[7:0]};
			  end
			  else
				  rx_state<=idle;
		  end
  end		
  six_55: begin                                              //接收6个0x55//
		if ((datain[7:0]==8'h55)&&(e_rxdv==1'b1)) begin
			  if (state_counter==5) begin
					state_counter<=0;
					rx_state<=spd_d5;
			  end
			  else
					state_counter<=state_counter+1'b1;
		end
		else			
		  rx_state<=idle;
  end
  spd_d5: begin                                              //接收1个0xd5//
		if((datain[7:0]==8'hd5)&&(e_rxdv==1'b1)) 
		  rx_state<=rx_mac;			
		else 
		  rx_state<=idle;
  end	
  rx_mac: begin                    //接收目标mac address和源mac address
		if(e_rxdv==1'b1)	begin
			if(state_counter<5'd11)	begin
				  mymac<={mymac[87:0],datain};
				  state_counter<=state_counter+1'b1;
			end
			else begin
				state_counter<=5'd0;
				if((mymac[87:72]==16'h000a)&&(mymac[71:56]==16'h3501)&&(mymac[55:40]==16'hfec0))   //判断目标MAC Address是否为本FPGA
					rx_state<=rx_IP_Protocol;
				else
					rx_state<=rx_IP_Protocol;
			end
		end
		else
			rx_state<=idle;				
  end
  rx_IP_Protocol: begin                                              //接收2个字节的IP TYPE//
	  if(e_rxdv==1'b1) begin
			if(state_counter<5'd1) begin
				 myIP_Prtcl<={myIP_Prtcl[7:0],datain[7:0]};
				 state_counter<=state_counter+1'b1;
			end
			else	begin
				 state_counter<=5'd0;
				 rx_state<=rx_IP_layer;
			end
		end
		else 
		rx_state<=idle;
	end		  
	rx_IP_layer: begin               //接收20字节的udp虚拟包头,ip address
		if(e_rxdv==1'b1) begin
			if(state_counter<5'd19)	begin
				myIP_layer<={myIP_layer[151:0],datain[7:0]};
				state_counter<=state_counter+1'b1;
			end
			else begin
				IP_layer<={myIP_layer[151:0],datain[7:0]};
				state_counter<=5'd0;
				rx_state<=rx_UDP_layer;
			end
		end
		else 
			rx_state<=idle;
	end 					
	rx_UDP_layer: begin                //接受8字节UDP的端口号及UDP数据包长	  
		rx_total_length<=IP_layer[143:128];
		if(e_rxdv==1'b1) begin
			if(state_counter<5'd7)	begin
				myUDP_layer<={myUDP_layer[55:0],datain[7:0]};
				state_counter<=state_counter+1'b1;
			end
			else begin
				UDP_layer<={myUDP_layer[55:0],datain[7:0]};
				rx_data_length<= myUDP_layer[23:8];                //UDP数据包的长度						
				state_counter<=5'd0;
				rx_state<=rx_data;
			end
		end
		else 
			rx_state<=idle;
	end  
	rx_data: begin                                             //接收UDP的数据       
			if(e_rxdv==1'b1) begin
				if (data_counter==rx_data_length-9) begin         //存最后的数据,真正的UDP数据需要减去8字节的UDP包头
					 data_counter<=0;
					 rx_state<=rx_finish;							 
			 
						  data_o<={mydata[23:0],datain[7:0]};
						  byte_counter<=0;
		 
				end
				else begin
					 data_counter<=data_counter+1'b1;
					 if(byte_counter<3'd3)	begin
						  mydata<={mydata[23:0],datain[7:0]};
						  byte_counter<=byte_counter+1'b1; 
					 end
					 else begin
						  data_o<={mydata[23:0],datain[7:0]};
						  byte_counter<=3'd0;						  
					 end	
				end							 
			end
			else
				 rx_state<=idle;
	 end 
	 rx_finish: begin        
			 rx_state<=idle;
	 end		
	 default:rx_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),//网口时钟
					  .flag  (flag),//发送接收周期性标志信号
					  .addr  (ADDR),//地址
					  .TX_EN (TX_EN),//控制网口的EN信号
					  .TX_ER (TX_ER)//控制网口的ER信号
                );


//寄存器中读取数据或者存放数据 
package_wr package_wr_u(
                  .MDC    (MDC),
						.flagi  (flag),
						.mdio_in(mdio_in),
						.wr_rd  (wr_rd),
						.mdio   (mdio),
						.flag   (flag_),
						.RST_N  (RST_N)
                 );
12_049_m

4.完整算法代码文件

V

猜你喜欢

转载自blog.csdn.net/hlayumi1234567/article/details/130230427