当前位置: 首页 > news >正文

详解CRC校验原理以及FPGA实现

文章目录

  • 一、什么是CRC校验?
  • 二、实现CRC校验原理以及步骤
    • 2.1 用多项式表示二元码数据
    • 2.2 选择一个生成多项式作为校验
    • 2.3 计算CRC校验码
  • 三、CRC判断数据是否错误的原理以及步骤
    • 3.1 将收到的数据与生成多项式求余
    • 3.2 数据发生错误再进行CRC校验判断
  • 四、FPGA实现CRC
    • 4.1 线性移位反馈寄存器
    • 4.2 LFSR工作原理
    • 4.3 仿真验证


一、什么是CRC校验?

  CRC(Cyclic Redundancy Check,循环冗余校验)是一种广泛使用的错误检测技术,主要用于检测数据在传输或存储过程中是否发生了错误。它通过对数据进行特定的数学运算,生成一个固定长度的校验码(CRC 校验码),并将其附加到数据后面。接收方在收到数据时,可以通过相同的运算来验证数据的完整性。

  CRC 校验的基本思路是将数据视为一个多项式,并通过模 2 除法(即不考虑进位的二进制除法)来计算校验值:

  1. 选择生成多项式:CRC 校验使用一个预定义的生成多项式(通常是一个二进制数),这个多项式的选择会影响 CRC 校验的性能和错误检测能力。
  2. 数据多项式:将待校验的数据视为一个多项式,使用二进制表示。
  3. 模 2 除法:用数据多项式除以生成多项式,得到的余数就是 CRC 校验码。
  4. 附加校验码:将 CRC 校验码附加到原始数据后面,形成完整的数据包。

二、实现CRC校验原理以及步骤

2.1 用多项式表示二元码数据

   将输入的数据看成一个多项式,其多项式的公式如下:

G ( X ) = g n x n + g n − 1 x n − 1 + g n − 2 x n − 2 + g 2 x 2 + g 1 x 1 + g 0 x 0 = ∑ i = 0 i = n g i x i G(X)=g_nx^n + g_{n-1}x^{n-1} + g_{n-2}x^{n-2} + g_2x^2 + g_1x^1 + g_0x^0 = \sum_{i=0}^{i=n}g_ix^i G(X)=gnxn+gn1xn1+gn2xn2+g2x2+g1x1+g0x0=i=0i=ngixi

  • g i g_i gi表示二元码中第i位的数
  • x i x^i xi表示二元码中第i位

   例如:一个多项式为 G ( X ) = x 4 + x + 1 = 1 ∗ x 4 + 0 ∗ x 3 + 0 ∗ x 2 + 1 ∗ x 1 + 1 ∗ x 0 G(X)=x^4 + x + 1=1*x^4 + 0*x^3 + 0*x^2 + 1*x^1 + 1*x^0 G(X)=x4+x+1=1x4+0x3+0x2+1x1+1x0
则这个多项式表示数据为{1,0,0,1,1},反之亦然,如果知道一个数据,也就知道这个数据对应的多项式。

2.2 选择一个生成多项式作为校验

   生成多项式满足:仅仅能够被1和自身整除,常见的生成多项式有以下:

在这里插入图片描述
  这里面多项式的宽度以及多项式的值是去掉了最高位1的,比如我们上面举例 G ( X ) = x 4 + x + 1 G(X)=x^4 + x + 1 G(X)=x4+x+1表示为{1,0,0,1,1},一共五位,换成16进制为13。截图里去掉了最高位1,就变成了{0,0,1,1}宽度为4,初始值03。

2.3 计算CRC校验码

  在上面我们知道了二元序列的多项式表示,以及一些常见的生成多项式,我们就要计算出我们需要的CRC校验码,具体计算就是除法取余数。例如:我们需要传输的数据为:{1,0,0,1,0,1,0,1},我们选择CRC4的生成多项式 G ( X ) = x 4 + x + 1 G(X)=x^4 + x + 1 G(X)=x4+x+1来计算CRC校验码。

  1. 将需要传输的数据最低位补n个0,这里的n是指生成多项式中x的最高次方,这里CRC4的最高次方是4,因此需要在数据最低为补4个0,变成为{1,0,0,1,0,1,0,1,0000}

  2. 用补0后的数据整除生成多项式取得余数,二进制取余数用模2除法,步骤如下:

在这里插入图片描述

  1. 将余数{0,1,0,0}就是CRC校验码,填充到传输数据的末尾即可得到整个CRC编码{1,0,0,1,0,1,0,1,0100}

  我们用CRC校验生成网站,计算一下本次结果和我们手算的是否一致,{1,0,0,1,0,1,0,1}换成16进制为95,打开网站:

在这里插入图片描述
  可以看到我们用网站计算的结果和手算的结果一致。

三、CRC判断数据是否错误的原理以及步骤

  接收方收到整个数据包后,将整个数据对约定好的生成多项式进行模2取余操作,最后判断余数是否为0,如果余数为0表示数据传输无误,如果不为0表示数据传输有错,还是用上面的例子来操作一遍:

3.1 将收到的数据与生成多项式求余

在这里插入图片描述

  如果余数为0,就表示这次收到的数据没有发生错误;如果数据包发生了错误,无论1位还是多位,余数一定不为0;

3.2 数据发生错误再进行CRC校验判断

  我们随机将收到的数据两位取反,表示收到的数据收到噪声干扰出错了,我们再与生成多项式取余操作:

在这里插入图片描述
  由此可见,如果传输过程中,数据发生了错误最终CRC校验码不等于0。

四、FPGA实现CRC

  实现CRC的关键就是取余数,在FPGA中可以使用线性移位反馈寄存器来实现取余。

4.1 线性移位反馈寄存器

  LFSR(线性反馈移位寄存器,Linear Feedback Shift Register)是一种用于生成伪随机序列的电路或算法。它在数字电路、通信系统和密码学中有广泛的应用。LFSR 通过使用线性反馈机制来生成新的位,通常用于加密、错误检测和伪随机数生成等领域。

LFSR的基本组成:

  1. 寄存器:LFSR 由一系列的位存储单元(通常是触发器)组成,这些位存储在寄存器中。寄存器的长度通常用n表示。
  2. 反馈多项式:LFSR 的反馈是通过一个反馈多项式来实现的,该多项式定义了哪些位会参与反馈计算。反馈多项式通常表示为: G ( X ) = g n x n + g n − 1 x n − 1 + g n − 2 x n − 2 + g 2 x 2 + g 1 x 1 + g 0 x 0 G(X)=g_nx^n + g_{n-1}x^{n-1} + g_{n-2}x^{n-2} + g_2x^2 + g_1x^1 + g_0x^0 G(X)=gnxn+gn1xn1+gn2xn2+g2x2+g1x1+g0x0
  3. 移位操作:在每个时钟周期,LFSR 会将寄存器中的所有位向右移位,并将新的反馈位放入寄存器的最高位
    在这里插入图片描述

4.2 LFSR工作原理

  • 首先将移位寄存器里面的寄存器赋非0初值,也叫种子。刚开始 R 0 , R 1 , R 2 , . . . . . . , R n − 1 {R_0,R_1,R_2,......,R_n-1} R0R1R2......Rn1表示种子。
  • 然后根据生成多项式,来确定反馈位(通常是某些位的异或结果);即: g 0 , g 1 , g 2 , g 3 , . . . . . . . , g n − 2 , g n − 1 , g n {g_0,g_1,g_2,g_3,.......,g_n-2,g_n-1,g_n} g0g1g2g3.......gn2gn1gn表示抽头系数。
  • 最后移位,将输入的数据低n位从高到低移动进来,移动结束后, R 0 , R 1 , R 2 , . . . . . . , R n − 1 {R_0,R_1,R_2,......,R_n-1} R0R1R2......Rn1表示余数。

