去年在做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