基于FPGA的UDP协议栈设计第一章_MAC层设计

这篇具有很好参考价值的文章主要介绍了基于FPGA的UDP协议栈设计第一章_MAC层设计。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言:以太网MAC层报文解析

基于FPGA的UDP协议栈设计第一章_MAC层设计,UDP协议栈设计,udp,fpga开发,网络协议,网络
前导码:7个0h55和一个起始界定符SFD,0hD5,不过大部分地方好像是7个0hAA,就是bit顺序相反,不过我用FPGA接收到的上位机的网口数据是55,估计是大小端传输问题吧。:有时候有可能是六个55一个D5
基于FPGA的UDP协议栈设计第一章_MAC层设计,UDP协议栈设计,udp,fpga开发,网络协议,网络
类型:IP:0X0800。ARP:0X0806

一、MAC发送模块

发送模块按部就班按照协议格式进行组帧即可,木有难度,只有俩点注意一下。

1.1、组帧FIFO

用户进入的数据需要先存入FIFO,因为用户数据不能立马填入MAC帧当中,需要先填充前面的前导码,MAC地址等内容

1.1、发送端CRC校验码

直接通过网址http://crctool.easics.be/产生相应的CRC校验模块即可。
基于FPGA的UDP协议栈设计第一章_MAC层设计,UDP协议栈设计,udp,fpga开发,网络协议,网络
简单介绍一下代码如何使用:
原始文件:下载下来是这样的

module CRC32_D8;

  // polynomial: x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x^1 + 1
  // data width: 8
  // convention: the first serial bit is D[7]
  function [31:0] nextCRC32_D8;

    input [7:0] Data;
    input [31:0] crc;
    reg [7:0] d;
    reg [31:0] c;
    reg [31:0] newcrc;
  begin
    d = Data;
    c = crc;

    newcrc[0] = d[6] ^ d[0] ^ c[24] ^ c[30];
    newcrc[1] = d[7] ^ d[6] ^ d[1] ^ d[0] ^ c[24] ^ c[25] ^ c[30] ^ c[31];
    newcrc[2] = d[7] ^ d[6] ^ d[2] ^ d[1] ^ d[0] ^ c[24] ^ c[25] ^ c[26] ^ c[30] ^ c[31];
    newcrc[3] = d[7] ^ d[3] ^ d[2] ^ d[1] ^ c[25] ^ c[26] ^ c[27] ^ c[31];
    newcrc[4] = d[6] ^ d[4] ^ d[3] ^ d[2] ^ d[0] ^ c[24] ^ c[26] ^ c[27] ^ c[28] ^ c[30];
    newcrc[5] = d[7] ^ d[6] ^ d[5] ^ d[4] ^ d[3] ^ d[1] ^ d[0] ^ c[24] ^ c[25] ^ c[27] ^ c[28] ^ c[29] ^ c[30] ^ c[31];
    newcrc[6] = d[7] ^ d[6] ^ d[5] ^ d[4] ^ d[2] ^ d[1] ^ c[25] ^ c[26] ^ c[28] ^ c[29] ^ c[30] ^ c[31];
    newcrc[7] = d[7] ^ d[5] ^ d[3] ^ d[2] ^ d[0] ^ c[24] ^ c[26] ^ c[27] ^ c[29] ^ c[31];
    newcrc[8] = d[4] ^ d[3] ^ d[1] ^ d[0] ^ c[0] ^ c[24] ^ c[25] ^ c[27] ^ c[28];
    newcrc[9] = d[5] ^ d[4] ^ d[2] ^ d[1] ^ c[1] ^ c[25] ^ c[26] ^ c[28] ^ c[29];
    newcrc[10] = d[5] ^ d[3] ^ d[2] ^ d[0] ^ c[2] ^ c[24] ^ c[26] ^ c[27] ^ c[29];
    newcrc[11] = d[4] ^ d[3] ^ d[1] ^ d[0] ^ c[3] ^ c[24] ^ c[25] ^ c[27] ^ c[28];
    newcrc[12] = d[6] ^ d[5] ^ d[4] ^ d[2] ^ d[1] ^ d[0] ^ c[4] ^ c[24] ^ c[25] ^ c[26] ^ c[28] ^ c[29] ^ c[30];
    newcrc[13] = d[7] ^ d[6] ^ d[5] ^ d[3] ^ d[2] ^ d[1] ^ c[5] ^ c[25] ^ c[26] ^ c[27] ^ c[29] ^ c[30] ^ c[31];
    newcrc[14] = d[7] ^ d[6] ^ d[4] ^ d[3] ^ d[2] ^ c[6] ^ c[26] ^ c[27] ^ c[28] ^ c[30] ^ c[31];
    newcrc[15] = d[7] ^ d[5] ^ d[4] ^ d[3] ^ c[7] ^ c[27] ^ c[28] ^ c[29] ^ c[31];
    newcrc[16] = d[5] ^ d[4] ^ d[0] ^ c[8] ^ c[24] ^ c[28] ^ c[29];
    newcrc[17] = d[6] ^ d[5] ^ d[1] ^ c[9] ^ c[25] ^ c[29] ^ c[30];
    newcrc[18] = d[7] ^ d[6] ^ d[2] ^ c[10] ^ c[26] ^ c[30] ^ c[31];
    newcrc[19] = d[7] ^ d[3] ^ c[11] ^ c[27] ^ c[31];
    newcrc[20] = d[4] ^ c[12] ^ c[28];
    newcrc[21] = d[5] ^ c[13] ^ c[29];
    newcrc[22] = d[0] ^ c[14] ^ c[24];
    newcrc[23] = d[6] ^ d[1] ^ d[0] ^ c[15] ^ c[24] ^ c[25] ^ c[30];
    newcrc[24] = d[7] ^ d[2] ^ d[1] ^ c[16] ^ c[25] ^ c[26] ^ c[31];
    newcrc[25] = d[3] ^ d[2] ^ c[17] ^ c[26] ^ c[27];
    newcrc[26] = d[6] ^ d[4] ^ d[3] ^ d[0] ^ c[18] ^ c[24] ^ c[27] ^ c[28] ^ c[30];
    newcrc[27] = d[7] ^ d[5] ^ d[4] ^ d[1] ^ c[19] ^ c[25] ^ c[28] ^ c[29] ^ c[31];
    newcrc[28] = d[6] ^ d[5] ^ d[2] ^ c[20] ^ c[26] ^ c[29] ^ c[30];
    newcrc[29] = d[7] ^ d[6] ^ d[3] ^ c[21] ^ c[27] ^ c[30] ^ c[31];
    newcrc[30] = d[7] ^ d[4] ^ c[22] ^ c[28] ^ c[31];
    newcrc[31] = d[5] ^ c[23] ^ c[29];
    nextCRC32_D8 = newcrc;
  end
  endfunction
