基于FPGA的CRC32_8原理与实现

别来无恙 提交于 2020-08-04 09:59:25

最近在开发万兆网mac,由于发送和接收要在数据的尾端添加或者校验CRC32_64,决定写一篇关于CRC的文章,此博客的意义在于帮助自己和大家理解FPGA并行CRC的实现方式,为了简单说明,以CRC32_8为例讲解。
1、CRC32_8生成多项式:CRC32=X32+X26+X23+X22+X16+X12+X11+X10+X8+X7+X5+X4+X2+X1+1
2、CRC校验原理
(1)将发送数据左移K位,右侧补零(其中K为生成多项式最高次幂);
(2)用移位补零后的数据对G(x)进行模2除法(其实就是异或运算);
(3)用得到的余数即为该数据的CRC校验码;
3、首先采用串行方式实现CRC32_8的校验功能
在这里插入图片描述 4、数据由高位依次输入,当输入最后1bit数据时,CRC寄存器中即为校验值,同时如果将D0时刻的表达式表示出来,则为并行CRC的计算公式。
CRC[0] = D[6] ^ D[0] ^ C[24] ^ C[30];
CRC[1] = D[7] ^ D[6] ^ D[1] ^ D[0] ^ C[24] ^ C[25] ^ C[30] ^ C[31];
CRC[2] = D[7] ^ D[6] ^ D[2] ^ D[1] ^ D[0] ^ C[24] ^ C[25] ^ C[26] ^ C[30] ^ C[31];
CRC[3] = D[7] ^ D[3] ^ D[2] ^ D[1] ^ C[25] ^ C[26] ^ C[27] ^ C[31];
CRC[4] = D[6] ^ D[4] ^ D[3] ^ D[2] ^ D[0] ^ C[24] ^ C[26] ^ C[27] ^ C[28] ^ C[30];
CRC[5] = D[7] ^ D[6] ^ D[5] ^ D[4] ^ D[3] ^ D[1] ^ D[0] ^ C[24] ^ C[25] ^ C[27] ^ C[28] ^ C[29] ^ C[30] ^ C[31];
CRC[6] = D[7] ^ D[6] ^ D[5] ^ D[4] ^ D[2] ^ D[1] ^ C[25] ^ C[26] ^ C[28] ^ C[29] ^ C[30] ^ C[31];
CRC[7] = D[7] ^ D[5] ^ D[3] ^ D[2] ^ D[0] ^ C[24] ^ C[26] ^ C[27] ^ C[29] ^ C[31];
CRC[8] = D[4] ^ D[3] ^ D[1] ^ D[0] ^ C[0] ^ C[24] ^ C[25] ^ C[27] ^ C[28];
CRC[9] = D[5] ^ D[4] ^ D[2] ^ D[1] ^ C[1] ^ C[25] ^ C[26] ^ C[28] ^ C[29];

CRC[30] = D[7] ^ D[4] ^ C[22] ^ C[28] ^ C[31];
CRC[31] = D[5] ^ C[23] ^ C[29];
由于表中数据较长,在此不做全部列出。
5、FPGA中v代码





















