verilog实现CRC

CRC (Cyclic Redundancy Check) 原理
CRC 是一种基于二进制除法的错误检测方法,广泛应用于数字网络和存储设备中,以检测数据传输或存储过程中的错误。以下是 CRC 的基本原理和步骤:

  1. 基本概念
    CRC 使用一个多项式生成器对数据进行编码和校验。该多项式通常称为生成多项式,表示为 𝐺(𝑥)G(x)。多项式的阶数决定了 CRC 的位数(例如,CRC-32 表示多项式阶数为 32)。
  2. 生成多项式
    生成多项式 𝐺(𝑥)G(x) 是一个二进制多项式,如 CRC-32 的生成多项式为: 𝐺(𝑥)=𝑥32+𝑥26+𝑥23+𝑥22+𝑥16+𝑥12+𝑥11+𝑥10+𝑥8+𝑥7+𝑥5+𝑥4+𝑥2+𝑥+1G(x)=x32+x26+x23+x22+x16+x12+x11+x10+x8+x7+x5+x4+x2+x+1
  3. 数据处理步骤
  4. 附加零位:
    • 在数据后面附加 𝑛n 个零位,𝑛n 是生成多项式的阶数。例如,对于 CRC-32,附加 32 个零位。
  5. 二进制除法:
    • 使用生成多项式 𝐺(𝑥)G(x) 对扩展后的数据进行二进制除法。除法的结果是余数,不使用商。
    • 二进制除法中,减法操作等同于异或 (XOR) 操作。
  6. CRC 码生成:
    • 余数就是 CRC 校验码。将余数附加到原始数据的末尾,形成传输数据。
  7. 接收端校验:
    • 接收端使用相同的生成多项式对接收到的数据进行二进制除法。如果余数为零,则表示数据没有错误;否则,数据存在错误。
  8. 具体示例
    假设数据为 11010110111101011011,生成多项式为 𝑥4+𝑥+1x4+x+1,表示为 1001110011。
  9. 数据附加零位: 1101011011→110101101100001101011011→11010110110000
  10. 二进制除法:
    11010110110000−10011010011−00011100001−000011000000−0000011100000011−110−00101−1000001−01000000111110000011100000011000100010100100100
    继续此过程,直到数据处理完毕,得到最终余数。
  11. CRC 码生成: 余数即为 CRC 码。
  12. 优点与应用
    • 优点:
    • 高效的错误检测能力。
    • 硬件和软件实现都非常简单和快速。
    • 应用:
    • 数据通信协议(如 Ethernet、USB)。
    • 存储设备的数据校验(如硬盘、SSD)。
    • 文件传输和压缩格式(如 ZIP 文件)。
  13. 总结
    CRC 是一种有效的错误检测机制,通过使用生成多项式进行二进制除法,生成并验证数据的校验码,确保数据的完整性。它在各种数字通信和存储系统中得到了广泛应用。

matlab仿真程序:

function crc = crc32(data)
    % 输入数据转换为二进制向量
    data_bin = de2bi(data, 8, 'left-msb');
    data_bin = data_bin';
    data_bin = data_bin(:)';
    
    % CRC 多项式定义
    poly = [1 1 1 0 1 0 1 1 0 1 1 1 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 0 0 1];
    poly_length = length(poly);
    
    % 在数据末尾附加多项式长度减1的零
    data_padded = [data_bin zeros(1, poly_length-1)];
    
    % 初始化CRC寄存器
    crc = zeros(1, poly_length);
    
    % CRC 计算
    for i = 1:length(data_bin)
        if xor(data_padded(i), crc(1))
            crc = xor(crc, [poly zeros(1, length(crc)-poly_length)]);
        end
        crc = [crc(2:end) 0];
    end
    
    % 最终CRC值
    crc = crc(1:poly_length-1);
    crc = bi2de(crc, 'left-msb');
end

% 测试数据
data = uint8('123456789');
crc_value = crc32(data);
disp(['CRC-32 值: ', num2str(crc_value)]);

verilog实现CRC:


//-----------------------------------------------------------------------------
// CRC module for data[7:0] ,   crc[31:0]=1+x^1+x^2+x^4+x^5+x^7+x^8+x^10+x^11+x^12+x^16+x^22+x^23+x^26+x^32;
//-----------------------------------------------------------------------------
module crc(
  input [7:0] data_in,
  input crc_en,
  output [31:0] crc_out,
  input rst,
  input clk);

  reg [31:0] lfsr_q,lfsr_c;

  assign crc_out = lfsr_q;

  always @(*) begin
    lfsr_c[0] = lfsr_q[24] ^ lfsr_q[30] ^ data_in[0] ^ data_in[6];
    lfsr_c[1] = lfsr_q[24] ^ lfsr_q[25] ^ lfsr_q[30] ^ lfsr_q[31] ^ data_in[0] ^ data_in[1] ^ data_in[6] ^ data_in[7];
    lfsr_c[2] = lfsr_q[24] ^ lfsr_q[25] ^ lfsr_q[26] ^ lfsr_q[30] ^ lfsr_q[31] ^ data_in[0] ^ data_in[1] ^ data_in[2] ^ data_in[6] ^ data_in[7];
    lfsr_c[3] = lfsr_q[25] ^ lfsr_q[26] ^ lfsr_q[27] ^ lfsr_q[31] ^ data_in[1] ^ data_in[2] ^ data_in[3] ^ data_in[7];
    lfsr_c[4] = lfsr_q[24] ^ lfsr_q[26] ^ lfsr_q[27] ^ lfsr_q[28] ^ lfsr_q[30] ^ data_in[0] ^ data_in[2] ^ data_in[3] ^ data_in[4] ^ data_in[6];
    lfsr_c[5] = lfsr_q[24] ^ lfsr_q[25] ^ lfsr_q[27] ^ lfsr_q[28] ^ lfsr_q[29] ^ lfsr_q[30] ^ lfsr_q[31] ^ data_in[0] ^ data_in[1] ^ data_in[3] ^ data_in[4] ^ data_in[5] ^ data_in[6] ^ data_in[7];
    lfsr_c[6] = lfsr_q[25] ^ lfsr_q[26] ^ lfsr_q[28] ^ lfsr_q[29] ^ lfsr_q[30] ^ lfsr_q[31] ^ data_in[1] ^ data_in[2] ^ data_in[4] ^ data_in[5] ^ data_in[6] ^ data_in[7];
    lfsr_c[7] = lfsr_q[24] ^ lfsr_q[26] ^ lfsr_q[27] ^ lfsr_q[29] ^ lfsr_q[31] ^ data_in[0] ^ data_in[2] ^ data_in[3] ^ data_in[5] ^ data_in[7];
    lfsr_c[8] = lfsr_q[0] ^ lfsr_q[24] ^ lfsr_q[25] ^ lfsr_q[27] ^ lfsr_q[28] ^ data_in[0] ^ data_in[1] ^ data_in[3] ^ data_in[4];
    lfsr_c[9] = lfsr_q[1] ^ lfsr_q[25] ^ lfsr_q[26] ^ lfsr_q[28] ^ lfsr_q[29] ^ data_in[1] ^ data_in[2] ^ data_in[4] ^ data_in[5];
    lfsr_c[10] = lfsr_q[2] ^ lfsr_q[24] ^ lfsr_q[26] ^ lfsr_q[27] ^ lfsr_q[29] ^ data_in[0] ^ data_in[2] ^ data_in[3] ^ data_in[5];
    lfsr_c[11] = lfsr_q[3] ^ lfsr_q[24] ^ lfsr_q[25] ^ lfsr_q[27] ^ lfsr_q[28] ^ data_in[0] ^ data_in[1] ^ data_in[3] ^ data_in[4];
    lfsr_c[12] = lfsr_q[4] ^ lfsr_q[24] ^ lfsr_q[25] ^ lfsr_q[26] ^ lfsr_q[28] ^ lfsr_q[29] ^ lfsr_q[30] ^ data_in[0] ^ data_in[1] ^ data_in[2] ^ data_in[4] ^ data_in[5] ^ data_in[6];
    lfsr_c[13] = lfsr_q[5] ^ lfsr_q[25] ^ lfsr_q[26] ^ lfsr_q[27] ^ lfsr_q[29] ^ lfsr_q[30] ^ lfsr_q[31] ^ data_in[1] ^ data_in[2] ^ data_in[3] ^ data_in[5] ^ data_in[6] ^ data_in[7];
    lfsr_c[14] = lfsr_q[6] ^ lfsr_q[26] ^ lfsr_q[27] ^ lfsr_q[28] ^ lfsr_q[30] ^ lfsr_q[31] ^ data_in[2] ^ data_in[3] ^ data_in[4] ^ data_in[6] ^ data_in[7];
    lfsr_c[15] = lfsr_q[7] ^ lfsr_q[27] ^ lfsr_q[28] ^ lfsr_q[29] ^ lfsr_q[31] ^ data_in[3] ^ data_in[4] ^ data_in[5] ^ data_in[7];
    lfsr_c[16] = lfsr_q[8] ^ lfsr_q[24] ^ lfsr_q[28] ^ lfsr_q[29] ^ data_in[0] ^ data_in[4] ^ data_in[5];
    lfsr_c[17] = lfsr_q[9] ^ lfsr_q[25] ^ lfsr_q[29] ^ lfsr_q[30] ^ data_in[1] ^ data_in[5] ^ data_in[6];
    lfsr_c[18] = lfsr_q[10] ^ lfsr_q[26] ^ lfsr_q[30] ^ lfsr_q[31] ^ data_in[2] ^ data_in[6] ^ data_in[7];
    lfsr_c[19] = lfsr_q[11] ^ lfsr_q[27] ^ lfsr_q[31] ^ data_in[3] ^ data_in[7];
    lfsr_c[20] = lfsr_q[12] ^ lfsr_q[28] ^ data_in[4];
    lfsr_c[21] = lfsr_q[13] ^ lfsr_q[29] ^ data_in[5];
    lfsr_c[22] = lfsr_q[14] ^ lfsr_q[24] ^ data_in[0];
    lfsr_c[23] = lfsr_q[15] ^ lfsr_q[24] ^ lfsr_q[25] ^ lfsr_q[30] ^ data_in[0] ^ data_in[1] ^ data_in[6];
    lfsr_c[24] = lfsr_q[16] ^ lfsr_q[25] ^ lfsr_q[26] ^ lfsr_q[31] ^ data_in[1] ^ data_in[2] ^ data_in[7];
    lfsr_c[25] = lfsr_q[17] ^ lfsr_q[26] ^ lfsr_q[27] ^ data_in[2] ^ data_in[3];
    lfsr_c[26] = lfsr_q[18] ^ lfsr_q[24] ^ lfsr_q[27] ^ lfsr_q[28] ^ lfsr_q[30] ^ data_in[0] ^ data_in[3] ^ data_in[4] ^ data_in[6];
    lfsr_c[27] = lfsr_q[19] ^ lfsr_q[25] ^ lfsr_q[28] ^ lfsr_q[29] ^ lfsr_q[31] ^ data_in[1] ^ data_in[4] ^ data_in[5] ^ data_in[7];
    lfsr_c[28] = lfsr_q[20] ^ lfsr_q[26] ^ lfsr_q[29] ^ lfsr_q[30] ^ data_in[2] ^ data_in[5] ^ data_in[6];
    lfsr_c[29] = lfsr_q[21] ^ lfsr_q[27] ^ lfsr_q[30] ^ lfsr_q[31] ^ data_in[3] ^ data_in[6] ^ data_in[7];
    lfsr_c[30] = lfsr_q[22] ^ lfsr_q[28] ^ lfsr_q[31] ^ data_in[4] ^ data_in[7];
    lfsr_c[31] = lfsr_q[23] ^ lfsr_q[29] ^ data_in[5];

  end // always

  always @(posedge clk, posedge rst) begin
    if(rst) begin
      lfsr_q <= {32{1'b1}};
    end
    else begin
      lfsr_q <= crc_en ? lfsr_c : lfsr_q;
    end
  end // always
endmodule // crc
  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MRHLT

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值