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

软件版本: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

由于IPARP数据包送至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 
15     input   wire                I_mac_rvalid,       //MAC接收到的数据有效信号
16     input   wire    [7:0]       I_mac_rdata,        //MAC接收的有效数据
17     input   wire    [15:0]      I_mac_rdata_type    //MAC接收到的帧类型
18 
19 );
20 reg                 ip_rx_data_valid;   //接收的有效IP信号
21 reg     [7:0]       ip_rx_data;         //接收的IP数据
22 reg                 arp_rx_data_valid;  //接收的有效ARP信号
23 reg     [7:0]       arp_rx_data;        //接收的有效ARP数据
24 
25 assign  O_ip_rvalid     =   ip_rx_data_valid;
26 assign  O_ip_rdata      =   ip_rx_data;
27 assign  O_arp_rvalid    =   arp_rx_data_valid;
28 assign  O_arp_rdata     =   arp_rx_data;
29 
30 localparam  ARP_TYPE    =   16'h0806;   //ARP包类型
31 localparam  IP_TYPE     =   16'h0800;   //IP 包类型
32 always@(posedge I_ip_arp_rclk or posedge I_ip_arp_reset) begin
33     if(I_ip_arp_reset) begin
34         ip_rx_data_valid    <=  1'b0;
35         ip_rx_data          <=  8'd0;
36         arp_rx_data_valid   <=  1'b0;
37         arp_rx_data         <=  8'd0;
38     end
39     else if(I_mac_rvalid) begin
40         if(I_mac_rdata_type == IP_TYPE) begin//IP包
41             ip_rx_data_valid    <=  1'b1;
42             ip_rx_data          <=  I_mac_rdata;
43         end
44         else if(I_mac_rdata_type == ARP_TYPE) begin//ARP包
45             arp_rx_data_valid   <=  1'b1;
46             arp_rx_data         <=  I_mac_rdata;
47         end
48         else begin
49             ip_rx_data_valid    <=  1'b0;
50             ip_rx_data          <=  8'd0;
51             arp_rx_data_valid   <=  1'b0;
52             arp_rx_data         <=  8'd0;
53         end
54     end
55     else begin
56         ip_rx_data_valid    <=  1'b0;
57         ip_rx_data          <=  8'd0;
58         arp_rx_data_valid   <=  1'b0;
59         arp_rx_data         <=  8'd0;
60     end
61 end
62 
63 endmodul

 

3.2.1 IP_ARP接收模块

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

 

3.2.2 IP_ARP发送模块

该模块接收IP层和ARP层传来的发送请求,通过busy信号与上层协议模块进行握手,来发送对应的数据。该模块的状态机转换图如图所示。

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