1.算法仿真效果
Quartusii18.0+DE2-115开发板测试结果如下:
一个DE2-115做发射,一个DE2-115做接收
发射0010
发射1001
发射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
```