当前位置:   article > 正文

【Verilog】CRC校验码生成器原理及verilog实现_crc verilog

crc verilog

目录

一、CRC的基本原理

 二、CRC生成步骤

2.1举个栗子

三、Verilog实现

四、参考资料

4.1 CRC在线计算器


一、CRC的基本原理

CRC :Cyclic Redundancy Check循环冗余校验码

        将被处理的报文比特序列当做一个二进制多项式A(x)的系数,任意一个由二进制位串组成的代码都可以和一个系数仅为‘0’和‘1’取值的多项式一一对应。例如:代码1010111对应的多项式为x6+x4+x2+x+1,而多项式为x5+x3+x2+x+1对应的代码101111,该系数乘以2^n(n为生成多项式g(x)中x的最高次幂)以后再除以发送方和接收方事先约定好的生成多项式g(x)后,求得的余数P(x)就是CRC校验码,把它附到原始的报文A(x)后面形成新的报文即为A(x)*x^n+P(x),并且发送到接收端,接收端从整个报文中提取出报文B(x)(即为发送端的A(x),此时不能保证发送正确所以用B(x)表示),然后用与接收端同样的做法将B(x)对应的二进制序列乘以2^n(左移n位)后,除以事先约定好的g(x)得到一个余数p’(x),此时如果接收报文中的CRC校验码与计算得到的校验码相同,即P(x)=p’(x),则传输正确,否则传输有误,重新传输。

上述工作过程中有几点需要注意:

       1.在进行CRC计算时,采用二进制(模2)运算法,即加法不进位,减法不借位,其本质就是两个操作数进行逻辑异或运算;

       2.在进行CRC计算前先将发送报文所表示的多项式A(x)乘以x^n,其中n为生成多项式g(x)的最高幂值。对二进制乘法来讲,A(x)*x^n就是将A(x)左移n             位,用来存放余数p(x),所以实际发送的报文就变为A(x)*x^n+p(x):

       3.生成多项式g(x)的首位和最后一位的系数必须为1,且生成多项式根据不同国家的标准有不同的形式。

CRC校验码检错的原理如下图

 二、CRC生成步骤

  1. 代码与多项式对应

如:1011001  ——> A(x) = x^6 + x^4 + x^3 + 1 (系数对应)

  1. 确定生成多项式

生成多项式g(x)由发送方与接收方提前约定好。

常用有: CRC-16 : x^16 + x^15 + x^2 + 1

  1. CRC生成

P(x) = A(x) * x^n / g(x)   n : g(x)中x的最高次幂

  1. 发送:新的报文

A(x) * x^n + P(x)

  1. 接收:生成CRC与发送CRC比对

接收到的报文为B(x),按步骤3生成接收数据的CRC:p’(x),再与发送方的P(x)比较,若相等,则传输正确。

2.1举个栗子

报文 : 1011001 ,则A(x) = x^6 + x^4 + x^3 + 1

约定生成多项式 : g(x) = x^4 + x^3 + 1(系数为:11001)(n = 4,CRC为4位)

——>A(x) * x^n = x^10 + x^8 + x^7 + x^4(系数为:10110010000)

——>多项式除法:(模2除法)除数和被除数做异或运算(最高位对齐)。

——>多项式除法:

1

0

1

1

0

0

1

0

0

0

0

^

1

1

0

0

1

0

1

1

1

1

0

1

0

0

0

0

^

1

1

0

0

1

0

0

1

1

1

1

0

0

0

0

^

1

1

0

0

1

0

0

1

1

1

0

0

0

1

1

0

0

1

0

0

1

0

1

0

求得余数为: 1010 (CRC)

将CRC附到原报文后面即为新发送的报文:1011001_1010

下面我们将通过verilog代码实现,以及CRC计算器来验证。

三、Verilog实现

  1. module crc_test(
  2. input clk,
  3. input rst,
  4. input [7:0] data_in,
  5. output reg[3:0] crc_out,
  6. output reg crc_vld
  7. );
  8. parameter polynomial = 5'b11001;
  9. localparam IDLE = 3'b001,
  10. CRC = 3'b010,
  11. DONE = 3'b100;
  12. reg [11:0] temp = 0;
  13. reg [2:0] state;
  14. wire [11:0] signal_temp;
  15. assign signal_temp = {data_in,4'b0};
  16. always @ (posedge clk or posedge rst)begin
  17. if(rst)begin
  18. state <= IDLE;
  19. crc_out <= 4'b0;
  20. crc_vld <= 1'b0;
  21. end
  22. else case(state)
  23. IDLE:begin
  24. crc_out<= 4'b0;
  25. crc_vld<= 1'b0;
  26. temp <= signal_temp;
  27. state <= CRC;
  28. end
  29. CRC:begin
  30. state <= CRC;
  31. crc_vld <= 1'b0;
  32. if(temp[11]) temp[11:7] <= temp[11:7] ^ polynomial;
  33. else if(temp[10])temp[10:6] <= temp[10:6] ^ polynomial;
  34. else if(temp[9])temp[9:5] <= temp[9:5] ^ polynomial;
  35. else if(temp[8])temp[8:4] <= temp[8:4] ^ polynomial;
  36. else if(temp[7])temp[7:3] <= temp[7:3] ^ polynomial;
  37. else if(temp[6])temp[6:2] <= temp[6:2] ^ polynomial;
  38. else if(temp[5])temp[5:1] <= temp[5:1] ^ polynomial;
  39. else if(temp[4])temp[4:0] <= temp[4:0] ^ polynomial;
  40. else state<=DONE;
  41. end
  42. DONE:begin
  43. crc_out <= temp[3:0];
  44. crc_vld <= 1'b1;
  45. state <= IDLE;
  46. end
  47. default : begin
  48. crc_out <= 4'b0;
  49. crc_vld <= 1'b1;
  50. state <= IDLE;
  51. end
  52. endcase
  53. end
  54. endmodule

运行结果: 4’ha --->-4’b1010

 

四、参考资料

CRC校验码的verilog实现与仿真结果_stubben_bear的专栏-CSDN博客_crc16 verilog

4.1 CRC在线计算器

CRC(循环冗余校验)在线计算_ip33.com

报文 :  1011001  (0x59)

生成多项式 : g(x) = x^4 + x^3 + 1

CRC :  1010     ( 0xa)

CRC计算结果截图:

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/321486
推荐阅读
相关标签
  

闽ICP备14008679号