CRC校验原理

线性分组码中有一种重要的码称为循环码(Cyclic code),这种码编码和解码都不太复杂,而且检(纠)错能力较强。循环码除了具有线性分组码的一般性质外,还具有循环性。循环性是指任一码组循环一位以后(即将最右端的一个码元移至左端,或反之)以后,仍然为该码中的一个码组

什么是CRC校验?

CRC即循环冗余校验码:

  • 是数据通信领域中最常用的一种查错校验码;
  • 其特征是信息字段校验字段的长度可以任意选定。

循环冗余检查(CRC, Cyclic Redundancy Check)是一种数据传输检错功能,对数据进行多项式计算(利用多项式,对数据进行模2除法),并将得到的结果附在帧的后面传输,接收设备接收后也执行类似的算法(依旧利用同一个多项式,对接收的数据进行模2除法,但是这里要求没有余数才算是正确传输),以保证数据传输的正确性和完整性。CRC利用除法及余数的原理,实现错误侦测的功能,具有原理清晰、实现简单等优点。

相比于奇偶校验(PCC)只能校验一位错误,循环冗余校验码的检错能力要更强,能够检出多位错误。

CRC校验原理

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

【百科】

循环冗余校验算法将是否除尽,作为数据信息的校验规则。对于能被多项式除尽的数据而言,其数据代码的误码率就较低;对于那些不能被多项式除尽的数据,需要对数据出错的地方进行分析,并将产生的余数进行减去。,如果让被校验数据减去余数,势必能为生成多项式所除尽,但网络通信中减法操作存在复杂的数学计算,无法使用拼装的方式进行数据编码。

基于此种情况,网络通信中引入模2运算的计算方式,模2运算包括:模2加、模2减、模2乘、模2除等四种二进制运算。模2运算不考虑进位和借位,即模2加法是不带进位的二进制加法运算,模2减法是不带借位的二进制减法运算。两个序列模二相加,即两个序列中对应位,相加不进位,相同为0不同为1。在两个二进制位相运算时,这两个位的值能确定最终的运算结果,而不受前一次运算的影响,因此模2运算的加减乘除属于异或运算。

 

模2除法:模2除法与算术除法类似,但每一位除的结果不影响其它位,即不向上一位借位,所以实际上就是异或。在循环冗余校验码(CRC)的计算中有应用到模2除法。模2加法运算为:1+1=0,0+1=1,0+0=0,无进位,也无借位;模2减法运算为:1-1=0,0-1=1,1-0=1,0-0=0,也无进位,无借位。

模2除法/乘法:

 

 

CRC校验步骤

CRC校验中有两个关键点:

(1)预先确定一个发送送端和接收端都用来作为除数的二进制比特串(或多项式G(x)),可以随机选择,也可以使用国际标准,但是最高位和最低位必须为1即生成多项式G(x)要求次数大于0,并且要求0次幂的系数为1。;

       G(x)为发送端和接收端预先约好的生成多项式。G(x)的选取对校验效果起着关键的作用,使用较多的生成多项式G(x)有CRC-16、CRC-CCITT、CRC-32等;

CRC16的生成多项式为:G(x)= X16+X10+X2+1

CRC32的生成多项式为:G(x)= X32+X26+X23+X22+X16+X12+X11+X10+X8+X7+X5+X4+X2+X1+1

 

(2)把原始帧(假设为k位, 对应信息多项式)与上面计算出的除数(二进制比特串或生成多项式 G(x),假设为m位)进行模2除法运算,余数作为CRC校验码

        CRC校验码计算示例:现假设选择的CRC生成多项式为G(X) = X4 + X3 + 1,要求出二进制序列10110011的CRC校验码。

设要发送的数据码有k位,则该数据码对应的多项式F(x)有k项,k的每一位取值只能为0或1,即F(x)中每项X^n的系数只能是0或1。

