CRC校验原理及其FPGA实现

269 阅读5分钟

CRC校验原理及其FPGA高效实现

引言

在数字通信和存储系统中,数据传输的可靠性至关重要。循环冗余校验(CRC)  作为一种高效、可靠的错误检测机制,被广泛应用于各类通信协议(如以太网、USB、CAN总线等)和存储系统。本文将深入探讨CRC校验的数学原理,并重点介绍其在FPGA上的高效实现方式。

一、CRC校验基础

1.1 什么是CRC校验?

CRC(Cyclic Redundancy Check)是一种基于多项式除法的错误检测编码技术。它通过在原始数据后附加一个校验码(冗余信息),使整个数据序列能被预定的生成多项式整除。接收端通过同样的多项式除法验证数据完整性。

1.2 CRC数学原理

  • 将数据视为二进制系数多项式

二进制数10110011,其中二进制数的每一位对应的是系数(),则对应多项式为:

1x7+0x6+1x5+1x4+0x3+0x2+1x1+11*x^7 + 0*x^6 + 1*x^5 + 1*x^4 + 0*x^3 + 0*x^2 + 1*x^1 + 1

可简写为: x7+x5+x4+x1+1x^7 + x^5 + x^4 + x^1 + 1

  • 使用预定义的生成多项式(如CRC-8: x8+x2+x+1x^8 + x^2 + x + 1
  • 进行模2多项式除法(异或运算)

模二运算除法(也称为GF(2)多项式除法)是循环冗余校验(CRC)的核心数学运算。这种特殊的除法在有限域(伽罗瓦域)中进行,具有独特的运算规则和特性。

模二运算基础

模二运算是在二元域(GF(2))中进行的运算,其基本规则:

  • 加法/减法 ≡ 异或(XOR)  运算:无进位/借位

    0 + 0 = 0    0 - 0 = 0
    0 + 1 = 1    0 - 1 = 1
    1 + 0 = 1    1 - 0 = 1
    1 + 1 = 0    1 - 1 = 0
    
  • 乘法 ≡ 与(AND)  运算:

    0 × 0 = 0
    0 × 1 = 0
    1 × 0 = 0
    1 × 1 = 1
    
模二除法特点
  • 使用异或运算代替传统减法
  • 无借位操作
  • 结果只有商和余数
  • 余数位数 = 除数位数 - 1
  • 余数即为CRC校验码

1.3 常见CRC标准

CRC算法参数与应用场景对照表

算法名称多项式公式宽度多项式初始值结果异或值输入反转输出反转应用场景
CRC-4/ITUx4+x+1x^4 + x + 14030000truetrueE-1通信线路多帧校验
CRC-5/EPCx5+x3+1x^5 + x^3 + 15090900falsefalseRFID电子标签(EPC Gen2标准)
CRC-5/ITUx5+x4+x2+1x^5 + x^4 + x^2 + 15150000truetrue早期电信设备控制信道
CRC-5/USBx5+x2+1x^5 + x^2 + 15051F1FtruetrueUSB信令包错误检测
CRC-6/ITUx6+x+1x^6 + x + 16030000truetrue低速串行通信(如旧式Modem)
CRC-7/MMCx7+x3+1x^7 + x^3 + 17090000falsefalseMMC/SD存储卡命令校验
CRC-8x8+x2+x+1x^8 + x^2 + x + 18070000falsefalseI²C/SMBus总线控制协议
CRC-8/ITUx8+x2+x+1x^8 + x^2 + x + 18070055falsefalseATM网络头部错误检测(HEC)
CRC-8/ROHCx8+x2+x+1x^8 + x^2 + x + 1807FF00truetrue移动网络鲁棒头压缩(ROHC协议)
CRC-8/MAXIMx8+x5+x4+1x^8 + x^5 + x^4 + 18310000truetrue1-Wire总线设备(如DS18B20)
CRC-16/IBMx16+x15+x2+1x^{16} + x^{15} + x^2 + 116800500000000truetrueModbus协议、USB数据包
CRC-16/MAXIMx16+x15+x2+1x^{16} + x^{15} + x^2 + 11680050000FFFFtruetrueMaxim芯片外设通信
CRC-16/USBx16+x15+x2+1x^{16} + x^{15} + x^2 + 1168005FFFFFFFFtruetrueUSB令牌包及数据完整性验证
CRC-16/MODBUSx16+x15+x2+1x^{16} + x^{15} + x^2 + 1168005FFFF0000truetrue工业Modbus-RTU协议
CRC-16/CCITTx16+x12+x5+1x^{16} + x^{12} + x^5 + 116102100000000truetrueX.25/V.41协议、蓝牙HCI
CRC-16/CCITT-FALSEx16+x12+x5+1x^{16} + x^{12} + x^5 + 1161021FFFF0000falsefalse嵌入式系统(非标准CCITT场景)
CRC-16/X25x16+x12+x5+1x^{16} + x^{12} + x^5 + 1161021FFFFFFFFtruetrue串行HDLC帧校验
CRC-16/XMODEMx16+x12+x5+1x^{16} + x^{12} + x^5 + 116102100000000falsefalseXMODEM文件传输协议、ZMODEM扩展
CRC-16/DNPx16+x13+x12+x11+x10+x8+x6+x5+x2+1x^{16} + x^{13} + x^{12} + x^{11} + x^{10} + x^8 + x^6 + x^5 + x^2 + 1163D650000FFFFtruetrue分布式网络协议(DNP3.0)
CRC-32x32+x26+x23+x22+x16+x12+x11+x10+x8+x7+x5+x4+x2+x+1x^{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 + 13204C11DB7FFFFFFFFFFFFFFFFtruetrue以太网、ZIP/RAR、PNG图像
CRC-32/MPEG-2x32+x26+x23+x22+x16+x12+x11+x10+x8+x7+x5+x4+x2+x+1x^{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 + 13204C11DB7FFFFFFFF00000000falsefalseMPEG-2传输流(TS包校验)

关键多项式说明

三、FPGA实现方法

3.1 串行实现(LFSR结构)

线性反馈移位寄存器(LFSR)是最基础的CRC实现方式,适合低速场景。

CRC-8串行实现(多项式:0x07)

module crc8_serial (
    input clk,
    input rst,
    input data_in,       // 串行输入数据
    input data_valid,    // 数据有效信号
    output reg [7:0] crc // CRC输出
);

always @(posedge clk) begin
    if (rst) begin
        crc <= 8'h00;  // 复位CRC寄存器
    end else if (data_valid) begin
        crc[0] <= data_in ^ crc[7];
        crc[1] <= crc[0] ^ (data_in ^ crc[7]);
        crc[2] <= crc[1] ^ (data_in ^ crc[7]);
        crc[3] <= crc[2];
        crc[4] <= crc[3];
        crc[5] <= crc[4];
        crc[6] <= crc[5];
        crc[7] <= crc[6];
    end
end

endmodule

3.2 并行实现(高效处理)

并行实现可同时处理多个数据位,极大提高吞吐量。

CRC-8并行实现(一次处理8位)

module crc8_parallel (
    input clk,
    input rst,
    input [7:0] data_in, // 8位并行输入
    input data_valid,
    output reg [7:0] crc
);

wire [7:0] next_crc;

always @(posedge clk) begin
    if (rst) crc <= 8'h00;
    else if (data_valid) crc <= next_crc;
end

// 并行CRC计算逻辑
assign next_crc[0] = data_in[6] ^ data_in[0] ^ crc[6];
assign next_crc[1] = data_in[7] ^ data_in[6] ^ data_in[1] ^ data_in[0] ^ crc[0] ^ crc[6] ^ crc[7];
assign next_crc[2] = data_in[7] ^ data_in[6] ^ data_in[2] ^ data_in[1] ^ data_in[0] ^ crc[0] ^ crc[1] ^ crc[6] ^ crc[7];
assign next_crc[3] = data_in[7] ^ data_in[3] ^ data_in[2] ^ data_in[1] ^ crc[1] ^ crc[2] ^ crc[7];
assign next_crc[4] = data_in[7] ^ data_in[4] ^ data_in[3] ^ data_in[2] ^ crc[2] ^ crc[3] ^ crc[7];
assign next_crc[5] = data_in[5] ^ data_in[4] ^ data_in[3] ^ crc[3] ^ crc[4];
assign next_crc[6] = data_in[6] ^ data_in[5] ^ data_in[4] ^ crc[4] ^ crc[5];
assign next_crc[7] = data_in[7] ^ data_in[6] ^ data_in[5] ^ crc[5] ^ crc[6];

endmodule

3.3 IP核实现

有些FPGA厂商会提供CRC IP核,根据用户手册配置使用即可,需注意时序。

image.png

三、CRC在线计算网站

CRC(循环冗余校验)在线计算_ip33.com

CRC在线计算