首页 > 编程语言 >[米联客-安路飞龙DR1-FPSOC] UDP通信篇连载-05 ARP层程序设计

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

时间:2024-08-09 18:55:23浏览次数:10  
标签:ARP arp UDP end cache begin mac 安路

软件版本: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.4 ARP层

该层具有接收ARP请求、发送ARP回复,和发送ARP请求、接收ARP回复的功能,并将接收到的对端的地址信息存入cache中。

3.4.1 ARP接收模块

该模块通过计数器接收28字节ARP信息字段。信息接收完成后,通过接收到的操作码判断接收到的数据包是ARP请求包还是ARP应答包。如果是应答包,将接收到的地址信息写入cache中;如果是请求包,判断目的IP地址与本地IP地址是否一致,若一致,将地址信息写入cache中,且发送至uiarp_rx模块,若不一致,则过滤该包。

if(OPER == ARP_REQUEST) begin//如果是ARP请求 ARP_REQUEST = 16'h0001(16'h01 ARP请求包 ; 16'h02 ARP应答)

                    if(TPA == I_ip_local_addr) begin        //比较接收到的ARP包里面的IP地址是否和本地IP地址一致

                        O_arp_req_ip_addr       <=  SPA;    //发送IP(远端源IP地址)

                        O_arp_req_mac_addr      <=  SHA;    //发送方MAC(远端源地址MAC)

                        O_arp_req_valid         <=  1'b1;   //设置ARP请求有效(通知发送ARP发送模块发送一个ARP应答给远端主机),保存远端主机的IP地址和MAC地址到cache

                        O_arp_reply_done        <=  1'b0;

                    end

                    else begin  

                        O_arp_req_ip_addr       <=  32'd0;

                        O_arp_req_mac_addr      <=  48'd0;

                        O_arp_req_valid         <=  1'b0;

                        O_arp_reply_done        <=  1'b0;

                    end

                end

3.4.2 ARP发送模块

该模块对ARP应答和ARP请求同时进行处理,首先对这两种逻辑进行仲裁,以避免发送冲突。如果既没有ARP应答也没有ARP请求,且内部ARP包发送逻辑非忙,则处理缓存的有效信号;如果只有ARP应答,没有ARP请求,且发送逻辑非忙,则请求发送ARP应答包,若发送逻辑忙,则将发送ARP应答包的请求缓存至reply_buffer_valid中,等待非忙时发出;如果只有ARP请求,没有ARP应答,且发送逻辑非忙,则请求发送ARP请求包,若发送逻辑忙,则将发送ARP请求包的请求缓存至request_buffer_valid中,等待非忙时发出;若ARP应答和ARP请求同时为高,则优先发送ARP请求,缓存ARP应答。

        case({I_arp_treq_en, I_arp_rreply_en})//本状态机实现了即便是同时有ARP应答或者ARP请求,都能确保完成发送

            2'b00:begin

                if((!O_arp_treq) && (!O_arp_tvalid)) begin//没有arp_treq请求,并且arp_tvalid为0 代表没有要发送的ARP数据

                    if(request_buffer_valid) begin//如果有未发送完的ARP请求,则继续发送

                        OPER                    <=  ARP_REQUEST;

                        TPA                     <=  ip_request_buffer;

                        THA                     <=  48'd0;

                        request_buffer_valid    <=  1'b0;//清除request_buffer_valid

                        O_arp_treq              <=  1'b1;

                    end

                    else if(reply_buffer_valid) begin//如果有未发送完的ARP应答,则继续发送

                        OPER                    <=  ARP_REPLY;

                        TPA                     <=  ip_reply_buffer;

                        THA                     <=  mac_reply_buffer;

                        reply_buffer_valid      <=  1'b0;//清除request_buffer_valid

                        O_arp_treq              <=  1'b1;                      

                    end

                end

            end

            2'b01:begin//发送ARP应答

                if((!O_arp_treq) && (!O_arp_tvalid)) begin

                    OPER                    <=  ARP_REPLY;

                    TPA                     <=  I_arp_rreply_ip_addr;

                    THA                     <=  I_arp_rreply_mac_addr;

                    O_arp_treq              <=  1'b1;  

                end

                else begin//需要arp应答

                    ip_reply_buffer         <=  I_arp_rreply_ip_addr;//寄存目的地址IP

                    mac_reply_buffer        <=  I_arp_rreply_mac_addr;//寄存目的地址MAC  

                    reply_buffer_valid      <=  1'b1;//需要发送ARP应答

                end

            end

            2'b10:begin//发送ARP请求,当ip_arp_tx发送IP包查询MAC没有查询到,执行ARP请求,请求远程主机提供MAC

                if((!O_arp_treq) && (!O_arp_tvalid)) begin

                    OPER                    <=  ARP_REQUEST;

                    TPA                     <=  I_arp_tip_addr;

                    THA                     <=  48'd0;

                    O_arp_treq              <=  1'b1;//ARP 发送              

                end

                else begin//arp请求包

                    ip_request_buffer       <=  I_arp_tip_addr;

                    request_buffer_valid    <=  1'b1;//ARP 请求有效标志

                end

            end

            2'b11:begin//既有ARP请求,又有ARP应答

                if((!O_arp_treq) && (!O_arp_tvalid)) begin

                    OPER                    <=  ARP_REQUEST;

                    TPA                     <=  I_arp_tip_addr;

                    THA                     <=  48'd0;

                    O_arp_treq              <=  1'b1;//ARP 发送

                end

                else begin

                    ip_request_buffer       <=  I_arp_tip_addr;

                    request_buffer_valid    <=  1'b1;//ARP请求有效

                end

                ip_reply_buffer         <=  I_arp_rreply_ip_addr;

                mac_reply_buffer        <=  I_arp_rreply_mac_addr;

                reply_buffer_valid      <=  1'b1;   //ARP应答有效

            end

        endcase

 