R(x)为生成的 r 阶冗余码多项式,R(x)的项数比G(x)要少一项。R(x)的计算方法为:以F(x)作为被除数,先将F(x)乘x′即左移r位,再以G(x)作为除数作模2运算。

EX:选定CRC校验的生成多项式G(x)=x^4+x^3+1,待传输二进制序列1011 0011,求出其发送端的CRC校验码以及接收端的校验过程。

答:下面是具体的计算过程:

发送端:

① 将选定的多项式转化为二进制序列:由G(X) = X4 + X3 + 1可知二进制一种有五位,第4位、第三位和第零位分别为1,则序列为11001

② 多项式的位数位5,则在数据帧的后面加上5-1位0,数据帧变为101100110000,然后使用模2除法除以除数11001,得到余数0100即为CRC校验码。

③ 将计算出来的CRC校验码0100添加在原始帧的后面,真正的数据帧为10110011 0100,再把这个数据帧发送到接收端。

④ 接收端收到数据帧10110011 0100后,依3旧 用上预先选定的除数11001,用模2除法除去,验证余数是否为0,如果为0,则说明数据帧没有出错。


发送端:

接收端:


Verilog设计

分析:CRC码由发送端计算,放置于发送信息报文的尾部。接收信息的设备再重新计算接收到信息报文的CRC,比较计算得到的CRC是否与接收到的相符,如果两者不相符,则表明出错。
校验码的计算多项式为(X16 + X15 + X2 + 1,1 1000 0000 0000 0101)。具体CRC16码的计算方法是:
        1.预置1个16位的寄存器为十六进制FFFF(即全为1);称此寄存器为CRC寄存器;
        2.把第一个8位二进制数据 (既通讯信息帧的第一个字节)与16位的CRC寄存器的低8位相异或,把结果放于CRC寄存器;
        3.把CRC寄存器的内容右移一 位(朝低位)用0填补最高位,并检查右移后的移出位;
        4.如果移出位为0:重复第3步(再次右移一位);
             如果移出位为1:CRC寄存器与多项式A001(1010 0000 0000 0001)进行异或;(Modbus)
        5.重复步骤3和4,直到右移8次,这样整个8位数据全部进行了处理;
        6.重复步骤2到步骤5,进行通讯信息帧下一个字节的处理;
        7.将该通讯信息帧所有字节按上述步骤计算完成后,得到的16位CRC寄存器的高、低字节进行交换;
        8.最后得到的CRC寄存器内容即为:CRC码。

 

下面举例说明CRC校验码的求法:(此例子摘自百度百科:CRC校验码)


信息字段代码为: 1011001;对应m(x)=x6+x4+x3+1
假设生成多项式为:g(x)=x4+x3+1;则对应g(x)的代码为: 11001
m(x)=x10+x8+x7+x4 对应的代码记为:10110010000;
采用多项式除法: 得余数为: 1010 (即CRC校验字段为:1010)
发送方:发出的传输字段为: 1 0 1 1 0 0 1 1010
给出余数(1010)的计算步骤:
除法没有数学上的含义,而是采用计算机的模二除法,即,除数和被除数做异或运算。进行异或运算时除数和被除数最高位对齐,按位异或。
10110010000
^

11001
--------------------------
01111010000
1111010000
^11001
-------------------------
0011110000
11110000
^11001
--------------------------
00111000
111000
^11001
-------------------
001010
则四位CRC校验码就为:1010。
 

 

补充:

CRC16常见的标准有以下几种,被用在各个规范中,其算法原理基本一致,就是在数据的输入和输出有所差异,下边把这些标准的差异列出,并给出C语言的算法实现。

CRC16_CCITT:多项式x16+x12+x5+1(0x1021),初始值0x0000,低位在前,高位在后,结果与0x0000异或

CRC16_CCITT_FALSE:多项式x16+x12+x5+1(0x1021),初始值0xFFFF,低位在后,高位在前,结果与0x0000异或

