CRC校验:
CRC即循环冗余校验码:是数据通信领域中最常用的一种查错校验码,其特征是信息字段和校验字段的长度可以任意选定。循环冗余检查(CRC)是一种数据传输检错功能,对数据进行多项式计算,并将得到的结果附在帧的后面,接收设备也执行类似的算法,以保证数据传输的正确性和完整性。
现假设选择的CRC生成多项式为G(X) = X4 + X3 + 1,要求出二进制序列10110011的CRC校验码。下面是具体的计算过程:
①将多项式转化为二进制序列,由G(X) = X4 + X3 + 1可知二进制一种有五位,第4位、第三位和第零位分别为1,则序列为11001
②多项式的位数位5,则在数据帧的后面加上(5-1)位0,数据帧变为101100110000,然后使用模2除法除以除数11001,得到余数。
③将计算出来的CRC校验码添加在原始帧的后面,真正的数据帧为101100110100,再把这个数据帧发送到接收端。
④接收端收到数据帧后,用上面选定的除数,用模2除法除去,验证余数是否为0,如果为0,则说明数据帧没有出错。
CRC 生成多项式:
是接受方和发送方的一个约定,也就是一个二进制数,在整个传输过程中,这个数始终保持不变。
在发送方,利用生成多项式对信息多项式做模2除生成校验码。在接受方利用生成多项式对收到的编码多项式做模2除检测和确定错误位置。
应满足以下条件:
a、生成多项式的最高位和最低位必须为1。
b、当被传送信息(CRC码)任何一位发生错误时,被生成多项式做模2除后应该使余数不为0。
c、不同位发生错误时,应该使余数不同。
d、对余数继续做模2除,应使余数循环。
将这些要求反映为数学关系是比较复杂的。但可以从有关资料查到常用的对应于不同码制的生成多项式如下:
CRC校验在线工具 在线网页生成工具
打开http://www.easics.com/webtools/crctool,根据需要设置CRC的多项式参数,点击生成Verilog或VHDL模块,此循环CRC校验模块的CRC_in初始输入为全1。网页工具如下图所示:
下面为此在线工具生成的CRC-12的40bit数据帧的CRC校验模块:
////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 1999-2008 Easics NV.
// This source file may be used and distributed without restriction
// provided that this copyright statement is not removed from the file
// and that any derivative work contains the original copyright notice
// and the associated disclaimer.
//
// THIS SOURCE FILE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS
// OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
// WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// Purpose : synthesizable CRC function
// * polynomial: x^12 + x^6 + x^4 + x^1 + 1
// * data width: 40
//
// Info : tools@easics.be
// http://www.easics.com
////////////////////////////////////////////////////////////////////////////////
module CRC12_D40;
// polynomial: x^12 + x^6 + x^4 + x^1 + 1
// data width: 40
// convention: the first serial bit is D[39]
function [11:0] nextCRC12_D40;
input [39:0] Data;
input [11:0] crc;
reg [39:0] d;
reg [11:0] c;
reg [11:0] newcrc;
begin
d = Data;
c = crc;
newcrc[0] = d[38] ^ d[36] ^ d[34] ^ d[33] ^ d[32] ^ d[30] ^ d[27] ^ d[23] ^ d[20] ^ d[18] ^ d[16] ^ d[11] ^ d[8] ^ d[6] ^ d[0] ^ c[2] ^ c[4] ^ c[5] ^ c[6] ^ c[8] ^ c[10];
newcrc[1] = d[39] ^ d[38] ^ d[37] ^ d[36] ^ d[35] ^ d[32] ^ d[31] ^ d[30] ^ d[28] ^ d[27] ^ d[24] ^ d[23] ^ d[21] ^ d[20] ^ d[19] ^ d[18] ^ d[17] ^ d[16] ^ d[12] ^ d[11] ^ d[9] ^ d[8] ^ d[7] ^ d[6] ^ d[1] ^ d[0] ^ c[0] ^ c[2] ^ c[3] ^ c[4] ^ c[7] ^ c[8] ^ c[9] ^ c[10] ^ c[11];
newcrc[2] = d[39] ^ d[38] ^ d[37] ^ d[36] ^ d[33] ^ d[32] ^ d[31] ^ d[29] ^ d[28] ^ d[25] ^ d[24] ^ d[22] ^ d[21] ^ d[20] ^ d[19] ^ d[18] ^ d[17] ^ d[13] ^ d[12] ^ d[10] ^ d[9] ^ d[8] ^ d[7] ^ d[2] ^ d[1] ^ c[0] ^ c[1] ^ c[3] ^ c[4] ^ c[5] ^ c[8] ^ c[9] ^ c[10] ^ c[11];
newcrc[3] = d[39] ^ d[38] ^ d[37] ^ d[34] ^ d[33] ^ d[32] ^ d[30] ^ d[29] ^ d[26] ^ d[25] ^ d[23] ^ d[22] ^ d[21] ^ d[20] ^ d[19] ^ d[18] ^ d[14] ^ d[13] ^ d[11] ^ d[10] ^ d[9] ^ d[8] ^ d[3] ^ d[2] ^ c[1] ^ c[2] ^ c[4] ^ c[5] ^ c[6] ^ c[9] ^ c[10] ^ c[11];
newcrc[4] = d[39] ^ d[36] ^ d[35] ^ d[32] ^ d[31] ^ d[26] ^ d[24] ^ d[22] ^ d[21] ^ d[19] ^ d[18] ^ d[16] ^ d[15] ^ d[14] ^ d[12] ^ d[10] ^ d[9] ^ d[8] ^ d[6] ^ d[4] ^ d[3] ^ d[0] ^ c[3] ^ c[4] ^ c[7] ^ c[8] ^ c[11];
newcrc[5] = d[37] ^ d[36] ^ d[33] ^ d[32] ^ d[27] ^ d[25] ^ d[23] ^ d[22] ^ d[20] ^ d[19] ^ d[17] ^ d[16] ^ d[15] ^ d[13] ^ d[11] ^ d[10] ^ d[9] ^ d[7] ^ d[5] ^ d[4] ^ d[1] ^ c[4] ^ c[5] ^ c[8] ^ c[9];
newcrc[6] = d[37] ^ d[36] ^ d[32] ^ d[30] ^ d[28] ^ d[27] ^ d[26] ^ d[24] ^ d[21] ^ d[17] ^ d[14] ^ d[12] ^ d[10] ^ d[5] ^ d[2] ^ d[0] ^ c[0] ^ c[2] ^ c[4] ^ c[8] ^ c[9];
newcrc[7] = d[38] ^ d[37] ^ d[33] ^ d[31] ^ d[29] ^ d[28] ^ d[27] ^ d[25] ^ d[22] ^ d[18] ^ d[15] ^ d[13] ^ d[11] ^ d[6] ^ d[3] ^ d[1] ^ c[0] ^ c[1] ^ c[3] ^ c[5] ^ c[9] ^ c[10];
newcrc[8] = d[39] ^ d[38] ^ d[34] ^ d[32] ^ d[30] ^ d[29] ^ d[28] ^ d[26] ^ d[23] ^ d[19] ^ d[16] ^ d[14] ^ d[12] ^ d[7] ^ d[4] ^ d[2] ^ c[0] ^ c[1] ^ c[2] ^ c[4] ^ c[6] ^ c[10] ^ c[11];
newcrc[9] = d[39] ^ d[35] ^ d[33] ^ d[31] ^ d[30] ^ d[29] ^ d[27] ^ d[24] ^ d[20] ^ d[17] ^ d[15] ^ d[13] ^ d[8] ^ d[5] ^ d[3] ^ c[1] ^ c[2] ^ c[3] ^ c[5] ^ c[7] ^ c[11];
newcrc[10] = d[36] ^ d[34] ^ d[32] ^ d[31] ^ d[30] ^ d[28] ^ d[25] ^ d[21] ^ d[18] ^ d[16] ^ d[14] ^ d[9] ^ d[6] ^ d[4] ^ c[0] ^ c[2] ^ c[3] ^ c[4] ^ c[6] ^ c[8];
newcrc[11] = d[37] ^ d[35] ^ d[33] ^ d[32] ^ d[31] ^ d[29] ^ d[26] ^ d[22] ^ d[19] ^ d[17] ^ d[15] ^ d[10] ^ d[7] ^ d[5] ^ c[1] ^ c[3] ^ c[4] ^ c[5] ^ c[7] ^ c[9];
nextCRC12_D40 = newcrc;
end
endfunction
endmodule