去年在做PATA接口的硬盘控制器时,用UDMA传输需要CRC校验,在这里把算法贴出来,给需要的人。多项式为G(X)=X16+X12+X5+1,初始值为0x4aba;
用Verilog编写的函数代码如下:
[15:0] nextCRC;//test succussful 2008-6-1 input [15:0] Data; input [15:0] CRC; reg [15:0] rDD; reg [15:0] crcResult; reg [15:0] Result; //begin rDD = Data; crcResult = CRC; Result[0] = rDD[15] ^ rDD[4] ^ rDD[11] ^ rDD[7] ^ rDD[3] ^crcResult[12] ^ crcResult[11] ^crcResult[8] ^ crcResult[4] ^ crcResult[0]; Result[1] = rDD[14] ^ rDD[10] ^ rDD[6] ^ rDD[3] ^ rDD[2] ^crcResult[13] ^ crcResult[12] ^ crcResult[9] ^ crcResult[5] ^ crcResult[1]; Result[2] = rDD[13] ^ rDD[9] ^ rDD[5] ^ rDD[2] ^ rDD[1] ^crcResult[14] ^crcResult[13] ^crcResult[10] ^ crcResult[6] ^ crcResult[2]; Result[3] = rDD[12] ^ rDD[8] ^ rDD[4] ^ rDD[1] ^ rDD[0] ^crcResult[15] ^ crcResult[14] ^ crcResult[11] ^ crcResult[7] ^ crcResult[3]; Result[4] = rDD[11] ^ rDD[7] ^ rDD[3] ^ rDD[0] ^crcResult[15] ^ crcResult[12] ^ crcResult[8] ^ crcResult[4]; Result[5] = rDD[15] ^ rDD[11] ^ rDD[10] ^ rDD[7] ^ rDD[6] ^ rDD[4] ^ rDD[3] ^ rDD[2]^crcResult[13] ^ crcResult[12] ^ crcResult[11] ^ crcResult[9] ^ crcResult[8] ^ crcResult[5] ^ crcResult[4] ^ crcResult[0]; Result[6] = rDD[14] ^ rDD[10] ^ rDD[9] ^ rDD[6] ^ rDD[5] ^ rDD[3] ^ rDD[2] ^ rDD[1] ^crcResult[14] ^crcResult[13] ^ crcResult[12] ^ crcResult[10] ^ crcResult[9] ^ crcResult[6] ^ crcResult[5] ^ crcResult[1]; Result[7] = rDD[13] ^ rDD[9] ^ rDD[8] ^ rDD[5] ^ rDD[4] ^ rDD[2] ^ rDD[1] ^ rDD[0] ^crcResult[15] ^ crcResult[14] ^ crcResult[13] ^ crcResult[11] ^ crcResult[10] ^ crcResult[7] ^ crcResult[6] ^ crcResult[2]; Result[8] = rDD[12] ^ rDD[8] ^ rDD[7] ^ rDD[4] ^ rDD[3] ^ rDD[1] ^ rDD[0] ^crcResult[15] ^ crcResult[14] ^ crcResult[12] ^ crcResult[11] ^ crcResult[8] ^ crcResult[7] ^ crcResult[3]; Result[9] = rDD[11] ^ rDD[7] ^ rDD[6] ^ rDD[3] ^ rDD[2] ^ rDD[0]^crcResult[15] ^ crcResult[13] ^ crcResult[12] ^ crcResult[9] ^ crcResult[8] ^ crcResult[4]; Result[10] = rDD[10] ^ rDD[6] ^ rDD[5] ^ rDD[2] ^ rDD[1] ^crcResult[14] ^crcResult[13] ^ crcResult[10] ^ crcResult[9] ^ crcResult[5]; Result[11] = rDD[9] ^ rDD[5] ^ rDD[4] ^ rDD[1] ^ rDD[0] ^crcResult[15] ^ crcResult[14] ^ crcResult[11] ^ crcResult[10] ^ crcResult[6]; Result[12] = rDD[15] ^ rDD[11] ^ rDD[8] ^ rDD[7] ^ rDD[0] ^crcResult[15] ^ crcResult[8] ^ crcResult[7] ^ crcResult[4] ^ crcResult[0]; Result[13] = rDD[14] ^ rDD[10] ^ rDD[7] ^ rDD[6] ^crcResult[9] ^ crcResult[8] ^ crcResult[5] ^ crcResult[1]; Result[14] = rDD[13] ^ rDD[9] ^ rDD[6] ^ rDD[5] ^crcResult[10] ^ crcResult[9] ^ crcResult[6] ^ crcResult[2]; Result[15] = rDD[12] ^ rDD[8] ^ rDD[5] ^ rDD[4] ^crcResult[11] ^ crcResult[10] ^ crcResult[7] ^ crcResult[3]; nextCRC = Result;
// end
end