CRC校验原理与Verilog实现方法相结合的复杂技术如何构建?

摘要:1 代码生成 verilog实现CRC校验,可以充分发挥FPGA的硬件特性,即并行运算的能力。 具体实现方式,可以参考我上一篇博客,关键是用线性反馈移位寄存器表示出多项式,另外注意校验数据高位在先。然后根据电路结构推导出逻辑表达式,再转换成
1 代码生成 verilog实现CRC校验,可以充分发挥FPGA的硬件特性,即并行运算的能力。 具体实现方式,可以参考我上一篇博客,关键是用线性反馈移位寄存器表示出多项式,另外注意校验数据高位在先。然后根据电路结构推导出逻辑表达式,再转换成verilog就行了。 更高效的方法是利用现成的代码生成工具,例如附件的链接就是一种在线的CRC校验代码生成工具。 我这里用代码生成工具生成多项式为x^4 + x^1 + 1,即CRC-4/ITU校验模型,校验输入数据位宽为4bit的代码,下面分享一下修改移植时的心得。 2 修改移植 这个多项式和我上一篇博客举例所用多项式一样,生成的代码和前面推导的逻辑表达式是一致的。生成的代码如下 function [3:0] nextCRC4_D4; input [3:0] Data; input [3:0] crc; reg [3:0] d; reg [3:0] c; reg [3:0] newcrc; begin d = Data; c = crc; newcrc[0] = d[3] ^ d[0] ^ c[0] ^ c[3]; newcrc[1] = d[3] ^ d[1] ^ d[0] ^ c[0] ^ c[1] ^ c[3]; newcrc[2] = d[2] ^ d[1] ^ c[1] ^ c[2]; newcrc[3] = d[3] ^ d[2] ^ c[2] ^ c[3]; nextCRC4_D4 = newcrc; end endfunction 其实这段代码有用的只是中间那四行行为级赋值语句,可以直接拷贝到工程里使用。其中d是4位的校验数据,c是CRC寄存器。 用这段代码做CRC校验时,有几点需要明确: 1)数据位宽。 2)输入输出是否高低位反转。 3)c的初值。 4)输出是否按位取反。 第1点取决于通信时1帧数据的长度,第2、3点一般在常用的CRC校验模型中规定好了。这里的CRC-4/ITU校验模型规定c的初值为0,输出不取反,输入输出高低位反转。 如果被校验数据data只有4bit,那么直接令data高低位反转,赋值给d。c=0,组合逻辑输出的newcrc进行高低位反转,得到的就是CRC校验码。 假如被校验的数据位数大于4bit,需要分字节进行“叠加”校验。 比如数据data[15:0]=1577h,那么可以按照这样的校验流程: 高字节低4bit(5h)反转后赋值给d——newcrc作为下次校验的c——高字节高4bit(1h)反转后赋值给d——newcrc作为下次校验的c的值——低字节低4bit(7h)反转后赋值给d——newcrc作为下次校验的c的值——低字节高4bit(7h)反转后赋值给d——newcrc反转后作为CRC校验码。 c的更新可以用寄存器实现。如下所示: reg [3:0] c; wire [3:0] d; //参与校验数据 assign d = {data_r[0], data_r[1], data_r[2], data_r[3]};//翻转数据位 assign newcrc[0] = crc_en & (d[3] ^ d[0] ^ c[0] ^ c[3]); assign newcrc[1] = crc_en & (d[3] ^ d[1] ^ d[0] ^ c[0] ^ c[1] ^ c[3]); assign newcrc[2] = crc_en & (d[2] ^ d[1] ^ c[1] ^ c[2]); assign newcrc[3] = crc_en & (d[3] ^ d[2] ^ c[2] ^ c[3]); always @(posedge clk or negedge rstn) begin   if(!rstn)     c <= 4'h0;//初始0   else begin     if(start_pos)       c <= 4'h0;     else if(crc_en)       c <= newcrc;   end end 3 功能验证 为了验证上面修改的代码功能,编写了测试代码,对16bit的数据求校验码。这里分别验证data[15:0]=1577h,data[15:0]=4511h两个数据的CRC校验码。
阅读全文