endmodule

具体实现可以看看其他文章介绍,每一个8bit数据的校验结果都用来和下一个8bit进行计算。前导码不参与校验
原始文件是一个function函数的形式,我们一般使用module的形式进行调用。记得进行大小端翻转。

module CRC32_D8(
	input			i_clk	,
	input			i_rst	,
	input			i_en	,
	input  [7 :0]	i_data	,
	output [31:0]	o_crc	
);

reg  [31:0] crc;
wire [7 :0] d;
wire [31:0] c;
wire [31:0] newcrc;
assign	o_crc = ~{crc[0] ,crc[1] ,crc[2] ,crc[3] ,crc[4] ,crc[5] ,crc[6] ,crc[7] ,
				  crc[8] ,crc[9] ,crc[10],crc[11],crc[12],crc[13],crc[14],crc[15],
				  crc[16],crc[17],crc[18],crc[19],crc[20],crc[21],crc[22],crc[23],
				  crc[24],crc[25],crc[26],crc[27],crc[28],crc[29],crc[30],crc[31]};

assign	d = {i_data[0],i_data[1],i_data[2],i_data[3],i_data[4],i_data[5],i_data[6],i_data[7]};
assign	c = crc;
assign	newcrc[0] = d[6] ^ d[0] ^ c[24] ^ c[30];
assign	newcrc[1] = d[7] ^ d[6] ^ d[1] ^ d[0] ^ c[24] ^ c[25] ^ c[30] ^ c[31];
assign	newcrc[2] = d[7] ^ d[6] ^ d[2] ^ d[1] ^ d[0] ^ c[24] ^ c[25] ^ c[26] ^ c[30] ^ c[31];
assign	newcrc[3] = d[7] ^ d[3] ^ d[2] ^ d[1] ^ c[25] ^ c[26] ^ c[27] ^ c[31];
assign	newcrc[4] = d[6] ^ d[4] ^ d[3] ^ d[2] ^ d[0] ^ c[24] ^ c[26] ^ c[27] ^ c[28] ^ c[30];
assign	newcrc[5] = d[7] ^ d[6] ^ d[5] ^ d[4] ^ d[3] ^ d[1] ^ d[0] ^ c[24] ^ c[25] ^ c[27] ^ c[28] ^ c[29] ^ c[30] ^ c[31];
assign	newcrc[6] = d[7] ^ d[6] ^ d[5] ^ d[4] ^ d[2] ^ d[1] ^ c[25] ^ c[26] ^ c[28] ^ c[29] ^ c[30] ^ c[31];
assign	newcrc[7] = d[7] ^ d[5] ^ d[3] ^ d[2] ^ d[0] ^ c[24] ^ c[26] ^ c[27] ^ c[29] ^ c[31];
assign	newcrc[8] = d[4] ^ d[3] ^ d[1] ^ d[0] ^ c[0] ^ c[24] ^ c[25] ^ c[27] ^ c[28];
assign	newcrc[9] = d[5] ^ d[4] ^ d[2] ^ d[1] ^ c[1] ^ c[25] ^ c[26] ^ c[28] ^ c[29];
assign	newcrc[10] = d[5] ^ d[3] ^ d[2] ^ d[0] ^ c[2] ^ c[24] ^ c[26] ^ c[27] ^ c[29];
assign	newcrc[11] = d[4] ^ d[3] ^ d[1] ^ d[0] ^ c[3] ^ c[24] ^ c[25] ^ c[27] ^ c[28];
assign	newcrc[12] = d[6] ^ d[5] ^ d[4] ^ d[2] ^ d[1] ^ d[0] ^ c[4] ^ c[24] ^ c[25] ^ c[26] ^ c[28] ^ c[29] ^ c[30];
assign	newcrc[13] = d[7] ^ d[6] ^ d[5] ^ d[3] ^ d[2] ^ d[1] ^ c[5] ^ c[25] ^ c[26] ^ c[27] ^ c[29] ^ c[30] ^ c[31];
assign	newcrc[14] = d[7] ^ d[6] ^ d[4] ^ d[3] ^ d[2] ^ c[6] ^ c[26] ^ c[27] ^ c[28] ^ c[30] ^ c[31];
assign	newcrc[15] = d[7] ^ d[5] ^ d[4] ^ d[3] ^ c[7] ^ c[27] ^ c[28] ^ c[29] ^ c[31];
assign	newcrc[16] = d[5] ^ d[4] ^ d[0] ^ c[8] ^ c[24] ^ c[28] ^ c[29];
assign	newcrc[17] = d[6] ^ d[5] ^ d[1] ^ c[9] ^ c[25] ^ c[29] ^ c[30];
assign	newcrc[18] = d[7] ^ d[6] ^ d[2] ^ c[10] ^ c[26] ^ c[30] ^ c[31];
assign	newcrc[19] = d[7] ^ d[3] ^ c[11] ^ c[27] ^ c[31];
assign	newcrc[20] = d[4] ^ c[12] ^ c[28];
assign	newcrc[21] = d[5] ^ c[13] ^ c[29];
assign	newcrc[22] = d[0] ^ c[14] ^ c[24];
assign	newcrc[23] = d[6] ^ d[1] ^ d[0] ^ c[15] ^ c[24] ^ c[25] ^ c[30];
assign	newcrc[24] = d[7] ^ d[2] ^ d[1] ^ c[16] ^ c[25] ^ c[26] ^ c[31];
assign	newcrc[25] = d[3] ^ d[2] ^ c[17] ^ c[26] ^ c[27];
assign	newcrc[26] = d[6] ^ d[4] ^ d[3] ^ d[0] ^ c[18] ^ c[24] ^ c[27] ^ c[28] ^ c[30];
assign	newcrc[27] = d[7] ^ d[5] ^ d[4] ^ d[1] ^ c[19] ^ c[25] ^ c[28] ^ c[29] ^ c[31];
assign	newcrc[28] = d[6] ^ d[5] ^ d[2] ^ c[20] ^ c[26] ^ c[29] ^ c[30];
assign	newcrc[29] = d[7] ^ d[6] ^ d[3] ^ c[21] ^ c[27] ^ c[30] ^ c[31];
assign	newcrc[30] = d[7] ^ d[4] ^ c[22] ^ c[28] ^ c[31];
assign	newcrc[31] = d[5] ^ c[23] ^ c[29];

