欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

基于FPGA的CRC32_8原理与实现

程序员文章站 2022-06-22 22:59:29
最近在开发万兆网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+12、CRC校验原理(1)将发送数据左移K位,右侧补零(其中K为生成多项式最高次幂);(2)用移位补零后的数据对G(x)进行模2除法(其实就是异或运...

最近在开发万兆网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的校验功能
基于FPGA的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时,软件工具输出
基于FPGA的CRC32_8原理与实现
ISE仿真输出
基于FPGA的CRC32_8原理与实现
可知,当初始条件相同时,逻辑代码与工具生成的CRC校验是相同的,可以验证,编写的逻辑代码正确。
7、由CRC32_8可知CRC32_64的相关代码过程,由于原理基本相同,不在赘述。

本文地址:https://blog.csdn.net/sinat_39724439/article/details/107636537

相关标签: crc ISE fpga