可编程逻辑
UDP协议是一种不可靠的协议,也就是说在传输的过程中如果出错了,并不会去重新传输这个协议包,这个和TCP是不一样的。如果我们需要传输一些即使丢包也不太影响质量的数据的时候便可以采取UDP协议。比如做图像,音频等数据的传输,采用UDP协议会更好一点,因为在传输的时候即使丢失了一些包,也不会产生太大的影响,反而如果采用TCP这种出错会重传的协议在网络环境不好的时候反而会引入较大的延迟从而影响体验。但是对于传输文件等功能来说就需要采用ftp这种基于tcp的协议了,毕竟谁都不愿意收到的文件里面有大量的错误。
现在FPGA里面先实现UDP协议的回环测试。整个工程目录和我们之前实现ARP协议一样FPGA以太网--ARP协议,分为tx rx crc和ctrl四个模块。

对于一个以太网帧需要分为下图几个部分(图片来源于正点原子的资料)

因此在rx模块中我们定义了状态机的以下几个状态,分别用于解析前导码,以太网帧头,IP首部,UDP首部,数据和校验码。

状态机跳转如下:
always @(*) begin
case (curr_state)
IDLE:begin
if(rxd == 8'h55 && valid == 1'b1)begin
next_state = PREAMLE;
end
else begin
next_state = IDLE;
end
end
PREAMLE:begin
if(preamleError == 1'b1)begin
next_state = IDLE;
end
else if(preamleSucess == 1'b1)begin
next_state = FRAME_HEAD;
end
else if(valid == 1'b0)begin
next_state = IDLE;
end
else begin
next_state = PREAMLE;
end
end
FRAME_HEAD:begin
if(headError == 1'b1)begin
next_state = IDLE;
end
else if(headSucess == 1'b1)begin
next_state = IP_HEAD;
end
else if(valid == 1'b0)begin
next_state = IDLE;
end
else begin
next_state = FRAME_HEAD;
end
end
IP_HEAD:begin
if(ipHeadError == 1'b1)begin
next_state = IDLE;
end
else if(ipHeadSucess == 1'b1)begin
next_state = UDP_HEAD;
end
else if(valid == 1'b0)begin
next_state = IDLE;
end
else begin
next_state = IP_HEAD;
end
end
UDP_HEAD:begin
if(udp_head_cnt == 8'd7)begin
next_state = DATA;
end
else if(valid == 1'b0)begin
next_state = IDLE;
end
else begin
next_state = UDP_HEAD;
end
end
DATA:begin
if(udp_data_cnt == udp_len - 16'd1)begin
next_state = FCS;
end
else if(valid == 1'b0)begin
next_state = IDLE;
end
else begin
next_state = DATA;
end
end
FCS:begin
if(valid == 1'b0)begin
next_state = IDLE;
end
else begin
next_state = FCS;
end
end
default: begin
next_state = IDLE;
end
endcase
end
在tx中用于udp数据的发送:

当valid为高的时候发起一次udp的发送请求同时将发送长度,mac,ip,port等数据都传进来,当可以发送数据的时候会把ready信号置高。
需要注意的是在以太网发送的过程中,两个以太网帧之间是需要有间隔的,这样才能完成正常的传输。因此我们定义了一个gap来完成这个过程。

为了完成UDP回环测试,使用QT制作一个测试小工具

可以设置IP和端口,下面为发送窗口,上面是回环回来的数据。


可以看到UDP环回测试成功。
审核编辑:刘清
全部0条评论
快来发表一下你的评论吧 !