Social Icons

twitterfacebookgoogle plusrss feedemail

11/15/2013

[verilog][c] CRC 循環冗餘校驗 實踐

最近幾位學弟妹在問verilog的作業(QAM 16、QAM256以及CRC),順便也學習寫了一下

CRC的概述我這邊就不說明了,請參考WiKi 或者是這篇文章,在這邊只介紹程式碼。
(不過稍微注意一下維基百科裡面原理是對的,但下面舉的例子有點問題)


CRC 16 的 Verilog 程式碼(P(x) = x16+ x12+ x5+ x0)

module CRC_Unit(BITVAL, BITSTRB, CLEAR, CRC);
   input        BITVAL;                            // Next input bit
   input        BITSTRB;                           // Current bit valid (Clock)
   input        CLEAR;                             // Init CRC value
   output [15:0] CRC;                               // Current output CRC value

   reg    [15:0] CRC;                               // We need output registers
   wire         inv;
   
   assign inv = BITVAL ^ CRC[15];                   // XOR required?
   
   always @(posedge BITSTRB or posedge CLEAR) begin
      if (CLEAR) begin
         CRC = 0;                                  // Init before calculation
         end
      else begin
         CRC[15] = CRC[14];
         CRC[14] = CRC[13];
         CRC[13] = CRC[12];
         CRC[12] = CRC[11] ^ inv;
         CRC[11] = CRC[10];
         CRC[10] = CRC[9];
         CRC[9] = CRC[8];
         CRC[8] = CRC[7];
         CRC[7] = CRC[6];
         CRC[6] = CRC[5];
         CRC[5] = CRC[4] ^ inv;
         CRC[4] = CRC[3];
         CRC[3] = CRC[2];
         CRC[2] = CRC[1];
         CRC[1] = CRC[0];
         CRC[0] = inv;
         end
      end
   
endmodule



CRC 16 的 C程式碼(P(x) = x16+ x12+ x5+ x0)
char *MakeCRC(char *BitString)
   {
   static char Res[17];                                 // CRC Result
   char CRC[16];
   int  i;
   char DoInvert;
   
   for (i=0; i<16; ++i)  CRC[i] = 0;                    // Init before calculation
   
   for (i=0; i<strlen(BitString); ++i)
      {
      DoInvert = ('1'==BitString[i]) ^ CRC[15];         // XOR required?

      CRC[15] = CRC[14];
      CRC[14] = CRC[13];
      CRC[13] = CRC[12];
      CRC[12] = CRC[11] ^ DoInvert;
      CRC[11] = CRC[10];
      CRC[10] = CRC[9];
      CRC[9] = CRC[8];
      CRC[8] = CRC[7];
      CRC[7] = CRC[6];
      CRC[6] = CRC[5];
      CRC[5] = CRC[4] ^ DoInvert;
      CRC[4] = CRC[3];
      CRC[3] = CRC[2];
      CRC[2] = CRC[1];
      CRC[1] = CRC[0];
      CRC[0] = DoInvert;
      }
      
   for (i=0; i<16; ++i)  Res[15-i] = CRC[i] ? '1' : '0'; // Convert binary to ASCII
   Res[16] = 0;                                         // Set string terminator

   return(Res);
   }

// A simple test driver:

#include <stdio.h>

int main()
   {
   char *Data, *Result;                                       // Declare two strings

   Data = "1101000101000111";
   Result = MakeCRC(Data);                                    // Calculate CRC
   
   printf("CRC of [%s] is [%s] with P=[10001000000100001]\n", Data, Result);
   
   return(0);
   }

CRC 32 的 Verilog 程式碼
(P(x) = x32+ x26+ x23+ x22+ x16+ x12+ x11+ x10+ x8+ x7+ x5+ x4+ x2+ x1+ x0)

module CRC_Unit(BITVAL, BITSTRB, CLEAR, CRC);
   input        BITVAL;                            // Next input bit
   input        BITSTRB;                           // Current bit valid (Clock)
   input        CLEAR;                             // Init CRC value
   output [31:0] CRC;                               // Current output CRC value

   reg    [31:0] CRC;                               // We need output registers
   wire         inv;
   
   assign inv = BITVAL ^ CRC[31];                   // XOR required?
   
   always @(posedge BITSTRB or posedge CLEAR) begin
      if (CLEAR) begin
         CRC = 0;                                  // Init before calculation
         end
      else begin
         CRC[31] = CRC[30];
         CRC[30] = CRC[29];
         CRC[29] = CRC[28];
         CRC[28] = CRC[27];
         CRC[27] = CRC[26];
         CRC[26] = CRC[25] ^ inv;
         CRC[25] = CRC[24];
         CRC[24] = CRC[23];
         CRC[23] = CRC[22] ^ inv;
         CRC[22] = CRC[21] ^ inv;
         CRC[21] = CRC[20];
         CRC[20] = CRC[19];
         CRC[19] = CRC[18];
         CRC[18] = CRC[17];
         CRC[17] = CRC[16];
         CRC[16] = CRC[15] ^ inv;
         CRC[15] = CRC[14];
         CRC[14] = CRC[13];
         CRC[13] = CRC[12];
         CRC[12] = CRC[11] ^ inv;
         CRC[11] = CRC[10] ^ inv;
         CRC[10] = CRC[9] ^ inv;
         CRC[9] = CRC[8];
         CRC[8] = CRC[7] ^ inv;
         CRC[7] = CRC[6] ^ inv;
         CRC[6] = CRC[5];
         CRC[5] = CRC[4] ^ inv;
         CRC[4] = CRC[3] ^ inv;
         CRC[3] = CRC[2];
         CRC[2] = CRC[1] ^ inv;
         CRC[1] = CRC[0] ^ inv;
         CRC[0] = inv;
         end
      end
   
endmodule



相關參考網站:
1.基於FPGA的CRC校驗碼生成器
2.線上CRC計算



沒有留言:

張貼留言

俗話說
凡走過必留下痕跡,凡住過必留下鄰居
凡爬過必留下樓梯,凡來過必留下IP
看過文章之後歡迎留下您寶貴的意見喔!

 
 
无觅相关文章插件,迅速提升网站流量