若O_arp_treq和uiip_arp_tx模块发送的I_arp_tbusy完成握手,则开始发送ARP包,并且通过判断ARP包的类型来确定发送的目的地址。通过计数器cnt发送28字节有效数据,再通过计数器pad_cnt在末尾补18个字节的0,即完成发送,开始等待下一次握手。

case(STATE)

            WAIT_BUFFER_READY:begin

                if(O_arp_treq && I_arp_tbusy) begin

                    O_arp_tdata     <=  HTYPE[15:8];    //硬件类型-以太网类型

                    O_arp_tvalid    <=  1'b1;           //ARP数据有效

                    cnt             <=  cnt + 1'b1;    

                    if(OPER == ARP_REQUEST) begin       //如果是ARP请求

                        O_arp_tdest_mac_addr    <=  48'hff_ff_ff_ff_ff_ff;  //ARP目的地址为广播地址

                        O_arp_ttype             <=  1'b1;                   //通知ip_arp_tx ARP类型为ARP请求

                    end

                    else begin

                        O_arp_tdest_mac_addr    <=  THA;

                        O_arp_ttype             <=  1'b0;       //通知ip_arp_tx ARP类型为ARP应答  

                    end

                    O_arp_treq      <=  1'b0;

                    STATE           <=  SEND_ARP_PACKET;

                end

                else

                    STATE           <=  WAIT_BUFFER_READY;

            end

            SEND_ARP_PACKET:begin

                case(cnt)

                    1:  begin   O_arp_tdata <=  HTYPE[7:0];                 cnt <= cnt + 1'b1;end

                    2:  begin   O_arp_tdata <=  PTYPE[15:8];                cnt <= cnt + 1'b1;end

                    3:  begin   O_arp_tdata <=  PTYPE[7:0];                 cnt <= cnt + 1'b1;end

                    4:  begin   O_arp_tdata <=  HLEN;                       cnt <= cnt + 1'b1;end

                    5:  begin   O_arp_tdata <=  PLEN;                       cnt <= cnt + 1'b1;end

                    6:  begin   O_arp_tdata <=  OPER[15:8];                 cnt <= cnt + 1'b1;end

                    7:  begin   O_arp_tdata <=  OPER[7:0];                  cnt <= cnt + 1'b1;end

                    8:  begin   O_arp_tdata <=  I_mac_local_addr[47:40];    cnt <= cnt + 1'b1;end

                    9:  begin   O_arp_tdata <=  I_mac_local_addr[39:32];    cnt <= cnt + 1'b1;end

                    10: begin   O_arp_tdata <=  I_mac_local_addr[31:24];    cnt <= cnt + 1'b1;end

                    11: begin   O_arp_tdata <=  I_mac_local_addr[23:16];    cnt <= cnt + 1'b1;end

                    12: begin   O_arp_tdata <=  I_mac_local_addr[15:8];     cnt <= cnt + 1'b1;end

                    13: begin   O_arp_tdata <=  I_mac_local_addr[7:0];      cnt <= cnt + 1'b1;end

                    14: begin   O_arp_tdata <=  I_ip_local_addr[31:24];     cnt <= cnt + 1'b1;end

                    15: begin   O_arp_tdata <=  I_ip_local_addr[23:16];     cnt <= cnt + 1'b1;end

                    16: begin   O_arp_tdata <=  I_ip_local_addr[15:8];      cnt <= cnt + 1'b1;end

                    17: begin   O_arp_tdata <=  I_ip_local_addr[7:0];       cnt <= cnt + 1'b1;end

                    18: begin   O_arp_tdata <=  THA[47:40];                 cnt <= cnt + 1'b1;end

                    19: begin   O_arp_tdata <=  THA[39:32];                 cnt <= cnt + 1'b1;end

                    20: begin   O_arp_tdata <=  THA[31:24];                 cnt <= cnt + 1'b1;end

                    21: begin   O_arp_tdata <=  THA[23:16];                 cnt <= cnt + 1'b1;end

                    22: begin   O_arp_tdata <=  THA[15:8];                  cnt <= cnt + 1'b1;end

                    23: begin   O_arp_tdata <=  THA[7:0];                   cnt <= cnt + 1'b1;end

                    24: begin   O_arp_tdata <=  TPA[31:24];                 cnt <= cnt + 1'b1;end

                    25: begin   O_arp_tdata <=  TPA[23:16];                 cnt <= cnt + 1'b1;end

                    26: begin   O_arp_tdata <=  TPA[15:8];                  cnt <= cnt + 1'b1;end

                    27: begin   O_arp_tdata <=  TPA[7:0];                   cnt <= cnt + 1'b1;end                  

                    28: begin

                        O_arp_tdata <=  8'd0;

                        if(pad_cnt == 5'd17) begin  //通过在末尾添加0以确保数据长度为46

                            cnt     <=  cnt + 1'b1;

                            pad_cnt <=  5'd0;

                        end

                        else begin

                            cnt     <=  cnt;

                            pad_cnt <=  pad_cnt + 1'b1;

                        end

                    end

                    29: begin

                        O_arp_tdata     <=  8'd0;

                        O_arp_tvalid    <=  1'b0;

                        O_arp_tdest_mac_addr    <=  48'd0;

                        O_arp_ttype     <=  1'b0;

                        cnt             <=  5'd0;

                        STATE           <=  WAIT_BUFFER_READY;

                    end

                    default:begin

                        O_arp_tdata     <=  8'd0;

                        O_arp_tvalid    <=  1'b0;

                        cnt             <=  5'd0;

                        STATE           <=  WAIT_BUFFER_READY;

                    end

                endcase

            end

        endcase

    end

end

3.4.3 CACHE模块

mac_cache模块相当于一个RAM,通过IP作为地址,写入或读出MAC地址。写入mac_cache模块的地址信息远程主机发送的ARP应答包或ARP请求包中的地址,在IP层发送UDP数据报文时,需要在mac_cache中读出和IP地址对应的MAC地址。

`timescale 1ns/1ps

module  mac_cache

(

    input   wire                I_wclk,

    input   wire                I_reset,

    input   wire                I_wen,

    input   wire    [31:0]      I_wip_addr,

    input   wire    [47:0]      I_wmac_addr,

 

    input   wire                I_rclk,

    input   wire                I_ren,

    input   wire    [31:0]      I_rip_addr,

    output  reg     [47:0]      O_rmac_addr,

    output  reg                 O_rmac_done

);

reg             mac_cache_flag      [0:3];

reg     [31:0]  ip_address_cache    [0:3];

reg     [47:0]  mac_address_cache   [0:3];

reg     [1:0]   index;

 

always@(posedge I_wclk or posedge I_reset) begin

    if(I_reset) begin

        mac_cache_flag[0]       <=  1'b0;

        ip_address_cache[0]     <=  32'd0;

        mac_address_cache[0]    <=  48'd0;

        mac_cache_flag[1]       <=  1'b0;

        ip_address_cache[1]     <=  32'd0;

        mac_address_cache[1]    <=  48'd0;

        mac_cache_flag[2]       <=  1'b0;

        ip_address_cache[2]     <=  32'd0;

        mac_address_cache[2]    <=  48'd0;

        mac_cache_flag[3]       <=  1'b0;

        ip_address_cache[3]     <=  32'd0;

        mac_address_cache[3]    <=  48'd0;

        index                   <=  2'd0;

    end

    else begin

        if(I_wen) begin

            if(mac_cache_flag[0] && ip_address_cache[0] == I_wip_addr)

                mac_address_cache[0]        <=  I_wmac_addr;

            else if(mac_cache_flag[1] && ip_address_cache[1] == I_wip_addr)

                mac_address_cache[1]        <=  I_wmac_addr;

            else if(mac_cache_flag[2] && ip_address_cache[2] == I_wip_addr)

                mac_address_cache[2]        <=  I_wmac_addr;

            else if(mac_cache_flag[3] && ip_address_cache[3] == I_wip_addr)

                mac_address_cache[3]        <=  I_wmac_addr;

            else begin

                mac_cache_flag[index]       <=  1'b1;

                ip_address_cache[index]     <=  I_wip_addr;

                mac_address_cache[index]    <=  I_wmac_addr;

                index                       <=  index + 1'b1;

            end

        end

        else begin

            mac_cache_flag[0]       <=  mac_cache_flag[0];

            ip_address_cache[0]     <=  ip_address_cache[0];        

            mac_address_cache[0]    <=  mac_address_cache[0];  

            mac_cache_flag[1]       <=  mac_cache_flag[1];      

            ip_address_cache[1]     <=  ip_address_cache[1];    

            mac_address_cache[1]    <=  mac_address_cache[1];  

            mac_cache_flag[2]       <=  mac_cache_flag[2];      

            ip_address_cache[2]     <=  ip_address_cache[2];        

            mac_address_cache[2]    <=  mac_address_cache[2];  

            mac_cache_flag[3]       <=  mac_cache_flag[3];      

            ip_address_cache[3]     <=  ip_address_cache[3];        

            mac_address_cache[3]    <=  mac_address_cache[3];  

        end

    end

end

 

always@(posedge I_rclk or posedge I_reset) begin

    if(I_reset) begin

        O_rmac_addr     <=  48'd0;

        O_rmac_done     <=  1'b0;

    end

    else begin

        if(I_ren) begin

            O_rmac_done     <=  1'b1;

            if(mac_cache_flag[0] && I_rip_addr == ip_address_cache[0])

                O_rmac_addr <=  mac_address_cache[0];

            else if(mac_cache_flag[1] && I_rip_addr == ip_address_cache[1])

                O_rmac_addr <=  mac_address_cache[1];

            else if(mac_cache_flag[2] && I_rip_addr == ip_address_cache[2])

                O_rmac_addr <=  mac_address_cache[2];

            else if(mac_cache_flag[3] && I_rip_addr == ip_address_cache[3])

                O_rmac_addr <=  mac_address_cache[3];

            else

                O_rmac_addr <=  48'd0;

        end

        else begin

            O_rmac_addr <=  O_rmac_addr;

            O_rmac_done <=  1'b0;

        end

    end

end

endmodule

标签:ARP,arp,UDP,end,cache,begin,mac,安路
From: https://www.cnblogs.com/milianke/p/18351343

相关文章

  • [米联客-安路飞龙DR1-FPSOC] UDP通信篇连载-06 UDP层程序设计
    软件版本:Anlogic-TD5.9.1-DR1_ES1.1操作系统:WIN1064bit硬件平台:适用安路(Anlogic)FPGA实验平台:米联客-MLK-L1-CZ06-DR1M90G开发板板卡获取平台:https://milianke.tmall.com/登录"米联客"FPGA社区http://www.uisrc.com视频课程、答疑解惑! 3.5UDP层该层实现用户数据和U......
  • [米联客-安路飞龙DR1-FPSOC] UDP通信篇连载-07 ICMP层程序设计
    软件版本:Anlogic-TD5.9.1-DR1_ES1.1操作系统:WIN1064bit硬件平台:适用安路(Anlogic)FPGA实验平台:米联客-MLK-L1-CZ06-DR1M90G开发板板卡获取平台:https://milianke.tmall.com/登录"米联客"FPGA社区http://www.uisrc.com视频课程、答疑解惑! 3.6ICMP层该层在程序中为IP层......
  • [米联客-安路飞龙DR1-FPSOC] UDP通信篇连载-01 以太网协议介绍
    软件版本:Anlogic-TD5.9.1-DR1_ES1.1操作系统:WIN1064bit硬件平台:适用安路(Anlogic)FPGA实验平台:米联客-MLK-L1-CZ06-DR1M90G开发板板卡获取平台:https://milianke.tmall.com/登录"米联客"FPGA社区http://www.uisrc.com视频课程、答疑解惑! ​1概述本文介绍了基于XILIN......
  • [米联客-安路飞龙DR1-FPSOC] UDP通信篇连载-02 MAC层程序设计
    软件版本:Anlogic-TD5.9.1-DR1_ES1.1操作系统:WIN1064bit硬件平台:适用安路(Anlogic)FPGA实验平台:米联客-MLK-L1-CZ06-DR1M90G开发板板卡获取平台:https://milianke.tmall.com/登录"米联客"FPGA社区http://www.uisrc.com视频课程、答疑解惑! 3程序设计前面我们介绍了以太......
  • [米联客-安路飞龙DR1-FPSOC] UDP通信篇连载-03 IP_ARP层程序设计
    软件版本:Anlogic-TD5.9.1-DR1_ES1.1操作系统:WIN1064bit硬件平台:适用安路(Anlogic)FPGA实验平台:米联客-MLK-L1-CZ06-DR1M90G开发板板卡获取平台:https://milianke.tmall.com/登录"米联客"FPGA社区http://www.uisrc.com视频课程、答疑解惑! 3.2IP_ARP层由于IP和ARP数据......
  • C# & Unity 面向对象补全计划 七大原则 之 合成/聚合复用原则( CARP)难度:☆☆☆☆ 总结:
    本文仅作学习笔记与交流,不作任何商业用途,作者能力有限,如有不足还请斧正本系列作为七大原则和设计模式的进阶知识,看不懂没关系请看专栏:http://t.csdnimg.cn/mIitr,查漏补缺1.合成/聚合复用原则(CARP)        合成/聚合复用原则就是在一个新的对象里面使用一些已有的......
  • 大神Andrej Karpathy亲授:大语言模型入门
    前言OpenAI大家熟知的技术大神有两位,一位是首席科学家Ilya,很多人这几天可能因为OpenAI董事会风波而反复听过这个名字;另外一位则是温文儒雅的AndrejKarpathy。如果说Ilya的标签是ChatGPT之父,神级大牛;那么AndrejKarpathy的额外标签则是当之无愧这世界上最优秀的AI导师之一。本......
  • 使用SixLabors.ImageSharp 进行图片的缩放C#.net core,可跨平台运行
    引用命令空间usingSixLabors.ImageSharp;using SixLabors.ImageSharp.Formats.Png;using SixLabors.ImageSharp.Processing; publicstaticvidResize(byte[]imageBytes,intwidth=400){usingvarsteam=newMemoryStream(imageBytes);using(varimage=......
  • [米联客-安路飞龙DR1-FPSOC] SDK入门篇连载-02 FPSoc程序固化入门
    软件版本:Anlogic-TD5.9.1-DR1_ES1.1操作系统:WIN1064bit硬件平台:适用安路(Anlogic)FPGA实验平台:米联客-MLK-L1-CZ06-DR1M90G开发板板卡获取平台:https://milianke.tmall.com/登录"米联客"FPGA社区http://www.uisrc.com视频课程、答疑解惑! 1概述在应用的调试过程中,我们......
  • [米联客-安路飞龙DR1-FPSOC] SDK入门篇连载-03 GPIO PS/PL实验
    软件版本:Anlogic-TD5.9.1-DR1_ES1.1操作系统:WIN1064bit硬件平台:适用安路(Anlogic)FPGA实验平台:米联客-MLK-L1-CZ06-DR1M90G开发板板卡获取平台:https://milianke.tmall.com/登录"米联客"FPGA社区http://www.uisrc.com视频课程、答疑解惑! 1概述本课对FPSoC芯片GPIO进......