[X]关闭

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

文档创建者:FPGA课程
浏览次数:199
最后更新:2024-08-09
文档课程分类-安路-DR1
安路-DR1: FPSOC-DR1-FPGA部分 » 2_FPGA实验篇(仅旗舰) » 4-FPGA UDP通信
软件版本: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.2 IP_ARP
由于IP和ARP数据包送至MAC层要经过同一个通道,需要对发送的数据包类型进行判断和仲裁,这就需要额外增加一个IP_ARP层。
  1. /*******************************uiip_arp_rx模块*********************
  2. --以下是米联客设计的uiip_arp_rx模块
  3. 1.该模块1用于区分接收数据是IP包还是ARP包
  4. *********************************************************************/
  5. `timescale 1ns/1ps
  6. module  uiip_arp_rx
  7. (
  8.     input   wire                I_ip_arp_reset,     //复位
  9.     input   wire                I_ip_arp_rclk,      //RX 接收时钟
  10.     output  wire                O_ip_rvalid,        //接收的有效IP信号
  11.     output  wire    [7:0]       O_ip_rdata,         //接收的IP数据
  12.     output  wire                O_arp_rvalid,       //接收的有效ARP信号
  13.     output  wire    [7:0]       O_arp_rdata,        //接收的有效ARP数据

  14.     input   wire                I_mac_rvalid,       //MAC接收到的数据有效信号
  15.     input   wire    [7:0]       I_mac_rdata,        //MAC接收的有效数据
  16.     input   wire    [15:0]      I_mac_rdata_type    //MAC接收到的帧类型

  17. );
  18. reg                 ip_rx_data_valid;   //接收的有效IP信号
  19. reg     [7:0]       ip_rx_data;         //接收的IP数据
  20. reg                 arp_rx_data_valid;  //接收的有效ARP信号
  21. reg     [7:0]       arp_rx_data;        //接收的有效ARP数据

  22. assign  O_ip_rvalid     =   ip_rx_data_valid;
  23. assign  O_ip_rdata      =   ip_rx_data;
  24. assign  O_arp_rvalid    =   arp_rx_data_valid;
  25. assign  O_arp_rdata     =   arp_rx_data;

  26. localparam  ARP_TYPE    =   16'h0806;   //ARP包类型
  27. localparam  IP_TYPE     =   16'h0800;   //IP 包类型
  28. always@(posedge I_ip_arp_rclk or posedge I_ip_arp_reset) begin
  29.     if(I_ip_arp_reset) begin
  30.         ip_rx_data_valid    <=  1'b0;
  31.         ip_rx_data          <=  8'd0;
  32.         arp_rx_data_valid   <=  1'b0;
  33.         arp_rx_data         <=  8'd0;
  34.     end
  35.     else if(I_mac_rvalid) begin
  36.         if(I_mac_rdata_type == IP_TYPE) begin//IP包
  37.             ip_rx_data_valid    <=  1'b1;
  38.             ip_rx_data          <=  I_mac_rdata;
  39.         end
  40.         else if(I_mac_rdata_type == ARP_TYPE) begin//ARP包
  41.             arp_rx_data_valid   <=  1'b1;
  42.             arp_rx_data         <=  I_mac_rdata;
  43.         end
  44.         else begin
  45.             ip_rx_data_valid    <=  1'b0;
  46.             ip_rx_data          <=  8'd0;
  47.             arp_rx_data_valid   <=  1'b0;
  48.             arp_rx_data         <=  8'd0;
  49.         end
  50.     end
  51.     else begin
  52.         ip_rx_data_valid    <=  1'b0;
  53.         ip_rx_data          <=  8'd0;
  54.         arp_rx_data_valid   <=  1'b0;
  55.         arp_rx_data         <=  8'd0;
  56.     end
  57. end

  58. endmodule
复制代码
3.2.1 IP_ARP接收模块
该模块接收到MAC帧经过MAC层解包得到的数据包,通过类型字段判断该包是IP包还是ARP包,将其送入对应的模块中处理。

3.2.2 IP_ARP发送模块
该模块接收IP层和ARP层传来的发送请求,通过busy信号与上层协议模块进行握手,来发送对应的数据。该模块的状态机转换图如图所示。
2504661-20240809185320330-1380674520.jpg
IDLE:如果是IP层发送的请求,且arp_req_pend信号没有挂起时,进入CHECK_MAC_CACHEE状态,进入ARP层查询mac_cache中缓存的MAC地址。如果是ARP层发送的请求,在MAC层非忙时,将arp_tbusy拉高,表示可以发送ARP包,进入WAIT_ARP_PACKET状态。
CHECK_MAC_CACHE:若没有查询到IP地址对应的MAC地址,则使能O_arp_treq_en信号,请求ARP层发送ARP广播包,并且将arp_req_pend挂起(该信号挂起时不能发送IP包),回到IDLE状态,等待ARP层发送请求信号。若查询到MAC地址,进入WAIT_IP_PACKET状态,等待IP层将有效数据发送过来。
WAIT_IP_PACKET:若I_ip_valid拉高,说明IP包有效数据开始传入,接收传来的数据并将其发送至MAC层,进入SEND_IP_PACKET状态。
SEND_IP_PACKET:等待一帧IP包数据全部发送完成时,回到IDLE状态。
WAIT_ARP_PACKET:I_arp_valid拉高,说明ARP包有效数据开始传入,接收传来的数据并将其发送至MAC层,进入SEND_ARP_PACKET状态。
SEND_ARP_PACKET:如果发送的数据包是ARP应答包,数据全部发送完成时,回到IDLE状态。如果发送的数据包是ARP请求包,则要进入SEND_ARP_REPLY状态,等待接收到对方发送ARP应答包。
SEND_ARP_REPLY:接收到ARP应答包后,将arp_req_pend信号拉低,回到IDLE状态。若超时未收到应答,则回到IDLE状态,此时由于arp_req_pend信号一直为高,该模块会持续发送ARP请求直至收到应答。
  1. always@(posedge I_ip_arp_clk or posedge I_ip_arp_reset)begin
  2.     if(I_ip_arp_reset) begin
  3.         O_mac_cache_ren         <=  1'b0;   //查询MAC cache
  4.         O_mac_cache_rip_addr    <=  32'd0;  //查询MAC cache地址
  5.         O_arp_tbusy             <=  1'b0;   //ip_arp_tx arp 发送准备好   
  6.         O_arp_treq_en           <=  1'b0;   //ip_arp_tx arp请求发送ARP包(当发送IP包,没有找打cache中的MAC的时候发送)
  7.         O_arp_treq_ip_addr      <=  32'd0;  //ARP可以发送模块通过发送带有目的IP地址的ARP请求,获取目的远程主机的MAC地址
  8.         
  9.         O_ip_tbusy              <=  1'b0;   //ip_arp_tx可以发送IP包

  10.         O_mac_tdata_type        <=  2'd0;   //MAC发送数据类型
  11.         O_mac_tvalid            <=  1'b0;   //MAC发送数据有效
  12.         O_mac_tdata             <=  8'd0;   //MAC发送数据
  13.         O_mac_tdest_addr        <=  48'd0;  //MAC发送地址

  14.         tmac_addr_temp          <=  48'd0;
  15.         arp_req_pend            <=  1'b0;
  16.         dst_ip_unreachable      <=  1'b0;
  17.         arp_wait_time           <=  30'd0;
  18.         STATE                   <=  IDLE;
  19.     end
  20.     else begin
  21.         case(STATE)
  22.             IDLE:begin
  23.                 O_arp_treq_en   <=  1'b0;
  24.                 if(!I_mac_tbusy) begin//MAC层不忙
  25.                     if(I_arp_treq) begin//是否有ARP请求
  26.                         O_arp_tbusy             <=  1'b1;           //可以发送ARP包
  27.                         O_ip_tbusy              <=  1'b0;
  28.                         STATE                   <=  WAIT_ARP_PACKET;//等待ARP响应
  29.                     end
  30.                     else if(I_ip_treq && ~arp_req_pend) begin   //如果是IP请求,并且之前的ARP请求没有pend
  31.                         O_arp_tbusy             <=  1'b0;
  32.                         O_ip_tbusy              <=  1'b0;
  33.                         O_mac_cache_ren         <=  1'b1;               //如果是IP请求,先从mac cache通过IP地址获取MAC地址
  34.                         O_mac_cache_rip_addr    <=  I_ip_tdest_addr;    //通过IP地址查询MAC cache
  35.                         STATE                   <=  CHECK_MAC_CACHE;   
  36.                     end
  37.                     else begin
  38.                         O_arp_tbusy             <= 1'b0;
  39.                         O_ip_tbusy              <= 1'b0;                        
  40.                         STATE                   <= IDLE;                        
  41.                     end
  42.                 end
  43.                 else begin
  44.                     O_arp_tbusy             <= 1'b0;
  45.                     O_ip_tbusy              <= 1'b0;
  46.                     O_mac_cache_ren         <= 1'b0;
  47.                     O_mac_cache_rip_addr    <= 48'd0;
  48.                     STATE                   <= IDLE;
  49.                 end
  50.             end
  51.             CHECK_MAC_CACHE:begin//查询MAC cache,如果没有查到MAC会请求ARP层发送ARP请求
  52.                 O_mac_cache_ren         <=  1'b0;
  53.                 if(I_mac_cache_rdone) begin                     //MAC cache查询完成
  54.                     if(I_mac_cache_rdest_addr == 48'd0) begin   //如果没有查询到对应的MAC,请求ARP层发送ARP请求
  55.                         O_arp_treq_en           <=  1'b1;       //请求ARP层发送ARP
  56.                         O_ip_tbusy              <=  1'b0;
  57.                         O_arp_treq_ip_addr      <=  O_mac_cache_rip_addr;   //如果没有查询到MAC需要根据提供的IP地址请求ARP层发送ARP包获取MAC
  58.                         arp_req_pend            <=  1'b1;                   //arp请求Pend结束前不处理其他的arp请求
  59.                         STATE                   <=  IDLE;                   //回到IDLE状态,等待ARP层发送ARP包
  60.                     end
  61.                     else begin
  62.                         tmac_addr_temp          <=  I_mac_cache_rdest_addr; //从MAC cache查询到MAC地址
  63.                         O_ip_tbusy              <=  1'b1;                   //返回IP层的ACK
  64.                         O_arp_treq_en           <=  1'b0;
  65.                         arp_req_pend            <=  1'b0;
  66.                         STATE                   <=  WAIT_IP_PACKET;
  67.                     end
  68.                 end
  69.                     else
  70.                         STATE                   <=  CHECK_MAC_CACHE;
  71.             end
  72.             WAIT_ARP_REPLY:begin//等待远程主机的ARP响应(ARP层的recieve模块会接收到ARP响应)
  73.                 if(I_arp_treply_done) begin//响应
  74.                     arp_req_pend            <=  1'b0;
  75.                     arp_wait_time           <=  30'd0;
  76.                     dst_ip_unreachable      <=  1'b0;
  77.                     STATE                   <=  IDLE;
  78.                 end
  79.                 else begin
  80.                     if(arp_wait_time == ARP_TIMEOUT_VALUE) begin//超时,未收到响应
  81.                         arp_req_pend            <=  1'b1;
  82.                         O_arp_tbusy             <=  1'b0;
  83.                         O_arp_treq_en           <=  1'b1;
  84.                         O_arp_treq_ip_addr      <=  I_ip_tdest_addr;
  85.                         dst_ip_unreachable      <=  1'b1;
  86.                         arp_wait_time           <=  30'd0;
  87.                         STATE                   <=  IDLE;                       
  88.                     end
  89.                     else begin
  90.                         arp_req_pend            <=  1'b1;
  91.                         O_arp_tbusy             <=  1'b1;
  92.                         dst_ip_unreachable      <=  1'b0;
  93.                         arp_wait_time           <=  arp_wait_time + 1'b1;
  94.                         STATE                   <=  WAIT_ARP_REPLY;
  95.                     end
  96.                 end
  97.             end
  98.             WAIT_ARP_PACKET:begin//ARP包有效,打拍后直接输出给MAC层  
  99.                 if(I_arp_tvalid) begin
  100.                     O_mac_tdata_type        <=  {1'b1,I_arp_tdata_type};//2'b10:arp reply; 2'b11:arp request ;2'b01 ip
  101.                     O_mac_tvalid            <=  1'b1;
  102.                     O_mac_tdata             <=  I_arp_tdata;
  103.                     O_mac_tdest_addr        <=  I_arp_tdest_mac_addr;
  104.                     STATE                   <=  SEND_ARP_PACKET;
  105.                 end
  106.                 else begin
  107.                     O_mac_tdata_type        <=  2'd0;
  108.                     O_mac_tvalid            <=  1'b0;
  109.                     O_mac_tdata             <=  8'd0;
  110.                     O_mac_tdest_addr        <=  48'd0;
  111.                     STATE                   <=  WAIT_ARP_PACKET;                    
  112.                 end
  113.             end
  114.             SEND_ARP_PACKET:begin       //继续打拍后输出给MAC层
  115.                 if(I_arp_tvalid) begin  //如果ARP包有效
  116.                     O_mac_tvalid            <=  1'b1;
  117.                     O_mac_tdata             <=  I_arp_tdata;
  118.                     STATE                   <=  SEND_ARP_PACKET;                    
  119.                 end
  120.                 else begin
  121.                     O_arp_tbusy             <=  1'b0;
  122.                     O_mac_tdata_type        <=  2'd0;
  123.                     O_mac_tvalid            <=  1'b0;
  124.                     O_mac_tdata             <=  8'd0;
  125.                     O_mac_tdest_addr        <=  48'd0;
  126.                     if(arp_req_pend)    //如果该信号有效,代表IP层发送IP包的时候没有从本地cache查询到MAC地址,而发送的ARP请求包,因此下一步等待远程主机发送ARP响应
  127.                         STATE               <=  WAIT_ARP_REPLY;
  128.                     else
  129.                         STATE               <=  IDLE;   //如果是单纯的ARP层发送的包,到此结束           
  130.                 end
  131.             end
  132.             WAIT_IP_PACKET:begin    //IP包的传输   
  133.                 if(I_ip_tvalid) begin
  134.                     O_mac_tdata_type        <=  2'b01;
  135.                     O_mac_tvalid            <=  1'b1;
  136.                     O_mac_tdata             <=  I_ip_tdata;
  137.                     O_mac_tdest_addr        <=  tmac_addr_temp;
  138.                     STATE                   <=  SEND_IP_PACKET;
  139.                 end
  140.                 else begin         
  141.                     O_mac_tdata_type        <=  2'd0;
  142.                     O_mac_tvalid            <=  1'b0;
  143.                     O_mac_tdata             <=  8'd0;
  144.                     O_mac_tdest_addr        <=  48'd0;
  145.                     STATE                   <=  WAIT_IP_PACKET;
  146.                 end
  147.             end
  148.             SEND_IP_PACKET:begin    //IP包的传输
  149.                 if(I_ip_tvalid) begin
  150.                     O_mac_tvalid            <=  1'b1;
  151.                     O_mac_tdata             <=  I_ip_tdata;
  152.                     STATE                   <=  SEND_IP_PACKET;
  153.                 end
  154.                 else begin
  155.                     O_ip_tbusy              <= 1'b0;
  156.                     O_mac_tdata_type        <= 2'd0;
  157.                     O_mac_tvalid            <= 1'b0;
  158.                     O_mac_tdata             <= 8'd0;
  159.                     O_mac_tdest_addr        <= 48'd0;
  160.                     STATE                   <= IDLE;                    
  161.                 end
  162.             end
  163.         endcase
  164.     end
  165. end
复制代码
copycode.gif
copycode.gif
copycode.gif
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则