[X]关闭

[米联客-安路飞龙DR1-FPSOC] UDP通信篇连载-06 UDP层程序设计

文档创建者:FPGA课程
浏览次数:197
最后更新:2024-08-09
文档课程分类-安路-DR1
安路-DR1: FPSOC-DR1-FPGA部分 » 2_FPGA实验篇(仅旗舰) » 4-FPGA UDP通信
本帖最后由 FPGA课程 于 2024-8-9 19:55 编辑

软件版本:Anlogic -TD5.9.1-DR1_ES1.1
操作系统:WIN10 64bit
硬件平台:适用安路(Anlogic)FPGA
实验平台:米联客-MLK-L1-CZ06-DR1M90G开发板
板卡获取平台:https://milianke.tmall.com/
登录"米联客"FPGA社区 http://www.uisrc.com 视频课程、答疑解惑!
3.5 UDP
该层实现用户数据和UDP报文的互转,相比于其它层次的设计,该层的逻辑相对简单。
3.5.1 UDP接收模块
通过计数器将UDP报文头部信息拆解,提取出端口号和长度信息。通过提取的长度对有效数据进行计数,从而得到有效数据并发送给用户端。
  1. always@(posedge I_R_udp_clk or posedge I_reset) begin
  2.     if(I_reset) begin
  3.         cnt                 <=  4'd0;
  4.         O_R_udp_valid       <=  1'b0;
  5.         O_R_udp_data        <=  8'd0;
  6.         O_R_udp_len         <=  16'd0;
  7.         udp_src_port        <=  16'd0;
  8.         udp_dest_port       <=  16'd0;
  9.         udp_pkg_len         <=  16'd0;
  10.         udp_data_cnt        <=  16'd0;
  11.     end
  12.     else if(I_udp_ip_rvalid) begin
  13.         udp_data_cnt    <=  udp_data_cnt + 1'b1;
  14.         case(cnt)
  15.             0   :begin  udp_src_port[15:8]  <=  I_udp_ip_rdata; cnt <=  cnt + 1'b1;end  //UDP接收源端口(远程主机端口)
  16.             1   :begin  udp_src_port[7:0]   <=  I_udp_ip_rdata; cnt <=  cnt + 1'b1;end  //UDP接收源端口(远程主机端口)
  17.             2   :begin  udp_dest_port[15:8] <=  I_udp_ip_rdata; cnt <=  cnt + 1'b1;end  //UDP接收目的端口(本地主机端口)
  18.             3   :begin  udp_dest_port[7:0]  <=  I_udp_ip_rdata; cnt <=  cnt + 1'b1;end  //UDP接收目的端口(本地主机端口)
  19.             4   :begin  udp_pkg_len[15:8]   <=  I_udp_ip_rdata; cnt <=  cnt + 1'b1;end  //UDP数据包长度
  20.             5   :begin  udp_pkg_len[7:0]    <=  I_udp_ip_rdata; cnt <=  cnt + 1'b1;end  //UDP数据包长度
  21.             6   :begin  cnt <=  cnt + 1'b1;end                                          //跳过检验和
  22.             7   :begin  cnt <=  cnt + 1'b1;end                                          //跳过校验和
  23.             8   :begin
  24.                 O_R_udp_valid       <=  1'b1;                                           //UDP接收数据有效
  25.                 O_R_udp_data        <=  I_udp_ip_rdata;
  26.                 O_R_udp_len         <=  udp_pkg_len - 16'd8;
  27.                 cnt                 <=  cnt + 1'b1;
  28.             end
  29.             9   :begin
  30.                 if(udp_pkg_len < 16'd26) begin
  31.                     if(udp_data_cnt == udp_pkg_len) begin
  32.                         O_R_udp_valid       <=  1'b0;
  33.                         O_R_udp_data        <=  8'd0;
  34.                         cnt                 <=  cnt + 1'b1;
  35.                     end     
  36.                     else begin
  37.                         O_R_udp_valid       <=  1'b1;
  38.                         O_R_udp_data        <=  I_udp_ip_rdata;
  39.                         cnt                 <=  cnt;                    
  40.                     end         
  41.                 end
  42.                 else begin
  43.                     O_R_udp_valid       <=  1'b1;
  44.                     O_R_udp_data        <=  I_udp_ip_rdata;
  45.                     cnt                 <=  cnt;
  46.                 end
  47.             end
  48.             10  :begin
  49.                 O_R_udp_valid       <=  1'b0;
  50.                 O_R_udp_data        <=  8'd0;
  51.                 cnt                 <=  cnt;
  52.             end
  53.             default:    cnt <=  4'd0;
  54.         endcase
  55.     end
  56.     else if(!I_udp_ip_rvalid) begin
  57.         udp_pkg_len         <=  16'd0;
  58.         udp_src_port        <=  16'd0;
  59.         udp_dest_port       <=  16'd0;
  60.         udp_data_cnt        <=  16'd0;
  61.         O_R_udp_len         <=  16'd0;
  62.         O_R_udp_data        <=  8'd0;
  63.         O_R_udp_valid       <=  1'b0;
  64.         cnt                 <=  4'd0;
  65.     end
  66. end
复制代码

3.5.2 UDP发送模块
状态机转换图如下:
2504661-20240809185714305-475365572.jpg
IDLE:当用户端发送写请求,且uiip_tx模块不忙时,进入WAIT_ACK状态。
WAIT_ACK:等待uiip_tx模块将udp_ip_tbusy信号拉高,完成握手,进入SEND_UDP_HEADER状态,开始发送UDP报文头部。
SEND_UDP_HEADER:将8个字节的UDP报文头部添加在有效数据之前,头部数据发送完成后,进入SEND_UDP_PACKET状态。
SEND_UDP_PACKET:将经过shift_ram移位8位的数据拼接在包头之后,通过计数器判断发送数据的数量,待数据发送完成后,回到IDLE状态,等待下一次发送请求。
  1. always@(posedge I_W_udp_clk or posedge I_reset) begin
  2.     if(I_reset) begin
  3.         cnt                 <=  4'd0;
  4.         O_udp_ip_tvalid     <=  1'b0;
  5.         O_udp_ip_tdata      <=  8'd0;
  6.         O_udp_ip_tpkg_len   <=  16'd0;
  7.         trans_data_cnt      <=  16'd0;
  8.         STATE               <=  IDLE;
  9.     end
  10.     else begin
  11.         case(STATE)
  12.             IDLE:begin
  13.                 if(I_W_udp_req & (~I_udp_ip_tbusy)) //当有写UDP请求,并且ip_tx模块不忙(当I_udp_ip_tbusy=1代表正在ip层正在传输数据)
  14.                     STATE   <=  WAIT_ACK;           //进入WAIT_ACK
  15.                 else
  16.                     STATE   <=  IDLE;
  17.             end
  18.             WAIT_ACK:begin
  19.                 if(I_udp_ip_tbusy)                  //如果ip_tx模块准备好,代表udp_layer可以发送数据
  20.                     STATE   <=  SEND_UDP_HEADER;
  21.                 else
  22.                     STATE   <=  WAIT_ACK;
  23.             end
  24.             SEND_UDP_HEADER:begin
  25.                 case(cnt)
  26.                     0   :begin
  27.                         if(I_W_udp_valid) begin
  28.                             O_udp_ip_tvalid     <=  1'b1;                   //udp包数据有效
  29.                             O_udp_ip_tdata      <=  I_udp_local_port[15:8]; //UDP报文源端口              
  30.                             O_udp_ip_tpkg_len   <=  I_W_udp_len + 16'h0008; //UDP报文长度,其中8bytes为udp首部      
  31.          
  32.                             cnt                 <=  cnt + 1'b1;
  33.                         end
  34.                         else
  35.                             cnt                 <=  0;
  36.                     end
  37.                     1   :begin
  38.                         O_udp_ip_tdata          <=  I_udp_local_port[7:0];  //UDP报文源端口
  39.                         cnt                     <=  cnt + 1'b1;
  40.                     end
  41.                     2   :begin
  42.                         O_udp_ip_tdata          <=  I_udp_dest_port[15:8];  //UDP报文目的端口
  43.                         cnt                     <=  cnt + 1'b1;
  44.                     end
  45.                     3   :begin
  46.                         O_udp_ip_tdata          <=  I_udp_dest_port[7:0];   //UDP报文目的端口
  47.                         cnt                     <=  cnt + 1'b1;
  48.                     end
  49.                     4   :begin
  50.                         O_udp_ip_tdata          <=  O_udp_ip_tpkg_len[15:8];//UDP报文长度
  51.                         cnt                     <=  cnt + 1'b1;
  52.                     end
  53.                     5   :begin
  54.                         O_udp_ip_tdata          <=  O_udp_ip_tpkg_len[7:0]; //UDP报文长度
  55.                         cnt                     <=  cnt + 1'b1;
  56.                     end
  57.                     6   :begin
  58.                         O_udp_ip_tdata          <=  CHECKSUM[7:0];          //校验和
  59.                         cnt                     <=  cnt + 1'b1;
  60.                     end
  61.                     7   :begin
  62.                         O_udp_ip_tdata          <=  CHECKSUM [7:0];         //校验和
  63.                         cnt                     <=  0;
  64.                         STATE                   <=  SEND_UDP_PACKET;
  65.                     end
  66.                     default: cnt    <=  0;
  67.                 endcase
  68.             end
  69.             SEND_UDP_PACKET:begin
  70.                 if(trans_data_cnt != (O_udp_ip_tpkg_len - 16'd8)) begin
  71.                     O_udp_ip_tvalid     <=  1'b1;
  72.                     O_udp_ip_tdata      <=  shift_data_out;
  73.                     trans_data_cnt      <=  trans_data_cnt + 1'b1;
  74.                     STATE               <=  SEND_UDP_PACKET;
  75.                 end
  76.                 else begin
  77.                     trans_data_cnt      <=  16'd0;
  78.                     O_udp_ip_tdata      <=  8'd0;
  79.                     O_udp_ip_tvalid     <=  1'b0;
  80.                     O_udp_ip_tpkg_len   <=  16'd0;
  81.                     cnt                 <=  0;
  82.                     STATE               <=  IDLE;
  83.                 end
  84.             end
  85.             default: STATE          <=  IDLE;
  86.         endcase
  87.     end
  88. end
复制代码

copycode.gif
copycode.gif
copycode.gif
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则