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
看過文章之後歡迎留下您寶貴的意見喔!