always @(posedge i_clk or posedge i_rst) begin
	if(i_rst)
		crc <= 32'hffffffff;
	else if(i_en)
		crc <= newcrc;
	else
		crc <= crc;
end

endmodule

二、MAC接收模块

2.1、接收端CRC校验

接收模块对数据逐字节按照协议进行解析即可,并且要比对CRC校验结果,把前面的前导码去掉很简单,那么要怎么去除后面四个byte的校验码呢,此时需要对数据进行打拍处理,比如把数据打5拍,第一拍数据结束的时候,第五拍数据刚好就是在有效数据刚刚结束的地方,如黄线部分。
基于FPGA的UDP协议栈设计第一章_MAC层设计,UDP协议栈设计,udp,fpga开发,网络协议,网络
接收到的CRC校验可以通过第一拍数据进行不断移位操作便可以得到;本地则对第五拍数据进行校验,即可同步得到接收报文里面的CRC和本地检查结果的CRC。进行对比,得出结论。

2.1、接收端CRC处理模块

该模块需要实现以下功能:将MAC_RX接收到的数据同步存储到本地RAM,然后根据MAC_RX模块得到的校验结果决定该数据需要继续向上一层传输(CRC比对正确)还是直接丢弃(CRC比对错误)。

1、设计思路

具体实现过程是通过一个环形RAM,随着接收数据的进入,会一个个存入RAM当中,并且地址进行累加,如果CRC正确,那么地址则停留在此,不进行回退,如果数据错误,那么RAM地址则直接回退到上一次写数据结束的地方,因此就可以通过覆盖此数据以实现将数据丢弃的功能。