4.3 仿真验证

  根据前面的CRC计算原理以及LFSR原理,我们搭建电路如上所示,我们还是用最开始的例子:传输的数据为{1,0,0,1,0,1,0,1},选择生成多项式 G ( X ) = x 4 + x + 1 G(X)=x^4 + x + 1 G(X)=x4+x+1,仿真代码如下:

`timescale 1ns / 1psmodule tb_crc4_lfsr();reg                                                 sys_clk ;reg                                                 sys_rst ;reg                                                 din     ;//发送信息为1001_0101
//后面补4个0就是10010101_0000
initial beginsys_clk = 0;sys_rst = 1;din = 0;#200@(posedge sys_clk)sys_rst = 0;#500@(posedge sys_clk)din = 1;@(posedge sys_clk)din = 0;@(posedge sys_clk)din = 0;@(posedge sys_clk)din = 1;@(posedge sys_clk)din = 0;@(posedge sys_clk)din = 1;@(posedge sys_clk)din = 0;@(posedge sys_clk)din = 1;@(posedge sys_clk)din = 0;@(posedge sys_clk)din = 0;@(posedge sys_clk)din = 0;@(posedge sys_clk)din = 0;#200 $stop;
endalways #5 sys_clk = ~sys_clk;crc4_lfsr u_crc4_lfsr(.sys_clk         ( sys_clk        	),.sys_rst         ( sys_rst         	),.din             ( din             	),.crc_code_valid  (   				),.crc_code        (         			)
);
endmodule

在这里插入图片描述

  可以看到我们计算出来的CRC校验码为{0,1,0,0}和我们前面计算的一致。我们将计算好的CRC校验码加到发送信息后四位,再经过LFSR看一下结果,仿真代码如下:

`timescale 1ns / 1psmodule tb_crc4_lfsr();reg                                                 sys_clk ;reg                                                 sys_rst ;reg                                                 din     ;//发送信息为1001_0101
//后面补4个0就是10010101_0000
initial beginsys_clk = 0;sys_rst = 1;din = 0;#200@(posedge sys_clk)sys_rst = 0;#500@(posedge sys_clk)din = 1;@(posedge sys_clk)din = 0;@(posedge sys_clk)din = 0;@(posedge sys_clk)din = 1;@(posedge sys_clk)din = 0;@(posedge sys_clk)din = 1;@(posedge sys_clk)din = 0;@(posedge sys_clk)din = 1;@(posedge sys_clk)din = 0;@(posedge sys_clk)din = 0;@(posedge sys_clk)din = 0;@(posedge sys_clk)din = 0;#200 //加入前面计算好的余数0100,总共信息位就是10010101_0100@(posedge sys_clk)din = 1;@(posedge sys_clk)din = 0;@(posedge sys_clk)din = 0;@(posedge sys_clk)din = 1;@(posedge sys_clk)din = 0;@(posedge sys_clk)din = 1;@(posedge sys_clk)din = 0;@(posedge sys_clk)din = 1;@(posedge sys_clk)din = 0;@(posedge sys_clk)din = 1;@(posedge sys_clk)din = 0;@(posedge sys_clk)din = 0;#200 $stop;
endalways #5 sys_clk = ~sys_clk;crc4_lfsr u_crc4_lfsr(.sys_clk         ( sys_clk        	),.sys_rst         ( sys_rst         	),.din             ( din             	),.crc_code_valid  (   				),.crc_code        (         			)
);
endmodule

在这里插入图片描述
   可以看到,将计算好的余数添加到信息位后面,再经过LFSR后得到余数为0,表示数据无误。我们随机将打反一位数据,仿真代码如下:

