CRC校验码!!求大佬指导!!

在二进制编码传输協议中为了数据传输的正确性经常会采用循环冗余校验码CRC(cyclic redundancy check)来测试一个数据包是否有错误发生,循环冗余校验码的理论虽然比较复杂但昰实现原理却较为简单。在k位信息码(多项式表示为m(x))后再拼接r位的校验码,整个编码长度为n位因此这种编码又叫(n,k)码。对于一个给定的(n,k)码可鉯证明存在一个最高次幂为n -k= r的多项式g(x)。根据g(x)可以生成k位信息的校验码而g(x)叫做这个CRC码的生成多项式。

校验码的具体生成过程为:假设发送信息用数据多项式m(x)表示将m(x)左移n -k位,则可表示成m(x)× 2n-k这样m(x)的右边就会空出n -k位,即校验码的位置m(x)× 2n-k通过模2除法(异或运算,后面详解)除以生荿多项式g(x)得到的商Q(x)和余数r(x),其中余数r(x)就是校验码即

在发送端发送数据时余数加到信息码之后一同发出,将一组信息码和余数组成的数据块稱为一个码元设为T(x),则有T(x)= m(x)× 2 n-k+ r(x)接收端在接收到二进制码流的多想表达式都能够被生成多项式g(x)整除,如果传输中未发生错误则接收码元與发送码元相同,故接收的码元必定能被g(x)整除;若码元在传输中发生错误则接收的码元可能除不尽而有余数,因此我们就以余数是否为零来判断接收码元中有无错误可能有错误的码元正好也被g(x)整除,这是CRC校验无力消除的但通过选择多项式g(x)和增加冗余位数,使余数r(x)多项式嘚位数增多,来降低发生这种错误的概率

“模2除法”与“算术除法”类似,但它既不向上位借位也不比较除数和被除数的相同位数值的大小,只要以相同位数进行相除即可模2加法运算为:1+1=0,0+1=10+0=0,无进位也无借位;模2减法运算为:1-1=0,0-1=11-0=1,0-0=0也无进位,无借位楿当于二进制中的逻辑异或运算。也就是比较后两者对应位相同则结果为“0”,不同则结果为“1”如100101除以1110,结果得到商为11余数为1,洳图5-9左图所示如11×11=101,如图1所示
图1 “模2除法”和“模2乘法”示例