2、考虑问题

在此过程中还需要记录每一次数据的类型和长度,同步存储到相应的FIFO当中。这是为什么呢?
首先我们考虑设计的RAM最大长度,由于MAC数据最大长度为1500,所以RAM最小为1500,当到达一个1500的数据后,它会先存入RAM,随后等待校验结果,正确则开始输出,倘若随后来到的数据包很小,比如连续到达俩个46的数据包,而此时第一个1500的数据包依旧还在发送,所以我们必须要将每一个到达的数据的类型和长度都存入FIFO,才能够在后续发送他们的时候知道他们的长度和类型,如果不知道数据长度,就没办法正确从RAM中将他们读出。

总结

除了CRC相关模块以外,并没有其它难度,完整代码可以参考本人GitHub:https://github.com/shun6-6/Tri_Eth_UDP_pro_stack文章来源地址https://www.toymoban.com/news/detail-854465.html

到了这里,关于基于FPGA的UDP协议栈设计第一章_MAC层设计的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 基于FPGA的实用UDP设计(包含源工程文件)

      前文对ARP协议、ICMP协议、UDP协议分别做了讲解,并且通过FPGA实现了三种协议,最终实现的UDP协议工程中也包含了ARP和ICMP协议,对应的总体框架如图所示。 图1 基于FPGA的UDP协议实现   尽管上述模块包含3种协议的接收和发送,但实际上都是通过一个网口收发数据,所以

    2024年02月22日
    浏览(45)
  • FPGA 高端项目:基于 SGMII 接口的 UDP 协议栈,提供2套工程源码和技术支持

    FPGA 高端项目:基于 SGMII 接口的 UDP 协议栈,提供2套工程源码和技术支持 目前网上的fpga实现udp基本生态如下: 1:verilog编写的udp收发器,但中间的FIFO或者RAM等调用了IP,或者不带ping功能,这样的代码功能正常也能用,但不带ping功能基本就是废物,在实际项目中不会用这样的

    2024年01月21日
    浏览(49)
  • FPGA基于Tri Mode Ethernet MAC实现UDP通信 提供3套工程源码和技术支持

    目前网上的fpga实现udp基本生态如下: 1:verilog编写的udp收发器,但不带ping功能,这样的代码功能正常也能用,但不带ping功能基本就是废物,在实际项目中不会用这样的代码,试想,多机互联,出现了问题,你的网卡都不带ping功能,连基本的问题排查机制都不具备,这样的代

    2024年02月16日
    浏览(44)
  • FPGA纯verilog实现UDP协议栈 AXIS用户接口,可替代Tri Mode Ethernet MAC,提供三套工程源码和技术支持

    FPGA高端项目:纯verilog的 UDP 协议栈,提供11套工程源码和技术支持 目前网上的fpga实现udp基本生态如下: 1:verilog编写的udp收发器,但中间的FIFO或者RAM等调用了IP,或者不带ping功能,这样的代码功能正常也能用,但不带ping功能基本就是废物,在实际项目中不会用这样的代码,

    2024年02月13日
    浏览(51)
  • 千兆以太网传输层 UDP 协议原理与 FPGA 实现(UDP接收)

    相关文章: (1)千兆以太网网络层 ARP 协议的原理与 FPGA 实现 (2)千兆以太网硬件设计及链路层 MAC 协议格式 (3)CRC校验原理及实现 (4)RGMII 与 GMII 转换电路设计 (5)千兆以太网网络层 IP 协议介绍与 IP 校 验和算法实现 (6)千兆以太网传输层 UDP 协议原理与 FPGA 实现(

    2024年02月04日
    浏览(128)
  • 紫光同创FPGA实现UDP协议栈带ping功能,基于YT8511和RTL8211,提供2套PDS工程源码和技术支持

    紫光同创FPGA实现UDP协议栈带ping功能,基于YT8511和RTL8211,提供2套PDS工程源码和技术支持 “苟利国家生死以,岂因祸福避趋之!”大洋彼岸的我优秀地下档员,敏锐地洞察到祖国的短板在于高精尖半导体的制造领域,于是本着为中华民族伟大复兴的中国梦贡献绵薄之力的初心

    2024年02月08日
    浏览(65)
  • FPGA UDP协议栈:基于88E1111,支持RGMII、GMII、SGMII三种模式,提供3套工程源码和技术支持

    FPGA UDP协议栈:基于88E1111,支持RGMII、GMII、SGMII三种模式,提供3套工程源码和技术支持 目前网上的fpga实现udp基本生态如下: 1:verilog编写的udp收发器,但中间的FIFO或者RAM等调用了IP,或者不带ping功能,这样的代码功能正常也能用,但不带ping功能基本就是废物,在实际项目中

    2024年02月02日
    浏览(132)
  • 明德扬FPGA至简设计原理与应用 第一篇 FPGA基础知识 第一章 FPGA简介

    FPGA 的全称为 Field-Programmable Gate Array, 即现场可编程门阵列。FPGA 就是一个可以“改变”内部结构的芯片,而让这个芯片来实现怎样的功能,就需要通过编程即设计HDL,经过 EDA工具编译、综合、布局布线成后转换为可烧录的文件,最终加载到 FPGA 器件中去,改变 FPGA 内部的连

    2024年01月16日
    浏览(79)
  • 基于FPGA的UDP 通信(二)

    前文链接:基于FPGA的UDP 通信(一) 本文继续介绍与以太网数据协议相关的内容。 IEEE802.3标准规定了,以太网数据传输的格式: 字段解释: 字段名称 字段长度/(字节) 含义 前导码 7 用于数据帧同步;发送7个字节的 8\\\'h55 帧开始符( SFD) 1 标明下一个字节为目的 MAC 字段;

    2024年01月19日
    浏览(46)
  • 基于FPGA的UDP 通信(一)

    手头的FPGA开发板上有一个千兆网口,最近准备做一下以太网通信的内容。本文先介绍基本的理论知识。 FPGA芯片型号:xc7a35tfgg484-2 网口芯片(PHY):RTL8211 网络接口:RJ45 以太网是一种计算机局域网技术。IEEE组织的IEEE 802.3标准制定了以太网的技术标准,它规定了包括物理层的

    2024年02月03日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包