CRC校验原理及verilog实现

计算方法

从计算到原理,更易接受

知识准备

首先学会模2除法,就是异或操作:看例子

CRC校验原理及verilog实现_第1张图片

按步骤

1选择CRC生成多项式,这个一般提供标准

如在IBM的SDLC(同步数据链路控制)规程中使用的CRC-16(也就是这个除数一共是17位)生成多项式g(x)= x16 + x15 + x2 +1(对应二进制比特串为:11000000000000101);

而在ISO HDLC(高级数据链路控制)规程、ITU的SDLC、X.25、V.34、V.41、V.42等中使用CCITT-16生成多项式g(x)=x16 + x15 + x5 +1(对应二进制比特串为:11000000000100001)。

次幂数字对应第几位,最高位和最低位0位需要为1.因此上述两个均为16+1位,首位为1,中间挑了一位为1.

2做模2除法计算,写除数,被除数,求余数(即为CRC码)

知道一个知识,校验码的位数比生成多项式的位数少1

题目:
已知

       	生成式:G(X) = X4 + X3 + 1
		数据:10110011 

求:

		CRC码

解:

	除数:11001(根据生成式写)
	被除数:10110011_0000(末尾补共校验码长度的0,长度除数-1)

计算
CRC校验原理及verilog实现_第2张图片
所以,校验码为0100
从而,数据为10110011_0100

3作用

数据 10110011_0100如果没错,再除以11001应该是整除的;如果不是整除,那么传输出现了差错。

练习题

假设CRC生成多项式为G(X) = X5 + X4 +X+1,要发送的二进制序列为100101110,求CRC校验码是多少。(答案文末)

ref
https://blog.csdn.net/lycb_gz/article/details/8201987

plus 具体原理

循环冗余校验检错方案

上节介绍的奇偶校验码(PCC)只能校验一位错误,本节所要介绍的循环冗余校验码(CRC)的检错能力更强,可以检出多位错误。

  1. CRC校验原理
    CRC校验原理看起来比较复杂,好难懂,因为大多数书上基本上是以二进制的多项式形式来说明的。其实很简单的问题,其根本思想就是先在要发送的帧后面附加一个数(这个就是用来校验的校验码,但要注意,这里的数也是二进制序列的,下同),生成一个新帧发送给接收端。当然,这个附加的数不是随意的,它要使所生成的新帧能与发送端和接收端共同选定的某个特定数整除(注意,这里不是直接采用二进制除法,而是采用一种称之为“模2除法”)。到达接收端后,再把接收到的新帧除以(同样采用“模2除法”)这个选定的除数。因为在发送端发送数据帧之前就已通过附加一个数,做了“去余”处理(也就已经能整除了),所以结果应该是没有余数。如果有余数,则表明该帧在传输过程中出现了差错。

    【说明】“模2除法”与“算术除法”类似,但它既不向上位借位,也不比较除数和被除数的相同位数值的大小,只要以相同位数进行相除即可。模2加法运算为:1+1=0,0+1=1,0+0=0,无进位,也无借位;模2减法运算为:1-1=0,0-1=1,1-0=1,0-0=0,也无进位,无借位。相当于二进制中的逻辑异或运算。也就是比较后,两者对应位相同则结果为“0”,不同则结果为“1”。如100101除以1110,结果得到商为11,余数为1,如图5-9左图所示。如11×11=101,如图5-9右图所示。
    CRC校验原理及verilog实现_第3张图片
    具体来说,CRC校验原理就是以下几个步骤:

(1)先选择(可以随机选择,也可按标准选择,具体在后面介绍)一个用于在接收端进行校验时,对接收的帧进行除法运算的除数(是二进制比较特串,通常是以多项方式表示,所以CRC又称多项式编码方法,这个多项式也称之为“生成多项式”)。