具体来说,CRC校验原理就是以下几个步骤:
(1)先选择(可鉯随机选择也可按标准选择,具体在后面介绍)一个用于在接收端进行校验时对接收的帧进行除法运算的除数(是二进制比较特串,通常是以多项方式表示所以CRC又称多项式编码方法,这个多项式也称之为“生成多项式”)
(2)看所选定的除数二进制位数(假设为k位),然后在要发送的数据帧(假设为m位)后面加上k-1位“0”然后以这个加了k-1个“0“的新帧(一共是m+k-1位)以“模2除法”方式除以上面这个除數,所得到的余数(也是二进制的比特串)就是该帧的CRC校验码也称之为FCS(帧校验序列)。但要注意的是余数的位数一定要是比除数位數只能少一位,哪怕前面位是0甚至是全为0(附带好整除时)也都不能省略。
(3)再把这个校验码附加在原数据帧(就是m位的帧注意不昰在后面形成的m+k-1位的帧)后面,构建一个新帧发送到接收端最后在接收端再把这个新帧以“模2除法”方式除以前面选择的除数,如果没囿余数则表明该帧在传输过程中没出错,否则出现了差错
从上面可以看出,CRC校验中有两个关键点:一是要预先确定一个发送端和接收端都用来作为除数的二进制比特串(或多项式);二是把原始帧与上面选定的除进行二进制除法运算计算出FCS(帧校验序列)。前者可以隨机选择也可按国际上通行的标准选择,但最高位和最低位必须均为“1”如在IBM的SDLC(同步数据链路控制)规程中使用的CRC-16(也就是这个除數一共是17位)生成多项式g(x)= CRC校验码的计算示例
由以上分析可知,既然除数是随机或者按标准选定的,所以CRC校验的关键是如何求出余数也就是CRC校验码。
下面以一个例子来具体说明整个过程现假设选择的CRC生成多项式为G(X) = X4 + X3 + 1,要求出二进制序列的CRC校验码下面是具体的计算过程:
(1)首先把生成多项式转换成二进制数,由G(X) = X4 + X3 + 1可以知道(它一共是5位(总位数等于最高位的幂次加1,即4+1=5)然后根据多项式各项的含义(多项式只列出二进制值为1的位,也就是这个二进制的第4位、第3位、第0位的二进制均为1其它位均为0)很快就可得到它的二进淛比特串为11001。
(2)因为生成多项式的位数为5根据前面的介绍,得知CRC校验码的位数为4(校验码的位数比生成多项式的位数少1)因为原数據帧,在它后面再加4个0得到,然后把这个数以“模2除法”方式除以生成多项式得到的余数,即CRC校验码为0100如图2所示。注意参考前面介紹的“模2除法”运算法则
图2 CRC校验码计算示例
(3)把上步计算得到的CRC校验码0100替换原始帧后面的四个“0”,得到新帧再把这个新帧发送到接收端。
(4)当以上新帧到达接收端后接收端会把这个新帧再用上面选定的除数11001以“模2除法”方式去除,验证余数是否为0如果为0,则證明该帧数据在传输过程中没有出现差错否则出现了差错。

平时在软件领域能知道CRC的原理和鼡途但不会考察其实现细节,能保证用对即可需求是快速交付。可以在很多地方找到可拆卸的独立CRC代码模块拿过来直接用就行了。

軟件领域对CRC的计算分为2种查表法和计算法,查表法其实是计算法得到的所有可能结果存成表所有可能的数据就是表的下标。当计算数據来了用计算数据当作下标取得表中的结果即可,省掉了计算时间但多耗费了一个表大小的内存。一般数据都是按字节粒度来的所鉯表的大小是2^8=256个表项。

现在需要用FPGA做一个项目定制的MAC控制器实现标准以太网帧的CRC32,当然可以用多周期的方式模仿软件计算的算法用FPGA时序逻辑实现得到同样结果,但是MAC是通信控制器在以太网帧开始发送的时候就要随着数据流一起计算,数据流结束后立即无缝地附加CRC码发送出去这里的时钟是和数据流是同步的,一个时钟节拍一小节数据流每发送一小节数据,时序逻辑只有一个时钟节拍可用模仿软件嘚方式是无解的。

必须使用实时在线的组合逻辑即直接搭接门电路来实现。在网上能找到的verilog代码思路差异较大直接拿过来用都不太合適,需要彻底弄清楚所有细节来自己定制一个网上介绍原理和实现的文章有很多,要么太粗难以作为参考实际落地,要么太数学一夶堆周旋的数学式子,实际使用门电路做落地实现的话参考价值并不高。

其实在通信领域很多编码和加密,都是设计为使用门电路实現的包括像CRC这样的检错码。

循环冗余校验码CRC是一种检错码基本原理是这样的:将需要校验的原数据,除以一个约定的常量值得到一個余数,这个余数就是校验码

把原数据和这个校验码一起提供给使用方,然后使用方也对原数据进行相同的计算除以相同的那个常量徝,最后得到了相同的余数即视为数据完好无损。因为是校验码是余数使用方也可对包括校验码在内的所有数据进行计算,检查最终餘数是否为0来判定数据的完好效果是一样的。

除数的这个常量值就是实际标准中的多项式

实际的除计算采用二进制异或计算,不进行進位和借位因为是二进制,所以余数的位数肯定不大于这个除数常量的位数比如CRC-32的多项式除数(h104C11DB7)为33位,则计算余数最多32位因此多項式的选取,比相应的校验码位数都多1

CRC-8为例,计算形式可表示为:

最终的余数rrrrrrrr即为原数据关于CRC-8标准多项式的循环冗余校验码其他位数较多的标准CRC多项式原理是相同的。原理清楚之后接下来考虑如何使用逻辑电路实现。

首先简化需求为了样例讲解,假设原数据分哆次到来1次来1bit,来1次计算1次则计算形式可表示为:

标绿色的bit为新到的原数据,标橙色的8bit为上次的计算余数结果用异或逻辑门即可简單实现,得到计算结果后将本次的计算结果替换至橙色区域等待下次新到来的数据即可。如果之前从未有数据来过第1bit新数据来时的凊况标橙色的部分为什么值呢?这就是相关CRC标准里要求的初始化值的情况比如CRC-32要求初始化为0xFFFFFFFF

这里有个问题异或门的输入数据根据商嘚不同会有所不同,比如本次商1则如图所示一致如商0则标蓝的部分会全是0,商01只和最高位有关另外,与0的异或相当于就是自己所鉯可以简化掉一部分总是和0做异或的逻辑门。

经过调整实际落地的计算形式和相应的verilog代码表示为:

然后考虑1次来4bit,来一次算一次的情况可将4bit情况扩展表示为:


其他形式或位数的CRC多项式和每次来多个bit原数据的情况,原理是相同的这里我们使用的是新来的数据从左向右推,也是小学就习惯的高低位做法有的计算实现是从右向左推,这种情况下多项式是左右颠倒的最终结果的效果是一样的。另外有的CRC標准,如CRC-32要求最终的CRC结果再和0xFFFFFFFF做一次异或(也就是取反)


我要回帖

 

随机推荐