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

发布时间 2023-06-07 23:51:45作者: 我爱C编程

1.算法仿真效果

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

 

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

 

发射0010

 

发射1001

 

 

发射1011

 

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

        UDP User Datagram Protocol的简称, 中文名是用户数据报协议,是OSIOpen System Interconnection,开放式系统互联) 参考模型中一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务,IETF RFC 768 [1]  UDP的正式规范。UDPIP报文的协议号是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,如果想要可靠性,那么就选TCPUDP 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