(2)看所选定的除数二进制位数(假设为k位),然后在要发送的数据帧(假设为m位)后面加上k-1位“0”,然后以这个加了k-1个“0“的新帧(一共是m+k-1位)以“模2除法”方式除以上面这个除数,所得到的余数(也是二进制的比特串)就是该帧的CRC校验码,也称之为FCS(帧校验序列)。但要注意的是,余数的位数一定要是比除数位数只能少一位,哪怕前面位是0,甚至是全为0(附带好整除时)也都不能省略。

(3)再把这个校验码附加在原数据帧(就是m位的帧,注意不是在后面形成的m+k-1位的帧)后面,构建一个新帧发送到接收端,最后在接收端再把这个新帧以“模2除法”方式除以前面选择的除数,如果没有余数,则表明该帧在传输过程中没出错,否则出现了差错。

从上面可以看出,CRC校验中有两个关键点:一是要预先确定一个发送端和接收端都用来作为除数的二进制比特串(或多项式);二是把原始帧与上面选定的除进行二进制除法运算,计算出FCS。前者可以随机选择,也可按国际上通行的标准选择,但最高位和最低位必须均为“1”,

答案
11010

verilog代码

/*-----------------------------------------------------------------------
								         \\\|///
							          \\  - -  //
								        (  @ @  )  
+-----------------------------oOOo-(_)-oOOo-----------------------------+
CONFIDENTIAL IN CONFIDENCE
This confidential and proprietary software may be only used as authorized
by a licensing agreement from CrazyBingo (Thereturnofbingo).
In the event of publication, the following notice is applicable:
Copyright (C) 2012-20xx CrazyBingo Corporation
The entire notice above must be reproduced on all authorized copies.
Author				:		laneado
Technology blogs 	: 		http://download.csdn.net/user/cucgyfjklx
Email Address 		: 		[email protected]
Filename			   :		crc5_chk.v
Date				   :		2017-06-12
Description			:		Design for crc5_chk.
Modification History	:
Date			By			     Version			Change Description
=========================================================================
11/11/11		CrazyBingo	    1.0				Original
17/06/12		CrazyBingo	    2.0				Modification
-------------------------------------------------------------------------
|                                     Oooo								|
+-------------------------------oooO--(   )-----------------------------+
                               (   )   ) /
                                \ (   (_/
                                 \_)
-----------------------------------------------------------------------*/
`timescale 1ns/1ns

module crc5_chk(
    input            rst_n,
    input            clk,
    input     [3:0]  data_in,
    input            en, 
    output reg[4:0]  crc
);

integer i;
reg  feedback;
reg  [4:0]  crc_tmp;
always @(posedge clk or negedge rst_n)
begin
    if( !rst_n ) 
        crc  <=  5'b0;         
    else if( en == 1'b0 )
        crc  <=  5'b0;
    else
        crc  <=  crc_tmp;
end


always@( data_in or crc )
begin
    crc_tmp  =  crc;
    for(i=3; i>=0; i=i-1)
    begin
      feedback    =  crc_tmp[4] ^ data_in[i];
      crc_tmp[4]  =  crc_tmp[3];
      crc_tmp[3]  =  crc_tmp[2];
      crc_tmp[2]  =  crc_tmp[1] ^ feedback;
      crc_tmp[1]  =  crc_tmp[0];
      crc_tmp[0]  =  feedback;
   end
end

endmodule 

tb

/*-----------------------------------------------------------------------
								         \\\|///
							          \\  - -  //
								        (  @ @  )  
+-----------------------------oOOo-(_)-oOOo-----------------------------+
CONFIDENTIAL IN CONFIDENCE
This confidential and proprietary software may be only used as authorized
by a licensing agreement from CrazyBingo (Thereturnofbingo).
In the event of publication, the following notice is applicable:
Copyright (C) 2012-20xx CrazyBingo Corporation
The entire notice above must be reproduced on all authorized copies.
Author				:		laneado
Technology blogs 	: 		http://download.csdn.net/user/cucgyfjklx
Email Address 		: 		[email protected]
Filename			   :		CRC5_TB.v
Date				   :		2017-06-12
Description			:		Design for Testbench.
Modification History	:
Date			By			     Version			Change Description
=========================================================================
11/11/11		CrazyBingo	    1.0				Original
17/06/12		CrazyBingo	    2.0				Modification
-------------------------------------------------------------------------
|                                     Oooo								|
+-------------------------------oooO--(   )-----------------------------+
                               (   )   ) /
                                \ (   (_/
                                 \_)
-----------------------------------------------------------------------*/

`timescale 1ns/1ns

