循环冗余校验码(CRC),简称循环码,是一种常用的、具有检错、纠错能力的校验码,在早期的通信中运用广泛。循环冗余校验码常用于外存储器和计算机同步通信的数据校验。
CRC码存储或传送后,在接收方进行校验过程,以判断数据是否有错,若有错则进行纠错。一个CRC码一定能被生成多项式整除,所以在接收方对码字用同样的生成多项式相除,如果余数为0,则码字没有错误;若余数不为0,则说明某位出错,不同的出错位置余数不同。对(n,k)码制,在生成多项式确定时,出错位置和余数的对应关系是确定的。
在通信系统中,载荷在进行信道编码前,首先进行CRC编码。在不同的标准中,CRC多项式可能会有不同。
当我们应用FPGA进行通信系统设计时,发射端数据需进行CRC校验、信道编码、加扰、调制等一系列处理,生成OFDM符号映射到天线端口,再进行模拟调制到中频或射频发射出去。
通常对于CRC校验,需考虑两个因素:一是输入数据位宽;二是CRC生成多项式。
数据位宽,根据系统设计需要确定,CRC生成多项式根据相关协议或标准确定。
例如,在5G NR中,CRC生成多项式有以下几种:
那么,我们怎么用verilog HDL或VHDL代码去实现呢?
首先,我们得明白CRC校验的原理,剩下的就是搬砖的事了。
人总是喜欢偷懒,“拿来主义”总是存在,并且甚嚣尘上。
于是,热心的码农们,一边写代码,一边维护着各种开源网站,各种技术博客,各种“号”。
于是,总有人在默默地为我们付出。
一个是easics,一个是outputlogic。
在easics的CRC Generation Tool中,我们选择好多项式,确定好位宽和输出语言,于是一个crc功能的verilog代码就生成了。
代码如下:
////////////////////////////////////////////////////////////////////////////////// Copyright (C) 1999-2008 Easics NV.// This source file may be used and distributed without restriction// provided that this copyright statement is not removed from the file// and that any derivative work contains the original copyright notice// and the associated disclaimer.//// THIS SOURCE FILE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS// OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED// WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.//// Purpose : synthesizable CRC function// * polynomial: x^24 + x^23 + x^18 + x^17 + x^14 + x^11 + x^10 + x^7 + x^6 + x^5 + x^4 + x^3 + x^1 + 1// * data width: 32//// Info : tools@easics.be// http://www.easics.com////////////////////////////////////////////////////////////////////////////////module CRC24_D32;
// polynomial: x^24 + x^23 + x^18 + x^17 + x^14 + x^11 + x^10 + x^7 + x^6 + x^5 + x^4 + x^3 + x^1 + 1 // data width: 32 // convention: the first serial bit is D[31] function [23:0] nextCRC24_D32;
input [31:0] Data; input [23:0] crc; reg [31:0] d; reg [23:0] c; reg [23:0] newcrc; begin d = Data; c = crc;
newcrc[0] = d[30] ^ d[27] ^ d[23] ^ d[22] ^ d[21] ^ d[20] ^ d[19] ^ d[18] ^ d[17] ^ d[16] ^ d[14] ^ d[10] ^ d[5] ^ d[4] ^ d[3] ^ d[2] ^ d[1] ^ d[0] ^ c[2] ^ c[6] ^ c[8] ^ c[9] ^ c[10] ^ c[11] ^ c[12] ^ c[13] ^ c[14] ^ c[15] ^ c[19] ^ c[22]; newcrc[1] = d[31] ^ d[30] ^ d[28] ^ d[27] ^ d[24] ^ d[16] ^ d[15] ^ d[14] ^ d[11] ^ d[10] ^ d[6] ^ d[0] ^ c[2] ^ c[3] ^ c[6] ^ c[7] ^ c[8] ^ c[16] ^ c[19] ^ c[20] ^ c[22] ^ c[23]; newcrc[2] = d[31] ^ d[29] ^ d[28] ^ d[25] ^ d[17] ^ d[16] ^ d[15] ^ d[12] ^ d[11] ^ d[7] ^ d[1] ^ c[3] ^ c[4] ^ c[7] ^ c[8] ^ c[9] ^ c[17] ^ c[20] ^ c[21] ^ c[23]; newcrc[3] = d[29] ^ d[27] ^ d[26] ^ d[23] ^ d[22] ^ d[21] ^ d[20] ^ d[19] ^ d[14] ^ d[13] ^ d[12] ^ d[10] ^ d[8] ^ d[5] ^ d[4] ^ d[3] ^ d[1] ^ d[0] ^ c[0] ^ c[2] ^ c[4] ^ c[5] ^ c[6] ^ c[11] ^ c[12] ^ c[13] ^ c[14] ^ c[15] ^ c[18] ^ c[19] ^ c[21]; newcrc[4] = d[28] ^ d[24] ^ d[19] ^ d[18] ^ d[17] ^ d[16] ^ d[15] ^ d[13] ^ d[11] ^ d[10] ^ d[9] ^ d[6] ^ d[3] ^ d[0] ^ c[1] ^ c[2] ^ c[3] ^ c[5] ^ c[7] ^ c[8] ^ c[9] ^ c[10] ^ c[11] ^ c[16] ^ c[20]; newcrc[5] = d[30] ^ d[29] ^ d[27] ^ d[25] ^ d[23] ^ d[22] ^ d[21] ^ d[12] ^ d[11] ^ d[7] ^ d[5] ^ d[3] ^ d[2] ^ d[0] ^ c[3] ^ c[4] ^ c[13] ^ c[14] ^ c[15] ^ c[17] ^ c[19] ^ c[21] ^ c[22]; newcrc[6] = d[31] ^ d[28] ^ d[27] ^ d[26] ^ d[24] ^ d[21] ^ d[20] ^ d[19] ^ d[18] ^ d[17] ^ d[16] ^ d[14] ^ d[13] ^ d[12] ^ d[10] ^ d[8] ^ d[6] ^ d[5] ^ d[2] ^ d[0] ^ c[0] ^ c[2] ^ c[4] ^ c[5] ^ c[6] ^ c[8] ^ c[9] ^ c[10] ^ c[11] ^ c[12] ^ c[13] ^ c[16] ^ c[18] ^ c[19] ^ c[20] ^ c[23]; newcrc[7] = d[30] ^ d[29] ^ d[28] ^ d[25] ^ d[23] ^ d[16] ^ d[15] ^ d[13] ^ d[11] ^ d[10] ^ d[9] ^ d[7] ^ d[6] ^ d[5] ^ d[4] ^ d[2] ^ d[0] ^ c[1] ^ c[2] ^ c[3] ^ c[5] ^ c[7] ^ c[8] ^ c[15] ^ c[17] ^ c[20] ^ c[21] ^ c[22]; newcrc[8] = d[31] ^ d[30] ^ d[29] ^ d[26] ^ d[24] ^ d[17] ^ d[16] ^ d[14] ^ d[12] ^ d[11] ^ d[10] ^ d[8] ^ d[7] ^ d[6] ^ d[5] ^ d[3] ^ d[1] ^ c[0] ^ c[2] ^ c[3] ^ c[4] ^ c[6] ^ c[8] ^ c[9] ^ c[16] ^ c[18] ^ c[21] ^ c[22] ^ c[23]; newcrc[9] = d[31] ^ d[30] ^ d[27] ^ d[25] ^ d[18] ^ d[17] ^ d[15] ^ d[13] ^ d[12] ^ d[11] ^ d[9] ^ d[8] ^ d[7] ^ d[6] ^ d[4] ^ d[2] ^ c[0] ^ c[1] ^ c[3] ^ c[4] ^ c[5] ^ c[7] ^ c[9] ^ c[10] ^ c[17] ^ c[19] ^ c[22] ^ c[23]; newcrc[10] = d[31] ^ d[30] ^ d[28] ^ d[27] ^ d[26] ^ d[23] ^ d[22] ^ d[21] ^ d[20] ^ d[17] ^ d[13] ^ d[12] ^ d[9] ^ d[8] ^ d[7] ^ d[4] ^ d[2] ^ d[1] ^ d[0] ^ c[0] ^ c[1] ^ c[4] ^ c[5] ^ c[9] ^ c[12] ^ c[13] ^ c[14] ^ c[15] ^ c[18] ^ c[19] ^ c[20] ^ c[22] ^ c[23]; newcrc[11] = d[31] ^ d[30] ^ d[29] ^ d[28] ^ d[24] ^ d[20] ^ d[19] ^ d[17] ^ d[16] ^ d[13] ^ d[9] ^ d[8] ^ d[4] ^ d[0] ^ c[0] ^ c[1] ^ c[5] ^ c[8] ^ c[9] ^ c[11] ^ c[12] ^ c[16] ^ c[20] ^ c[21] ^ c[22] ^ c[23]; newcrc[12] = d[31] ^ d[30] ^ d[29] ^ d[25] ^ d[21] ^ d[20] ^ d[18] ^ d[17] ^ d[14] ^ d[10] ^ d[9] ^ d[5] ^ d[1] ^ c[1] ^ c[2] ^ c[6] ^ c[9] ^ c[10] ^ c[12] ^ c[13] ^ c[17] ^ c[21] ^ c[22] ^ c[23]; newcrc[13] = d[31] ^ d[30] ^ d[26] ^ d[22] ^ d[21] ^ d[19] ^ d[18] ^ d[15] ^ d[11] ^ d[10] ^ d[6] ^ d[2] ^ c[2] ^ c[3] ^ c[7] ^ c[10] ^ c[11] ^ c[13] ^ c[14] ^ c[18] ^ c[22] ^ c[23]; newcrc[14] = d[31] ^ d[30] ^ d[21] ^ d[18] ^ d[17] ^ d[14] ^ d[12] ^ d[11] ^ d[10] ^ d[7] ^ d[5] ^ d[4] ^ d[2] ^ d[1] ^ d[0] ^ c[2] ^ c[3] ^ c[4] ^ c[6] ^ c[9] ^ c[10] ^ c[13] ^ c[22] ^ c[23]; newcrc[15] = d[31] ^ d[22] ^ d[19] ^ d[18] ^ d[15] ^ d[13] ^ d[12] ^ d[11] ^ d[8] ^ d[6] ^ d[5] ^ d[3] ^ d[2] ^ d[1] ^ c[0] ^ c[3] ^ c[4] ^ c[5] ^ c[7] ^ c[10] ^ c[11] ^ c[14] ^ c[23]; newcrc[16] = d[23] ^ d[20] ^ d[19] ^ d[16] ^ d[14] ^ d[13] ^ d[12] ^ d[9] ^ d[7] ^ d[6] ^ d[4] ^ d[3] ^ d[2] ^ c[1] ^ c[4] ^ c[5] ^ c[6] ^ c[8] ^ c[11] ^ c[12] ^ c[15]; newcrc[17] = d[30] ^ d[27] ^ d[24] ^ d[23] ^ d[22] ^ d[19] ^ d[18] ^ d[16] ^ d[15] ^ d[13] ^ d[8] ^ d[7] ^ d[2] ^ d[1] ^ d[0] ^ c[0] ^ c[5] ^ c[7] ^ c[8] ^ c[10] ^ c[11] ^ c[14] ^ c[15] ^ c[16] ^ c[19] ^ c[22]; newcrc[18] = d[31] ^ d[30] ^ d[28] ^ d[27] ^ d[25] ^ d[24] ^ d[22] ^ d[21] ^ d[18] ^ d[10] ^ d[9] ^ d[8] ^ d[5] ^ d[4] ^ d[0] ^ c[0] ^ c[1] ^ c[2] ^ c[10] ^ c[13] ^ c[14] ^ c[16] ^ c[17] ^ c[19] ^ c[20] ^ c[22] ^ c[23]; newcrc[19] = d[31] ^ d[29] ^ d[28] ^ d[26] ^ d[25] ^ d[23] ^ d[22] ^ d[19] ^ d[11] ^ d[10] ^ d[9] ^ d[6] ^ d[5] ^ d[1] ^ c[1] ^ c[2] ^ c[3] ^ c[11] ^ c[14] ^ c[15] ^ c[17] ^ c[18] ^ c[20] ^ c[21] ^ c[23]; newcrc[20] = d[30] ^ d[29] ^ d[27] ^ d[26] ^ d[24] ^ d[23] ^ d[20] ^ d[12] ^ d[11] ^ d[10] ^ d[7] ^ d[6] ^ d[2] ^ c[2] ^ c[3] ^ c[4] ^ c[12] ^ c[15] ^ c[16] ^ c[18] ^ c[19] ^ c[21] ^ c[22]; newcrc[21] = d[31] ^ d[30] ^ d[28] ^ d[27] ^ d[25] ^ d[24] ^ d[21] ^ d[13] ^ d[12] ^ d[11] ^ d[8] ^ d[7] ^ d[3] ^ c[0] ^ c[3] ^ c[4] ^ c[5] ^ c[13] ^ c[16] ^ c[17] ^ c[19] ^ c[20] ^ c[22] ^ c[23]; newcrc[22] = d[31] ^ d[29] ^ d[28] ^ d[26] ^ d[25] ^ d[22] ^ d[14] ^ d[13] ^ d[12] ^ d[9] ^ d[8] ^ d[4] ^ c[0] ^ c[1] ^ c[4] ^ c[5] ^ c[6] ^ c[14] ^ c[17] ^ c[18] ^ c[20] ^ c[21] ^ c[23]; newcrc[23] = d[29] ^ d[26] ^ d[22] ^ d[21] ^ d[20] ^ d[19] ^ d[18] ^ d[17] ^ d[16] ^ d[15] ^ d[13] ^ d[9] ^ d[4] ^ d[3] ^ d[2] ^ d[1] ^ d[0] ^ c[1] ^ c[5] ^ c[7] ^ c[8] ^ c[9] ^ c[10] ^ c[11] ^ c[12] ^ c[13] ^ c[14] ^ c[18] ^ c[21]; nextCRC24_D32 = newcrc; end endfunctionendmodule
当然,这不是一个可以直接使用的模块,还需手动改一下格式。
有没有更完整的CRC生成器呢?
于是outputlogic出场了。只需要两步,就可以完成。
设定数据位宽,多项式位宽,若针对特定协议,例如USB、PCIe等,可直接选好协议。然后点击“Apply”,进入step2,选择多项式,生成verilog代码,完毕!
源代码如下:
//-----------------------------------------------------------------------------// Copyright (C) 2009 OutputLogic.com// This source file may be used and distributed without restriction// provided that this copyright statement is not removed from the file// and that any derivative work contains the original copyright notice// and the associated disclaimer.//// THIS SOURCE FILE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS// OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED// WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.//-----------------------------------------------------------------------------// CRC module for data[31:0] , crc[23:0]=1+x^1+x^3+x^4+x^5+x^6+x^7+x^10+x^11+x^14+x^17+x^18+x^23+x^24;//-----------------------------------------------------------------------------module crc( input [31:0] data_in, input crc_en, output [23:0] crc_out, input rst, input clk);
reg [23:0] lfsr_q,lfsr_c;
assign crc_out = lfsr_q;
always @(*) begin lfsr_c[0] = lfsr_q[2] ^ lfsr_q[6] ^ lfsr_q[8] ^ lfsr_q[9] ^ lfsr_q[10] ^ lfsr_q[11] ^ lfsr_q[12] ^ lfsr_q[13] ^ lfsr_q[14] ^ lfsr_q[15] ^ lfsr_q[19] ^ lfsr_q[22] ^ data_in[0] ^ data_in[1] ^ data_in[2] ^ data_in[3] ^ data_in[4] ^ data_in[5] ^ data_in[10] ^ data_in[14] ^ data_in[16] ^ data_in[17] ^ data_in[18] ^ data_in[19] ^ data_in[20] ^ data_in[21] ^ data_in[22] ^ data_in[23] ^ data_in[27] ^ data_in[30]; lfsr_c[1] = lfsr_q[2] ^ lfsr_q[3] ^ lfsr_q[6] ^ lfsr_q[7] ^ lfsr_q[8] ^ lfsr_q[16] ^ lfsr_q[19] ^ lfsr_q[20] ^ lfsr_q[22] ^ lfsr_q[23] ^ data_in[0] ^ data_in[6] ^ data_in[10] ^ data_in[11] ^ data_in[14] ^ data_in[15] ^ data_in[16] ^ data_in[24] ^ data_in[27] ^ data_in[28] ^ data_in[30] ^ data_in[31]; lfsr_c[2] = lfsr_q[3] ^ lfsr_q[4] ^ lfsr_q[7] ^ lfsr_q[8] ^ lfsr_q[9] ^ lfsr_q[17] ^ lfsr_q[20] ^ lfsr_q[21] ^ lfsr_q[23] ^ data_in[1] ^ data_in[7] ^ data_in[11] ^ data_in[12] ^ data_in[15] ^ data_in[16] ^ data_in[17] ^ data_in[25] ^ data_in[28] ^ data_in[29] ^ data_in[31]; lfsr_c[3] = lfsr_q[0] ^ lfsr_q[2] ^ lfsr_q[4] ^ lfsr_q[5] ^ lfsr_q[6] ^ lfsr_q[11] ^ lfsr_q[12] ^ lfsr_q[13] ^ lfsr_q[14] ^ lfsr_q[15] ^ lfsr_q[18] ^ lfsr_q[19] ^ lfsr_q[21] ^ data_in[0] ^ data_in[1] ^ data_in[3] ^ data_in[4] ^ data_in[5] ^ data_in[8] ^ data_in[10] ^ data_in[12] ^ data_in[13] ^ data_in[14] ^ data_in[19] ^ data_in[20] ^ data_in[21] ^ data_in[22] ^ data_in[23] ^ data_in[26] ^ data_in[27] ^ data_in[29]; lfsr_c[4] = lfsr_q[1] ^ lfsr_q[2] ^ lfsr_q[3] ^ lfsr_q[5] ^ lfsr_q[7] ^ lfsr_q[8] ^ lfsr_q[9] ^ lfsr_q[10] ^ lfsr_q[11] ^ lfsr_q[16] ^ lfsr_q[20] ^ data_in[0] ^ data_in[3] ^ data_in[6] ^ data_in[9] ^ data_in[10] ^ data_in[11] ^ data_in[13] ^ data_in[15] ^ data_in[16] ^ data_in[17] ^ data_in[18] ^ data_in[19] ^ data_in[24] ^ data_in[28]; lfsr_c[5] = lfsr_q[3] ^ lfsr_q[4] ^ lfsr_q[13] ^ lfsr_q[14] ^ lfsr_q[15] ^ lfsr_q[17] ^ lfsr_q[19] ^ lfsr_q[21] ^ lfsr_q[22] ^ data_in[0] ^ data_in[2] ^ data_in[3] ^ data_in[5] ^ data_in[7] ^ data_in[11] ^ data_in[12] ^ data_in[21] ^ data_in[22] ^ data_in[23] ^ data_in[25] ^ data_in[27] ^ data_in[29] ^ data_in[30]; lfsr_c[6] = lfsr_q[0] ^ lfsr_q[2] ^ lfsr_q[4] ^ lfsr_q[5] ^ lfsr_q[6] ^ lfsr_q[8] ^ lfsr_q[9] ^ lfsr_q[10] ^ lfsr_q[11] ^ lfsr_q[12] ^ lfsr_q[13] ^ lfsr_q[16] ^ lfsr_q[18] ^ lfsr_q[19] ^ lfsr_q[20] ^ lfsr_q[23] ^ data_in[0] ^ data_in[2] ^ data_in[5] ^ data_in[6] ^ data_in[8] ^ data_in[10] ^ data_in[12] ^ data_in[13] ^ data_in[14] ^ data_in[16] ^ data_in[17] ^ data_in[18] ^ data_in[19] ^ data_in[20] ^ data_in[21] ^ data_in[24] ^ data_in[26] ^ data_in[27] ^ data_in[28] ^ data_in[31]; lfsr_c[7] = lfsr_q[1] ^ lfsr_q[2] ^ lfsr_q[3] ^ lfsr_q[5] ^ lfsr_q[7] ^ lfsr_q[8] ^ lfsr_q[15] ^ lfsr_q[17] ^ lfsr_q[20] ^ lfsr_q[21] ^ lfsr_q[22] ^ data_in[0] ^ data_in[2] ^ data_in[4] ^ data_in[5] ^ data_in[6] ^ data_in[7] ^ data_in[9] ^ data_in[10] ^ data_in[11] ^ data_in[13] ^ data_in[15] ^ data_in[16] ^ data_in[23] ^ data_in[25] ^ data_in[28] ^ data_in[29] ^ data_in[30]; lfsr_c[8] = lfsr_q[0] ^ lfsr_q[2] ^ lfsr_q[3] ^ lfsr_q[4] ^ lfsr_q[6] ^ lfsr_q[8] ^ lfsr_q[9] ^ lfsr_q[16] ^ lfsr_q[18] ^ lfsr_q[21] ^ lfsr_q[22] ^ lfsr_q[23] ^ data_in[1] ^ data_in[3] ^ data_in[5] ^ data_in[6] ^ data_in[7] ^ data_in[8] ^ data_in[10] ^ data_in[11] ^ data_in[12] ^ data_in[14] ^ data_in[16] ^ data_in[17] ^ data_in[24] ^ data_in[26] ^ data_in[29] ^ data_in[30] ^ data_in[31]; lfsr_c[9] = lfsr_q[0] ^ lfsr_q[1] ^ lfsr_q[3] ^ lfsr_q[4] ^ lfsr_q[5] ^ lfsr_q[7] ^ lfsr_q[9] ^ lfsr_q[10] ^ lfsr_q[17] ^ lfsr_q[19] ^ lfsr_q[22] ^ lfsr_q[23] ^ data_in[2] ^ data_in[4] ^ data_in[6] ^ data_in[7] ^ data_in[8] ^ data_in[9] ^ data_in[11] ^ data_in[12] ^ data_in[13] ^ data_in[15] ^ data_in[17] ^ data_in[18] ^ data_in[25] ^ data_in[27] ^ data_in[30] ^ data_in[31]; lfsr_c[10] = lfsr_q[0] ^ lfsr_q[1] ^ lfsr_q[4] ^ lfsr_q[5] ^ lfsr_q[9] ^ lfsr_q[12] ^ lfsr_q[13] ^ lfsr_q[14] ^ lfsr_q[15] ^ lfsr_q[18] ^ lfsr_q[19] ^ lfsr_q[20] ^ lfsr_q[22] ^ lfsr_q[23] ^ data_in[0] ^ data_in[1] ^ data_in[2] ^ data_in[4] ^ data_in[7] ^ data_in[8] ^ data_in[9] ^ data_in[12] ^ data_in[13] ^ data_in[17] ^ data_in[20] ^ data_in[21] ^ data_in[22] ^ data_in[23] ^ data_in[26] ^ data_in[27] ^ data_in[28] ^ data_in[30] ^ data_in[31]; lfsr_c[11] = lfsr_q[0] ^ lfsr_q[1] ^ lfsr_q[5] ^ lfsr_q[8] ^ lfsr_q[9] ^ lfsr_q[11] ^ lfsr_q[12] ^ lfsr_q[16] ^ lfsr_q[20] ^ lfsr_q[21] ^ lfsr_q[22] ^ lfsr_q[23] ^ data_in[0] ^ data_in[4] ^ data_in[8] ^ data_in[9] ^ data_in[13] ^ data_in[16] ^ data_in[17] ^ data_in[19] ^ data_in[20] ^ data_in[24] ^ data_in[28] ^ data_in[29] ^ data_in[30] ^ data_in[31]; lfsr_c[12] = lfsr_q[1] ^ lfsr_q[2] ^ lfsr_q[6] ^ lfsr_q[9] ^ lfsr_q[10] ^ lfsr_q[12] ^ lfsr_q[13] ^ lfsr_q[17] ^ lfsr_q[21] ^ lfsr_q[22] ^ lfsr_q[23] ^ data_in[1] ^ data_in[5] ^ data_in[9] ^ data_in[10] ^ data_in[14] ^ data_in[17] ^ data_in[18] ^ data_in[20] ^ data_in[21] ^ data_in[25] ^ data_in[29] ^ data_in[30] ^ data_in[31]; lfsr_c[13] = lfsr_q[2] ^ lfsr_q[3] ^ lfsr_q[7] ^ lfsr_q[10] ^ lfsr_q[11] ^ lfsr_q[13] ^ lfsr_q[14] ^ lfsr_q[18] ^ lfsr_q[22] ^ lfsr_q[23] ^ data_in[2] ^ data_in[6] ^ data_in[10] ^ data_in[11] ^ data_in[15] ^ data_in[18] ^ data_in[19] ^ data_in[21] ^ data_in[22] ^ data_in[26] ^ data_in[30] ^ data_in[31]; lfsr_c[14] = lfsr_q[2] ^ lfsr_q[3] ^ lfsr_q[4] ^ lfsr_q[6] ^ lfsr_q[9] ^ lfsr_q[10] ^ lfsr_q[13] ^ lfsr_q[22] ^ lfsr_q[23] ^ data_in[0] ^ data_in[1] ^ data_in[2] ^ data_in[4] ^ data_in[5] ^ data_in[7] ^ data_in[10] ^ data_in[11] ^ data_in[12] ^ data_in[14] ^ data_in[17] ^ data_in[18] ^ data_in[21] ^ data_in[30] ^ data_in[31]; lfsr_c[15] = lfsr_q[0] ^ lfsr_q[3] ^ lfsr_q[4] ^ lfsr_q[5] ^ lfsr_q[7] ^ lfsr_q[10] ^ lfsr_q[11] ^ lfsr_q[14] ^ lfsr_q[23] ^ data_in[1] ^ data_in[2] ^ data_in[3] ^ data_in[5] ^ data_in[6] ^ data_in[8] ^ data_in[11] ^ data_in[12] ^ data_in[13] ^ data_in[15] ^ data_in[18] ^ data_in[19] ^ data_in[22] ^ data_in[31]; lfsr_c[16] = lfsr_q[1] ^ lfsr_q[4] ^ lfsr_q[5] ^ lfsr_q[6] ^ lfsr_q[8] ^ lfsr_q[11] ^ lfsr_q[12] ^ lfsr_q[15] ^ data_in[2] ^ data_in[3] ^ data_in[4] ^ data_in[6] ^ data_in[7] ^ data_in[9] ^ data_in[12] ^ data_in[13] ^ data_in[14] ^ data_in[16] ^ data_in[19] ^ data_in[20] ^ data_in[23]; lfsr_c[17] = lfsr_q[0] ^ lfsr_q[5] ^ lfsr_q[7] ^ lfsr_q[8] ^ lfsr_q[10] ^ lfsr_q[11] ^ lfsr_q[14] ^ lfsr_q[15] ^ lfsr_q[16] ^ lfsr_q[19] ^ lfsr_q[22] ^ data_in[0] ^ data_in[1] ^ data_in[2] ^ data_in[7] ^ data_in[8] ^ data_in[13] ^ data_in[15] ^ data_in[16] ^ data_in[18] ^ data_in[19] ^ data_in[22] ^ data_in[23] ^ data_in[24] ^ data_in[27] ^ data_in[30]; lfsr_c[18] = lfsr_q[0] ^ lfsr_q[1] ^ lfsr_q[2] ^ lfsr_q[10] ^ lfsr_q[13] ^ lfsr_q[14] ^ lfsr_q[16] ^ lfsr_q[17] ^ lfsr_q[19] ^ lfsr_q[20] ^ lfsr_q[22] ^ lfsr_q[23] ^ data_in[0] ^ data_in[4] ^ data_in[5] ^ data_in[8] ^ data_in[9] ^ data_in[10] ^ data_in[18] ^ data_in[21] ^ data_in[22] ^ data_in[24] ^ data_in[25] ^ data_in[27] ^ data_in[28] ^ data_in[30] ^ data_in[31]; lfsr_c[19] = lfsr_q[1] ^ lfsr_q[2] ^ lfsr_q[3] ^ lfsr_q[11] ^ lfsr_q[14] ^ lfsr_q[15] ^ lfsr_q[17] ^ lfsr_q[18] ^ lfsr_q[20] ^ lfsr_q[21] ^ lfsr_q[23] ^ data_in[1] ^ data_in[5] ^ data_in[6] ^ data_in[9] ^ data_in[10] ^ data_in[11] ^ data_in[19] ^ data_in[22] ^ data_in[23] ^ data_in[25] ^ data_in[26] ^ data_in[28] ^ data_in[29] ^ data_in[31]; lfsr_c[20] = lfsr_q[2] ^ lfsr_q[3] ^ lfsr_q[4] ^ lfsr_q[12] ^ lfsr_q[15] ^ lfsr_q[16] ^ lfsr_q[18] ^ lfsr_q[19] ^ lfsr_q[21] ^ lfsr_q[22] ^ data_in[2] ^ data_in[6] ^ data_in[7] ^ data_in[10] ^ data_in[11] ^ data_in[12] ^ data_in[20] ^ data_in[23] ^ data_in[24] ^ data_in[26] ^ data_in[27] ^ data_in[29] ^ data_in[30]; lfsr_c[21] = lfsr_q[0] ^ lfsr_q[3] ^ lfsr_q[4] ^ lfsr_q[5] ^ lfsr_q[13] ^ lfsr_q[16] ^ lfsr_q[17] ^ lfsr_q[19] ^ lfsr_q[20] ^ lfsr_q[22] ^ lfsr_q[23] ^ data_in[3] ^ data_in[7] ^ data_in[8] ^ data_in[11] ^ data_in[12] ^ data_in[13] ^ data_in[21] ^ data_in[24] ^ data_in[25] ^ data_in[27] ^ data_in[28] ^ data_in[30] ^ data_in[31]; lfsr_c[22] = lfsr_q[0] ^ lfsr_q[1] ^ lfsr_q[4] ^ lfsr_q[5] ^ lfsr_q[6] ^ lfsr_q[14] ^ lfsr_q[17] ^ lfsr_q[18] ^ lfsr_q[20] ^ lfsr_q[21] ^ lfsr_q[23] ^ data_in[4] ^ data_in[8] ^ data_in[9] ^ data_in[12] ^ data_in[13] ^ data_in[14] ^ data_in[22] ^ data_in[25] ^ data_in[26] ^ data_in[28] ^ data_in[29] ^ data_in[31]; lfsr_c[23] = lfsr_q[1] ^ lfsr_q[5] ^ lfsr_q[7] ^ lfsr_q[8] ^ lfsr_q[9] ^ lfsr_q[10] ^ lfsr_q[11] ^ lfsr_q[12] ^ lfsr_q[13] ^ lfsr_q[14] ^ lfsr_q[18] ^ lfsr_q[21] ^ data_in[0] ^ data_in[1] ^ data_in[2] ^ data_in[3] ^ data_in[4] ^ data_in[9] ^ data_in[13] ^ data_in[15] ^ data_in[16] ^ data_in[17] ^ data_in[18] ^ data_in[19] ^ data_in[20] ^ data_in[21] ^ data_in[22] ^ data_in[26] ^ data_in[29];
end // always
always @(posedge clk, posedge rst) begin if(rst) begin lfsr_q <= {24{1'b1}}; end else begin lfsr_q <= crc_en ? lfsr_c : lfsr_q; end end // alwaysendmodule // crc
赶紧试试吧,三分钟搞定CRC校验模块,效率直线上升,码农们。