FPGA RGMII 以太网接口之ARP

FPGA RGMII以太网接口之ARP

一、引言

RGMII(Reduced Gigabit Media Independent Interface)是一种用于连接以太网 MAC(Media Access Control)层和 PHY(Physical Layer)层的接口标准,通常用于实现千兆以太网通信。ARP(Address Resolution Protocol)是一种用于将 IP 地址解析为 MAC 地址的协议。

二、RGMII的基本配置及ARP协议

  1. 硬件配置
    确保硬件上 RGMII 接口正确连接,以太网 PHY 芯片正常工作,并且 MAC 层与 PHY 能够正常通信。通常需要配置以下几个信号:
    在这里插入图片描述

    RGMII 的时钟信号(TX_CLK, RX_CLK)。
    RGMII 的数据信号(TXD, RXD)。
    PHY 的配置寄存器(例如,自动协商模式、速度、双工模式等)。

  2. 以太网控制器驱动
    以太网控制器(MAC 层)需要正确初始化,并能够通过 RGMII 接口与 PHY 通信。通常需要完成以下工作:
    初始化 MAC 控制器。
    配置 MAC 地址。
    启用接收和发送功能。
    MAC帧协议

前同步码 分隔符 目的地址 源地址 长度/类型 数据/填充 校验字段
同步码7字节 分隔符1字节 目的地址6字节 源地址6字节 长度/类型2字节 数据/填充46~1500字节 校验字段4字节
  1. 实现 ARP 协议
    ARP 协议的核心功能是将 IP 地址解析为 MAC 地址。以下是实现 ARP 的基本步骤:
    (1) ARP 报文格式
    ARP 报文的格式如下:
    硬件类型(2 字节):例如以太网为 0x0001。
    协议类型(2 字节):例如 IPv4 为 0x0800。
    硬件地址长度(1 字节):例如 MAC 地址长度为 6。
    协议地址长度(1 字节):例如 IPv4 地址长度为 4。
    操作码(2 字节):例如 ARP 请求为 1,ARP 应答为 2。
    发送方 MAC 地址(6 字节)。
    发送方 IP 地址(4 字节)。
    目标 MAC 地址(6 字节)。
    目标 IP 地址(4 字节)。
    (2) 发送 ARP 请求
    当需要解析一个 IP 地址时,发送 ARP 请求:
    构造 ARP 请求报文。
    将目标 MAC 地址设置为广播地址(FF:FF:FF:FF:FF:FF)。
    通过以太网控制器发送报文。
    (3) 接收 ARP 应答
    当接收到 ARP 应答时:
    解析 ARP 报文,提取目标 IP 地址和对应的 MAC 地址。
    将 IP-MAC 映射存储到 ARP 缓存表中。
    (4) 处理 ARP 请求
    当接收到 ARP 请求时:
    检查目标 IP 地址是否为本机 IP 地址。
    如果是,则构造 ARP 应答报文并发送。

三、工作原理图

在这里插入图片描述

四、ARP应用层软件代码

// ARP 报文结构
typedef struct {
   
    uint16_t hw_type;
    uint16_t proto_type;
    uint8_t hw_len;
    uint8_t proto_len;
    uint16_t opcode;
    uint8_t sender_mac[6];
    uint8_t sender_ip[4];
    uint8_t target_mac[6];
    uint8_t target_ip[4];
} arp_packet_t;

// 发送 ARP 请求
void send_arp_request(uint8_t *target_ip) {
   
    arp_packet_t arp_request;
    // 填充 ARP 请求报文
    arp_request.hw_type = htons(0x0001); // 以太网
    arp_request.proto_type = htons(0x0800); // IPv4
    arp_request.hw_len = 6;
    arp_request.proto_len = 4;
    arp_request.opcode = htons(1); // ARP 请求
    memcpy(arp_request.sender_mac, my_mac, 6);
    memcpy(arp_request.sender_ip, my_ip, 4);
    memset(arp_request.target_mac, 0xFF, 6); // 广播地址
    memcpy(arp_request.target_ip, target_ip, 4);
    // 发送 ARP 请求
    ethernet_send((uint8_t *)&arp_request, sizeof(arp_packet_t));
}

