前言
在上一章节中,笔者就以太网的CRC计算规则做了简单介绍,并对实现流程进行了讲解,以及代码仿真验证,在本节中,笔者将就以太网MAC层的接收代码做逻辑实现,并且做CRC计算,只有当板卡计算得到的CRC计算结果,与接收数据中的CRC校验结果一致,才认为本帧数据可靠,进行进一步接收利用,并且还需要判断MAC地址是否符合以及接收的报文类型是IP报文还是ARP报文,以传给不同的协议层模块进行处理,对于MAC地址的判断,主要判断当前数据要发送给的MAC地址是否是本机MAC地址或者是广播地址,这两类地址都进行接收,而对于源MAC地址,在初次建立连接时,可能不会配置上位机的MAC地址,所以这里不做校验,但做接收处理,在后续的IP层或者ARP层,进行IP地址判断,或者ARP表缓存即可。
代码实现逻辑梳理
- 接收到有效数据流
- 对有效数据流进行时序打拍,启动计数器,判断前导码和帧界定起始符是否正确,对于前导码,以太网的PHY芯片在接收过程中,可能7个H55,只会接收6个H55,所以在计数器计数时,当计数到6时,若此时数据为H55,应做一个计数器值的时钟周期保留,以保证在后面的数据流提取,以及MAC地址提取时,计数值的指向正确,否则,目的MAC的起始计数器值会存在差异,当只有6个H55,目的MAC在第8个数据开始,当有7个H55,目的MAC在第九个数据开始,造成后续差异,数据流处理会复杂。
- 缓存目的MAC地址,源MAC地址,协议类型,并启动CRC计算,若在CRC计算过程中,判断出MAC地址不符合,停止CRC计算,输出MAC地址错误信号。
- 去除MAC头部信息,将数据流存入RAM中,当MAC地址错误时,不进行数据缓存,当数据缓存完成,但CRC计算结果最终错误,清除本帧在RAM的地址存放,不进行数据的输出。
- 当CRC计算正确,根据报文类型,输入至IP处理模块或ARP处理模块。
- 注意事项,当以太网传来两帧数据,假设第一帧长度为500,第二帧长度为80,可能会导致第一帧CRC校验还没完成(情况比较极限),而第二帧数据已经到来,或是在输出第一帧数据时,第二帧数据到来,也要进行缓存,对于两帧的数据长度,为避免混淆,所以需要对每帧的数据长度进行FIFO缓存,保证CRC计算后,每帧输出数据的完整性与准确性。
- 注意事项,以太网PHY层处理后的数据,并没有数据长度信号,需要在该层进行实现,而FCS字段,位于末尾四个字节,不参与CRC计算,而数据流情况下,无法判断数据何时到达了FCS校验字段,故进入CRC计算的数据应该延迟5个时钟周期(4个计算周期+1个CRC计算延迟周期),在检测到,输入输入数据流下降沿时,在时序上,也正好吻合除了FCS字段外,全部进行了CRC校验,在下面的仿真测试中,会就该时序现象做重点观察,对于这类时序延迟处理,在编写代码时,首先明白原理,计算延迟,代码实现,再经过仿真调试,一次成功是比较困难的,仿真是必不可少的环节。
FPGA代码实现及仿真测试
在本节中,不对数据的缓存做详细介绍,如果后续有必要,会在之后的章节做详细的逻辑介绍,本节中,只实现逻辑梳理的所有功能。
仿真测试1,上位机传来一批数据,目的MAC为8’h11,8’h22,8’h33,8’h44,8’h55,8’h66,源MAC为
8’hA5,8’h67,8’hB3,8’hA6,8’hD5,8’hE6,目的MAC地址与板卡MAC地址一致
其中o_cache总线是输出去除MAC以及末尾FCS字段的数据报文,从图中可以看出,CRC计算结果与上位机发送来的CRC一致,r_rec_fcs即为上位机传来的CRC结果。仿真结果正确。
仿真测试2,上位机传来一批数据,目的MAC为8’h11,8’h22,8’h33,8’h44,8’h55,8’h77,源MAC为
8’hA5,8’h67,8’hB3,8’hA6,8’hD5,8’hE6,目的MAC地址与板卡MAC地址不一致。
仿真可真,校验出MAC地址不符合,不对本帧数据进行输出,且停止CRC校验。