USB中TOKEN的CRC5與CRC16校驗(神奇的工具生成Verilog實現)


USB2.0IP設計

      最近,在學習USB2.0IP的設計,其中包含了CRC校驗碼的內容,之前學習千兆以太網曾經用到過CRC32校驗(https://www.cnblogs.com/Xwangzi66/p/14185143.html),CRC詳細原理可見括號的鏈接,今天則從怎么用工具快速生成Verilog代碼的角度介紹。

    一 確定CRC5的多項式

        G(X)= X^5 + X^2 + 1,輸入數據的位寬為11bit,即CRC5中的輸入信號[10:0]data_i.

    二 在線網頁生成CRC5的Verilog代碼

    鏈接如下:https://www.easics.com/crctool/

    在線生成CRC5校驗代碼如下圖:第一步是確定多項式,此處是CRC5的多項式。第二步選擇CRC的類別,如CRC16,CRC32等。第三步,選擇待校驗數據的位寬。第四步,選擇輸出的編程語言,用Verilog實現。第五步,下載打開就🆗。注意填好郵箱,此處為了保護本人隱私則空着。

2.在線工具生成CRC5的Verilog代碼

 

 1 module CRC5_D11;
 2 
 3   // polynomial: x^5 + x^2 + 1
 4   // data width: 11
 5   // convention: the first serial bit is D[10]
 6   function [4:0] nextCRC5_D11;
 7 
 8     input [10:0] Data;
 9     input [4:0] crc;
10     reg [10:0] d;
11     reg [4:0] c;
12     reg [4:0] newcrc;
13   begin
14     d = Data;
15     c = crc;
16 
17     newcrc[0] = d[10] ^ d[9] ^ d[6] ^ d[5] ^ d[3] ^ d[0] ^ c[0] ^ c[3] ^ c[4];
18     newcrc[1] = d[10] ^ d[7] ^ d[6] ^ d[4] ^ d[1] ^ c[0] ^ c[1] ^ c[4];
19     newcrc[2] = d[10] ^ d[9] ^ d[8] ^ d[7] ^ d[6] ^ d[3] ^ d[2] ^ d[0] ^ c[0] ^ c[1] ^ c[2] ^ c[3] ^ c[4];
20     newcrc[3] = d[10] ^ d[9] ^ d[8] ^ d[7] ^ d[4] ^ d[3] ^ d[1] ^ c[1] ^ c[2] ^ c[3] ^ c[4];
21     newcrc[4] = d[10] ^ d[9] ^ d[8] ^ d[5] ^ d[4] ^ d[2] ^ c[2] ^ c[3] ^ c[4];
22     nextCRC5_D11 = newcrc;
23   end
24   endfunction
25 endmodule

 

                          三  修改成自己USB的IP設計的CRC5校驗模塊

          通過在線工具生成后,自己可以修改模塊名,輸入輸出信號名,寄存器名,以更好地用在自己的FPGA項目中,本人CRC5修改如下:

 1 module usbh_crc5
 2 (
 3     input [4:0]     crc_i,
 4     input [10:0]    data_i,
 5     output [4:0]    crc_o
 6 );
 7 
 8 //-----------------------------------------------------------------
 9 // Implementation
10 //-----------------------------------------------------------------
11 assign crc_o[0] =    data_i[10] ^ data_i[9] ^ data_i[6] ^ data_i[5] ^ data_i[3] ^ data_i[0] ^
12                        crc_i[0] ^ crc_i[3] ^ crc_i[4];
13 
14 assign crc_o[1] =    data_i[10] ^ data_i[7] ^ data_i[6] ^ data_i[4] ^ data_i[1] ^
15                        crc_i[0] ^ crc_i[1] ^ crc_i[4];
16 
17 assign crc_o[2] =    data_i[10] ^ data_i[9] ^ data_i[8] ^ data_i[7] ^ data_i[6] ^ data_i[3] ^ data_i[2] ^ data_i[0] ^
18                        crc_i[0] ^ crc_i[1] ^ crc_i[2] ^ crc_i[3] ^ crc_i[4];
19 
20 assign crc_o[3] =    data_i[10] ^ data_i[9] ^ data_i[8] ^ data_i[7] ^ data_i[4] ^ data_i[3] ^ data_i[1] ^ 
21                        crc_i[1] ^ crc_i[2] ^ crc_i[3] ^ crc_i[4];
22 
23 assign crc_o[4] =    data_i[10] ^ data_i[9] ^ data_i[8] ^ data_i[5] ^ data_i[4] ^ data_i[2] ^
24                        crc_i[2] ^ crc_i[3] ^ crc_i[4];
25 
26 endmodule

   通過修改后,代碼更簡潔高效,更方便調用,直接在USB中調用即可!

后續的CRC16的Verilog實現,同CRC5生成方法一樣,先用在線工具生成,再修改一些模塊名,輸入輸出信號即可。

CRC16代碼如下:

 1 module usbh_crc16
 2 (
 3     input [15:0]    crc_i,
 4     input [7:0]     data_i,
 5     output [15:0]   crc_o
 6 );
 7 
 8 //-----------------------------------------------------------------
 9 // Implementation
10 //-----------------------------------------------------------------
11 assign crc_o[15] =    data_i[0] ^ data_i[1] ^ data_i[2] ^ data_i[3] ^ data_i[4] ^
12                         data_i[5] ^ data_i[6] ^ data_i[7] ^ crc_i[7] ^ crc_i[6] ^
13                         crc_i[5] ^ crc_i[4] ^ crc_i[3] ^ crc_i[2] ^
14                         crc_i[1] ^ crc_i[0];
15 assign crc_o[14] =    data_i[0] ^ data_i[1] ^ data_i[2] ^ data_i[3] ^ data_i[4] ^ data_i[5] ^
16                         data_i[6] ^ crc_i[6] ^ crc_i[5] ^ crc_i[4] ^
17                         crc_i[3] ^ crc_i[2] ^ crc_i[1] ^ crc_i[0];
18 assign crc_o[13] =    data_i[6] ^ data_i[7] ^ crc_i[7] ^ crc_i[6];
19 assign crc_o[12] =    data_i[5] ^ data_i[6] ^ crc_i[6] ^ crc_i[5];
20 assign crc_o[11] =    data_i[4] ^ data_i[5] ^ crc_i[5] ^ crc_i[4];
21 assign crc_o[10] =    data_i[3] ^ data_i[4] ^ crc_i[4] ^ crc_i[3];
22 assign crc_o[9] =     data_i[2] ^ data_i[3] ^ crc_i[3] ^ crc_i[2];
23 assign crc_o[8] =     data_i[1] ^ data_i[2] ^ crc_i[2] ^ crc_i[1];
24 assign crc_o[7] =     data_i[0] ^ data_i[1] ^ crc_i[15] ^ crc_i[1] ^ crc_i[0];
25 assign crc_o[6] =     data_i[0] ^ crc_i[14] ^ crc_i[0];
26 assign crc_o[5] =     crc_i[13];
27 assign crc_o[4] =     crc_i[12];
28 assign crc_o[3] =     crc_i[11];
29 assign crc_o[2] =     crc_i[10];
30 assign crc_o[1] =     crc_i[9];
31 assign crc_o[0] =     data_i[0] ^ data_i[1] ^ data_i[2] ^ data_i[3] ^ data_i[4] ^ data_i[5] ^
32                         data_i[6] ^ data_i[7] ^ crc_i[8] ^ crc_i[7] ^ crc_i[6] ^
33                         crc_i[5] ^ crc_i[4] ^ crc_i[3] ^ crc_i[2] ^
34                         crc_i[1] ^ crc_i[0];
35 
36 endmodule
Crc16 Code

 

總結,一直都是根據多項式,確定硬件電路的形式,然后查表,如V3學院千兆以太網的CRC32校驗教程,很繁瑣,得理解原理,今天意外知道一種新的方法,通過在線工具生成Verilog實現:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM