CRC校验 - 基于FPGA的实现
0 背景
CRC即循环冗余校验:常用于数据通信领域中,通常由发送端添加校验码于单帧数据的尾部,并由接受方进行提取和校验该帧数据传输是否正确。
循环冗余检查(CRC)是一种数据传输检错功能,对数据进行多项式计算,并将得到的结果附在帧的后面,接收设备也执行类似的算法,以保证数据传输的正确性和完整性。
1 FPGA硬件实现CRC校验
CRC计算采用模2除法,本质是对应比特位的异或运算。计算原理我仔细推究,通常硬件实现方式分为2种:
1- 串行计算,并输出CRC校验码。好处:顺序计算,便于理解和编程实现,且节省资源; 缺点:不如并行计算速率快;
2- 并行计算,并输出CRC校验码。优缺点与串行计算相反;
2 FPGA实现CRC校验代码生成工具
开源工具已有基于FPGA的CRC校验代码生成工具(轮子已造好) 链接地址:https://www.easics.com/crctool/
CRC校验代码在线计算工具。 链接地址:https://www.easics.com/crctool/
3 举例:CRC-8 MAXIM --- X^8 + X^5 + X^4 + 1
该校验模型参数配置信息及FPGA代码实现如下:采用并行计算方式
`timescale 1ns/1ps
//
参数模型:CRC-8 MAXIM --- X^8 + X^5 + X^4 + 1
输入位宽:8bit
初始值:0x00
结果异或值:0x00
CRC在线计算网址:http://www.ip33.com/crc.html
***该参数模型:输入数据按高低位反转
***该参数模型:输出数据按高低位反转
//
module crc8_test (
input wire I_clk , //
input wire I_reset , //
input wire i_din_valid , //输入数据有效
input wire [7:0] i_din , //输入数据
output wire o_dout_valid , //输出CRC值有效
output wire [7:0] o_dout //输出CRC
);
reg [7:0] r_dout;
wire [7:0] d;
wire [7:0] c;
case1
输入数据按位不反转
// assign d = i_din;
default case
输入数据按位反转
assign d = {i_din[0],i_din[1],i_din[2],i_din[3],i_din[4],i_din[5],i_din[6],i_din[7]};
assign c = r_dout;
always @(posedge I_clk) begin
if (I_reset)
r_dout <= 8'h00; //初始值
else if (i_din_valid)
begin //计算逻辑
r_dout[0] <= d[6] ^ d[4] ^ d[3] ^ d[0] ^ c[0] ^ c[3] ^ c[4] ^ c[6];
r_dout[1] <= d[7] ^ d[5] ^ d[4] ^ d[1] ^ c[1] ^ c[4] ^ c[5] ^ c[7];
r_dout[2] <= d[6] ^ d[5] ^ d[2] ^ c[2] ^ c[5] ^ c[6];
r_dout[3] <= d[7] ^ d[6] ^ d[3] ^ c[3] ^ c[6] ^ c[7];
r_dout[4] <= d[7] ^ d[6] ^ d[3] ^ d[0] ^ c[0] ^ c[3] ^ c[6] ^ c[7];
r_dout[5] <= d[7] ^ d[6] ^ d[3] ^ d[1] ^ d[0] ^ c[0] ^ c[1] ^ c[3] ^ c[6] ^ c[7];
r_dout[6] <= d[7] ^ d[4] ^ d[2] ^ d[1] ^ c[1] ^ c[2] ^ c[4] ^ c[7];
r_dout[7] <= d[5] ^ d[3] ^ d[2] ^ c[2] ^ c[3] ^ c[5];
end
end
reg r_dout_valid = 0;
always @(posedge I_clk) //输入数据在一个时钟内完成CRC计算,下一个时钟输出
begin
r_dout_valid <= i_din_valid;
end
assign o_dout_valid = r_dout_valid;
default case
输出数据按位反转
assign o_dout = {r_dout[0],r_dout[1],r_dout[2],r_dout[3],r_dout[4],r_dout[5],r_dout[6],r_dout[7]};
// case1
// 输出数据不按位反转
// assign o_dout = r_dout ;
endmodule // end the crc8_test model;
4 仿真测试结果对比:CRC-8 MAXIM
输入数据为4字节:0x12 0x34 0x56 0x78
CRC-8 MAXIM校验结果:0x98
对比可知,FPGA仿真结果与CRC工具计算结果相等,测试通过。