1 前言
(1) 什么是CRC校驗?
CRC即循環(huán)冗余校驗碼:是數(shù)據(jù)通信領域中最常用的一種查錯校驗碼,其特征是信息字段和校驗字段的長度可以任意選定。循環(huán)冗余檢查(CRC)是一種數(shù)據(jù)傳輸檢錯功能,對數(shù)據(jù)進行多項式計算,并將得到的結果附在幀的后面,接收設備也執(zhí)行類似的算法,以保證數(shù)據(jù)傳輸?shù)恼_性和完整性。
LFSR計算CRC,可以用多項式G(x)表示,G(x) = X16+X12+X5+1模型可如下圖所示。
(2) 校驗原理
其根本思想就是先在要發(fā)送的幀后面附加一個數(shù)(這個就是用來校驗的校驗碼,但要注意,這里的數(shù)也是二進制序列的,下同),生成一個新幀發(fā)送給接收端。當然,這個附加的數(shù)不是隨意的,它要使所生成的新幀能與發(fā)送端和接收端共同選定的某個特定數(shù)整除(注意,這里不是直接采用二進制除法,而是采用一種稱之為“模2除法”)。到達接收端后,再把接收到的新幀除以(同樣采用“模2除法”)這個選定的除數(shù)。因為在發(fā)送端發(fā)送數(shù)據(jù)幀之前就已通過附加一個數(shù),做了“去余”處理(也就已經(jīng)能整除了),所以結果應該是沒有余數(shù)。如果有余數(shù),則表明該幀在傳輸過程中出現(xiàn)了差錯。
要校驗的數(shù)據(jù)加上此數(shù)據(jù)計算出來的crc組成新的數(shù)據(jù)幀,如下圖所示。
模2除法:
模2除法與算術除法類似,但每一位除的結果不影響其它位,即不向上一位借位,所以實際上就是異或。在循環(huán)冗余校驗碼(CRC)的計算中有應用到模2除法。
(3) 步驟
CRC校驗中有兩個關鍵點,一是預先確定一個發(fā)送送端和接收端都用來作為除數(shù)的二進制比特串(或多項式),可以隨機選擇,也可以使用國際標準,但是最高位和最低位必須為1;二是把原始幀與上面計算出的除數(shù)進行模2除法運算,計算出CRC碼。
1. 選擇合適的除數(shù)
2. 看選定除數(shù)的二進制位數(shù),然后再要發(fā)送的數(shù)據(jù)幀上面加上這個位數(shù)-1位的0,然后用新生成的幀以模2除法的方式除上面的除數(shù),得到的余數(shù)就是該幀的CRC校驗碼。注意,余數(shù)的位數(shù)一定只比除數(shù)位數(shù)少一位,也就是CRC校驗碼位數(shù)比除數(shù)位數(shù)少一位,如果前面位是0也不能省略。
3. 將計算出來的CRC校驗碼附加在原數(shù)據(jù)幀后面,構建成一個新的數(shù)據(jù)幀進行發(fā)送;最后接收端在以模2除法方式除以前面選擇的除數(shù),如果沒有余數(shù),則說明數(shù)據(jù)幀在傳輸?shù)倪^程中沒有出錯。
(4) 計算實例
現(xiàn)假設選擇的CRC生成多項式為G(X) = X4+ X3+ 1,要求出二進制序列10110011的CRC校驗碼。下面是具體的計算過程:
①將多項式轉化為二進制序列,由G(X) = X4+ X3+ 1可知二進制一種有五位,第4位、第三位和第零位分別為1,則序列為11001
②多項式的位數(shù)位5,則在數(shù)據(jù)幀的后面加上5-1位0,數(shù)據(jù)幀變?yōu)?01100110000,然后使用模2除法除以除數(shù)11001,得到余數(shù)。
③將計算出來的CRC校驗碼添加在原始幀的后面,真正的數(shù)據(jù)幀為101100110100,再把這個數(shù)據(jù)幀發(fā)送到接收端。
④接收端收到數(shù)據(jù)幀后,用上面選定的除數(shù),用模2除法除去,驗證余數(shù)是否為0,如果為0,則說明數(shù)據(jù)幀沒有出錯。
2 流程
(1)并行計算crc用verilog語言描述是復雜繁瑣的,所以可以使用在線工具生成verilog或者VHDL模板:http://www.easics.com/webtools/crctool,模板生成的代碼稍加修改即可使用。
(2)本次校驗模型為G(x) = X16+X12+X5+1。在在線工具中操作相關選項生成模板。
模板v文件如下:
1 //////////////////////////////////////////////////////////////////////////////// 2 // Copyright (C) 1999-2008 Easics NV. 3 // This source file may be used and distributed without restriction 4 // provided that this copyright statement is not removed from the file 5 // and that any derivative work contains the original copyright notice 6 // and the associated disclaimer. 7 // 8 // THIS SOURCE FILE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS 9 // OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 10 // WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 11 // 12 // Purpose : synthesizable CRC function 13 // * polynomial: x^16 + x^12 + x^5 + 1 14 // * data width: 16 15 // 16 // Info : tools@easics.be 17 // http://www.easics.com 18 //////////////////////////////////////////////////////////////////////////////// 19 module CRC16_D16; 20 21 // polynomial: x^16 + x^12 + x^5 + 1 22 // data width: 16 23 // convention: the first serial bit is D[15] 24 function [15:0] nextCRC16_D16; 25 26 input [15:0] Data; 27 input [15:0] crc; 28 reg [15:0] d; 29 reg [15:0] c; 30 reg [15:0] newcrc; 31 begin 32 d = Data; 33 c = crc; 34 35 newcrc[0] = d[12] ^ d[11] ^ d[8] ^ d[4] ^ d[0] ^ c[0] ^ c[4] ^ c[8] ^ c[11] ^ c[12]; 36 newcrc[1] = d[13] ^ d[12] ^ d[9] ^ d[5] ^ d[1] ^ c[1] ^ c[5] ^ c[9] ^ c[12] ^ c[13]; 37 newcrc[2] = d[14] ^ d[13] ^ d[10] ^ d[6] ^ d[2] ^ c[2] ^ c[6] ^ c[10] ^ c[13] ^ c[14]; 38 newcrc[3] = d[15] ^ d[14] ^ d[11] ^ d[7] ^ d[3] ^ c[3] ^ c[7] ^ c[11] ^ c[14] ^ c[15]; 39 newcrc[4] = d[15] ^ d[12] ^ d[8] ^ d[4] ^ c[4] ^ c[8] ^ c[12] ^ c[15]; 40 newcrc[5] = d[13] ^ d[12] ^ d[11] ^ d[9] ^ d[8] ^ d[5] ^ d[4] ^ d[0] ^ c[0] ^ c[4] ^ c[5] ^ c[8] ^ c[9] ^ c[11] ^ c[12] ^ c[13]; 41 newcrc[6] = d[14] ^ d[13] ^ d[12] ^ d[10] ^ d[9] ^ d[6] ^ d[5] ^ d[1] ^ c[1] ^ c[5] ^ c[6] ^ c[9] ^ c[10] ^ c[12] ^ c[13] ^ c[14]; 42 newcrc[7] = d[15] ^ d[14] ^ d[13] ^ d[11] ^ d[10] ^ d[7] ^ d[6] ^ d[2] ^ c[2] ^ c[6] ^ c[7] ^ c[10] ^ c[11] ^ c[13] ^ c[14] ^ c[15]; 43 newcrc[8] = d[15] ^ d[14] ^ d[12] ^ d[11] ^ d[8] ^ d[7] ^ d[3] ^ c[3] ^ c[7] ^ c[8] ^ c[11] ^ c[12] ^ c[14] ^ c[15]; 44 newcrc[9] = d[15] ^ d[13] ^ d[12] ^ d[9] ^ d[8] ^ d[4] ^ c[4] ^ c[8] ^ c[9] ^ c[12] ^ c[13] ^ c[15]; 45 newcrc[10] = d[14] ^ d[13] ^ d[10] ^ d[9] ^ d[5] ^ c[5] ^ c[9] ^ c[10] ^ c[13] ^ c[14]; 46 newcrc[11] = d[15] ^ d[14] ^ d[11] ^ d[10] ^ d[6] ^ c[6] ^ c[10] ^ c[11] ^ c[14] ^ c[15]; 47 newcrc[12] = d[15] ^ d[8] ^ d[7] ^ d[4] ^ d[0] ^ c[0] ^ c[4] ^ c[7] ^ c[8] ^ c[15]; 48 newcrc[13] = d[9] ^ d[8] ^ d[5] ^ d[1] ^ c[1] ^ c[5] ^ c[8] ^ c[9]; 49 newcrc[14] = d[10] ^ d[9] ^ d[6] ^ d[2] ^ c[2] ^ c[6] ^ c[9] ^ c[10]; 50 newcrc[15] = d[11] ^ d[10] ^ d[7] ^ d[3] ^ c[3] ^ c[7] ^ c[10] ^ c[11]; 51 nextCRC16_D16 = newcrc; 52 end 53 endfunction 54 endmodule
(3)修改模板最終如下:
1 `timescale 1ns/1ps 2 module crc16_test ( 3 input wire i_clk , //時鐘; 4 input wire i_rst_n , //同步復位; 5 input wire i_din_valid , //輸入數(shù)據(jù)有效; 6 input wire [15:0] i_din , //輸入數(shù)據(jù); 7 output wire o_dout_valid , //輸出CRC值有效; 8 output wire [15:0] o_dout //輸出CRC; 9 ); 10 reg [15:0] r_dout; 11 wire [15:0] d; 12 wire [15:0] c; 13 assign d = i_din; 14 assign c = r_dout; 15 always @(posedge i_clk) begin 16 if (~i_rst_n) 17 r_dout <= 16'hffff; //初始值為ffff; 18 else if (i_din_valid) 19 begin //計算邏輯; 20 r_dout[0] = d[12] ^ d[11] ^ d[8] ^ d[4] ^ d[0] ^ c[0] ^ c[4] ^ c[8] ^ c[11] ^ c[12]; 21 r_dout[1] = d[13] ^ d[12] ^ d[9] ^ d[5] ^ d[1] ^ c[1] ^ c[5] ^ c[9] ^ c[12] ^ c[13]; 22 r_dout[2] = d[14] ^ d[13] ^ d[10] ^ d[6] ^ d[2] ^ c[2] ^ c[6] ^ c[10] ^ c[13] ^ c[14]; 23 r_dout[3] = d[15] ^ d[14] ^ d[11] ^ d[7] ^ d[3] ^ c[3] ^ c[7] ^ c[11] ^ c[14] ^ c[15]; 24 r_dout[4] = d[15] ^ d[12] ^ d[8] ^ d[4] ^ c[4] ^ c[8] ^ c[12] ^ c[15]; 25 r_dout[5] = d[13] ^ d[12] ^ d[11] ^ d[9] ^ d[8] ^ d[5] ^ d[4] ^ d[0] ^ c[0] ^ c[4] ^ c[5] ^ c[8] ^ c[9] ^ c[11] ^ c[12] ^ c[13]; 26 r_dout[6] = d[14] ^ d[13] ^ d[12] ^ d[10] ^ d[9] ^ d[6] ^ d[5] ^ d[1] ^ c[1] ^ c[5] ^ c[6] ^ c[9] ^ c[10] ^ c[12] ^ c[13] ^ c[14]; 27 r_dout[7] = d[15] ^ d[14] ^ d[13] ^ d[11] ^ d[10] ^ d[7] ^ d[6] ^ d[2] ^ c[2] ^ c[6] ^ c[7] ^ c[10] ^ c[11] ^ c[13] ^ c[14] ^ c[15]; 28 r_dout[8] = d[15] ^ d[14] ^ d[12] ^ d[11] ^ d[8] ^ d[7] ^ d[3] ^ c[3] ^ c[7] ^ c[8] ^ c[11] ^ c[12] ^ c[14] ^ c[15]; 29 r_dout[9] = d[15] ^ d[13] ^ d[12] ^ d[9] ^ d[8] ^ d[4] ^ c[4] ^ c[8] ^ c[9] ^ c[12] ^ c[13] ^ c[15]; 30 r_dout[10] = d[14] ^ d[13] ^ d[10] ^ d[9] ^ d[5] ^ c[5] ^ c[9] ^ c[10] ^ c[13] ^ c[14]; 31 r_dout[11] = d[15] ^ d[14] ^ d[11] ^ d[10] ^ d[6] ^ c[6] ^ c[10] ^ c[11] ^ c[14] ^ c[15]; 32 r_dout[12] = d[15] ^ d[8] ^ d[7] ^ d[4] ^ d[0] ^ c[0] ^ c[4] ^ c[7] ^ c[8] ^ c[15]; 33 r_dout[13] = d[9] ^ d[8] ^ d[5] ^ d[1] ^ c[1] ^ c[5] ^ c[8] ^ c[9]; 34 r_dout[14] = d[10] ^ d[9] ^ d[6] ^ d[2] ^ c[2] ^ c[6] ^ c[9] ^ c[10]; 35 r_dout[15] = d[11] ^ d[10] ^ d[7] ^ d[3] ^ c[3] ^ c[7] ^ c[10] ^ c[11]; 36 end 37 end 38 reg r_dout_valid = 0; 39 always @(posedge i_clk) //輸入數(shù)據(jù)在一個時鐘內完成CRC計算,下一個時鐘輸出; 40 begin 41 r_dout_valid <= i_din_valid; 42 end 43 44 assign o_dout_valid = r_dout_valid; 45 assign o_dout = r_dout ; 46 47 endmodule // end the crc16_test model;
3 仿真
仿真結果和在線工具計算結果進行比較,在線工具地址:http://www.ip33.com/crc.html。
(1)編寫tb文件,對代碼進行測試,測試結果如下圖所示:
(2)在線校驗。輸入需要校驗的數(shù)據(jù),選擇參數(shù)模型,輸入初始值(此次crc結果的前一個crc值,代碼中初始化為ffff)??梢詫Ρ劝l(fā)現(xiàn)計算無誤。
第一次計算0011(初始值為ffff),結果為1f1f。
第二次計算0013(初始值為1f1f),結果為d2c1。
4 綜合
本次綜合參考芯片為:xc7k325tffg676-2
(1) 資源使用量如下圖所示。
(2) 模塊時鐘約束為100M,裕量如下圖所示,滿足時序要求。
-
crc
+關注
關注
0文章
201瀏覽量
29762 -
Verilog
+關注
關注
28文章
1358瀏覽量
111036 -
校驗碼
+關注
關注
0文章
11瀏覽量
7665 -
模型
+關注
關注
1文章
3433瀏覽量
49548
原文標題:4 綜合
文章出處:【微信號:gh_9d70b445f494,微信公眾號:FPGA設計論壇】歡迎添加關注!文章轉載請注明出處。
發(fā)布評論請先 登錄
相關推薦
有關基于verilog的CRC校驗的問題
怎么用verilog HDL或VHDL去實現(xiàn)CRC校驗呢
CRC算法原理及C語言實現(xiàn)
Verilog HDL語言實現(xiàn)時序邏輯電路
CRC校驗碼算法的研究與實現(xiàn)
CRC算法原理和CRC編碼的實現(xiàn)方式與使用Verilog對CRC編碼進行描述

使用verilog語言實現(xiàn)數(shù)字鐘的工程文件合集免費下載

CRC校驗原理及實現(xiàn)

評論