module crc5_tb;                //鐟曚椒璞㈤惇鐔烘畱module閺傚洣娆//---------------------------------------
//clock generate module
reg  clk;                        //閹跺oduleé–ºå‚šæ´£å¨†ãˆ¤æƒƒé•î†¾ç¿»é–¸å¿‹å„±è¤°å¤å¹‹éŽ°î„‚æ‘ é–¸å±¸æšœeg閸ㄥ绱濇æ‹
å®¥å’å•å¨‘æ’³ç°¼ç» ï½‡â‚¬ç”µæ‡“ç»¨reg  rst_n;
reg  rst_n;
reg  en;
reg  [3:0] data_in;               
wire [4:0]  crc;                  //閹跺﹨绶î
¢å´™éå‹«ç¶å¨‘撶儤鈧崵鍤巜ire閸ㄥ绱濇æ‹
å®¥å’å•å¨‘æ’³ç°¼ç» ï½‡â‚¬ç”µæ‡“ç»¨localparam  PERIOD  =  20;       //50MHz
localparam  PERIOD  =  100; 

initial
begin
  clk  =  0;
  forever  #( PERIOD / 2 )
  clk  =  ~clk;
end

task task_reset;
begin
  rst_n  =  0;
  repeat(2)@( negedge clk );
  rst_n  =  1;
end
endtask

/**************娴犺法婀℃笟瀣閻ㄥ嫭鐗稿蹇ョ礉娴犺法婀℃す鍗炲З閺*************
//---------------------------------------------------
//the target component instantiation
reg  spi_cs;
reg  spi_sck;
reg  spi_mosi;
//---------------------------------------------------
//SPI Data receive from MCU
wire        rxd_flag;
wire[7:0]   rxd_data;
spi_receive u_spi_receiver
(
  //global clock
  .clk      (clk_ref),
  .rst_n    (sys_rst_n),
  
  //mcu spi interface
  .spi_cs   (spi_cs),
  .spi_sck  (spi_sck),
  .spi_mosi (spi_mosi),
//.spi_miso (spi_miso)

  //user interface
  .rxd_flag (rxd_flag),
  .rxd_data (rxd_data) 
);
***************************************************/

//---------------------------------------------------
//the target component instantiation

crc5_chk u_crc5_chk                    //4娴ï½
秷顓搁弫鏉挎珤娓氬îƒ
瀵查惃鍕伐鐎
(  //global clock
  .clk      (clk),
  .rst_n    (rst_n),
  .en       (en),
  .data_in  (data_in),
  .crc      (crc)
); 

//---------------------------------------------------
//system initialization
task task_sysinit;
begin
  data_in  =  0;
  en       =  0;
end
endtask

//---------------------------------------------------
//testbench of the RTL
initial
begin
  task_sysinit;
  task_reset;
  
  #200;
  data_in  =  4'b1010;
  #200;
  en  =  1;
  #100;
  en  =  0;
  
  #200;
  data_in  =  4'b1110;
  #200;
  en  =  1;  
  #100;
  en  =  0;
end

endmodule

ref
https://blog.csdn.net/qq_34070723/article/details/89736772?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task
https://blog.csdn.net/qq_40532956/article/details/80113408

你可能感兴趣的:(verilog)