CRC校验码

CRC校验码简介

  循环冗余码校验(Cyclical Redundancy Check),简称CRC。是数据通讯领域中最长用的一种差错校验码,其特征是信息字段和校验字段的长度可以任意选定。

CRC校验码原理

  循环冗余校验同其他差错检测方式一样,通过在要传输的k比特数据D后添加(n-k)比特冗余位(又称帧检验序列,Frame Check Sequence,FCS)F形成n比特的传输帧T,再将其发送出去。
  特别的,循环冗余校验提供一个预先设定的(n-k+1)比特整数P,并且要求添加的(n-k)比特F满足:
     T mod P == 0  
CRC校验码_第1张图片
基于上述要求,实际应用时,发送方和接收方按照下面方式通信:
  1.发送方和接收方在通信前,约定好整数P。
  2.发送方在发送前根据数据D确定满足(1)式的F,生成CRC码T。T即为数据位与校验位的拼接。发送T。
  接收方收到CRC码T,根据result = T mod P运算,当且仅当result = 0时接收方人为没错。

CRC公式

  模二运算采用无进位的二进制加法,相当于异或(XOR)运算操作。
  我们需要添加的帧序列F为:F = 2n-kD mod P;
CRC校验码_第2张图片

常用的CRC版本

常用的P应该满足:
  1.最高位和最低位都是1。
  2.当被传送信息的任何一位发生错误时,P不能被T整除。
  3.不同位发生错误时,余数应该不同。
  4.对余数继续做模二除法时,应当使余数循环。
下面展示常用的CRC版本

名称 多项式 表示法 应用举例
CRC-8 X8 + X2+ X + 1 0x107
CRC-12 X12 + X11 + X3 + X2 + X + 1 0x180F telecom systems
CRC-16 X16 + X15 + X2 + 1 0x180F Bisync, Modbus, USB, ANSI X3.28, SIA DC-07, many others; also known as CRC-16 and CRC-16-ANSI
CRC-CCITT X16 + X12 + X2 + 1 0x11021 ISO HDLC, ITU X.25, V.34/V.41/V.42, PPP-FCS
CRC-32 X32 + X26+X23 + X22 + X 16 + X12 + X11 + X10 + X8 + X7 + X5 + X4 + X2 + X + 1 0x104c11DB7 ZIP, RAR, IEEE 802 LAN/FDDI, IEEE 1394, PPP-FCS
CRC-32C X32 + X28+X27 + X26 + X 25 + X23 + X22 + X20 + X19 + X18 + X14 + X13 + X11 + X10 + X9 + X8 X6 + 1 0x11EDC6F41 iSCSI, SCTP, G.hn payload, SSE4.2, Btrfs, ext4, Ceph

利用FPGA实现以太网CRC校验

  千兆网中的校验码为CRC32。
  根据CRC32的多项式可以画出移位寄存器连接图
CRC校验码_第3张图片

CRC计算过程

IEEE规定校验和解校验的默认初始状态都是全1.
  1.设置CRC寄存器,并全部赋值为1;
  2.将数据的最高位到最低位依次移入32位CRC寄存器中并在指定地方进行异或运算
  3.移入完成后32位寄存器中的值即为CRC校验位的值。
解校验时将信息位(以太网帧不包含7个0h55和1个0hd5的同步头)和校验位一起移入计算CRC的异或电路,异或电路中的值为解校验的结果,千兆网解校验的结果为32’h C704DD7B。

CRC计算代码

//***********************************************************************
//CRC32的生成多项式为:G(x)= x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 
//+ x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x^1 + 1

assign d = din;	
assign c = crc32_value;