CRC16_XMODEM:多项式x16+x12+x5+1(0x1021),初始值0x0000,低位在后,高位在前,结果与0x0000异或

CRC16_X25:多项式x16+x12+x5+1(0x1021),初始值0x0000,低位在前,高位在后,结果与0xFFFF异或

CRC16_MODBUS:多项式x16+x15+x2+1(0x8005),初始值0xFFFF,低位在前,高位在后,结果与0x0000异或

CRC16_IBM:多项式x16+x15+x2+1(0x8005),初始值0x0000,低位在前,高位在后,结果与0x0000异或

CRC16_MAXIM:多项式x16+x15+x2+1(0x8005),初始值0x0000,低位在前,高位在后,结果与0xFFFF异或

CRC16_USB:多项式x16+x15+x2+1(0x8005),初始值0xFFFF,低位在前,高位在后,结果与0xFFFF异或

 

————————————————
原文链接:https://blog.csdn.net/li200503028/article/details/26591243

下面给出CRC校验码的verilog实现方式:
本例中实现了求得8bit信息序列的CRC校验码,生成多项式取g(x)=X^16+X^12+X^5+1,对应的生成序列为1_0001_0000_0010_0001,输入的8bit序列data左移16位后得到stemp={data,16‘b0000_0000_0000_0000} ,每次异步复位信号rst_n复位时将crc的值清零并把线型变量stemp的值打入寄存器temp中,然后通过时序电路将temp与生成多项式对应的序列进行多次按位异或,最终得到一个小于生成序列的temp后,temp[15:0]的值即为CRC校验序列,并把它赋给输出crc。
 下面是code:


//信息码      : 8bit
//生成多项式  :1_0001_0000_0010_0001
//附加位      :0000 0000 0000 0000
//传输的码    : data+0000 0000 0000 0000 =24位
module crc(
     clk  ,
     data ,
    rst_n ,
    crc  
);
input      [7:0]   data   ;
input              clk    ;
input              rst_n  ;
output reg [15:0]  crc=0  ;
wire       [23:0]  stemp  ; 
reg        [23:0]  temp=0 ;
parameter polynomial=17'b1_0001_0000_0010_0001;
assign stemp={data,16'b0000000000000000};

always @ (posedge clk or negedge rst_n)
 begin 
    if(!rst_n)
          begin
              crc  <= 0     ;
              temp <= stemp ; 
              end
    else 
        begin
          if(temp[23])      temp[23:7]<=temp[23:7]^polynomial;
          else if(temp[22]) temp[22:6]<=temp[22:6]^polynomial;
          else if(temp[21]) temp[21:5]<=temp[21:5]^polynomial;
          else if(temp[20]) temp[20:4]<=temp[20:4]^polynomial;
          else if(temp[19]) temp[19:3]<=temp[19:3]^polynomial;
          else if(temp[18]) temp[18:2]<=temp[18:2]^polynomial;
          else if(temp[17]) temp[17:1]<=temp[17:1]^polynomial;
          else if(temp[16]) temp[16:0]<=temp[16:0]^polynomial;
          else   crc<=temp[15:0];    
          end
 end  
endmodule


testbench:

module testbench;
// Inputs
reg clk;
reg [7:0] data;
reg rst_n;

// Outputs
wire [15:0] crc;

// Instantiate the Unit Under Test (UUT)
crc uut (
.clk(clk), 
.data(data), 
.rst_n(rst_n), 
.crc(crc)
);
initial begin
// Initialize Inputs

clk=0;
data=0;
rst_n=0;
#100

data =8'b10110110;
rst_n = 1;

// Wait 100 ns for global reset to finish
#50;
rst_n =0;
#50
rst_n =1;
                #1000

data =8'b01001100;
rst_n = 1;
#50;
rst_n =0;
#50
rst_n =1;
#1000

data =8'b10110011;
rst_n = 1;
#50;
rst_n =0;
#50
rst_n =1;
#1000

data =8'b10010110;
rst_n = 1;
#50;
rst_n =0;
#50
rst_n =1;
#1000

data =8'b10100101;
rst_n = 1;
#50;
rst_n =0;
#50
rst_n =1;
// Add stimulus here
end
      always #10 clk=~clk;
endmodule


下面是仿真结果:
testbench中加了5组输入的data值,仿真结果已通过软件《CRC计算器》验证,全部正确。

 

 

 

 

 

  • 15
    点赞
  • 140
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: FPGA CRC校验原理是使用循环冗余校验算法对数据进行校验。CRC校验通常用于数据传输或存储时,以防止数据在传输或存储过程中被破坏或篡改。在FPGA中,CRC校验器通常是由硬件实现的模块,可以通过FPGA的可编程逻辑进行设计。 CRC校验原理是将需要校验的数据分成一定大小的数据块,每个数据块都传送时进行校验。校验数据块时,FPGA会计算数据块的CRC码,然后与数据传输或存储设备中存储的CRC码进行比较。 在FPGA中,校验数据块的过程通常由硬件实现的模块完成。该模块会输入需要校验的数据块和预定义的CRC码种子,然后按照预定义的算法进行计算。计算完成后,该模块会输出新的CRC码,然后FPGA会与存储或传输设备中的CRC码进行比较,以确定数据块是否正确。 总的来说,FPGA CRC校验是一种用于数据传输或存储过程中数据校验的方法。在硬件实现中,FPGA会根据预定义的算法对数据进行计算,并与存储或传输设备中存储的CRC码进行比较,以确保数据传输或存储的可靠性。 ### 回答2: FPGA CRC校验是一种基于硬件的数据校验方法,它通过将待校验的数据流和预定的校验码值一起输入到FPGA芯片中,利用硬件电路实现CRC计算。CRC校验是一种能够检测数据传输过程中是否发生了错误的技术,它可以检测到单比特错、双比特错甚至更多比特的错。 具体来说,FPGA CRC校验的实现原理是通过将输入的数据流和预定义的CRC校验码一同送入CRC电路中,经过一系列的移位、异或和反转操作得到校验结果,然后将校验值与输出的校验结果比较,如果出现差错,则表示数据包出现错误。FPGA CRC校验是一种高效、稳定的校验方法,它广泛应用于数字通信、网络传输、存储设备等领域。 总之,FPGA CRC校验是一种依靠硬件实现的数据完整性校验方式,它通过预定义的校验算法计算出数据包的校验值,并与实际校验结果进行比较,从而检测数据传输过程中是否发生了差错,保证数据在传输过程中的安全可靠。 ### 回答3: FPGA作为一种灵活可编程的集成电路,可以灵活地实现各种数字电子系统中的处理、控制、通信、计算等功能,其中CRC校验是一种应用比较广泛的数据校验协议。其原理是在传输数据的时候,通过添加一个校验码到数据后面,接收端可以通过对数据和校验码进行计算来验证数据的准确性。 在FPGA中实现CRC校验,通常采用硬件的实现方式,首先通过CRC算法计算生成CRC校验码表,然后将该表存储在FPGA中。在数据传输过程中,FPGA通过对数据和CRC校验码表进行异或运算,得到计算结果,并将该计算结果加到原始数据的末尾,然后将数据和校验码一起发送。接收端接收数据后,同样对数据和CRC校验码表进行异或计算,并将其与接收到的校验码进行比较,如果相同则表明数据传输正确,否则需要重新传输。 FPGA实现CRC校验具有高速、低功耗、可靠性强等优点,特别适合高速数据传输领域,如网络通信、存储设备、无线通信等领域。此外,FPGA还具有可编程性强、适应性广泛等优点,可以根据不同应用需求进行优化设计,提高数据的可靠性和传输速率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值