FPGA学习记录——CRC校验码

1.CRC校验码是什么:

循环冗余校验(Cyclic Redundancy Check, CRC)是一种数字通信中常用的信道编码技术,主要用来检测或校验数据传输或者保存后可能出现的错误。它是利用除法及余数的原理来作错误侦测的。

CRC码有两部分组成,前半部分是信息码,后半部分是校验码。若CRC码共长n bit,信息码长k bit,就称为(n,k)码,剩余的(n-k)bit为校验码。

2.CRC校验码生成步骤:

假设待传送的k位信息码为(m_{k-1},m_{k-2},...m_{2},m_{1}),其所对应的多项式为:

M(x)=m_{k-1}x^{k-1}+m_{k-2}x^{k-2}+...+m_{1}x^{1}+m_{0}

其中=0或1,x的幂数对应于各码元的位置,eg:

M(x)=x^{7}+x^{4}+x^{2}+x表示100101101

第一步:将信息多项式左移r=n-k位,【注:校验码元r的位数比生成码最高位数少一位

第二步:将左移后的信息多项式除以生成多项式g(x)【注:g(x)末项一定为1】,得到余式r(x),即为CRC校验码多项式,对应r位校验码元。此处用到的是模二除法——按位异或。

国际上比较通行的生成多项式

第三步:生成码字

3.CRC校验流程:

4.代码:

module v_crc(
    input [7:0] data,//信息码8位
    input clk,//时钟信号
    input rst,//复位信号
    output reg [15:0] crc//生成的CRC校验码元
    );
    wire [23:0] stemp;//信息码移位数据
    reg [23:0] temp;//移位数据用于除法运算
      
    parameter gx=17'b1_0001_0000_0010_0001;//生成码元g(x)采用CRC-CCITT
    assign stemp={data,16'b0000000000000000};
    
    always@(posedge clk or negedge rst)
    begin
      if(!rst)
       begin
        crc<=0;
        temp<=stemp;
       end
      else//实现模二除法
      begin
       if(temp[23])
        temp[23:7]<=temp[23:7]^gx;
       else if(temp[22])
        temp[22:6]<=temp[22:6]^gx;
       else if(temp[21])
        temp[21:5]<=temp[21:5]^gx;
       else if(temp[20])
        temp[20:4]<=temp[20:4]^gx;
       else if(temp[19])
        temp[19:3]<=temp[19:3]^gx;
       else if(temp[18])
        temp[18:2]<=temp[18:2]^gx;
       else if(temp[17])
        temp[17:1]<=temp[17:1]^gx;
       else if(temp[16])
        temp[16:0]<=temp[16:0]^gx;
       else
        crc=temp[15:0];
      end
    end
endmodule

 5.仿真:

module sim_crc(

    );
   reg [7:0] data;
   reg clk;
   reg rst;
   wire [15:0] crc;
   
   v_crc U1(
   data,clk,rst,crc
   );
   
   initial
   begin
    clk=0;
    rst=0;  
    data[7:0]=8'b10100010;//假设输入的信息码为10100010
   end
   
   always #10 clk=~clk;
   always #10 rst=1;
endmodule

### CRC校验码计算方法 CRC(Cyclic Redundancy Check)是一种用于检测据传输过程中可能现错误的技术。通过特定算法生成一个校验附加到原始据之后,接收端可以利用相同的算法重新计算并对比接收到的据是否一致。 #### 计算过程概述 为了说明首位为`0`的情形下CRC的具体操作流程,先简要回顾一下通用的CRC计算步骤: 1. 将待编的信息序列转换成二进制形式; 2. 把该二进制串左移若干位(取决于所选CRC标准规定的宽度),并在低位补零作为初始余; 3. 使用预定义好的生成多项式去除上述所得,此除法遵循模2运算规则即不考虑借位情况下的按位异或(XOR)操作; 4. 上述第三步的结果再次用作新的被除继续执行相同的操作直到整个消息都被处理完毕为止;最终留下来的商即是所需的CRC校验码[^1]。 针对首字节为`0x00`(即十进制中的0)这种特殊情况来说,在实际应用中通常不会因为最前面存在连续多个‘0’而改变任何事情——这些前导'0's会被忽略掉只保留有效载荷部分参与后续的CRC计算之中[^2]。 举例而言,如果有一个8比特长度的消息`0x0A`(`00001010`)需要加上CRC-CCITT(16bits),那么即使原信息是以`0x00`开头也不会影响最后得的校验结果。具体实现上可以通过Verilog硬件描述语言编写如下逻辑电路完成这一功能: ```verilog module crc_ccitt #(parameter WIDTH=16, INITVAL=16'hFFFF)( input wire clk, input wire rst_n, input wire ena, input wire [7:0] din, output reg [WIDTH-1:0] crc_out); // Internal registers declaration omitted for brevity. always @(posedge clk or negedge rst_n) begin : proc_crc_calculation if (!rst_n) // Reset state machine and internal variables. ... else if (ena && !last_byte_flag) begin // Shift register content left by one byte width. shift_reg <= {shift_reg[WIDTH-9:0],din}; // Perform XOR operation with polynomial when MSB is set. if(shift_reg[WIDTH-1]) shift_reg ^= POLYNOMIAL; last_byte_flag <= 1'b0; end end ... endmodule ``` 这段代片段展示了如何在一个FPGA环境中构建CRC计算器模块的一部分,其中包含了对输入据流逐个字节进行处理的核心机制。得注意的是这里假设了最高有效位(MSB)优先的方式来进行位级上的XOR比较,并且每当遇到非最后一组据时都会将其加入当前累加器内等待进一步处理[^3]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值