always@(posedge sclk)
	if (dsin == 0)
		crc32_value <= 32'hFFFFFFFF;
	else
	begin
	    crc32_value[0]<=c[24]^c[30]^d[1]^d[7];
	    crc32_value[1]<=c[25]^c[31]^d[0]^d[6]^c[24]^c[30]^d[1]^d[7];
	    crc32_value[2]<=c[26]^d[5]^c[25]^c[31]^d[0]^d[6]^c[24]^c[30]^d[1]^d[7];
	    crc32_value[3]<=c[27]^d[4]^c[26]^d[5]^c[25]^c[31]^d[0]^d[6];
	    crc32_value[4]<=c[28]^d[3]^c[27]^d[4]^c[26]^d[5]^c[24]^c[30]^d[1]^d[7];
	    crc32_value[5]<=c[29]^d[2]^c[28]^d[3]^c[27]^d[4]^c[25]^c[31]^d[0]^d[6]^c[24]^c[30]^d[1]^d[7];
	    crc32_value[6]<=c[30]^d[1]^c[29]^d[2]^c[28]^d[3]^c[26]^d[5]^c[25]^c[31]^d[0]^d[6];
	    crc32_value[7]<=c[31]^d[0]^c[29]^d[2]^c[27]^d[4]^c[26]^d[5]^c[24]^d[7];
	    crc32_value[8]<=c[0]^c[28]^d[3]^c[27]^d[4]^c[25]^d[6]^c[24]^d[7];
	    crc32_value[9]<=c[1]^c[29]^d[2]^c[28]^d[3]^c[26]^d[5]^c[25]^d[6];
	    crc32_value[10]<=c[2]^c[29]^d[2]^c[27]^d[4]^c[26]^d[5]^c[24]^d[7];
	    crc32_value[11]<=c[3]^c[28]^d[3]^c[27]^d[4]^c[25]^d[6]^c[24]^d[7];
	    crc32_value[12]<=c[4]^c[29]^d[2]^c[28]^d[3]^c[26]^d[5]^c[25]^d[6]^c[24]^c[30]^d[1]^d[7];
	    crc32_value[13]<=c[5]^c[30]^d[1]^c[29]^d[2]^c[27]^d[4]^c[26]^d[5]^c[25]^c[31]^d[0]^d[6];
	    crc32_value[14]<=c[6]^c[31]^d[0]^c[30]^d[1]^c[28]^d[3]^c[27]^d[4]^c[26]^d[5];
	    crc32_value[15]<=c[7]^c[31]^d[0]^c[29]^d[2]^c[28]^d[3]^c[27]^d[4];
	    crc32_value[16]<=c[8]^c[29]^d[2]^c[28]^d[3]^c[24]^d[7];
	    crc32_value[17]<=c[9]^c[30]^d[1]^c[29]^d[2]^c[25]^d[6];
	    crc32_value[18]<=c[10]^c[31]^d[0]^c[30]^d[1]^c[26]^d[5];
	    crc32_value[19]<=c[11]^c[31]^d[0]^c[27]^d[4];
	    crc32_value[20]<=c[12]^c[28]^d[3];
	    crc32_value[21]<=c[13]^c[29]^d[2];
	    crc32_value[22]<=c[14]^c[24]^d[7];
	    crc32_value[23]<=c[15]^c[25]^d[6]^c[24]^c[30]^d[1]^d[7];
	    crc32_value[24]<=c[16]^c[26]^d[5]^c[25]^c[31]^d[0]^d[6];
	    crc32_value[25]<=c[17]^c[27]^d[4]^c[26]^d[5];
	    crc32_value[26]<=c[18]^c[28]^d[3]^c[27]^d[4]^c[24]^c[30]^d[1]^d[7];
	    crc32_value[27]<=c[19]^c[29]^d[2]^c[28]^d[3]^c[25]^c[31]^d[0]^d[6];
	    crc32_value[28]<=c[20]^c[30]^d[1]^c[29]^d[2]^c[26]^d[5];
	    crc32_value[29]<=c[21]^c[31]^d[0]^c[30]^d[1]^c[27]^d[4];
	    crc32_value[30]<=c[22]^c[31]^d[0]^c[28]^d[3];
	    crc32_value[31]<=c[23]^c[29]^d[2];
	end

你可能感兴趣的:(#,千兆以太网协议,fpga开发)