前言
万兆以太网设计最终章节,巨型以太网数据帧传输设计。对于标准以太网而言,数据传输范围为46-1500字节,当大于1500字节后数据将无法传输。在IP层的报文描述当中,有一个分片字段,通过该字段即可实现将巨型数据帧拆分为多个小于1500字节的数据进行传输。
一、UDP_RX模块设计
在UDP接收模块当中增加以下新设计:
- 将接收到的数据先存入RAM当中,如果当前数据是一个单独的包,则立刻输出,如果是一个分片数据包,则继续等待所有分片输入后,一次性输出完整的巨型数据帧。通过w_recv_pkt_end 信号判断当前是否接收到了完整的数据包。看似简单,实则经历了极其漫长的调试工作。。
//完整的一个包输入指示信号
//表示没有分片,那么last到来即一个包结束; 分片但是当前分片后没有更多片
assign w_recv_pkt_end = r_udp_pkt_valid && ((rs_axis_ip_last && r_udp_split == 0 && r_udp_offset == 0) ||
(rs_axis_ip_last && r_udp_split == 1 && r_udp_more_split == 0));
- r_udp_pkt_valid指示信号,该信号用于判断当前数据是否是一个有效的UDP数据包,只有当数据有效,我们才会将其数据存入RAM,并且将其长度信息存入FIFO。(看似简单,实则调试时候诸多BUG源于此信号判断)
//检测是否为UDP数据包,通过user当中的type字段判断即可
always @(posedge i_clk or posedge i_rst) begin
if(i_rst)
r_udp_pkt_valid <= 'd0;
else if(s_axis_ip_valid && !rs_axis_ip_valid && s_axis_ip_user[36:29] == 8'd17 && w_ip_flags[2] == 0)//分片udp没有包头
r_udp_pkt_valid <= 'd1;
else if(s_axis_ip_valid && !rs_axis_ip_valid && ((s_axis_ip_user[36:29] != 8'd17) || (s_axis_ip_data[47:32] != ri_dymanic_src_port)))
r_udp_pkt_valid <= 'd0;
else if(s_axis_ip_valid && !rs_axis_ip_valid && s_axis_ip_user[36:29] == 8'd17 && s_axis_ip_data[