详解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 除法(即不考虑进位的二进制除法)来计算校验值:
- 选择生成多项式:CRC 校验使用一个预定义的生成多项式(通常是一个二进制数),这个多项式的选择会影响 CRC 校验的性能和错误检测能力。
- 数据多项式:将待校验的数据视为一个多项式,使用二进制表示。
- 模 2 除法:用数据多项式除以生成多项式,得到的余数就是 CRC 校验码。
- 附加校验码:将 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+gn−1xn−1+gn−2xn−2+g2x2+g1x1+g0x0=i=0∑i=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=1∗x4+0∗x3+0∗x2+1∗x1+1∗x0
则这个多项式表示数据为{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校验码。
-
将需要传输的数据最低位补n个0,这里的n是指生成多项式中x的最高次方,这里CRC4的最高次方是4,因此需要在数据最低为补4个0,变成为{1,0,0,1,0,1,0,1,0,0,0,0}
-
用补0后的数据整除生成多项式取得余数,二进制取余数用模2除法,步骤如下:
- 将余数{0,1,0,0}就是CRC校验码,填充到传输数据的末尾即可得到整个CRC编码{1,0,0,1,0,1,0,1,0,1,0,0}
我们用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的基本组成:
- 寄存器:LFSR 由一系列的位存储单元(通常是触发器)组成,这些位存储在寄存器中。寄存器的长度通常用n表示。
- 反馈多项式: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+gn−1xn−1+gn−2xn−2+g2x2+g1x1+g0x0
- 移位操作:在每个时钟周期,LFSR 会将寄存器中的所有位向右移位,并将新的反馈位放入寄存器的最高位
4.2 LFSR工作原理
- 首先将移位寄存器里面的寄存器赋非0初值,也叫种子。刚开始 R 0 , R 1 , R 2 , . . . . . . , R n − 1 {R_0,R_1,R_2,......,R_n-1} R0,R1,R2,......,Rn−1表示种子。
- 然后根据生成多项式,来确定反馈位(通常是某些位的异或结果);即: 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} g0,g1,g2,g3,.......,gn−2,gn−1,gn表示抽头系数。
- 最后移位,将输入的数据低n位从高到低移动进来,移动结束后, R 0 , R 1 , R 2 , . . . . . . , R n − 1 {R_0,R_1,R_2,......,R_n-1} R0,R1,R2,......,Rn−1表示余数。
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,在App权限配置中,添加读取和写入的权限 <uses-permission android:name"android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name"android.permission.WRITE_EXTERNAL_STORAGE"/&g…...

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

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提供了一套强大的版本管理机制,允许开发者管理项目的版本号,并在不同的版本之间进行升级和降级。以下是如何使用Maven进行版本管理的详细步骤和代码示例: 步骤 1: 定义项目版本 在pom.xml文件中,你需要定义项目的版本号。版…...
AWS RDS MySQL内存使用
1. AWS RDS所拥有的内存(实例类型),和数据库能够使用的内存是不同的。RDS实例为操作系统和 RDS 管理进程预留了内存,数据库使用内存大小,小于数据库实例类的硬件规格中所示的值(以 GiB 为单位)[…...

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

基于SSM志愿者招募系统的设计
管理员账户功能包括:系统首页,个人中心,用户管理,志愿组织管理,组织信息管理,组织申请管理,志愿活动管理活动报名管理 用户账号功能包括:系统首页,个人中心,…...

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

微信小程序生成二维码
目前是在开发小程序端 --> 微信小程序。然后接到需求:根据 form 表单填写内容生成二维码(第一版:表单目前需要客户进行自己输入,然后点击生成按钮实时生成二维码,不需要向后端请求,不存如数据库…...
自由软件与开源软件:异同与联系
自由软件与开源软件:异同与联系 随着信息技术的快速发展,自由软件运动与开源软件运动成为推动软件开发领域变革的重要力量。虽然这两个概念在日常对话中常被交替使用,但它们各自有着不同的理念和发展历程。本文将探讨自由软件运动与开源软件…...

Vue中ref、reactive、toRef、toRefs的区别
一、ref、reactive setup 函数中默认定义的变量并不是响应式的(即数据变了以后页面不会跟着变),如果想让变量变为响应式的变量,需要使用 ref 和 reactive 函数修饰变量。 ref 函数可以把基本类型变量变为响应式引用reactive 函数…...

凸极式发电机的相量图分析和计算,内功率因数角和外功率因数角和功角的定义。
图1:同步发电机稳态相量图 若发电机为凸极式,由于凸极机正、交轴同步电抗不等,即xd≠xq,因此必须先借助虚构电动势 E ˙ Q E ˙ q − ( x d − x q ) I ˙ d \dot{E}_Q\dot{E}_q-(x_d-x_q)\dot{I}_d E˙QE˙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项目,会弹出swagger登录验证框,虽然采用Furion简化了项目加载过程及配置,但是学习源码过程就比较恼火,很多设置及功能搞不清楚到低是怎么启用的,本文记录学习Admin.NET项目中swagger的设置…...
在 openEuler 22.03 服务器上搭建 web 服务教程
一、项目背景与目标 在当今数字化时代,web 服务的搭建对于企业和个人来说都具有至关重要的意义。本项目旨在在 openEuler 22.03 服务器上搭建一个稳定、高效的 web 服务,以满足特定的业务需求。具体目标如下: 在 openEuler 22.03 服务器上成功安装和配置 Apache web 服务器…...

如何取消自动配置ipv4地址:步骤详解与实用指南
在现代网络环境中,自动配置IPv4地址(APIPA,即自动专用IP寻址)虽然为设备连接提供了便利,但在某些特定场景下,如服务器配置、网络故障排除等,手动设置静态IP地址成为必要之选。自动配置的IPv4地址…...

Appium下载安装配置保姆教程(图文详解)
目录 一、Appium软件介绍 1.特点 2.工作原理 3.应用场景 二、环境准备 安装 Node.js 安装 Appium 安装 JDK 安装 Android SDK 安装Python及依赖包 三、安装教程 1.Node.js安装 1.1.下载Node 1.2.安装程序 1.3.配置npm仓储和缓存 1.4. 配置环境 1.5.测试Node.j…...
FTXUI::Dom 模块
DOM 模块定义了分层的 FTXUI::Element 树,可用于构建复杂的终端界面,支持响应终端尺寸变化。 namespace ftxui {...// 定义文档 定义布局盒子 Element document vbox({// 设置文本 设置加粗 设置文本颜色text("The window") | bold | color(…...

Axure零基础跟我学:展开与收回
亲爱的小伙伴,如有帮助请订阅专栏!跟着老师每课一练,系统学习Axure交互设计课程! Axure产品经理精品视频课https://edu.csdn.net/course/detail/40420 课程主题:Axure菜单展开与收回 课程视频:...

vxe-table vue 表格复选框多选数据,实现快捷键 Shift 批量选择功能
vxe-table vue 表格复选框多选数据,实现快捷键 Shift 批量选择功能 查看官网:https://vxetable.cn 效果 代码 通过 checkbox-config.isShift 启用批量选中,启用后按住快捷键和鼠标批量选取 <template><div><vxe-grid v-bind"gri…...

Excel 怎么让透视表以正常Excel表格形式显示
目录 1、创建数据透视表 2、设计 》报表布局 》以表格形式显示 3、设计 》分类汇总 》不显示分类汇总 1、创建数据透视表 2、设计 》报表布局 》以表格形式显示 3、设计 》分类汇总 》不显示分类汇总...

Centos 7 服务器部署多网站
一、准备工作 安装 Apache bash sudo yum install httpd -y sudo systemctl start httpd sudo systemctl enable httpd创建网站目录 假设部署 2 个网站,目录结构如下: bash sudo mkdir -p /var/www/site1/html sudo mkdir -p /var/www/site2/html添加测试…...
后端下载限速(redis记录实时并发,bucket4j动态限速)
✅ 使用 Redis 记录 所有用户的实时并发下载数✅ 使用 Bucket4j 实现 全局下载速率限制(动态)✅ 支持 动态调整限速策略✅ 下载接口安全、稳定、可监控 🧩 整体架构概览 模块功能Redis存储全局并发数和带宽令牌桶状态Bucket4j Redis分布式限…...

Python 解释器安装全攻略(适用于 Linux / Windows / macOS)
目录 一、Windows安装Python解释器1.1 下载并安装Python解释1.2 测试安装是否成功1.3 设置pip的国内镜像------永久配置 二、macOS安装Python解释器三、Linux下安装Python解释器3.1 Rocky8.10/Rocky9.5安装Python解释器3.2 Ubuntu2204/Ubuntu2404安装Python解释器3.3 设置pip的…...

鸿蒙APP测试实战:从HDC命令到专项测试
普通APP的测试与鸿蒙APP的测试有一些共同的特征,但是也有一些区别,其中共同特征是,它们都可以通过cmd的命令提示符工具来进行app的性能测试。 其中区别主要是,对于稳定性测试的命令的区别,性能指标获取方式的命令的区…...

Redis:常用数据结构 单线程模型
🌈 个人主页:Zfox_ 🔥 系列专栏:Redis 🔥 常用数据结构 🐳 Redis 当中常用的数据结构如下所示: Redis 在底层实现上述数据结构的过程中,会在源码的角度上对于上述的内容进行特定的…...