千兆以太网TCP协议的FPGA实现
转自https://blog.csdn.net/zhipao6108/article/details/82386355
千兆以太网TCP协议的FPGA实现
Lzx
2017/4/20
写在前面,这应该是我大四最后一个工程性的作品了,以后要养成写文档记录的习惯。说明下,本工程为纯verilog实现的硬件TCP收发器,不同于其他的使用MCU构建软件协议栈的方案,如有同学学习实验需要用到,可以找我拿代码,商用的话不好意思,还请Pay。
联系方式QQ:929259243
本文将从以下几个方面进行讲述:
1、 以太网基础(主要讲下tcp协议)。
2、 基于FPGA的TCP协议实现方案。
3、 调试方法。
4、 问题记录。
5、 实验过程。
一、以太网基础:(这里只是说下大概念,具体详细的讨论、认知,推荐看《计算机网络》(谢希仁))
以太网主要分为数据链路层、网络层、运输层、应用层。
数据链路层,某种程度可以理解成以太网的MAC层。我们来看下它的具体定义:
“所谓链路,就是从一个结点到相邻结点的一段物理线路,中间没有任何其他的交换结点。数据链路则是另外一个概念。因为当需要在一条线路上传送数据时,必须有一条物理线路外,还必须有一些必要的通信协议来控制这些数据的传输。把实现这些协议的硬件和软件加到链路上,就构成了数据链路”简而言之,也就是说数据链路层负责处理物理硬件接口细节。它定义了将数据组成正确帧的规范和在网络中传输帧的规范。
网络层,网络层位于数据链路层之上,它负责处理分组在网络中的活动。同时,它负责提供互联网的“虚拟网络”镜像(可以理解成IP地址)。本层定义了网络中传输的“信息包”格式,以及从一个终端到达另一个终端的路由转发机制(路由器转发)。本层包括IP、ICMP、IGMP、ARP等协议。
运输层,在以太网通讯中我们面临这样一个问题,前面所述的协议可以实现电脑A到电脑B的通讯。然而A、B上都有很多的进程在跑,光用上面的协议是不能实现电脑A上的进程1到电脑B上的进程2的通信,也就是我们说的端到端的通讯。为解决这个问题便有了TCP协议和UDP协议。TCP协议是面向连接的(两个进程要传输数据要先建立一个链接),它提供可靠的数据传输服务,提供诸如流量控制、拥塞控制、超时重传等功能。UDP协议是面向无连接的传输协议,不提供可靠的传输,但保证实时性。举个例子,如果你通过以太网发送一封邮件,那么你的侧重点一定是对方收到邮件一定是跟我发的一模一样才好。这时候传输用的就是TCP协议了,它能保证可靠性。再比如,如果一公司正在开网络视频会议,你一定希望画面能是及时画面,而不是因为某些原因导致的10s、20s前的画面,这时候使用的UDP协议。
应用层:定义了应用程序使用互联网的规范,负责处理特定的应用程序细节。如FTP、SMTP、Telnet等。
讲了这么多概念,我们来看下一次完整的互联网是数据传输是如何进行的。
主机H1将数据通过层层打包后传输给R1(路由器),R1对从H1传来的包解析(解析道网络层),并根据提取出的目的IP找寻到下一个可转发路由器的硬件地址R2(或者主机硬件地址)。然后将数据包重新打包,改变源地址、目的地址,发给R2。以此类推,发送给主机H2,解包后交给应用进程。值得注意的是,这个过程中,数据包的源、目的IP始终不变,但它的源、目的硬件地址却是一直在改变的。从这个大家应该也可以体会出IP地址和硬件地址的区别了吧。
上面用了一个“层层打包”的笼统词汇,然而具体的打包是如何进行的呢?
举个例子:如上图这是从网络层到数据链路层的打包,IP数据包包裹了成MAC帧发出。其他各层也是如此的包含关系。(如下图)
以上为一点基础知识,让大家大概的了解下以太网,如果要想有点更深入的体会,还是要多读下《计算机网络》这本书。
下面详细说下TCP通信过程。
1、 建立链接。
如上图,TCP建立连接,也就是我们常说的三次握手,它需要三步完成。在TCP的三次握手中,发送第一个SYN的一端执行的是主动打开。而接收这个SYN并发回下一个SYN的另一端执行的是被动打开。
这里以客户端向服务器发起连接来说明。
1) 第1步:客户端向服务器发送一个同步数据包请求建立连接,该数据包中,初始序列号(seq)是客户端随机产生的一个值,确认号是0;
2) 第2步:服务器收到这个同步请求数据包后,会对客户端进行一个同步确认。这个数据包中,序列号(seq)是服务器随机产生的一个值,确认号是客户端的初始序列号+1;
3) 第3步:客户端收到这个同步确认数据包后,再对服务器进行一个确认。该数据包中,序列号是上一个同步请求数据包中的确认号值,确认号是服务器的初始序列号+1。
注意:因为一个SYN将占用一个序号,所以要加1。
初始序列号(seq)随时间而变化的,而且不同的操作系统也会有不同的实现方式,所以每个连接的初始序列号是不同的。TCP连接两端会在建立连接时,交互一些信息,如窗口大小、MSS等,以便为接着的数据传输做准备。
RFC793指出ISN可以看作是一个32bit的计数器,每4ms加1,这样选择序号的目的在于防止在网络中被延迟的分组在以后被重复传输,而导致某个连接的一端对它作错误的判断。
2、传输:(以客户端向服务器发数据说明)
第1次传输数据包时(记为A),其序列号(seq)和应答号(ack)应与建立连接第3步发出的包的相同。
服务器返回的应答包(第一次到第N次)(记为B)的seq应与A的ack相同。它的ack为A的seq+所传数据长度。
第二次到第N次传输包C,它的seq与上一次的应答包的ack相同,ack与上一次的应答包的seq相同。
例:传输态:
Client(发送数据包) Sever(返回的应答包)
1、S=01 0F C9 65 S=68EF 8D 53
A=68 EF 8D 53 A=01 0FC9 81
2、S=01 0F C9 81 S=68EF 8D 53
A=68 EF 8D 53 A=010F C9 9D
……
3、释放连接。
如图,这里我就不过多累述了。简要说明一下,图中的关闭时双向的,即AàB关闭了链接,BàA仍然可以传输数据。所以关闭时候记得全都关了,它才会释放链接。
二、FPGA实现方案
这里,我们实现的是FPGA TCP协议的自环测试,框图如下:
注:代码中MDIO没有实现,因为后来我发现用PHY默认的配置即可。PHY其实可以理解成一个AD+DA+具有自协商功能的控制器。
其他都很好理解,TCP控制模块负责接收端和发送端的协调沟通。
其中TCP控制模块状态机如图:
这里给出发送状态机:
接收的与发送的类似,就不上图了。这里贴上各包的包头格式,方便查阅:
TCP首部
三、调试工具和方法:
软件:
1、Wireshark:从网卡上直接抓取数据,并可以对数据进行简单的分析检查。如校验校验和。注(这里抓出来的看不到前导码和MAC帧的校验和。显示出来说明上述都正确,若不显示,最基本的MAC帧也是错误的)
2、 NetAssist:上位机软件。可以设置端口,用于显示传到该端口的数据,可以设成服务器、客户机、UDP三种工作方式。
3、 Chipscope:dataport设小一些,这个很占资源,不然编译出来的东西在125M下跑很容易出问题,最好就去掉它,少用。
4、 Modelsim:有时候逻辑上的问题去做仿真是个好选择。
硬件:
1、 交叉网线一条:不是普通网线。为什么不是普通网线呢,因为普通网线不能实现PC对PC对发。对发可以让我们采集到一些标准数据,可以跟我们的实验数据对比,方便我们排查问题。
2、 两台电脑。
3、 ALX516开发板一块。
调试的方法:
采集标准数据,对照调试自己的代码。如,你想看正确的建立链接这个过程和你写的有什么区别,可以用两台PC对发,用wireshark抓取建立链接的包,在与自己代码产生的对比,往往就能知道自己写的哪里出了问题。
一般先做仿真,确认逻辑无误后,再上板调试。
四、问题记录:
1、TCP协议不支持广播。
2、建立连接时第一个数据包一定要带OPTION选项。
3、由于频率较高(125M),缺少FPGA片内信号直接观察的手段。(加上chipscope常常会使时序恶化,本身这个东西就是ram,非常占资源。)外部只有500M采样的示波器,看不了。调试只能使用插入标志位,让led灯亮灭显示状态的笨办法来确定问题。
4、发送端有一处设计缺陷,即从ram中取出数据计算校验和时候,是以双字为单位,判断门限设置不恰当,造成发送模块只能发送以4字节为倍数的字符串。尚待改进。
5、wireshark看别人发来的数据一般完整,看自己发给别人的数据一般校验和都有问题。不过无大碍,可以用。
五、实验步骤:
1、在发送模块目的地址,请修改成你pc的网卡地址,并重新编译。如图:
2、 请将网络适配器的IPV4设成如图:
3、 打开NetAssiant,打开TCP Sever,设置成如图,点连接。
4、 这时可以打入8字节、12字节(4的倍数)的字符串,点发送,完成自环测试。如果不按4的倍数发送的话,请重新输入。
5、 最后请不要忘记点断开按钮,毕竟TCP协议是个严谨的东西。
千兆以太网TCP协议的FPGA实现的更多相关文章
- 【转】简谈基于FPGA的千兆以太网
原文地址: http://blog.chinaaet.com/luhui/p/5100052903 大家好,又到了学习时间了,学习使人快乐.今天我们来简单的聊一聊以太网,以太网在FPGA学习中属于比较 ...
- 【小梅哥FPGA进阶学习之旅】基于Altera FPGA 的DDR2+千兆以太网电路设计
DDR2电路设计 在高速大数据的应用中,高速大容量缓存是必不可少的硬件.当前在FPGA系统中使用较为广泛的高速大容量存储器有经典速度较低的单数据速率的SDRAM存储器,以及速度较高的双速率DDR.DD ...
- 【重新发布,代码开源】FPGA设计千兆以太网MAC(1)——通过MDIO接口配置与检测PHY芯片
原创博客,转载请注明出处:[重新发布,代码开源]FPGA设计千兆以太网MAC(1)——通过MDIO接口配置与检测PHY芯片 - 没落骑士 - 博客园 https://www.cnblogs.com/m ...
- AC6102 开发板千兆以太网UDP传输实验2
AC6102 开发板千兆以太网UDP传输实验 在芯航线AC6102开发板上,设计了一路GMII接口的千兆以太网电路,通过该以太网电路,用户可以将FPGA采集或运算得到的数据传递给其他设备如PC或服务器 ...
- AC6102 开发板千兆以太网UDP传输实验
AC6102 开发板千兆以太网UDP传输实验 在芯航线AC6102开发板上,设计了一路GMII接口的千兆以太网电路,通过该以太网电路,用户可以将FPGA采集或运算得到的数据传递给其他设备如PC或服务器 ...
- 237-基于Xilinx Kintex-7 XC7K325T 的FMC/千兆以太网/SATA/四路光纤数据转发卡
基于Xilinx Kintex-7 XC7K325T 的FMC/千兆以太网/SATA/四路光纤数据转发卡 一. 板卡概述 本板卡基于Xilinx公司的FPGAXC7K325T-2FFG900 芯片, ...
- 迅为IMX6开发板支持全网通4G模块丨GPS模块丨WIFI蓝牙丨千兆以太网
迅为i.MX6开发板丨迅为i.MX6Q开发板丨四核imx6开发板丨Cortec-A9开发板丨资料介绍: 特点: 处理器:Freescale Cortex-A9四核i.MX6Q主频1GHz 核心板配置: ...
- 【VS开发】千兆以太网的传输速度
千兆以太网主流标准 千兆以太网络技术早在上世纪90年代末就已成熟,其中,1995年国际标准化组织TIA/EIA颁布了1000Base-TX标准,该标准的目的是把双绞线用于千兆以太网中,其目的是在6类非 ...
- FPGA设计千兆以太网MAC(2)——以太网协议及设计规划
上篇该系列博文中通过MDIO接口实现了PHY芯片的状态检测,验证其已处于1000M 全双工工作模式.在设计MAC逻辑之前,要先清楚MAC与PHY之间的接口以及以太网协议细节,这样才能保证网络的兼容性. ...
随机推荐
- python学习第一周(1)
备注:一般规范代码,可以操作code-reformat code 1. #!/usr/bin/env python 脚本语言第一行 作用:文件中代码用指定可执行程序运行,在unix类的操作系统才有意义 ...
- 使用spark DStream的foreachRDD时要注意哪些坑?
答案: 两个坑, 性能坑和线程坑 DStream是抽象类,它把连续的数据流拆成很多的小RDD数据块, 这叫做“微批次”, spark的流式处理, 都是“微批次处理”. DStream内部实现上有批次处 ...
- AspNetCore2身份验证
1.在Startup类的Configure方法,添加身份验证的中间件AuthenticationMiddleware app.UseAuthentication(); 2.在Startup类的Conf ...
- EntityFramework Code-First 简易教程(九)-------一对多
一对多(One-to-Many)关系: 下面,我们来介绍Code-First的一对多关系,比如,在一个Standard(年级)类中包含多个Student类. 如果想了解更多关于one-to-one,o ...
- 使用Python语言理解递归
递归 一个函数在执行过程中一次或多次调用其本身便是递归,就像是俄罗斯套娃一样,一个娃娃里包含另一个娃娃. 递归其实是程序设计语言学习过程中很快就会接触到的东西,但有关递归的理解可能还会有一些遗漏,下面 ...
- 【PAT】B1032 挖掘机技术哪家强(20 分)
#include<cstdio> const int maxx= 100010; int school[maxx]={0}; int main() { int n,schid,schsco ...
- JQuery 获取多个select标签option的text内容
根据option的id属性,修改text值 $("#sel_div .select_class option[id='-选择省-']").text(data.province).a ...
- C#Url处理类
using System; using System.Text.RegularExpressions; using System.Web; using System.Collections.Speci ...
- (11)Python包
- MessageQueue 相关概念
/** * Implements a thread-local storage, that is, a variable for which each thread * has its own v ...