`timescale 1ns / 1ps

module CRC32_8_TEST(
	input clk,
	input rst_n,
	input clr,//同步清零
	input  din_vld,
	input [7:0] din,
	
	output reg dout_vld,
	output reg [31:0] dout//crc校验结果
);

// polynomial: 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
// data width: 8

wire [7:0] D;
wire [31:0] C;
	
assign D = din;
assign C = dout;

always@(posedge clk or negedge rst_n)begin
	if(!rst_n)
		dout <= 32'hffff_ffff;
	else if(clr)
		dout <= 32'hffff_ffff;
	else if(din_vld)begin
		dout[0] <= D[6] ^ D[0] ^ C[24] ^ C[30];
		dout[1] <= D[7] ^ D[6] ^ D[1] ^ D[0] ^ C[24] ^ C[25] ^ C[30] ^ C[31];
		dout[2] <= D[7] ^ D[6] ^ D[2] ^ D[1] ^ D[0] ^ C[24] ^ C[25] ^ C[26] ^ C[30] ^ C[31];
		dout[3] <= D[7] ^ D[3] ^ D[2] ^ D[1] ^ C[25] ^ C[26] ^ C[27] ^ C[31];
		dout[4] <= D[6] ^ D[4] ^ D[3] ^ D[2] ^ D[0] ^ C[24] ^ C[26] ^ C[27] ^ C[28] ^ C[30];
		dout[5] <= D[7] ^ D[6] ^ D[5] ^ D[4] ^ D[3] ^ D[1] ^ D[0] ^ C[24] ^ C[25] ^ C[27] ^ C[28] ^ C[29] ^ C[30] ^ C[31];
		dout[6] <= D[7] ^ D[6] ^ D[5] ^ D[4] ^ D[2] ^ D[1] ^ C[25] ^ C[26] ^ C[28] ^ C[29] ^ C[30] ^ C[31];
		dout[7] <= D[7] ^ D[5] ^ D[3] ^ D[2] ^ D[0] ^ C[24] ^ C[26] ^ C[27] ^ C[29] ^ C[31];
		dout[8] <= D[4] ^ D[3] ^ D[1] ^ D[0] ^ C[0] ^ C[24] ^ C[25] ^ C[27] ^ C[28];
		dout[9] <= D[5] ^ D[4] ^ D[2] ^ D[1] ^ C[1] ^ C[25] ^ C[26] ^ C[28] ^ C[29];
		dout[10] <= D[5] ^ D[3] ^ D[2] ^ D[0] ^ C[2] ^ C[24] ^ C[26] ^ C[27] ^ C[29];
		dout[11] <= D[4] ^ D[3] ^ D[1] ^ D[0] ^ C[3] ^ C[24] ^ C[25] ^ C[27] ^ C[28];
		dout[12] <= D[6] ^ D[5] ^ D[4] ^ D[2] ^ D[1] ^ D[0] ^ C[4] ^ C[24] ^ C[25] ^ C[26] ^ C[28] ^ C[29] ^ C[30];
		dout[13] <= D[7] ^ D[6] ^ D[5] ^ D[3] ^ D[2] ^ D[1] ^ C[5] ^ C[25] ^ C[26] ^ C[27] ^ C[29] ^ C[30] ^ C[31];
		dout[14] <= D[7] ^ D[6] ^ D[4] ^ D[3] ^ D[2] ^ C[6] ^ C[26] ^ C[27] ^ C[28] ^ C[30] ^ C[31];
		dout[15] <= D[7] ^ D[5] ^ D[4] ^ D[3] ^ C[7] ^ C[27] ^ C[28] ^ C[29] ^ C[31];
		dout[16] <= D[5] ^ D[4] ^ D[0] ^ C[8] ^ C[24] ^ C[28] ^ C[29];
		dout[17] <= D[6] ^ D[5] ^ D[1] ^ C[9] ^ C[25] ^ C[29] ^ C[30];
		dout[18] <= D[7] ^ D[6] ^ D[2] ^ C[10] ^ C[26] ^ C[30] ^ C[31];
		dout[19] <= D[7] ^ D[3] ^ C[11] ^ C[27] ^ C[31];
		dout[20] <= D[4] ^ C[12] ^ C[28];
		dout[21] <= D[5] ^ C[13] ^ C[29];
		dout[22] <= D[0] ^ C[14] ^ C[24];
		dout[23] <= D[6] ^ D[1] ^ D[0] ^ C[15] ^ C[24] ^ C[25] ^ C[30];
		dout[24] <= D[7] ^ D[2] ^ D[1] ^ C[16] ^ C[25] ^ C[26] ^ C[31];
		dout[25] <= D[3] ^ D[2] ^ C[17] ^ C[26] ^ C[27];
		dout[26] <= D[6] ^ D[4] ^ D[3] ^ D[0] ^ C[18] ^ C[24] ^ C[27] ^ C[28] ^ C[30];
		dout[27] <= D[7] ^ D[5] ^ D[4] ^ D[1] ^ C[19] ^ C[25] ^ C[28] ^ C[29] ^ C[31];
		dout[28] <= D[6] ^ D[5] ^ D[2] ^ C[20] ^ C[26] ^ C[29] ^ C[30];
		dout[29] <= D[7] ^ D[6] ^ D[3] ^ C[21] ^ C[27] ^ C[30] ^ C[31];
		dout[30] <= D[7] ^ D[4] ^ C[22] ^ C[28] ^ C[31];
		dout[31] <= D[5] ^ C[23] ^ C[29];
	end
end

always@(posedge clk or negedge rst_n)begin
	if(!rst_n)
		dout_vld <= 0;
	else 
		dout_vld <= din_vld;
end

endmodule

6、当8位数据输入为0xAB时,软件工具输出
在这里插入图片描述
ISE仿真输出
在这里插入图片描述
可知,当初始条件相同时,逻辑代码与工具生成的CRC校验是相同的,可以验证,编写的逻辑代码正确。
7、由CRC32_8可知CRC32_64的相关代码过程,由于原理基本相同,不在赘述。




标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!