`timescale 1ns / 1psmodule tb_crc4_lfsr();reg                                                 sys_clk ;reg                                                 sys_rst ;reg                                                 din     ;//发送信息为1001_0101
//后面补4个0就是10010101_0000
initial beginsys_clk = 0;sys_rst = 1;din = 0;#200@(posedge sys_clk)sys_rst = 0;#500@(posedge sys_clk)din = 1;@(posedge sys_clk)din = 0;@(posedge sys_clk)din = 0;@(posedge sys_clk)din = 1;@(posedge sys_clk)din = 0;@(posedge sys_clk)din = 1;@(posedge sys_clk)din = 0;@(posedge sys_clk)din = 1;@(posedge sys_clk)din = 0;@(posedge sys_clk)din = 0;@(posedge sys_clk)din = 0;@(posedge sys_clk)din = 0;#200 //加入前面计算好的余数0100,总共信息位就是10010101_0100,我们随机打反一位数据,信息变成 11010101_0100@(posedge sys_clk)din = 1;@(posedge sys_clk)din = 1;@(posedge sys_clk)din = 0;@(posedge sys_clk)din = 1;@(posedge sys_clk)din = 0;@(posedge sys_clk)din = 1;@(posedge sys_clk)din = 0;@(posedge sys_clk)din = 1;@(posedge sys_clk)din = 0;@(posedge sys_clk)din = 1;@(posedge sys_clk)din = 0;@(posedge sys_clk)din = 0;#200 $stop;
endalways #5 sys_clk = ~sys_clk;crc4_lfsr u_crc4_lfsr(.sys_clk         ( sys_clk        	),.sys_rst         ( sys_rst         	),.din             ( din             	),.crc_code_valid  (   				),.crc_code        (         			)
);
endmodule

在这里插入图片描述
   可以看到,如果传输过程中,数据位发生了错误,那么经过解码后的余数不为0;

相关文章:

详解CRC校验原理以及FPGA实现

文章目录 一、什么是CRC校验?二、实现CRC校验原理以及步骤2.1 用多项式表示二元码数据2.2 选择一个生成多项式作为校验2.3 计算CRC校验码 三、CRC判断数据是否错误的原理以及步骤3.1 将收到的数据与生成多项式求余3.2 数据发生错误再进行CRC校验判断 四、FPGA实现CR…...

企业如何通过架构蓝图实现数字化转型

数字化转型的关键——架构蓝图的力量 在当今的商业世界,数字化转型已经不再是一个选择,而是企业生存与发展不可回避的战略行动。企业希望通过数字化提高效率、增强灵活性,并为客户提供更好的体验。然而,数字化转型不仅仅涉及技术…...

React第十三章(useTransition)

useTransition useTransition 是 React 18 中引入的一个 Hook,用于管理 UI 中的过渡状态,特别是在处理长时间运行的状态更新时。它允许你将某些更新标记为“过渡”状态,这样 React 可以优先处理更重要的更新,比如用户输入&#x…...

IDEA使用Maven Helper查看整个项目的jar冲突

在插件市场安装Maven Helper,安装好后,重启IDEA;双击打开可能存在jar冲突的pom文件;在右侧面板查看冲突,text是引入的依赖明细,点击Dependecy Analyzer选项卡即可查看冲突的jar。...

uniapp项目 存储数据到手机本地

打开manifest.json&#xff0c;在App权限配置中&#xff0c;添加读取和写入的权限 <uses-permission android:name"android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name"android.permission.WRITE_EXTERNAL_STORAGE"/&g…...

景联文科技医疗数据处理平台:强化医疗数据标注与管理,推动医疗数字化新篇章

随着医疗科技快速进步与广泛应用&#xff0c;医疗信息的规模正在迅速扩张&#xff0c;如何有效管理这些医疗数据成为了关键议题。 医疗数据不仅包括传统的纸质病历&#xff0c;还有电子病历、实验室检测结果、医学影像等多样化的数字信息。为确保这些数据能为临床决策、科研分析…...

vue使用高德地图实现轨迹显隐

<template><div><el-button type"primary" click"pathShowOrHide">轨迹显/隐</el-button><div id"container" /></div> </template><script> import AMapLoader from amap/amap-jsapi-loaderex…...

Maven(20) 如何使用Maven进行版本管理?

Maven提供了一套强大的版本管理机制&#xff0c;允许开发者管理项目的版本号&#xff0c;并在不同的版本之间进行升级和降级。以下是如何使用Maven进行版本管理的详细步骤和代码示例&#xff1a; 步骤 1: 定义项目版本 在pom.xml文件中&#xff0c;你需要定义项目的版本号。版…...

AWS RDS MySQL内存使用

1. AWS RDS所拥有的内存&#xff08;实例类型&#xff09;&#xff0c;和数据库能够使用的内存是不同的。RDS实例为操作系统和 RDS 管理进程预留了内存&#xff0c;数据库使用内存大小&#xff0c;小于数据库实例类的硬件规格中所示的值&#xff08;以 GiB 为单位&#xff09;[…...

Vue指令:v-else、v-else-if

目录 1.语法&#xff1a; 2. 题目 3.页面展示 4.结构 1.语法&#xff1a; 1.作用&#xff1a;辅助v-if进行判断渲染 2.语法&#xff1a;v-else 、v-esle-if"表达式" 2. 题目 <!DOCTYPE html> <html lang"en"> <head><meta chars…...

基于SSM志愿者招募系统的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;志愿组织管理&#xff0c;组织信息管理&#xff0c;组织申请管理&#xff0c;志愿活动管理活动报名管理 用户账号功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;…...

数学建模与优化算法:从基础理论到实际应用

数学建模和优化算法&#xff0c;它们不仅帮助我们理解和描述复杂系统的行为&#xff0c;还能找到系统性能最优化的解决方案。本文将从基础的数学理论出发&#xff0c;逐步深入到各种优化算法&#xff0c;并探讨它们在实际问题中的应用。 思维导图文件可获取&#xff1a;https:…...

微信小程序生成二维码

目前是在开发小程序端 --> 微信小程序。然后接到需求&#xff1a;根据 form 表单填写内容生成二维码&#xff08;第一版&#xff1a;表单目前需要客户进行自己输入&#xff0c;然后点击生成按钮实时生成二维码&#xff0c;不需要向后端请求&#xff0c;不存如数据库&#xf…...

自由软件与开源软件:异同与联系

自由软件与开源软件&#xff1a;异同与联系 随着信息技术的快速发展&#xff0c;自由软件运动与开源软件运动成为推动软件开发领域变革的重要力量。虽然这两个概念在日常对话中常被交替使用&#xff0c;但它们各自有着不同的理念和发展历程。本文将探讨自由软件运动与开源软件…...

Vue中ref、reactive、toRef、toRefs的区别

一、ref、reactive setup 函数中默认定义的变量并不是响应式的&#xff08;即数据变了以后页面不会跟着变&#xff09;&#xff0c;如果想让变量变为响应式的变量&#xff0c;需要使用 ref 和 reactive 函数修饰变量。 ref 函数可以把基本类型变量变为响应式引用reactive 函数…...

凸极式发电机的相量图分析和计算,内功率因数角和外功率因数角和功角的定义。

图1&#xff1a;同步发电机稳态相量图 若发电机为凸极式&#xff0c;由于凸极机正、交轴同步电抗不等&#xff0c;即xd≠xq&#xff0c;因此必须先借助虚构电动势 E ˙ Q E ˙ q − ( x d − x q ) I ˙ d \dot{E}_Q\dot{E}_q-(x_d-x_q)\dot{I}_d E˙Q​E˙q​−(xd​−xq​)…...

systemctl restart NetworkManager 重启后,文件/etc/resolv.conf修改失败

如果你在重启 NetworkManager 之后发现无法修改 /etc/resolv.conf 文件,这是因为 NetworkManager 会自动管理这个文件 为了解决这个问题,你可以采取以下两种方法之一: 方法一:禁用 NetworkManager 服务 使用以下命令停止 NetworkManager 服务:sudo systemctl stop Netwo…...

Admin.NET源码学习(5:swagger使用浅析)

直接启动Admin.NET.Web.Entry项目&#xff0c;会弹出swagger登录验证框&#xff0c;虽然采用Furion简化了项目加载过程及配置&#xff0c;但是学习源码过程就比较恼火&#xff0c;很多设置及功能搞不清楚到低是怎么启用的&#xff0c;本文记录学习Admin.NET项目中swagger的设置…...

在 openEuler 22.03 服务器上搭建 web 服务教程

一、项目背景与目标 在当今数字化时代,web 服务的搭建对于企业和个人来说都具有至关重要的意义。本项目旨在在 openEuler 22.03 服务器上搭建一个稳定、高效的 web 服务,以满足特定的业务需求。具体目标如下: 在 openEuler 22.03 服务器上成功安装和配置 Apache web 服务器…...

如何取消自动配置ipv4地址:步骤详解与实用指南

在现代网络环境中&#xff0c;自动配置IPv4地址&#xff08;APIPA&#xff0c;即自动专用IP寻址&#xff09;虽然为设备连接提供了便利&#xff0c;但在某些特定场景下&#xff0c;如服务器配置、网络故障排除等&#xff0c;手动设置静态IP地址成为必要之选。自动配置的IPv4地址…...

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...

iOS 26 携众系统重磅更新,但“苹果智能”仍与国行无缘

美国西海岸的夏天&#xff0c;再次被苹果点燃。一年一度的全球开发者大会 WWDC25 如期而至&#xff0c;这不仅是开发者的盛宴&#xff0c;更是全球数亿苹果用户翘首以盼的科技春晚。今年&#xff0c;苹果依旧为我们带来了全家桶式的系统更新&#xff0c;包括 iOS 26、iPadOS 26…...

对WWDC 2025 Keynote 内容的预测

借助我们以往对苹果公司发展路径的深入研究经验&#xff0c;以及大语言模型的分析能力&#xff0c;我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际&#xff0c;我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测&#xff0c;聊作存档。等到明…...

C++ 基础特性深度解析

目录 引言 一、命名空间&#xff08;namespace&#xff09; C 中的命名空间​ 与 C 语言的对比​ 二、缺省参数​ C 中的缺省参数​ 与 C 语言的对比​ 三、引用&#xff08;reference&#xff09;​ C 中的引用​ 与 C 语言的对比​ 四、inline&#xff08;内联函数…...

Neo4j 集群管理:原理、技术与最佳实践深度解析

Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...

在WSL2的Ubuntu镜像中安装Docker

Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包&#xff1a; for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...

Spring数据访问模块设计

前面我们已经完成了IoC和web模块的设计&#xff0c;聪明的码友立马就知道了&#xff0c;该到数据访问模块了&#xff0c;要不就这俩玩个6啊&#xff0c;查库势在必行&#xff0c;至此&#xff0c;它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据&#xff08;数据库、No…...

【7色560页】职场可视化逻辑图高级数据分析PPT模版

7种色调职场工作汇报PPT&#xff0c;橙蓝、黑红、红蓝、蓝橙灰、浅蓝、浅绿、深蓝七种色调模版 【7色560页】职场可视化逻辑图高级数据分析PPT模版&#xff1a;职场可视化逻辑图分析PPT模版https://pan.quark.cn/s/78aeabbd92d1...

tauri项目,如何在rust端读取电脑环境变量

如果想在前端通过调用来获取环境变量的值&#xff0c;可以通过标准的依赖&#xff1a; std::env::var(name).ok() 想在前端通过调用来获取&#xff0c;可以写一个command函数&#xff1a; #[tauri::command] pub fn get_env_var(name: String) -> Result<String, Stri…...

小木的算法日记-多叉树的递归/层序遍历

&#x1f332; 从二叉树到森林&#xff1a;一文彻底搞懂多叉树遍历的艺术 &#x1f680; 引言 你好&#xff0c;未来的算法大神&#xff01; 在数据结构的世界里&#xff0c;“树”无疑是最核心、最迷人的概念之一。我们中的大多数人都是从 二叉树 开始入门的&#xff0c;它…...