基于FPGA的CRC32_8原理与实现

最近在开发万兆网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的相关代码过程,由于原理基本相同,不在赘述。

  • 6
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
基于FPGA的HDMI CEC设计和实现是指使用可编程逻辑芯片(FPGA)来实现HDMI Consumer Electronics Control(CEC)的功能。 首先,需要了解HDMI CEC协议。HDMI CEC是一种通过HDMI连接的设备之间进行通信和控制的协议。它允许用户通过一个遥控器控制多个HDMI设备,实现统一的控制和交互。 实现基于FPGA的HDMI CEC功能的关键是通过HDMI接收和发送模块与其他HDMI设备进行通信。FPGA需要具备HDMI的接口和协议支持,以接收和发送HDMI的数据。 在HDMI接收模块中,FPGA需要解析从HDMI输入端口接收到的信号,提取出CEC数据,并根据CEC协议进行相关的处理。这包括解析CEC命令、地址识别、回复消息等。 在HDMI发送模块中,FPGA需要根据用户的操作或其他外部信号生成相应的CEC指令,并通过HDMI输出端口将指令发送给其他HDMI设备。这包括发送CEC命令、设备寻址、消息传递等。 实现基于FPGA的HDMI CEC功能还需要考虑相关的硬件和软件设计。硬件方面,需要选择适合的FPGA芯片和HDMI接口电路,并进行电路设计和布线。软件方面,需要编写FPGA的硬件描述语言(HDL)代码,以实现HDMI接收和发送模块的功能,并进行仿真和调试。 总结来说,基于FPGA的HDMI CEC设计和实现需要通过接收和发送模块实现与其他HDMI设备的通信,并根据CEC协议进行数据解析和处理。它能够实现多个HDMI设备之间的统一控制和交互,提供更便捷的用户体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值