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計算
- http://www.zorc.breitbandkatze.de/crc.html
- http://ghsi.de/CRC/index.php?Polynom=10001000000100001&Message=aa
沒有留言:
張貼留言
俗話說
凡走過必留下痕跡,凡住過必留下鄰居
凡爬過必留下樓梯,凡來過必留下IP
看過文章之後歡迎留下您寶貴的意見喔!