精华内容
下载资源
问答
  • 本实验将实现视频图像的以太网传输,也相当于用用黑金的 500 万摄像头 AN5642输出。以太网传输用 Ethernet UDP网口的 UDP 数据包,提取 JP FIFO 模块用于存储摄像头 OV5640数据包的长度时,触发一次 UDP 实验时AX...
  • 千兆以太网传输

    2016-04-14 20:40:25
    对当前千兆以太网的研究进行了调研
  • 【VS开发】千兆以太网传输速度

    千次阅读 2016-03-03 23:45:34
    千兆以太网络技术早在上世纪90年代末就已成熟,其中,1995年国际标准化组织TIA/EIA颁布了1000Base-TX标准,该标准的目的是把双绞线用于千兆以太网中,其目的是在6类非屏蔽双绞线(UTP)上以1000Mbps速率传输100米。...

    千兆以太网主流标准

    千兆以太网络技术早在上世纪90年代末就已成熟,其中,1995年国际标准化组织TIA/EIA颁布了1000Base-TX标准,该标准的目的是把双绞线用于千兆以太网中,其目的是在6类非屏蔽双绞线(UTP)上以1000Mbps速率传输100米。1000Base-TX基于4对双绞线,采用快速以太网中与100Base-TX标准类似的传输机制,是以两对线发送,两对线接收。由于每对线缆本身不进行双向的传输,线缆之间的串扰就大大降低,信号频率为250MHz,使用8B/10B编码方式,使用RJ-45连接器。

    展开全文
  • Verilog实现千兆以太网传输

    千次阅读 多人点赞 2018-07-16 10:00:28
    1本实验将实现 FPGA 芯片和 PC 之间进行千兆以太网数据通信, 通信协议采用 Ethernet UDP 通信协议。 FPGA 通过 GMII 总线和开发板上的 Gigabit PHY 芯片通信, Gigabit PHY芯片把数据通过网线发给 PC。在上次的实验...

    1

    本实验将实现 FPGA 芯片和 PC 之间进行千兆以太网数据通信, 通信协议采用 Ethernet  UDP 通信协议。 FPGA 通过 GMII 总线和开发板上的 Gigabit PHY 芯片通信, Gigabit PHY芯片把数据通过网线发给 PC。在上次的实验中,我们详细讲解了网络传输的过程中如何对数据进行传输,以及数据传输的格式,这次实验中,我们详细讲解如何使用Verilog语言来实现将UDP数据的发送。

    以太网数据通信的示意图如下:

    这里我再展示数据传输的格式图片。


      其中数据包括三个方面的内容:IPv4数据包头,UDP包头,和用户数据。

    IPv4数据包头:

    UDP数据包头。


    2


       AX515/AX530开发板我们采用了Realtek千兆GPHY芯片RTL8211E 来实现千兆以太网数据通信。当网口 Link 到千兆以太网时, FPGA 通过 GMII 总线和 PHY 芯片进行数据通信,当网口 Link 到百兆以太网时, PGA 通过 MII 总线和 PHY 芯片进行数据通信。 另外 FPGA 可以通过 MDI/MDIO 管理接口来配置或读取 PHY 芯片内部的寄存器。

    本实验以千兆以太网 GMII 通信为例来设计 verilog 程序。整个Ethernet_test测试是一个顶层模块,UDP发送模块。我们要发送的数据为Hello World。

    首先我们先实现UDP模块。 UDP模块包括UDP发送模块和CRC校验模块。RTL电路示意图:

     Ipsend模块是UDP发送模块。各个引脚的解释请看各个模块的Verilog代码。代码在下面。UDP发送顶层模块。



    UDP发送数据模块。









     UDP 发送模块实现把 RAM 里的数据组成 UDP IP 包格式通过 GMII 总线发给 PHY 芯片,PHY 芯片再把数据发送到开发板的网口。

    IP 数据包发送之前需要先发送 IP 数据包的包头,IP 包头由 8 个字节的前导码, 目标 MAC Address,源 MAC 地址和两个字节的 IP 包类型组成。前导码是由 7 个 0x55, 1个 0xD5 字节组成, 表示一个IP数据包传输的开始; 目标MAC Address为数据要发送对象的MAC地址,如果开发板的网口是和您的 PC 机相连, 那目标 MAC Address的值为你 PC 机的 MAC 地址。源 MAC Address 是指开发板本地的 MAC 地址。IP 包类型值为 0x0800。

    发完 IP 包头之后开始发送 IP 数据报首部,IP 数据报首部的格式我们在前面已经讲过,接着发送 ram中的数据,最后发送 4 个字节的 CRC32 的值。

    CRC模块我们不把代码贴出来了,请到最后我提供的链接进行下载。

    Ethernet顶层测试模块。





    Ethernet顶层设计模块是首先将发送的数据写进ram中,此时ram作为一个缓存,每次发送数据的时候首先需要去读取ram中的数据,将读取ram中的数据读入UDP模块中,然后进行按照数据发送的格式进行发送,每次发送的一帧数据即为Hello World。即为12字节。

    3


    实验结果:



    通过wireshark软件我们抓取Ethernet网络的数据,在wireshark抓包窗口我们可以看到开发板(192.168.0.2)向PC网口(192.168.0.2)发来的数据包,这里会显示数据包的目标MAC, 源MAC,IP包头和UDP包等信息。

    千兆以太网的数据传输速度非常快,而且是全双工传输,通过环路测试,UDP 通信的数据速度可以达到 900Mbps 以上,非常适合高速数据传输的场合,比如视频图像传输,高速数据采集等等。

      注意:以太网的数据帧的传输有包长的要求, 一般在46~1500字节。所以在发送以太网数据包的时候,数据帧的长度不能太短, 不然会导致PC数据包发送而FPGA收不到数据包的情况。

      工程链接地址:链接:http://pan.baidu.com/s/1geWb771 密码:64wf



    展开全文
  • 绍了千兆以太网接口以及TCP/IP协议,提出了几种设计方案,讲述了一种使用FPGA和MAC软核建立千兆以太网的方法。实验证明,这种方法稳定性好、传输带宽高、额外成本低,适用于大多数高速数据传输系统,是一种成本低、...
  • FPGA 千兆以太网 图像传输 OV5640 Quarter II 13.1
  • 目前,随着多媒体应用的普及,千兆以太网已经发展成为主流网络技术。大到成千上万人的大型企业,小到几十人的中小型企业,在建设企业局域网时都会把千兆以太网技术作为的高速网络技术。千兆以太网技术甚至正在...
  • 基于FPGA的千兆以太网CMOS图像数据传输系统设计
  • 利用黑金开发板和黑金以太网模块整合的一个以太网通信的程序,可以自己修改MAC,已验证可以实现功能
  • 针对现今迅速发展的互联网技术,以及以太网数据采集、传输等应用,本文提出了一种基于ZYNQ的千兆以太网数据包处理架构。通过对以太网数据包进行分类,交由不同模块处理从而提高了处理能力。将所提出的架构应用于实际...
  • 本实验将实现FPGA芯片和PC之间进行千兆以太网数据通信, 通信协议采用Ethernet UDP通信协议。 FPGA通过RGMII总线和开发板上的Gigabit PHY芯片通信, Gigabit PHY芯片把数据通过网线发给PC,程序中实现了ARP,UDP,PING...

    本原创教程由芯驿电子科技(上海)有限公司(ALINX)创作,版权归本公司所有,如需转载,需授权并注明出处(http://www.alinx.com)。

    适用于板卡型号:

    PGL22G

    1. 简介

    本实验将实现FPGA芯片和PC之间进行千兆以太网数据通信, 通信协议采用Ethernet UDP通信协议。 FPGA通过RGMII总线和开发板上的Gigabit PHY芯片通信, Gigabit PHY芯片把数据通过网线发给PC,程序中实现了ARP,UDP,PING功能,此外还实现了100/1000M自适应。

    2. 硬件介绍

    在开发板上通过1片RTL8211EG以太网PHY芯片为用户提供网络通信服务。以太网PHY芯片是连接到Pango FPGA的IO接口上。芯片支持10/100/1000 Mbps网络传输速率,通过RGMII接口跟FPGA进行数据通信。RTL8211EG支持MDI/MDX自适应,各种速度自适应,Master/Slave自适应,支持MDIO总线进行PHY的寄存器管理。当网口Link到千兆以太网时, FPGA通过RGMII总线和PHY芯片进行数据通信,当网口Link到百兆以太网时, FPGA通过MII总线和PHY芯片进行数据通信。另外FPGA可以通过MDI/MDIO管理接口来配置或读取PHY芯片内部的寄存器。在千兆的RGMII通信模式下(以U8为例), 发送数据时,发送时钟为125Mhz的E_GTXC信号, 数据为E_TXD[3:0], 数据有效信号为E_TXEN, E_TXC信号连接但没有使用; 接收数据时,接收时钟为125Mhz的E_RXC信号, 数据为E_RXC[3:0], 数据有效信号为E_RXDV。关于详细的管脚说明和RGMII/MII的通信时序,请大家参考RTL8211EG的芯片手册。

    硬件电路设计如下:

     

    开发板网络部分电路

    关于详细的管脚说明和RGMII的通信时序,请大家参考相关芯片手册。

    3. 以太网帧

    3.1 以太网帧格式

    下图为以太网的帧格式:

    前导码(Preamble):8字节,连续7个8’h55加1个8’hd5,表示一个帧的开始,用于双方设备数据的同步。

    目的MAC地址:6字节,存放目的设备的物理地址,即MAC地址

    源MAC地址:6字节,存放发送端设备的物理地址

    类型:2字节,用于指定协议类型,常用的有0800表示IP协议,0806表示ARP协议,8035

    表示RARP协议

    数据:46到1500字节,最少46字节,不足需要补全46字节,例如IP协议层就包含在数据

    部分,包括其IP头及数据。

    FCS:帧尾,4字节,称为帧校验序列,采用32位CRC校验,对目的MAC地址字段到数据字

    段进行校验。

    进一步扩展,以UDP协议为例,可以看到其结构如下,除了以太网首部的14字节,数据部分包含IP首部,UDP首部,应用数据共46~1500字节。

    3.2 ARP数据报格式

    ARP地址解析协议,即ARP(Address Resolution Protocol),根据IP地址获取物理地址。主机发送包含目的IP地址的ARP请求广播(MAC地址为48’hff_ff_ff_ff_ff_ff)到网络上的主机,并接收返回消息,以此确定目标的物理地址,收到返回消息后将IP地址和物理地址保存到缓存中,并保留一段时间,下次请求时直接查询ARP缓存以节约资源。下图为ARP数据报格式 。

    帧类型:ARP帧类型为两字节0806

    硬件类型:指链路层网络类型,1为以太网

    协议类型:指要转换的地址类型,采用0x0800 IP类型,之后的硬件地址长度和协议地址长度分别对应6和4

    OP字段中1表示ARP请求,2表示ARP应答

    例如:|ff ff ff ff ff ff|00 0a 35 01 fe c0|08 06|00 01|08 00|06|04|00 01|00 0a 35 01 fe c0

    |c0 a8 00 02| ff ff ff ff ff ff|c0 a8 00 03| 表示向192.168.0.3地址发送ARP请求。

    |00 0a 35 01 fe c0 | 60 ab c1 a2 d5 15 |08 06|00 01|08 00|06|04|00 02| 60 ab c1 a2 d5 15

    |c0 a8 00 03|00 0a 35 01 fe c0|c0 a8 00 02|表示向192.168.0.2地址发送ARP应答。

    3.3 IP 数据报格式

    因为UDP协议包只是IP包中的一种, 所以我们来介绍一下IP包的数据格式。下图为IP分组的报文头格式,报文头的前20个字节是固定的,后面的可变

    版本:占 4 位,指 IP 协议的版本目前的 IP 协议版本号为 4 (即 IPv4)

    首部长度:占4位,可表示的最大数值是15个单位(一个单位为 4 字节)因此IP 的首部长度的最大值是 60 字节

    区分服务:占8位,用来获得更好的服务,在旧标准中叫做服务类型,但实际上一直未被使用过.1998 年这个字段改名为区分服务.只有在使用区分服务(DiffServ)时,这个字段才起作用.一般的情况下都不使用这个字段

    总长度:占16位,指首部和数据之和的长度,单位为字节,因此数据报的最大长度为 65535 字节.总长度必须不超过最大传送单元 MTU

    标识:占16位,它是一个计数器,用来产生数据报的标识

    标志(flag):

    占3位,目前只有前两位有意义

    MF

    标志字段的最低位是 MF (More Fragment)

    MF=1 表示后面“还有分片”。MF=0 表示最后一个分片

    DF

    标志字段中间的一位是 DF (Don't Fragment)

    只有当 DF=0 时才允许分片

    片偏移:占12位,指较长的分组在分片后某片在原分组中的相对位置.片偏移以 8 个字节为偏移单位

    生存时间:占8位,记为TTL (Time To Live) 数据报在网络中可通过的路由器数的最大值,TTL 字段是由发送端初始设置一个 8 bit字段.推荐的初始值由分配数字 RFC 指定,当前值为 64.发送 ICMP 回显应答时经常把 TTL 设为最大值 255

    协议:占8位,指出此数据报携带的数据使用何种协议以便目的主机的IP层将数据部分上交给哪个处理过程, 1表示为 ICMP 协议, 2表示为 IGMP 协议, 6表示为 TCP 协议, 17表示为 UDP 协议

    首部检验和:占16位,只检验数据报的首部不检验数据部分,采用二进制反码求和,即将16位数据相加后,再将进位与低16位相加,直到进位为0,最后将16位取反。

    源地址和目的地址:都各占4 字节,分别记录源地址和目的地址

    3.4 UDP协议

    UDP是User Datagram Protocol(用户数据报协议)的英文缩写。UDP只提供一种基本的、低延迟的被称为数据报的通讯。所谓数据报,就是一种自带寻址信息,从发送端走到接收端的数据包。UDP协议经常用于图像传输、网络监控数据交换等数据传输速度要求比较高的场合。

    UDP协议的报头格式

    UDP报头由4个域组成,其中每个域各占用2个字节,具体如下:

    ① UDP源端口号

    ② 目标端口号

    ③ 数据报长度

    ④ 校验和

    UDP协议使用端口号为不同的应用保留其各自的数据传输通道。数据发送一方将UDP数据报通过源端口发送出去,而数据接收一方则通过目标端口接收数据。

    数据报的长度是指包括报头和数据部分在内的总字节数。因为报头的长度是固定的,所以该域主要被用来计算可变长度的数据部分(又称为数据负载)。数据报的最大长度根据操作环境的不同而各异。从理论上说,包含报头在内的数据报的最大长度为65535字节。不过,一些实际应用往往会限制数据报的大小,有时会降低到8192字节。

    UDP协议使用报头中的校验值来保证数据的安全。校验值首先在数据发送方通过特殊的算法计算得出,在传递到接收方之后,还需要再重新计算。如果某个数据报在传输过程中被第三方篡改或者由于线路噪音等原因受到损坏,发送和接收方的校验计算值将不会相符,由此UDP协议可以检测是否出错。虽然UDP提供有错误检测,但检测到错误时,错误校正,只是简单地把损坏的消息段扔掉,或者给应用程序提供警告信息。

    3.5 Ping功能

    ICMP是TCP/IP协议族的一个IP层子协议,包含在IP数据报里,用于IP主机、路由器之间传递控制消息。控制消息是指网络是否连通,主机是否可达等功能。其中ping功能采用回送请求和回答报文,回送请求报文类型为8’h08,回答报文类型为8’h00。

    4. SMI(MDC/MDIO)总线接口

    串行管理接口(Serial Management Interface),也被称作MII管理接口(MII Management Interface),包括MDC和MDIO两条信号线。MDIO是一个PHY的管理接口,用来读/写PHY的寄存器,以控制PHY的行为或获取PHY的状态,MDC为MDIO提供时钟,由MAC端提供,在本实验中也就是FPGA端。在RTL8211EG文档里可以看到MDC的周期最小为400ns,也就是最大时钟为2.5MHz。

    4.1 SMI帧格式

    如下图,为SMI的读写帧格式:

    名称说明
    Preamble由MAC发送32个连续的逻辑“1”,同步于MDC信号,用于MAC与PHY之间的同步
    ST帧开始位,固定为01
    OP操作码,10表示读,01表示写
    PHYADPHY的地址,5 bits
    REGAD寄存器地址,5 bits
    TATurn Around,MDIO方向转换,在写状态下,不需要转换方向,值为10,在读状态下,MAC输出端为高阻态,在第二个周期,PHY将MDIO拉低
    DATA共16bits数据
    IDLE空闲状态,此状态下MDIO为高阻态,由外部上拉电阻拉高

    4.2 读写时序

    1)读时序

     

     

    可以看到在Turn Around状态下,第一个周期MDIO为高阻态,第二个周期由PHY端拉低。

    2)写时序

     

     

    为了保证能够正确采集到数据,在MDC上升沿之前就把数据准备好,在本实验中为下降沿发送数据,上升沿接收数据。

    5. 程序设计

    本实验以千兆以太网RGMII通信为例来设计verilog程序,会先发送预设的UDP数据到网络,每秒钟发送一次,如果FPGA检测网口发来的UDP的数据包,会把接收到的数据包存储在FPGA内部的RAM中,再不断的把RAM中的数据包通过网口发回到ethernet网络。程序分为两部分,分别为发送和接收,实现了ARP,UDP,Ping功能。以下为原理实现框图:

    5.1 发送部分

    1)MAC层发送

    发送部分中, mac_tx.v为MAC层发送模块,首先在SEND_START状态,等待mac_tx_ready信号,如果有效,表明IP或ARP的数据已经准备好,可以开始发送。再进入发送前导码状态,结束时发送mac_data_req,请求IP或ARP的数据,之后进入发送数据状态,最后进入发送CRC状态。在发送数据过程中,需要同时进行CRC校验。

    信号名称方向宽度(bit)说明
    clkin1系统时钟
    rst_nin1异步复位,低电平复位
    crc_resultin32CRC32结果
    crcenout1CRC使能信号
    crcreout1CRC复位信号
    crc_dinout8CRC模块输入信号
    mac_frame_datain8从IP或ARP来的数据
    mac_tx_reqin1MAC的发送请求
    mac_tx_readyin1IP或ARP数据已准备好
    mac_tx_endin1IP或ARP数据已经传输完毕
    mac_tx_dataout8向PHY发送数据
    mac_send_endout1MAC数据发送结束
    mac_data_validout1MAC数据有效信号,即gmii_tx_en
    mac_data_reqout1MAC层向IP或ARP请求数据

    2)MAC发送模式

    工程中的mac_tx_mode.v为发送模式选择,根据发送模式是IP或ARP选择相应的信号与数据。

    信号名称方向宽度(bit)说明
    clkin1系统时钟
    rst_nin1异步复位,低电平复位
    mac_send_endin1MAC发送结束
    arp_tx_reqin1ARP发送请求
    arp_tx_readyin1ARP数据已准备好
    arp_tx_datain8ARP数据
    arp_tx_endin1ARP数据发送到MAC层结束
    arp_tx_ackin1ARP发送响应信号
    ip_tx_reqin1IP发送请求
    ip_tx_readyin1IP数据已准备好
    ip_tx_datain8IP数据
    ip_tx_endin1IP数据发送到MAC层结束
    mac_tx_readyout1MAC数据已准备好信号
    ip_tx_ackout1IP发送响应信号
    mac_tx_ackin1MAC发送响应信号
    mac_tx_reqout1MAC发送请求
    mac_tx_dataout8MAC发送数据
    mac_tx_endout1MAC数据发送结束

    3)ARP发送

    发送部分中,arp_tx.v为ARP发送模块, 在IDLE状态下,等待ARP发送请求或ARP应答请求信号,之后进入请求或应答等待状态,并通知MAC层,数据已经准备好,等待mac_data_req信号,之后进入请求或应答数据发送状态。由于数据不足46字节,需要补全46字节发送。

    信号名称方向宽度(bit)说明
    clkin1系统时钟
    rst_nin1异步复位,低电平复位
    destination_mac_addrin48发送的目的MAC地址
    source_mac_addrin48发送的源MAC地址
    source_ip_addrin32发送的源IP地址
    destination_ip_addrin32发送的目的IP地址
    mac_data_reqin1MAC层请求数据信号
    arp_request_reqin1ARP请求的请求信号
    arp_reply_ackout1ARP回复的应答信号
    arp_reply_reqin1ARP回复的请求信号
    arp_rec_source_ip_addrin32ARP接收的源IP地址,回复时放到目的IP地址
    arp_rec_source_mac_addrin48ARP接收的源MAC地址,回复时放到目的MAC地址
    mac_send_endin1MAC发送结束
    mac_tx_ackin1MAC发送应答
    arp_tx_readyout1ARP数据准备好
    arp_tx_dataout8ARP发送数据
    arp_tx_endout1ARP数据发送结束

    4)IP层发送

    在发送部分,ip_tx.v为IP层发送模块,在IDLE状态下,如果ip_tx_req有效,也就是UDP或ICMP发送请求信号,进入等待发送数据长度状态,之后进入产生校验和状态,校验和是将IP首部所有数据以16位相加,最后将进位再与低16位相加,直到进入为0,再将低16位取反,得出校验和结果。此程序中校验和以树型加法结构,并插入流水线,能有效降低加法部分的延迟,但缺点是会消耗较多逻辑资源。如下图ABCD四个输入,A与B相加,结果为E,C与D相加,结果为F,再将E与F相加,结果为G,在每个相加结果之后都有寄存器。

    在生成校验和之后,等待MAC层数据请求,开始发送数据,并在即将结束发送IP首部后请求UDP或ICMP数据。等发送完,进入IDLE状态。

    信号名称方向宽度(bit)说明
    clkin1系统时钟
    rst_nin1异步复位,低电平复位
    destination_mac_addrin48发送的目的MAC地址
    source_mac_addrin48发送的源MAC地址
    source_ip_addrin32发送的源IP地址
    destination_ip_addrin32发送的目的IP地址
    TTLin8生存时间
    ip_send_typein8上层协议号,如UDP,ICMP
    upper_layer_datain8从UDP或ICMP过来的数据
    upper_data_reqout1向上层请求数据
    mac_tx_ackin1MAC发送应答
    mac_send_endin1MAC发送结束信号
    mac_data_reqin1MAC层请求数据信号
    upper_tx_readyin1上层UDP或ICMP数据准备好
    ip_tx_reqin1发送请求,从上层过来
    ip_send_data_lengthin16发送数据总长度
    ip_tx_ackout 产生IP发送应答
    ip_tx_busyout P发送忙信号
    ip_tx_readyout1IP数据已准备好
    ip_tx_dataout8IP数据
    ip_tx_endout1IP数据发送到MAC层结束

    5)IP发送模式

    工程中的ip_tx_mode.v为发送模式选择,根据发送模式是UDP或ICMP选择相应的信号与数据。

    信号名称方向宽度(bit)说明
    clkin1系统时钟
    rst_nin1异步复位,低电平复位
    mac_send_endin1MAC数据发送结束
    udp_tx_reqin UDP发送请求
    udp_tx_readyin1UDP数据准备好
    udp_tx_datain8UDP发送数据
    udp_send_data_lengthin16UDP发送数据长度
    udp_tx_ackout1输出UDP发送应答
    icmp_tx_reqin1ICMP发送请求
    icmp_tx_readyin1ICMP数据准备好
    icmp_tx_datain8ICMP发送数据
    icmp_send_data_lengthin16ICMP发送数据长度
    icmp_tx_ackout1ICMP发送应答
    ip_tx_ackin1IP发送应答
    ip_tx_reqin1IP发送请求
    ip_tx_readyout1IP数据已准备好
    ip_tx_dataout8IP数据
    ip_send_typeout8上层协议号,如UDP,ICMP
    ip_send_data_lengthout16发送数据总长度

    6)UDP发送

    发送部分中,udp_tx.v为UDP发送模块,第一步将数据写入UDP发送RAM,同时计算校验和,第二步将RAM中数据发送出去。UDP校验和与IP校验和计算方法一致。在计算时需要将伪首部加上,伪首部包括目的IP地址,源IP地址,网络类型,UDP数据长度。

    信号名称方向宽度(bit)说明
    clkin1系统时钟
    rst_nin1异步复位,低电平复位
    source_ip_addrin32发送的源IP地址
    destination_ip_addrin32发送的目的IP地址
    udp_send_source_portin16源端口号
    udp_send_destination_portin16目的端口号
    udp_send_data_lengthin16UDP发送数据长度,用户需给出其值
    ram_wr_datain8写UDP的RAM数据
    ram_wr_enin1写RAM使能
    udp_ram_data_reqout1请求写RAM数据
    mac_send_endin1MAC发送结束信号
    udp_tx_reqin1UDP发送请求
    ip_tx_reqout1IP发送请求
    ip_tx_ackin1Ip应答
    udp_data_reqin1IP层请求数据
    udp_tx_readyout1UDP数据准备好
    udp_tx_dataout8UDP数据
    udp_tx_endout1UDP发送结束(未使用)
    almost_fullout1Fifo接近满标志

    5.2 接收部分

    1) MAC层接收

    在接收部分,其中mac_rx.v为mac层接收文件,首先在IDLE状态下需要判断rx_dv信号是否为高,在REC_PREAMBLE前导码状态下,接收前导码。之后进入接收MAC头部状态,即目的MAC地址,源MAC地址,类型,将它们缓存起来,并在此状态判断前导码是否正确,错误则进入REC_ERROR错误状态,在REC_IDENTIFY状态判断类型是IP(8’h0800)或ARP(8’h0806)。然后进入接收数据状态,将数据传送到IP或ARP模块,等待IP或ARP数据接收完毕,再接收CRC数据。并在接收数据的过程中对接收的数据进行CRC处理,将结果与接收到的CRC数据进行对比,判断数据是否接收正确,正确则结束,错误则进入ERROR状态。

    信号名称方向宽度(bit)说明
    clkin1系统时钟
    rst_nin1异步复位,低电平复位
    crc_resultin32CRC32结果
    crcenout1CRC使能信号
    crcreout1CRC复位信号
    crc_dinout8CRC模块输入信号
    rx_dvin1从PHY层过来的rx_dv信号
    mac_rx_datainin8从PHY层接收的数据
    checksum_errin1IP层校验和错误
    ip_rx_endin1IP层接收结束
    arp_rx_endin1ARP层接收结束
    ip_rx_reqout1请求IP层接收
    arp_rx_reqout1请求ARP接收
    mac_rx_dataoutout8MAC层接收数据输出给IP或ARP
    mac_rec_errorout1MAC层接收错误
    mac_rx_destination_mac_addrout48MAC接收的目的IP地址
    mac_rx_source_mac_addrout48MAC接收的源IP地址

    2) ARP接收

    工程中的arp_rx.v为ARP接收模块,实现ARP数据接收,在IDLE状态下,接收到从MAC层发来的arp_rx_req信号,进入ARP接收状态,在此状态下,提取出目的MAC地址,源MAC地址,目的IP地址,源IP地址,并判断操作码OP是请求还是应答。如果是请求,则判断接收到的目的IP地址是否为本机地址,如果是,发送应答请求信号arp_reply_req,如果不是,则忽略。如果OP是应答,则判断接收到的目的IP地址及目的MAC地址是否与本机一致,如果是,则拉高arp_found信号,表明接收到了对方的地址。并将对方的MAC地址及IP地址存入ARP缓存中。

    信号名称方向宽度(bit)说明
    clkin1系统时钟
    rst_nin1异步复位,低电平复位
    local_ip_addrin32本地IP地址
    local_mac_addrin48本地MAC地址
    arp_rx_datain8ARP接收数据
    arp_rx_reqin1ARP接收请求
    arp_rx_endout1ARP接收完成
    arp_reply_ackin1ARP回复应答
    arp_reply_reqout1ARP回复请求
    arp_rec_source_ip_addrin32ARP接收的源IP地址
    arp_rec_source_mac_addrin48ARP接收的源MAC地址
    arp_foundout1ARP接收到请求应答正确

    3) IP层接收模块

    在工程中,ip_rx为IP层接收模块,实现IP层的数据接收,信息提取,并进行校验和检查。首先在IDLE状态下,判断从MAC层发过来的ip_rx_req信号,进入接收IP首部状态,先在REC_HEADER0提取出首部长度及IP总长度,进入REC_HEADER1状态,在此状态提取出目的IP地址,源IP地址,协议类型,根据协议类型发送udp_rx_req或icmp_rx_req。在接收首部的同时进行校验和的检查,将首部接收的所有数据相加,存入32位寄存器,再将高16位与低16位相加,直到高16位为0 ,再将低16位取反,判断其是否为0,如果是0,则检验正确,否则错误,进入IDLE状态,丢弃此帧数据,等待下次接收。

    信号名称方向宽度(bit)说明
    clkin1系统时钟
    rst_nin1异步复位,低电平复位
    local_ip_addrin32本地IP地址
    local_mac_addrin48本地MAC地址
    ip_rx_datain8从MAC层接收的数据
    ip_rx_reqin1MAC层发送的IP接收请求信号
    mac_rx_destination_mac_addrin48MAC层接收的目的MAC地址
    udp_rx_reqout1UDP接收请求信号
    icmp_rx_reqout1ICMP接收请求信号
    ip_addr_check_errorout1地址检查错误信号
    upper_layer_data_lengthout16上层协议的数据长度
    ip_total_data_lengthout16数据总长度
    net_protocolout8网络协议号
    ip_rec_source_addrout32IP层接收的源IP地址
    ip_rec_destination_addrout32IP层接收的目的IP地址
    ip_rx_endout1IP层接收结束
    ip_checksum_errorout1IP层校验和检查错误信号

    4) UDP接收

    在工程中,udp_rx.v为UDP接收模块,在此模块首先接收UDP首部,再接收数据部分,并将数据部分存入RAM中,在接收的同时进行UDP校验和检查,如果UDP数据是奇数个字节,在计算校验和时,在最后一个字节后加上8’h00,并进行校验和计算。校验方法与IP校验和一样,如果校验正确,将拉高udp_rec_data_valid信号,表明接收的UDP数据有效,否则无效,等待下次接收。

    信号名称方向宽度(bit)说明
    clkin1系统时钟
    rst_nin1异步复位,低电平复位
    udp_rx_datain8UDP接收数据
    udp_rx_reqin1UDP接收请求
    mac_rec_errorin1MAC层接收错误
    net_protocolin8网络协议号
    ip_rec_source_addrin32IP层接收的源IP地址
    ip_rec_destination_addrin32IP层接收的目的IP地址
    ip_checksum_errorin1IP层校验和检查错误信号
    ip_addr_check_errorin1地址检查错误信号
    upper_layer_data_lengthin16上层协议的数据长度
    udp_rec_ram_rdataout8UDP接收RAM读数据
    udp_rec_ram_read_addrin11UDP接收RAM读地址
    udp_rec_data_lengthout16UDP接收数据长度
    udp_rec_data_validout1UDP接收数据有效

    5.3 SMI接口

    1)SMI读写控制模块

    smi_read_write.v文件用于SMI接口的读写控制,在IDLE状态下根据写请求或读请求到相应的状态,再根据SMI时序实现MDC和MDIO的控制。

    信号名称方向宽度(bit)说明
    clkin1系统时钟
    rst_nin1异步复位,低电平复位
    mdcout1MDC时钟
    mdioinout1MDIO数据
    phy_addrin5PHY地址
    reg_addrin5寄存器地址
    write_reqin1写请求
    write_datain16写数据
    read_reqin1读请求
    read_dataout16读数据
    data_validout1数据有效
    doneout1读或写结束

    2)SMI配置模块

    smi_config.v文件读取寄存器0x11的bit10和bit[15:14]来判断以太网是否已经连接和当前的以太网速度,默认状态下,PHY芯片是自动协商速度,根据对方的速度做匹配。bit 10为1则link成功,否则失败,bit[15:14]为00则是10M,01为100M,10或11为1000M,根据不同的速度点亮LED灯,没有link都不亮,10M亮一个灯,100M亮两个灯,1000M亮三个灯。

    信号名称方向宽度(bit)说明
    clkin1系统时钟
    rst_nin1异步复位,低电平复位
    mdcout1MDC时钟
    mdioinout1MDIO数据
    speedout2速度 00:10M; 01:100M; 10:1000M
    linkout1寄存器地址
    ledout4写请求

    5.4 10/100/1000M仲裁

    由于10/100M传输数据时是单边沿采集数据,因此一个周期传输4bit数据,而RGMII为双边沿采集数据,所以要进行数据的转换,如发送时,要将一周其8bit数据转成一周期4bit数据,因此要设置数据缓存,读数据速率为写数据的一半。

    1)TX buffer

    gmii_tx_buffer.v将要发送的8bit缓存到eth_data_fifo中,同时将数据长度缓存到len_fifo中,在状态机中判断长度FIFO中的数据是否大于0,是则表明已经缓存了数据,之后进入读FIFO数据状态,每两个周期读一次数据,此功能不好理解,最好用signaltap抓取信号帮助理解。

    信号名称方向宽度(bit)说明
    clkin1系统时钟
    rst_nin1异步复位,低电平复位
    eth_10_100m_enin110/100M使能信号
    linkin1Link信号
    gmii_tx_enin1内部的gmii发送使能
    gmii_txdin8内部的gmii发送数据
    e10_100_tx_enout110/100M发送使能
    e10_100_txdout810/100M发送数据

    2)RX buffer

    gmii_rx_buffer.v将接收的10/100M数据缓存到eth_data_fifo中,同时将数据长度缓存到len_fifo中,在状态机中判断长度FIFO中的数据是否大于0,是则表明已经缓存了数据,之后进入读FIFO数据状态,每两个周期读一次数据,最好用signaltap抓取信号帮助理解。

    信号名称方向宽度(bit)说明
    clkin1系统时钟
    rst_nin1异步复位,低电平复位
    eth_10_100m_enin1100M使能信号
    eth_10m_enin110M使能信号
    linkin1Link信号
    gmii_rx_dvin1外部的gmii接收有效
    gmii_rxdin8外部的gmii接收数据
    e10_100_rx_dvout110/100M接收有效信号
    e10_100_rxdout810/100M接收数据

    3)仲裁

    gmii_arbi.v用于三种速度的仲裁,同时设定了发送的间隔都为1S。

    信号名称方向宽度(bit)说明
    clkin1系统时钟
    rst_nin1异步复位,低电平复位
    speedin2以太网速度
    linkin1Link信号
    gmii_rx_dvin1外部的gmii接收有效
    gmii_rxdin8外部的gmii接收数据
    gmii_tx_enin1内部的gmii发送使能
    gmii_txdout8内部的gmii发送数据
    pack_total_lenout32延迟数值,每种速度都设置为1S
    e_rst_nout1复位MAC信号
    e_rx_dvout1仲裁后接收有效信号
    e_rxdout8仲裁后接收有效数据
    e_tx_enout1仲裁后发送使能信号
    e_txdout8仲裁后发送数据信号

    5.5 其他部分

    1)ICMP应答

    在工程中,icmp_reply.v实现ping功能,首先接收其他设备发过来的icmp数据,判断类型是否是回送请求(ECHO REQUEST),如果是,将数据存入RAM,并计算校验和,判断校验和是否正确,如果正确则进入发送状态,将数据发送出去。

    信号名称方向宽度(bit)说明
    clkin1系统时钟
    rst_nin1异步复位,低电平复位
    mac_send_endin1Mac发送结束信号
    ip_tx_ackin1IP发送应答
    icmp_rx_datain8ICMP接收数据
    icmp_rx_reqin1ICMP接收请求
    icmp_rev_errorin1接收错误信号
    upper_layer_data_lengthin16上层协议长度
    icmp_data_reqin1发送请求ICMP数据
    icmp_tx_readyout1ICMP发送准备好
    icmp_tx_dataout8ICMP发送数据
    icmp_tx_endout1ICMP发送结束
    icmp_tx_reqout1ICMP发送请求

    2)ARP缓存

    在工程中,arp_cache.v为arp缓存模块,将接收到的其他设备IP地址和MAC地址缓存,在发送数据之前,查询目的地址是否存在,如果不存在,则向目的地址发送ARP请求,等待应答。在设计文件中,只做了一个缓存空间,如果有需要,可扩展。

    信号名称方向宽度(bit)说明
    clkin1系统时钟
    rst_nin1异步复位,低电平复位
    arp_foundin1ARP接收到回复正确
    arp_rec_source_ip_addrin32ARP接收的源IP地址
    arp_rec_source_mac_addrin48ARP接收的源MAC地址
    destination_ip_addrin32目的IP地址
    destination_mac_addrout48目的MAC地址
    mac_not_existout1目的地址对应的MAC地址不存在

    3)CRC校验模块(crc.v)

    一个IP数据包的CRC32校验是在目标MAC 地址开始计算的,一直计算到一个包的最后一个数据为止。以太网的CRC32的verilog的算法和多项式可以在以下网站中直接生成:

    http://www.easics.com/webtools/crctool

    4)以太网测试模块(mac_test.v)

    测试模块实现数据流的控制,首先在按下按键后发送ARP请求信号,直到对方回应,进入发送UDP数据状态,如果在WAIT状态时发现UDP接收数据有效,则将接收的数据发送出去。循环1秒发送,在每次发送前需要检查目的IP地址是否能在ARP缓存里找到,如果没有,则发送ARP请求。

    信号名称方向宽度(bit)说明
    clk_50min1系统时钟
    rst_nin1异步复位,低电平复位
    pack_total_lenin32包长度
    push_buttonin1按键信号
    gmii_tx_clkin1GMII发送时钟
    gmii_rx_clkin1GMII接收时钟
    gmii_rx_dvin1接收数据有效信号
    gmii_rxdin8接收数据
    gmii_tx_enout1发送数据有效信号
    gmii_txdout8发送数据

    5)RGMII转GMII模块

    util_gmii_to_rgmii.v文件是将RGMII与GMII转换,提取出控制信号与数据信号。与PHY连接是RGMII接口。

    GMII接口

    RGMII接口

    RGMII接口是GMII接口的简化版,在时钟的上升沿及下降沿都采样数据,上升沿发送TXD[3:0]/RXD[3:0],下降沿发送TXD[7:4]/RXD[7:4],TX_EN传送TX_EN(上升沿)和TX_ER(下降沿)两种信息,RX_DV传送RX_DV(上升沿)和RX_ER(下降沿)两种信息。

    6. 下载和试验

    6.1 准备工作

    第一步:首先确认一下自己PC的网卡是否是千兆网卡,用户可以点击本地连接查看,再用五类+或者六类网线连接开发板的网口和PC的网口。  

    第二步:修改PC的IP地址为192.168.0.3。PC的IP Address需要和mac_test.v中设置一致,不然网络调试助手会接收不到开发板发送的UDP数据包。

    第三步:安装Wireshark是为了方便用户网络通信的调试,安装”\07_软件工具及驱动\网络调试工具\wireshark_cn”目录下的网络抓包工具Wireshark, 我们在实验的时候可以用这工具来查看PC网口发送的数据和接收到的数据的详细信息。

    6.2 以太网通信测试

    第一步:烧写ethernet_test.bit文件到FPGA,(如果需固化到FLASH中烧写ethernet_test.bin文件),等待两三秒,看到三个LED灯亮,为千兆网卡,两个灯亮为百兆网卡,如果都没亮,需要检查网口连接情况。

    第二步:以管理员权限打开CMD窗口,输入arp –a查看ARP绑定结果,可以看到开发板的IP地址和MAC地址已经缓存。

    第三步:在CMD窗口中,输入ping 192.168.0.2查看PC与开发板是否ping通。

    第四步:打开“\07_软件工具及驱动\网络调试工具\NetAssist “目录下的网络调试助手并设置参数如下,再按连接按钮(这里的本地的IP地址为PC的IP Address, 本地端口需要跟FPGA程序中的一致,为8080)。

    这时网络数据接收窗口会显示FPGA发给PC的以太网数据包"HELLO ALINX HEIJIN"目标主机的IP地址需要和FPGA程序中的IP地址一致,目标端口号也需要和FPGA程序的一致(8080)。如下图网络显示:

    第五步:再在网络调试助手的发送窗口发送一大串字符,在网络的数据接收窗口我们可以看到从FPGA返回的数据也变成刚发送的字符串。

    也可以发送较少字符,低于46字节,FPGA程序会自动补充至46字节,如下图:

    第六步:这一步对用户来讲是可选的,用户如果想查看更多数据包传输的信息,可以使用网络抓包工具Wireshark来查看PC的网卡接收和发送的网络数据,打开安装好的wireshark抓包工具,点击菜单抓包->网络接口。

    在弹出的抓包接口窗口选择PC的千兆网卡,按开始按钮开始抓包。

    在wireshark抓包窗口我们可以看到开发板(192.168.0.2)向PC网口(192.168.0.2)发来的数据包,这里会显示数据包的目标MAC, 源MAC,IP包头和UDP包等信息, 如下图开发板抓包窗口显示:

    6.3 以太网速度测试

    我们可以通过抓包工具wireshark测量以太网部分的数据发送的速度,因为千兆以太网理想模式网络的速度可以达到1Gbps,但实际因为每个数据包中有包头,CRC等非数据字符,而且每包之间有空隙,一般千兆以太网的数据传输速度最高在950Mbps左右。传输是上下对称传输,就是说上行和下行都能达到950Mbps左右。在这里,因为抓包wireshark只能统计接收的数据包,而不会发送数据,所以这里只是测试FPGA发给电脑的输送数据的速度。

    第一步:修改程序,修改工程中mac_test.v中的代码,如下图所示

    把上图中的红色标的”//”去掉,如下:

    第二步:编译综合完成后下载测试程序,下载完成后这时FPGA网络会进行动态绑定,PC机的IP设置请参照5.2章节(如已设置忽略)。

    打开wireshark,点击菜单“抓包”->"抓包参数选择”。在抓包选项中设置缓冲大小为1000megabyte,在10000个数据包之后停止抓包。(这里需要注意:如果不设置的话wireshark因为抓的包太多,处理不了导致软件崩溃)

    按开始后抓包,等待接收到10000个包后停止抓包,用时0.087932秒。

    我们可以看到每个数据包的内容都是00->FF的数据,总共是3个00->FF,1个00->e7的数据。总共是1000个有效数据。

    这里我们看到软件用了0.087932秒收到了10000个数据包,每个数据包里含有的有效数据是1000个字节(8bit)。所以我们可以算出以太网的传输速度为:

    传输速度 = 1000* 10000 * 8 / 0.087932 = 910Mbps

    这里提示一下,网络传输的速度跟包长也有关系,数据包长越长,效率就越高,传输数据的速度会变高;数据包越短,效率就越低,传输数据的速度就慢。这个道理我想大家应该明白的吧!

    下面是1000000包的时间是8.799832秒,自己可以按照上面的方面算下速度,速度是非常稳定的。

    6.4 以太网100M/1000M测试

    改变电脑的网卡速度,首先打开网络连接,找到本地网卡,右键点击属性弹出如下窗口,再点击配置。

    在弹出的窗口中找到链接速度,选择100Mbps全双工,点击确定,等待几秒钟,会发现LED灯会发生改变,之后再按前面的操作步骤进行测试。

    到这里为止,我们的以太网数据通信就全部结束了,要实现以太网的数据通信首先需要理解以太网数据包的格式和通信协议,还需要了解MAC和PHY之间的GMII,RGMII,MII,RMII接口的时序。千兆以太网的数据传输速度非常快,而且是全双工传输,而且UDP通信的数据速度可以达到900Mbps以上,非常适合高速数据传输的场合,比如视频图像传输,高速数据采集等等。

    展开全文
  • 采用SDH虚级联技术可为千兆以太网数据传输开辟大小合适的SDH通道,不但可以提高SDH网络带宽利用率而且可以动态地分配带宽资源。 关键词:同步数字体制(SDH) 虚级联 以太网随着1000MHz以太网技术的逐步成熟以及10...
  • 本文基于FPGA实现了ARP和UDP传输协议。 开发环境:Win7 开发软件:Quartus17.1、Modelsim SE-64 10.2c、Gvim编辑器、小兵以太网测试仪、Wireshark 开发硬件:小梅哥AC6102_V2开发板 注意:本工程都假设FPGA设备...

    本文基于FPGA实现了ARP和UDP传输协议。
    开发环境:Win7
    开发软件:Quartus17.1、Modelsim SE-64 10.2c、Gvim编辑器、小兵以太网测试仪、Wireshark
    开发硬件:小梅哥AC6102_V2开发板
    注意:本工程都假设FPGA设备IP地址为192.168.0.2(即0xc0_a8_00_02),MAC地址为0x00_0a_35_01_fe_c0,PC端IP地址为192.168.0.3(即0xc0_a8_00_03)

    1 以太网原理介绍

    1.1 以太网帧

    在以太网链路上的数据包称作以太网帧。以太网帧起始部分由前导码和帧开始符组成。后面紧跟着一个以太网报头,以MAC地址说明目的地址和源地址。帧的中部是该帧负载的包含其他协议报头的数据包(例如IP协议、ARP协议)。以太帧由一个32位冗余校验码结尾。它用于检验数据传输是否出现损坏。以太网帧格式如下图所示。
    在这里插入图片描述
    1.前导码和帧开始符是固定的,为7个0x55紧跟着1个0xd5
    2.目的MAC地址指明帧的接受者
    3.源MAC地址指明帧的发送者
    4.以太网类型,指示帧的类型,比如0x0800表示该帧是IP数据包,0x0806表示该帧是ARP协议数据包
    5.数据和填充就是所承载的数据包,跟前面以太网类型对应。
    6.帧校验序列是一个32位的循环校验码(FCS)。
      每一个设备都有一个不同的MAC地址,当一个设备A发送一个以太网帧,源MAC地址是自己的MAC地址,目的MAC地址如果是0xffffff,此时就是广播,所有与之连接的设备都会收到该帧,如果目的MAC地址是一个独特的MAC地址,那么本地MAC地址与之相同的设备将会接收到该以太网帧,然后通过判断以太网帧类型,进行下一步数据包解析。

    1.2 ARP协议

    ARP协议,全称为Address Resolution Protocol,即地址解析协议,ARP协议属于以太网帧的一种,前面以太网帧介绍中有说到,我们如果从设备A发送以太网帧到设备B,我们不可能每次都进行广播,那么设备A如何知道设备B的物理地址呢?ARP协议就是为了解决这个问题。
      首先设备A广播,发送ARP请求,等收到设备B的ARP应答以后就能知道设备B的MAC地址。ARP帧格式如下图所示
      在这里插入图片描述
    ARP字段就是前面以太网帧待填充的数据。
    硬件类型、上层协议类型、MAC地址长度、IP地址长度均固定不变。
    假设设备A的IP地址为192.168.0.2,MAC地址为0x00_0a_35_01_fe_c0,我们知道目的IP地址为192.168.0.3,不知道该IP地址对应的MAC地址,如果设备A想要和IP地址为192.168.0.3的设备B进行通信(如UDP或者IP通信),就必须知道它的MAC地址。此时设备A就需要广播发送ARP请求,接收方MAC地址填0xff_ff_ff_ff_ff_ff。这样IP地址为192.168.0.3的设备就会解析出这是一个ARP请求,它询问自身的MAC地址,此时它就会做出ARP应答,将自身的MAC地址发送给对应IP地址的设备A。
    注意发送ARP请求时,操作码为0x0001,应答时操作码为0x0002。

    1.3 IP协议

    TCP/IP协议定义了一个在因特网上传输的包,称为IP数据包,而IP数据报(IP Datagram)是个比较抽象的内容,是对数据包的结构进行分析。 由首部和数据两部分组成,其格式如下图图所示。首部的前一部分是固定长度,共20字节,是所有IP数据报必须具有的。在首部的固定部分的后面是一些可选字段,其长度是可变的。首部中的源地址和目的地址都是IP协议地址。
    在这里插入图片描述

    1.4 UDP协议

    UDP 协议是一种不可靠传输,发送方只负责将数据发送出去,而不管接收方是否正确的接收。 非常类似于 UART 串口传输。 但是,在很多场合,是可以接受这种潜在的不可靠性的,例如视频实时传输显示。 在这类系统中,由于数据并不需要进行运算并得到非常精确的结果用于其他功能,而仅仅是显示在屏幕上,因此可以接受一定程度的丢包或者误码。此类应用在 LED 大屏显示系统中应用非常广泛。UDP帧组成如下图所示
    在这里插入图片描述

    2 GMII接口介绍

    在芯航线 AC6102 开发板上,设计了一路 GMII 接口的千兆以太网电路,通过该以太网电路,用户可以将 FPGA 采集或运算得到的数据传递给其他设备如 PC 或服务器,或者接收其他设备传输过来的数据并进行处理。首先介绍一下GMII接口。
    在这里插入图片描述
    gmii_rx_clk是PHY发送过来的时钟,FPGA通过该时钟进行采样
    gmii_rx_dv是接收数据有效标志,与gmii_rx_data对齐
    gmii_rx_er是错误标志,当它有效时,说明发送帧错误
    gmii_rx_data是PHY发送过来的数据
    phy_rst_n是低电平复位信号
    gmii_tx_clk是FPGA发送时钟,这里直接使用gmii_rx_clk即可
    gmii_tx_en发送数据有效标志,与gmii_tx_data对齐
    gmii_tx_er是错误标志
    gmii_tx_data是FPGA发送给PHY的数据
    以上就是GMII接口所有的信号。
    在发送数据时,只需要按以下时序发送。
    在这里插入图片描述

    3 ARP协议实现

    在本工程中,ARP实现分两部分,一是由FPGA发送ARP请求,二是对发送过来的ARP应答进行解析,得到目的IP地址对应的MAC地址。
    这样我们就可以知道,发送ARP请求完整的帧内容了。如下图所示。(数据格式为16进制)
    在这里插入图片描述
    除了CRC32校验值之外,其他都是固定的,CRC32需要进行计算。关于CRC32的8位并行计算,大家可以参考下面这篇论文。千兆以太网MAC中CRC算法的设计与实现
    用CRC计算软件可以算出,也可以用FPGA实现。
    在这里插入图片描述
    由计算软件看出crc32校验结果为0x63f9a3ca,在发送时,按7-0、15-8、23-16、31-24的顺序发送。
    下面给出CRC32的FPGA实现代码:

    module  crc(
        input                       clk                             ,
        input                       rst_n                           ,
        input         [ 7: 0]       din                             ,
        input                       crc_en                          ,
        input                       crc_init                        ,
        output  reg   [31: 0]       crc                            
    );
    //======================================================================\
    //************** Define Parameter and Internal Signals *****************
    //======================================================================/
    wire    [ 7: 0]                 data                            ;
    wire    [31: 0]                 crc_next                        ;
    //======================================================================\
    //**************************** Main Code *******************************
    //======================================================================/
    assign data={din[0],din[1],din[2],din[3],din[4],din[5],din[6],din[7]};
    
    assign crc_next[0]  = crc[24] ^ crc[30] ^ data[0] ^ data[6];
    assign crc_next[1]  = crc[24] ^ crc[25] ^ crc[30] ^ crc[31] ^ data[0] ^ data[1] ^ data[6] ^ data[7];
    assign crc_next[2]  = crc[24] ^ crc[25] ^ crc[26] ^ crc[30] ^ crc[31] ^ data[0] ^ data[1] ^ data[2] ^ data[6] ^ data[7];
    assign crc_next[3]  = crc[25] ^ crc[26] ^ crc[27] ^ crc[31] ^ data[1] ^ data[2] ^ data[3] ^ data[7];
    assign crc_next[4]  = crc[24] ^ crc[26] ^ crc[27] ^ crc[28] ^ crc[30] ^ data[0] ^ data[2] ^ data[3] ^ data[4] ^ data[6];
    assign crc_next[5]  = crc[24] ^ crc[25] ^ crc[27] ^ crc[28] ^ crc[29] ^ crc[30] ^ crc[31] ^ data[0] ^ data[1] ^ data[3] ^ data[4] ^ data[5] ^ data[6] ^ data[7];
    assign crc_next[6]  = crc[25] ^ crc[26] ^ crc[28] ^ crc[29] ^ crc[30] ^ crc[31] ^ data[1] ^ data[2] ^ data[4] ^ data[5] ^ data[6] ^ data[7];
    assign crc_next[7]  = crc[24] ^ crc[26] ^ crc[27] ^ crc[29] ^ crc[31] ^ data[0] ^ data[2] ^ data[3] ^ data[5] ^ data[7];
    assign crc_next[8]  = crc[0]  ^ crc[24] ^ crc[25] ^ crc[27] ^ crc[28] ^ data[0] ^ data[1] ^ data[3] ^ data[4];
    assign crc_next[9]  = crc[1]  ^ crc[25] ^ crc[26] ^ crc[28] ^ crc[29] ^ data[1] ^ data[2] ^ data[4] ^ data[5];
    assign crc_next[10] = crc[2]  ^ crc[24] ^ crc[26] ^ crc[27] ^ crc[29] ^ data[0] ^ data[2] ^ data[3] ^ data[5];
    assign crc_next[11] = crc[3]  ^ crc[24] ^ crc[25] ^ crc[27] ^ crc[28] ^ data[0] ^ data[1] ^ data[3] ^ data[4];
    assign crc_next[12] = crc[4]  ^ crc[24] ^ crc[25] ^ crc[26] ^ crc[28] ^ crc[29] ^ crc[30] ^ data[0] ^ data[1] ^ data[2] ^ data[4] ^ data[5] ^ data[6];
    assign crc_next[13] = crc[5]  ^ crc[25] ^ crc[26] ^ crc[27] ^ crc[29] ^ crc[30] ^ crc[31] ^ data[1] ^ data[2] ^ data[3] ^ data[5] ^ data[6] ^ data[7];
    assign crc_next[14] = crc[6]  ^ crc[26] ^ crc[27] ^ crc[28] ^ crc[30] ^ crc[31] ^ data[2] ^ data[3] ^ data[4] ^ data[6] ^ data[7];
    assign crc_next[15] = crc[7]  ^ crc[27] ^ crc[28] ^ crc[29] ^ crc[31] ^ data[3] ^ data[4] ^ data[5] ^ data[7];
    assign crc_next[16] = crc[8]  ^ crc[24] ^ crc[28] ^ crc[29] ^ data[0] ^ data[4] ^ data[5];
    assign crc_next[17] = crc[9]  ^ crc[25] ^ crc[29] ^ crc[30] ^ data[1] ^ data[5] ^ data[6];
    assign crc_next[18] = crc[10] ^ crc[26] ^ crc[30] ^ crc[31] ^ data[2] ^ data[6] ^ data[7];
    assign crc_next[19] = crc[11] ^ crc[27] ^ crc[31] ^ data[3] ^ data[7];
    assign crc_next[20] = crc[12] ^ crc[28] ^ data[4];
    assign crc_next[21] = crc[13] ^ crc[29] ^ data[5];
    assign crc_next[22] = crc[14] ^ crc[24] ^ data[0];
    assign crc_next[23] = crc[15] ^ crc[24] ^ crc[25] ^ crc[30] ^ data[0] ^ data[1] ^ data[6];
    assign crc_next[24] = crc[16] ^ crc[25] ^ crc[26] ^ crc[31] ^ data[1] ^ data[2] ^ data[7];
    assign crc_next[25] = crc[17] ^ crc[26] ^ crc[27] ^ data[2] ^ data[3];
    assign crc_next[26] = crc[18] ^ crc[24] ^ crc[27] ^ crc[28] ^ crc[30] ^ data[0] ^ data[3] ^ data[4] ^ data[6];
    assign crc_next[27] = crc[19] ^ crc[25] ^ crc[28] ^ crc[29] ^ crc[31] ^ data[1] ^ data[4] ^ data[5] ^ data[7];
    assign crc_next[28] = crc[20] ^ crc[26] ^ crc[29] ^ crc[30] ^ data[2] ^ data[5] ^ data[6];
    assign crc_next[29] = crc[21] ^ crc[27] ^ crc[30] ^ crc[31] ^ data[3] ^ data[6] ^ data[7];
    assign crc_next[30] = crc[22] ^ crc[28] ^ crc[31] ^ data[4] ^ data[7];
    assign crc_next[31] = crc[23] ^ crc[29] ^ data[5];
    
    //crc 这里用下降沿采集,是为了crc能提前半拍送到eth_mac_send模块中,这个很重要
    //否则crc高8位会发送出错,自己可以修改代码试试看
    always  @(negedge clk or negedge rst_n)begin
        if(rst_n == 1'b0)begin
            crc <=  {32{1'b1}};
        end
        else if(crc_init)begin
            crc <=  {32{1'b1}};
        end
        else if(crc_en)begin
            crc <=  crc_next;
        end
    end
    
    
    endmodule
    
    

    下面是用SignalTap抓取到的信号,如下图所示。
    帧头部分:
    在这里插入图片描述
    帧尾FCS部分:
    在这里插入图片描述
    可以看出发送的校验码为0xca_a3_f9_63与CRC计算机软件计算结果一致。

    3.1 ARP请求

    FPGA实现ARP请求非常简单。首先定义模块信号。

    module  arp_request(
            input                   clk                             ,//125M
            input                   rst_n                           ,
            input         [31: 0]   src_ip_addr                     ,
            input         [31: 0]   dest_ip_addr                    ,
            input         [47: 0]   src_mac_addr                    ,
            input         [47: 0]   dest_mac_addr                   ,
            input         [31: 0]   crc                             ,
            output  reg             crc_init                        ,
            output  reg             crc_en                          ,
            //gmii 
            output  reg             gmii_tx_en                      ,
            output  reg   [ 7: 0]   gmii_tx_data                            
    );
    

    用计数器,在计数变化时,将每一个字节通过gmii_tx_data发送即可。具体请看工程源码。

    3.2 ARP应答解析

    在FPGA发送ARP请求后,对应IP地址将会做出APR应答发送其对应MAC地址,此时通过FPGA的ARP应答解析模块即可正确解析出目标MAC地址,从而为UDP协议传输奠定基础。
    具体实现:
    ①判断目标MAC地址是否是FPGA设备的MAC地址
    ②判断操作码是否是0x0002
    ③判断PC端IP地址是否是192.168.0.3
    ④判断目的IP地址是否是192.168.0.2
    只有以上条件均满足时,我们认为这是一条ARP应答包,从而更新IP为192.168.0.3对应的MAC地址。具体请看工程源码

    4 UDP协议传输实现

    在这里,我通过按键,生成1200个字节的数据,从0-255循环变化,然后封装成UDP包发送到PC端。从而实现UDP协议传输。
    由上面UDP介绍,我们可以知道发送一个UDP包的主要构成,如下图所示:
    在这里插入图片描述
    IP数据包的报头校验和:
    0x4500+0x04cc+0x0000+0x0000+0x4011+0xc0a8+0x0002+0xc0a8+0x0003 = 0x20b32
    0x0002+0x0b32 = 0x0b34
    checksum = ~(0x0b34) = 0xf4cb
    同样的,我们使用计数器来发送对应数据。
    UDP发送模块如下:

    module  udp_send(
            input                   clk                             ,
            input                   clk_50m                         ,
            input                   rst_n                           ,
            input         [31: 0]   src_ip_addr                     ,    
            input         [31: 0]   dest_ip_addr                    ,
            input         [47: 0]   src_mac_addr                    ,
            input         [47: 0]   dest_mac_addr                   ,
            //fifo
            input         [10: 0]   fifo_rdusedw                    ,
            input         [ 7: 0]   fifo_rd_data                    ,
            output  reg             fifo_rdreq                      ,
            //crc
            input         [31: 0]   crc                             ,
            output  reg             crc_init                        ,
            output  reg             crc_en                          ,
            //gmii
            output  reg             gmii_tx_en                      ,
            output  reg   [ 7: 0]   gmii_tx_data                     
    );
    //======================================================================\
    //************** Define Parameter and Internal Signals *****************
    //======================================================================/
    parameter   DATA_LEN        =   16'd1200                        ;//发送的UDP数据长度
    
    parameter   PREAMBLE        =   8'h55                           ;
    parameter   SFD             =   8'hd5                           ;
    parameter   LEN_TYPE        =   16'h0800                        ;
    
    parameter   VER_HDR_LEN     =   8'h45                           ;
    parameter   TOS             =   8'h00                           ;
    parameter   TOTAL_LEN       =   DATA_LEN+28                     ;
    parameter   ID              =   16'h0000                        ;
    parameter   RSV_DF          =   8'h00                           ;
    parameter   MF_FRAG_OFFSET  =   8'h00                           ;
    parameter   TTL             =   8'h40                           ;
    parameter   PROTOCOL        =   8'h11                           ;
    
    parameter   SRC_PORT        =   16'd5000                        ;
    parameter   DST_PORT        =   16'd6000                        ;
    parameter   UDP_LEN         =   DATA_LEN+8                      ;
    parameter   UDP_CHECKSUM    =   16'h0000                        ;
    
    
    wire    [19: 0]                 ip_check_sum1                   ;
    wire    [19: 0]                 ip_check_sum2                   ;
    wire    [15: 0]                 ip_check_sum                    ;
    
    
    reg                             trig_udp_send                   ;
    reg                             flag_udp_send                   ;
    
    reg     [10: 0]                 udp_byte_cnt                    ;
    wire                            add_udp_byte_cnt                ;
    wire                            end_udp_byte_cnt                ;
    
    reg     [ 7: 0]                 udp_data                        ;
    //======================================================================\
    //**************************** Main Code *******************************
    //======================================================================/
    //check_sum1 进位为17'hxff这种情况时,check_sum1,前16与后16位相加可能还会在第
    //17位进1
    assign  ip_check_sum1  =   {VER_HDR_LEN, 8'h00} + TOTAL_LEN + {TTL, PROTOCOL} + src_ip_addr[31:16] + src_ip_addr[15:0] + dest_ip_addr[31:16] + dest_ip_addr[15:0];//width<=20
    
    //check_sum2
    assign  ip_check_sum2   =   ip_check_sum1[19:16] + ip_check_sum1[15:0];//width<=17
    assign  ip_check_sum    =   ~(ip_check_sum2[19:16] + ip_check_sum2[15:0]);//width<=16
    
    
    //trig_udp_send
    always  @(posedge clk or negedge rst_n)begin
        if(!rst_n)begin
            trig_udp_send   <=  1'b0;
        end
        else if(fifo_rdusedw == DATA_LEN-1)begin//
            trig_udp_send   <=  1'b1;
        end
        else begin
            trig_udp_send   <=  1'b0;
        end
    end
    
    //flag_udp_send
    always  @(posedge clk or negedge rst_n)begin
        if(!rst_n)begin
            flag_udp_send   <=  1'b0;
        end
        else if(trig_udp_send)begin
            flag_udp_send   <=  1'b1;
        end
        else if(end_udp_byte_cnt)begin
            flag_udp_send   <=  1'b0;
        end
    end
    
    //udp_byte_cnt
    always @(posedge clk or negedge rst_n)begin
        if(!rst_n)begin
            udp_byte_cnt <= 0;
        end
        else if(add_udp_byte_cnt)begin
            if(end_udp_byte_cnt)
                udp_byte_cnt <= 0;
            else
                udp_byte_cnt <= udp_byte_cnt + 1;
        end
    end
    
    assign  add_udp_byte_cnt    =       flag_udp_send;       
    assign  end_udp_byte_cnt    =       add_udp_byte_cnt && udp_byte_cnt == DATA_LEN+54-1;//前导码+分隔符8个,MAC帧头14,CRC校验4   
    
    //fifo_rdreq
    always  @(posedge clk or negedge rst_n)begin
        if(!rst_n)begin
            fifo_rdreq   <=  1'b0; 
        end
        else if(udp_byte_cnt == 50-1)begin
            fifo_rdreq   <=  1'b1;  
        end
        else if(udp_byte_cnt == DATA_LEN+50-1)begin//校验码之前
            fifo_rdreq   <=  1'b0; 
        end
    end
    
    //--------------------------------------------------------------------\\
    //gmii_tx_en
    always  @(posedge clk or negedge rst_n)begin
        if(!rst_n)begin
            gmii_tx_en  <=  1'b0;
        end
        else if(flag_udp_send)begin
            gmii_tx_en  <=  1'b1;
        end
        else begin
            gmii_tx_en  <=  1'b0;
        end
    end
    
    //gmii_tx_data
    always  @(posedge clk or negedge rst_n)begin
        if(!rst_n)begin
            gmii_tx_data    <=  8'h00;
        end
        else if(flag_udp_send)begin
            case(udp_byte_cnt)
                0,1,2,3,4,5,6:  gmii_tx_data    <=  PREAMBLE;
                7:              gmii_tx_data    <=  SFD;
                //帧头
                8:              gmii_tx_data    <=  dest_mac_addr[47:40];
                9:              gmii_tx_data    <=  dest_mac_addr[39:32];
                10:             gmii_tx_data    <=  dest_mac_addr[31:24];
                11:             gmii_tx_data    <=  dest_mac_addr[23:16];
                12:             gmii_tx_data    <=  dest_mac_addr[15: 8];
                13:             gmii_tx_data    <=  dest_mac_addr[ 7: 0];
                14:             gmii_tx_data    <=  src_mac_addr[47:40];
                15:             gmii_tx_data    <=  src_mac_addr[39:32];
                16:             gmii_tx_data    <=  src_mac_addr[31:24];
                17:             gmii_tx_data    <=  src_mac_addr[23:16];
                18:             gmii_tx_data    <=  src_mac_addr[15: 8];
                19:             gmii_tx_data    <=  src_mac_addr[ 7: 0];
                20:             gmii_tx_data    <=  LEN_TYPE[15: 8];
                21:             gmii_tx_data    <=  LEN_TYPE[ 7: 0];
                //IP
                22:             gmii_tx_data    <=  VER_HDR_LEN;//8'h45    
                23:             gmii_tx_data    <=  TOS;           
                24:             gmii_tx_data    <=  TOTAL_LEN[15: 8];     
                25:             gmii_tx_data    <=  TOTAL_LEN[ 7: 0];  
                26:             gmii_tx_data    <=  ID[15: 8];            
                27:             gmii_tx_data    <=  ID[ 7: 0];       
                28:             gmii_tx_data    <=  RSV_DF;        
                29:             gmii_tx_data    <=  MF_FRAG_OFFSET;
                30:             gmii_tx_data    <=  TTL;           
                31:             gmii_tx_data    <=  PROTOCOL;
                32:             gmii_tx_data    <=  ip_check_sum[15: 8];           
                33:             gmii_tx_data    <=  ip_check_sum[ 7: 0]; 
                34:             gmii_tx_data    <=  src_ip_addr[31:24];           
                35:             gmii_tx_data    <=  src_ip_addr[23:16];
                36:             gmii_tx_data    <=  src_ip_addr[15: 8];           
                37:             gmii_tx_data    <=  src_ip_addr[ 7: 0];
                38:             gmii_tx_data    <=  dest_ip_addr[31:24];           
                39:             gmii_tx_data    <=  dest_ip_addr[23:16]; 
                40:             gmii_tx_data    <=  dest_ip_addr[15: 8];           
                41:             gmii_tx_data    <=  dest_ip_addr[ 7: 0]; 
                //udp    
                42:             gmii_tx_data    <=  SRC_PORT[15: 8];
                43:             gmii_tx_data    <=  SRC_PORT[7 : 0];    
                44:             gmii_tx_data    <=  DST_PORT[15: 8];    
                45:             gmii_tx_data    <=  DST_PORT[7 : 0];     
                46:             gmii_tx_data    <=  UDP_LEN[15: 8];
                47:             gmii_tx_data    <=  UDP_LEN[7 : 0];
                48:             gmii_tx_data    <=  UDP_CHECKSUM[15: 8]; 
                49:             gmii_tx_data    <=  UDP_CHECKSUM[7 : 0];           
                //crc         
                DATA_LEN+50:    gmii_tx_data    <=  ~{crc[24], crc[25], crc[26], crc[27], crc[28], crc[29], crc[30], crc[31]};
                DATA_LEN+51:    gmii_tx_data    <=  ~{crc[16], crc[17], crc[18], crc[19], crc[20], crc[21], crc[22], crc[23]};
                DATA_LEN+52:    gmii_tx_data    <=  ~{crc[8], crc[9], crc[10], crc[11], crc[12], crc[13], crc[14], crc[15]};
                DATA_LEN+53:    gmii_tx_data    <=  ~{crc[0], crc[1], crc[2], crc[3], crc[4], crc[5], crc[6], crc[7]};
                
                default:        gmii_tx_data    <=  fifo_rd_data; 
            endcase
        end 
        else begin
            gmii_tx_data    <=  8'h00;
        end
    end
    
    //---------------------------CRC-----------------------------------\\
    //crc_init
    always  @(posedge clk or negedge rst_n)begin
        if(!rst_n)begin
            crc_init    <=  1'b0;
        end
        else if(udp_byte_cnt == (8-1))begin
            crc_init    <=  1'b1;
        end
        else begin
            crc_init    <=  1'b0;
        end
    end
    
    //crc_en    
    always  @(posedge clk or negedge rst_n)begin
        if(!rst_n)begin
            crc_en  <=  1'b0;
        end
        else if(udp_byte_cnt == (9-1))begin//9-1
            crc_en  <=  1'b1;
        end
        else if(udp_byte_cnt == (DATA_LEN+51-1))begin//1251-1
            crc_en  <=  1'b0;
        end
    end
    endmodule
    
    

    下面是用SignalTap抓取信号示意图
    帧头部分,rdreq就是从fifp读取的数据然后通过封装成UDP发送
    在这里插入图片描述
    帧尾部分,可以看到,发送数据最后一个为175,的确发送了1200个数据(1199-1024=175)。
    在这里插入图片描述
    具体请看工程源码,然后自己下载跑一下就能理解了。
    下面是工程源码下载链接基于FPGA的千兆以太网传输实例——ARP和UDP的实现

    展开全文
  • 千兆以太网 crcGigabit Ethernet is a speed definition for the Ethernet protocol which can provide 1-gigabit data transmission per second. 1 Gigabit is equal to the 1,000Mbps speed. Gigabit Ethernet ...
  • 基于FPGA的千兆以太网通讯,采用UDP协议,实现数据高速传输,亲测可用
  • 本系统把高速数据采集技术和千兆以太网技术有机结合起来,实现了数据高速采集并远距离高速传输功能。
  • 基于千兆以太网的PC机与FPGA的高速数据传输.pdf
  • 目前,随着多媒体应用的普及,千兆以太网已经发展成为主流网络技术。大到成千上万人的大型企业,小到几十人的中小型企业,在建设企业局域网时都会把千兆以太网技术作为首选的高速网络技术。千兆以太网技术甚至...
  • 建成的厦门大学校园网为宽带网,在主干上即网络中心与主节点间可以选择千兆以太技术,主节点到分节点的带宽在100M以上,或者更高的集合带宽。升级后的校园网可为使用者提供多种宽带应用,如全校办公自动化、远程教学...
  • 千兆以太网标准

    千次阅读 2018-04-23 16:49:28
    千兆以太网(又名:吉比特以太网)是以gbit/s速率进行以太网帧传输的网络技术,由IEEE802.3定义。千兆以太网传输线缆主要有4种:1. 单模光纤(1000BaseLX);2. 多模光纤: 2-1.多模光纤-长波(1000BaseLX); 2...
  • 基于FPGA的两路千兆以太网光纤传输系统.pdf
  • AC6102 开发板千兆以太网UDP传输实验 在芯航线AC6102开发板上,设计了一路GMII接口的千兆以太网电路,通过该以太网电路,用户可以将FPGA采集或运算得到的数据传递给其他设备如PC或服务器,或者接收其他设备传输...
  • 基于FPGA千兆以太网数据传输系统设计.pdf
  • FPGA千兆以太网向PC传输数据时PC端需要做出的调整 ** 在FPGA上使用UDP协议向PC机发送数据包时,在FPGA代码上应该设置源Mac、ip地址,目的Mac、ip地址。 这里目的Mac、ip应为PC端的以太网相关参数。 例:源Mac:2C-FE...
  • 本实验将实现视频图像的以太网传输,也相当于用 FPGA 来实现网络摄像头的功能。这里采用黑金的 500 万摄像头 AN5642 模组,通过配置 OV5640 的寄存器实现 JPEG 视频压缩的图像输出。以太网传输用 Ethernet UDP 通信...
  • 结合TCP/IP网络模型,详细描述了TMS320C6657片内千兆以太网接口模块以及通信接口的硬件设计,介绍了网络开发包NDK的结构并运用NDK完成DSP通信接口软件设计,最终实现了DSP与PC间可靠稳定的网络传输
  • 基于FPGA的千兆以太网设计

    千次阅读 2020-06-27 11:47:49
    今天给大侠带来基于FPGA的千兆以太网设计,话不多说,上货。 一、设计概述 由于设计比较复杂,本篇带来设计流程以及设计思路,仅供各位大侠参考。 本篇通过管理数据输入输出MDIO配置PHY寄存器,使其工作在...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 10,396
精华内容 4,158
关键字:

千兆以太网的传输速度