CRC校验原理及其FPGA高效实现
引言
在数字通信和存储系统中,数据传输的可靠性至关重要。循环冗余校验(CRC) 作为一种高效、可靠的错误检测机制,被广泛应用于各类通信协议(如以太网、USB、CAN总线等)和存储系统。本文将深入探讨CRC校验的数学原理,并重点介绍其在FPGA上的高效实现方式。
一、CRC校验基础
1.1 什么是CRC校验?
CRC(Cyclic Redundancy Check)是一种基于多项式除法的错误检测编码技术。它通过在原始数据后附加一个校验码(冗余信息),使整个数据序列能被预定的生成多项式整除。接收端通过同样的多项式除法验证数据完整性。
1.2 CRC数学原理
- 将数据视为二进制系数多项式
二进制数10110011,其中二进制数的每一位对应的是系数(),则对应多项式为:
<math xmlns="http://www.w3.org/1998/Math/MathML"> 1 ∗ x 7 + 0 ∗ x 6 + 1 ∗ x 5 + 1 ∗ x 4 + 0 ∗ x 3 + 0 ∗ x 2 + 1 ∗ x 1 + 1 1*x^7 + 0*x^6 + 1*x^5 + 1*x^4 + 0*x^3 + 0*x^2 + 1*x^1 + 1 </math>1∗x7+0∗x6+1∗x5+1∗x4+0∗x3+0∗x2+1∗x1+1
可简写为: <math xmlns="http://www.w3.org/1998/Math/MathML"> x 7 + x 5 + x 4 + x 1 + 1 x^7 + x^5 + x^4 + x^1 + 1 </math>x7+x5+x4+x1+1
- 使用预定义的生成多项式(如CRC-8: <math xmlns="http://www.w3.org/1998/Math/MathML"> x 8 + x 2 + x + 1 x^8 + x^2 + x + 1 </math>x8+x2+x+1)
- 进行模2多项式除法(异或运算)
模二运算除法(也称为GF(2)多项式除法)是循环冗余校验(CRC)的核心数学运算。这种特殊的除法在有限域(伽罗瓦域)中进行,具有独特的运算规则和特性。
模二运算基础
模二运算是在二元域(GF(2))中进行的运算,其基本规则:
加法/减法 ≡ 异或(XOR) 运算:无进位/借位
ini0 + 0 = 0 0 - 0 = 0 0 + 1 = 1 0 - 1 = 1 1 + 0 = 1 1 - 0 = 1 1 + 1 = 0 1 - 1 = 0
乘法 ≡ 与(AND) 运算:
ini0 × 0 = 0 0 × 1 = 0 1 × 0 = 0 1 × 1 = 1
模二除法特点
- 使用异或运算代替传统减法
- 无借位操作
- 结果只有商和余数
- 余数位数 = 除数位数 - 1
- 余数即为CRC校验码
1.3 常见CRC标准
CRC算法参数与应用场景对照表
算法名称 | 多项式公式 | 宽度 | 多项式 | 初始值 | 结果异或值 | 输入反转 | 输出反转 | 应用场景 |
---|---|---|---|---|---|---|---|---|
CRC-4/ITU | <math xmlns="http://www.w3.org/1998/Math/MathML"> x 4 + x + 1 x^4 + x + 1 </math>x4+x+1 | 4 | 03 | 00 | 00 | true | true | E-1通信线路多帧校验 |
CRC-5/EPC | <math xmlns="http://www.w3.org/1998/Math/MathML"> x 5 + x 3 + 1 x^5 + x^3 + 1 </math>x5+x3+1 | 5 | 09 | 09 | 00 | false | false | RFID电子标签(EPC Gen2标准) |
CRC-5/ITU | <math xmlns="http://www.w3.org/1998/Math/MathML"> x 5 + x 4 + x 2 + 1 x^5 + x^4 + x^2 + 1 </math>x5+x4+x2+1 | 5 | 15 | 00 | 00 | true | true | 早期电信设备控制信道 |
CRC-5/USB | <math xmlns="http://www.w3.org/1998/Math/MathML"> x 5 + x 2 + 1 x^5 + x^2 + 1 </math>x5+x2+1 | 5 | 05 | 1F | 1F | true | true | USB信令包错误检测 |
CRC-6/ITU | <math xmlns="http://www.w3.org/1998/Math/MathML"> x 6 + x + 1 x^6 + x + 1 </math>x6+x+1 | 6 | 03 | 00 | 00 | true | true | 低速串行通信(如旧式Modem) |
CRC-7/MMC | <math xmlns="http://www.w3.org/1998/Math/MathML"> x 7 + x 3 + 1 x^7 + x^3 + 1 </math>x7+x3+1 | 7 | 09 | 00 | 00 | false | false | MMC/SD存储卡命令校验 |
CRC-8 | <math xmlns="http://www.w3.org/1998/Math/MathML"> x 8 + x 2 + x + 1 x^8 + x^2 + x + 1 </math>x8+x2+x+1 | 8 | 07 | 00 | 00 | false | false | I²C/SMBus总线控制协议 |
CRC-8/ITU | <math xmlns="http://www.w3.org/1998/Math/MathML"> x 8 + x 2 + x + 1 x^8 + x^2 + x + 1 </math>x8+x2+x+1 | 8 | 07 | 00 | 55 | false | false | ATM网络头部错误检测(HEC) |
CRC-8/ROHC | <math xmlns="http://www.w3.org/1998/Math/MathML"> x 8 + x 2 + x + 1 x^8 + x^2 + x + 1 </math>x8+x2+x+1 | 8 | 07 | FF | 00 | true | true | 移动网络鲁棒头压缩(ROHC协议) |
CRC-8/MAXIM | <math xmlns="http://www.w3.org/1998/Math/MathML"> x 8 + x 5 + x 4 + 1 x^8 + x^5 + x^4 + 1 </math>x8+x5+x4+1 | 8 | 31 | 00 | 00 | true | true | 1-Wire总线设备(如DS18B20) |
CRC-16/IBM | <math xmlns="http://www.w3.org/1998/Math/MathML"> x 16 + x 15 + x 2 + 1 x^{16} + x^{15} + x^2 + 1 </math>x16+x15+x2+1 | 16 | 8005 | 0000 | 0000 | true | true | Modbus协议、USB数据包 |
CRC-16/MAXIM | <math xmlns="http://www.w3.org/1998/Math/MathML"> x 16 + x 15 + x 2 + 1 x^{16} + x^{15} + x^2 + 1 </math>x16+x15+x2+1 | 16 | 8005 | 0000 | FFFF | true | true | Maxim芯片外设通信 |
CRC-16/USB | <math xmlns="http://www.w3.org/1998/Math/MathML"> x 16 + x 15 + x 2 + 1 x^{16} + x^{15} + x^2 + 1 </math>x16+x15+x2+1 | 16 | 8005 | FFFF | FFFF | true | true | USB令牌包及数据完整性验证 |
CRC-16/MODBUS | <math xmlns="http://www.w3.org/1998/Math/MathML"> x 16 + x 15 + x 2 + 1 x^{16} + x^{15} + x^2 + 1 </math>x16+x15+x2+1 | 16 | 8005 | FFFF | 0000 | true | true | 工业Modbus-RTU协议 |
CRC-16/CCITT | <math xmlns="http://www.w3.org/1998/Math/MathML"> x 16 + x 12 + x 5 + 1 x^{16} + x^{12} + x^5 + 1 </math>x16+x12+x5+1 | 16 | 1021 | 0000 | 0000 | true | true | X.25/V.41协议、蓝牙HCI |
CRC-16/CCITT-FALSE | <math xmlns="http://www.w3.org/1998/Math/MathML"> x 16 + x 12 + x 5 + 1 x^{16} + x^{12} + x^5 + 1 </math>x16+x12+x5+1 | 16 | 1021 | FFFF | 0000 | false | false | 嵌入式系统(非标准CCITT场景) |
CRC-16/X25 | <math xmlns="http://www.w3.org/1998/Math/MathML"> x 16 + x 12 + x 5 + 1 x^{16} + x^{12} + x^5 + 1 </math>x16+x12+x5+1 | 16 | 1021 | FFFF | FFFF | true | true | 串行HDLC帧校验 |
CRC-16/XMODEM | <math xmlns="http://www.w3.org/1998/Math/MathML"> x 16 + x 12 + x 5 + 1 x^{16} + x^{12} + x^5 + 1 </math>x16+x12+x5+1 | 16 | 1021 | 0000 | 0000 | false | false | XMODEM文件传输协议、ZMODEM扩展 |
CRC-16/DNP | <math xmlns="http://www.w3.org/1998/Math/MathML"> x 16 + x 13 + x 12 + x 11 + x 10 + x 8 + x 6 + x 5 + x 2 + 1 x^{16} + x^{13} + x^{12} + x^{11} + x^{10} + x^8 + x^6 + x^5 + x^2 + 1 </math>x16+x13+x12+x11+x10+x8+x6+x5+x2+1 | 16 | 3D65 | 0000 | FFFF | true | true | 分布式网络协议(DNP3.0) |
CRC-32 | <math xmlns="http://www.w3.org/1998/Math/MathML"> 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 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 </math>x32+x26+x23+x22+x16+x12+x11+x10+x8+x7+x5+x4+x2+x+1 | 32 | 04C11DB7 | FFFFFFFF | FFFFFFFF | true | true | 以太网、ZIP/RAR、PNG图像 |
CRC-32/MPEG-2 | <math xmlns="http://www.w3.org/1998/Math/MathML"> 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 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 </math>x32+x26+x23+x22+x16+x12+x11+x10+x8+x7+x5+x4+x2+x+1 | 32 | 04C11DB7 | FFFFFFFF | 00000000 | false | false | MPEG-2传输流(TS包校验) |
关键多项式说明
三、FPGA实现方法
3.1 串行实现(LFSR结构)
线性反馈移位寄存器(LFSR)是最基础的CRC实现方式,适合低速场景。
CRC-8串行实现(多项式:0x07)
verilog
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位)
verilog
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核,根据用户手册配置使用即可,需注意时序。
