CRC校验原理及Verilog实现

 CRC全称循环冗余校验(Cyclic Redundancy Check, CRC)

CRC校验的基本思路是数据发送方发送数据之前,先生成一个CRC校验码,可以是单bit也可以是多bit,并附在有效数据末尾,以串行方式发送到接收方。接收方接收到数据后,进行CRC校验,根据校验结果就可以知道数据是否有误。

CRC校验码的生成:将有效数据扩展后作为被除数,使用一个指定的多项式作为除数,进行模二除法,得到的余数就是校验码。

数据接收方的CRC校验:将接受的数据(有效数据+CRC校验码)扩展后作为被除数,用指定的多项式作为除数,进行模二除法,得到余数为0,则表示校验正确。

手算推导过程可见视频

【[CRC校验]手算与直观演示-哔哩哔哩】 https://b23.tv/2qvVvCF

以CRC16为例,他的生产多项式为:G(x) = x^{16}+x^{12}+x^{5}+1 。在计算开始时,CRC寄存器初始化为全0

// For CRC7: Use (7, 7'h00, 7'h09)
// For CRC16: Use (16, 16'h0000, 16'h1021)

module general_crc
#(  parameter WIDTH = 16,
    parameter [WIDTH-1] INIT_VALUE = 0,
    parameter [WIDTH-1] CRC_EQUATION = 0)
(    input    clk,
     input    res_n,
     input    init,    // initialize crc_value with INIT_VALUE
     input    enable,  // calculate crc_value from data_in
     input    draint,  // crc_calue is shifted out from data_out
     output   data_out,
     output reg [WIDTH-1 : 0]    crc_value, //parallel out crc_value
);
wire    crc_next;
wire    [WIDTH-1]    crc_temp;
assign    crc_next = data_in ^ crc_value[WIDTH-1];
assign    crc_temp = {crc_value[WIDTH-2], 1'b0};

always @ (posedge clk or negedge rst_n) begin
    if(!rst_n)
        crc_value <= {WIDTH{1'b0}};
    else if (init)
        crc_value <= INIT_VALUE;
    else if (enable)
        if(crc_next)
            crc_value <= crc_temp ^ CRC_EQUATION;
        else 
            crc_value <= crc_temp;
    else if (draint)
            crc_value <= crc_value[WIDTH-2];
end

assign crc_out = crc_value[WIDTH-1];

endmodule

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值