CRC校验 - 基于FPGA的实现

CRC校验 - 基于FPGA的实现

 

0  背景

       CRC即循环冗余校验:常用于数据通信领域中,通常由发送端添加校验码于单帧数据的尾部,并由接受方进行提取和校验该帧数据传输是否正确。

循环冗余检查(CRC)是一种数据传输检错功能,对数据进行多项式计算,并将得到的结果附在帧的后面,接收设备也执行类似的算法,以保证数据传输的正确性和完整性。

1 FPGA硬件实现CRC校验

        CRC计算采用模2除法,本质是对应比特位的异或运算。计算原理我仔细推究,通常硬件实现方式分为2种:

        1- 串行计算,并输出CRC校验码。好处:顺序计算,便于理解和编程实现,且节省资源;  缺点:不如并行计算速率快;

        2- 并行计算,并输出CRC校验码。优缺点与串行计算相反;

2  FPGA实现CRC校验代码生成工具

        开源工具已有基于FPGA的CRC校验代码生成工具(轮子已造好)    链接地址:https://www.easics.com/crctool/

       CRC校验代码在线计算工具。    链接地址:https://www.easics.com/crctool/

3  举例:CRC-8  MAXIM    --- X^8 + X^5 + X^4 + 1

        该校验模型参数配置信息及FPGA代码实现如下:采用并行计算方式


 `timescale 1ns/1ps
 
 //
  参数模型:CRC-8 MAXIM    --- X^8 + X^5 + X^4 + 1
  输入位宽:8bit
  初始值:0x00
  结果异或值:0x00
  CRC在线计算网址:http://www.ip33.com/crc.html
  ***该参数模型:输入数据按高低位反转
  ***该参数模型:输出数据按高低位反转
 //
 
 module crc8_test (
     input     wire              I_clk                 , //
     input     wire              I_reset               , //
     input     wire              i_din_valid           , //输入数据有效
     input     wire    [7:0]    i_din                 , //输入数据
     output    wire              o_dout_valid          , //输出CRC值有效
     output    wire    [7:0]    o_dout                  //输出CRC      
 );
 reg [7:0] r_dout;
 wire [7:0] d;
 wire [7:0] c;

case1 
输入数据按位不反转
// assign d = i_din;

default case 
输入数据按位反转 
 assign d = {i_din[0],i_din[1],i_din[2],i_din[3],i_din[4],i_din[5],i_din[6],i_din[7]}; 
 
 assign c = r_dout;
 always @(posedge I_clk) begin
     if (I_reset) 
         r_dout <= 8'h00; //初始值
     else if (i_din_valid) 
     begin //计算逻辑
        r_dout[0] <= d[6] ^ d[4] ^ d[3] ^ d[0] ^ c[0] ^ c[3] ^ c[4] ^ c[6];
		r_dout[1] <= d[7] ^ d[5] ^ d[4] ^ d[1] ^ c[1] ^ c[4] ^ c[5] ^ c[7];
		r_dout[2] <= d[6] ^ d[5] ^ d[2] ^ c[2] ^ c[5] ^ c[6];
		r_dout[3] <= d[7] ^ d[6] ^ d[3] ^ c[3] ^ c[6] ^ c[7];
		r_dout[4] <= d[7] ^ d[6] ^ d[3] ^ d[0] ^ c[0] ^ c[3] ^ c[6] ^ c[7];
		r_dout[5] <= d[7] ^ d[6] ^ d[3] ^ d[1] ^ d[0] ^ c[0] ^ c[1] ^ c[3] ^ c[6] ^ c[7];
		r_dout[6] <= d[7] ^ d[4] ^ d[2] ^ d[1] ^ c[1] ^ c[2] ^ c[4] ^ c[7];
		r_dout[7] <= d[5] ^ d[3] ^ d[2] ^ c[2] ^ c[3] ^ c[5];
     end
 end 
 reg r_dout_valid = 0;
 
 always @(posedge I_clk) //输入数据在一个时钟内完成CRC计算,下一个时钟输出
 begin
     r_dout_valid <= i_din_valid;
 end
 
 assign o_dout_valid = r_dout_valid;
 
 default case 
 输出数据按位反转 
 assign o_dout = {r_dout[0],r_dout[1],r_dout[2],r_dout[3],r_dout[4],r_dout[5],r_dout[6],r_dout[7]};  

// case1 
// 输出数据不按位反转
// assign o_dout = r_dout ;
 
 endmodule // end the crc8_test model;






4  仿真测试结果对比:CRC-8  MAXIM   

        输入数据为4字节:0x12  0x34  0x56  0x78

       CRC-8 MAXIM校验结果:0x98

CRC校验 - 基于FPGA的实现_第1张图片

CRC校验 - 基于FPGA的实现_第2张图片

        对比可知,FPGA仿真结果与CRC工具计算结果相等,测试通过。

 

 

 

 

 

你可能感兴趣的:(FPGA应用篇,CRC8,CRC16,CRC校验,CRC校验Verilog)