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

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

 

 

 

 

 

  • 7
    点赞
  • 100
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
FPGA实现CRC校验是一种常见的做法,可以通过硬件电路来计算CRC校验码。通常,需要使用一个生成多项式来进行CRC计算。生成多项式是一个固定的多项式,用于生成CRC校验码。在FPGA中,可以使用Verilog或VHDL等硬件描述语言来实现CRC校验。 首先,需要定义一个CRC模块,该模块包含输入数据、生成多项式、时钟信号和复位信号等。在模块内部,可以使用寄存器和逻辑门等元件来实现CRC计算。具体的实现方式可以参考引用\[2\]中的testbench代码。 在CRC模块中,需要根据生成多项式的规则来计算CRC校验码。生成多项式通常是一个多项式的二进制表示形式,可以根据不同的CRC标准选择相应的生成多项式。例如,CRC-32标准使用的生成多项式是引用\[3\]中给出的CRC-32。 在实现过程中,需要注意时钟信号的同步和数据的移位操作。通过逐位移位和异或运算,可以逐步计算出CRC校验码。最后,可以通过比较计算得到的CRC校验码和预期的校验码来判断是否校验正确。 总结起来,要在FPGA实现CRC校验,需要定义一个CRC模块,选择适当的生成多项式,并根据生成多项式的规则进行CRC计算。具体的实现方式可以参考引用\[2\]中的testbench代码。 #### 引用[.reference_title] - *1* *2* *3* [FPGA(一)——基于FPGACRC算法实现](https://blog.csdn.net/weixin_43361652/article/details/107954852)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值