【基础知识】~ 一举拿下 ”CRC“

【基础知识】~ 一举拿下 ”CRC“数据拼接时先接收到的数据放到 data b 的低位

本章目录:

一、题目

什么是CRC?CRC校验原理是怎么样子的?如何计算CRC(CRC的计算步骤)?再深入一点就是CRC的框图实现以及代码实现?

二、答案

  1. 什么是CRC

CRC(Cyclic Redundancy Check),称为循环冗余校验码,是数据通信领域中最常用的一种查错校验码,其特征是信息字段和校验字段的长度可以任意选定。CRC是一种数据传输检错功能,对数据进行多项式计算,并将得到的结果附在帧的后面,接收设备也执行类似的算法,以保证数据传输的正确性和完整性。

  1. CRC校验原理

CRC校验的根本思想是先在要发送的帧后面附加一个二进制序列,这个序列就是用来校验的校验码,生成一个新帧发送给接收端。注意的是,这个附加的序列不是随意的,它要使所生成的新帧能与发送端和接收端共同选定的某个特定的二进制序列整除(需要注意的是,这里不是直接采用二进制除法,而是采用一种称之为“模2除法”)。到达接收端后,再把接收到的新帧采用同样的方式除以这个选定的二进制序列。因为在发送端发送数据帧之前就已通过附加一个序列了,做了“去余”处理(也就已经能整除了),所以结果应该是没有余数。如果有余数,则表明该帧在传输过程中出现了差错。

  1. 如何计算CRC(步骤)

计算CRC校验码分为3步===>

  • 第一步:展开多项式得到CRC除数(也就是一般表达式中给出的式子);
  • 第二步:在原数据末端添加相应的0,0的个数等于多项式最高项次数;
  • 第三步:原数据从左往右,与CRC除数进行按位异或(注意:如果原数据高位有0,那就省略掉从最高位为1开始异或运算,直到原数据最后一位异或运算完成,所得到的就是CRC校验和,其长度为CRC除数-1,如果不够,前边补零,但一定长度为CRC除数-1那么长)。

举例说明:

比如我们要发送的数据是,二进制序列的表达式为x^4+x+1,则计算步骤如下:

  • 第一步:展开多项式得到CRC除数

根据表达式可以得到,CRC除数为10011

  • 第二步:在原数据末端添加相应的0

我们要发送的数据是,补全之后为000

  • 第三步:原数据从左往右,与CRC除数进行按位异或

000

10011


000

上边是第一次异或运算,红色部分先与CRC除数异或,得到绿色部分,因为绿色部分最高位是0,那就应该舍掉,直到最高位是1,之后运算如下:

00

10011


00000

可见,得到的结果如绿色部分,全为0,那就得舍掉,找到最高位是1,如下:

10011


00

同上的操作,如下:

10011


001110

最后舍掉前边的0,这里需要注意,因为最后我们需要满足 CRC校验和的长度为CRC除数-1,CRC除数长度是5位,减一之后为4位,所以我们可以省略掉前边的两个0,假如不够四位的话,前边就得补零补足四位才行。

根据我们上边计算出来的CRC校验位是1110,把其加到我们要发送的数据后边,最终的结果为110。

  1. CRC校验 框图

(注意:文章水印“IC二舅”是我本人的公众号哈!!!)
在这里插入图片描述
上边的五个图形代表CRC除数的5位数据,第一个图形把它称作“1探测器“,顾名思义,它的作用就是检测该位是不是1,是的话,那么就激活其余为1位上边的反相器,直到所有的数据传输完成。

还是以上边的那个例子继续说明:
在这里插入图片描述
现在传输数据的前五位已经送进去了,开始检测出了第一个1,随后,激活反相器,下一步就是变为10011,如下所示:
在这里插入图片描述
以此类推,直到最后一个数据送进去,结果如下:
在这里插入图片描述
最后得到校验和,把它加到我们要发送的数据末尾,即得到CRC校验,可知,与我们手动计算的结果一直!!!

  1. CRC校验 代码实现

VL30 数据串转并电路

电路的接口如下图所示。valid_a用来指示数据输入data_a的有效性,valid_b用来指示数据输出data_b的有效性;ready_a用来指示本模块是否准备好接收上游数据,本模块中一直拉高;clk是时钟信号;rst_n是异步复位信号。

在这里插入图片描述
代码实现:

// author:Uncle_IC // time: 2022.8.10 `timescale 1ns/1ns module s_to_p( input clk , input rst_n , input valid_a , input data_a , output reg ready_a , output reg valid_b , output reg [5:0] data_b ); //counter reg [2:0] count; always @ (posedge clk or negedge rst_n) begin if(!rst_n) begin count <= 3'd0; ready_a <= 1'b0; end else begin ready_a <= 1'b1; if(valid_a) begin if(count == 3'd5) begin count <= 3'd0; end else begin count <= count + 1'b1; end end end end //shift reg reg [5:0] data_b_reg; always @ (posedge clk or negedge rst_n) begin if(!rst_n) begin data_b_reg <= 6'd0; valid_b <= 1'b0; data_b <= 6'd0; end else begin if(valid_a) begin data_b_reg <= { 
   data_a, data_b_reg[5:1]}; if(count == 3'd5) begin valid_b <= 1'b1; data_b <= { 
   data_a, data_b_reg[5:1]}; end else begin valid_b <= 1'b0; data_b <= data_b; end end else begin data_b_reg <= data_b_reg; data_b <= data_b; end end end endmodule 

以上是来自我博客上边写的文章(仅是一部分),完整部分可以参照下边操作观看学习!!!

声明

本人所有系列的文章,仅供学习,不可商用,如有侵权,请告知,立删!!!

本人主要是记录学习过程,以供自己回头复习,再就是提供给后人参考,不喜勿喷!!!

如果觉得对你有用的话,记得收藏+评论!!!

全网各平台同名===> “IC二舅”

下一期如果有大家想看的 或者 哪块不懂想学习的,可以私聊或在群里提问都可以,“二舅” 给你安排上!!!

今天的文章 【基础知识】~ 一举拿下 ”CRC“分享到此就结束了,感谢您的阅读。
编程小号
上一篇 2024-12-08 21:27
下一篇 2024-12-08 21:21

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/bian-cheng-ji-chu/80760.html