// 处理接收到的 ARP 报文
void handle_arp_packet(uint8_t *packet) {
   
    arp_packet_t *arp_pkt = (arp_packet_t *)packet;
    if (ntohs(arp_pkt->opcode) == 1) {
    // ARP 请求
        if (memcmp(arp_pkt->target_ip, my_ip, 4) == 0) {
   
            // 发送 ARP 应答
            arp_packet_t arp_reply;
            arp_reply.hw_type = htons(0x0001);
            arp_reply.proto_type = htons(0x0800);
            arp_reply.hw_len = 6;
            arp_reply.proto_len = 4;
            arp_reply.opcode = htons(2); // ARP 应答
            memcpy(arp_reply.sender_mac, my_mac, 6);
            memcpy(arp_reply.sender_ip, my_ip, 4);
            memcpy(arp_reply.target_mac, arp_pkt->sender_mac, 6);
            memcpy(arp_reply.target_ip, arp_pkt->sender_ip, 4);
            ethernet_send((uint8_t *)&arp_reply, sizeof(arp_packet_t));
        }
    } else if (ntohs(arp_pkt->opcode) == 2) {
    // ARP 应答
        // 将 IP-MAC 映射存储到 ARP 缓存表
        arp_cache_add(arp_pkt->sender_ip, arp_pkt->sender_mac);
    }
}

五、FPGA实现与仿真

(1)实现代码分为发送和接收两个模

module arp(
    input                rst_n      , //复位信号,低电平有效
    //GMII接口
    input                gmii_rx_clk, //GMII接收数据时钟
    input                gmii_rx_dv , //GMII输入数据有效信号
    input        [7:0]   gmii_rxd   , //GMII输入数据
    input                gmii_tx_clk, //GMII发送数据时钟
    output               gmii_tx_en , //GMII输出数据有效信号
    output       [7:0]   gmii_txd   , //GMII输出数据          

    //用户接口
    output               arp_rx_done, //ARP接收完成信号
    output               arp_rx_type, //ARP接收类型 0:请求  1:应答
    output       [47:0]  src_mac    , //接收到目的MAC地址
    output       [31:0]  src_ip     , //接收到目的IP地址    
    input                arp_tx_en  , //ARP发送使能信号
    input                arp_tx_type, //ARP发送类型 0:请求  1:应答
    input        [47:0]  des_mac    , //发送的目标MAC地址
    input        [31:0]  des_ip     , //发送的目标IP地址
    output               tx_done      //以太网发送完成信号    
    );

//parameter define
//开发板MAC地址 00-11-22-33-44-55
parameter BOARD_MAC = 48'h00_11_22_33_44_55;    
//开发板IP地址 192.168.1.10 
parameter BOARD_IP  = {
   8'd192,8'd168,8'd1,8'd10};   
//目的MAC地址 ff_ff_ff_ff_ff_ff
parameter  DES_MAC   = 48'hff_ff_ff_ff_ff_ff;
//目的IP地址 192.168.1.102     
parameter  DES_IP    = {
   8'd192,8'd168,8'd1,8'd102};

//wire define
wire           crc_en  ; //CRC开始校验使能
wire           crc_clr ; //CRC数据复位信号 
wire   [7:0]   crc_d8  ; //输入待校验8位数据
wire   [31:0]  crc_data; //CRC校验数据
wire   [31:0]  crc_next; //CRC下次校验完成数据

//*****************************************************
//**                    main code
//*****************************************************

assign  crc_d8 = gmii_txd;

//ARP接收模块    
arp_rx 
   #(
    .BOARD_MAC       (BOARD_MAC),         //参数例化
    .BOARD_IP        (BOARD_IP )
    )
   u_arp_rx(
    .clk             (gmii_rx_clk),
    .rst_n           (rst_n),

    .gmii_rx_dv      (gmii_rx_dv),
    .gmii_rxd        (gmii_rxd  ),
    .arp_rx_done     (arp_rx_done),
    .arp_rx_type     (arp_rx_type),
    .src_mac         (src_mac    ),
    .src_ip          (src_ip     )
    );                                           

//ARP发送模块
arp_tx
   #(
    .BOARD_MAC       (BOARD_MAC),         //参数例化
    .BOARD_IP        (BOARD_IP ),
    .DES_MAC         (DES_MAC  ),
    .DES_IP          (DES_IP   )
    )
   u_arp_tx(
    .clk             (gmii_tx_clk),
    .rst_n           (rst_n
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值