Online CRC Calculation
Online CRC Calculation
Be careful: there are several ways to realize a CRC. They differ (at least) in the way which bit is shifted in first and also in the initialization of the flipflops.
A typical hardware implementation (LFSR - Linear Feedback Shift Register) is shown here:
Dr.-Ing. K. Gorontzi, 2005 |
The input bits are shifted into the very left XOR gate. The MSB (leftmost bit) of each byte is shifted in first.
Each flipflop represents a single CRC output bit. The leftmost flipflop is the MSB of the CRC. This implementation doesn't need to augment the serial input message with zeros.
Note that in our case the flipflops are cleared to zeros at the beginning of each CRC calculation.
A simple VERILOG implementation of the above polynom is shown here. You can directly
copy the source snippet to your code (distributed under LGPL):
// ========================================================================== // CRC Generation Unit - Linear Feedback Shift Register implementation // (c) Kay Gorontzi, GHSi.de, distributed under the terms of LGPL // ========================================================================== module CRC_Unit(BITVAL, BITSTRB, CLEAR, CRC); input BITVAL; // Next input bit input BITSTRB; // Current bit valid (Clock) input CLEAR; // Init CRC value output [7:0] CRC; // Current output CRC value reg [7:0] CRC; // We need output registers wire inv; assign inv = BITVAL ^ CRC[7]; // XOR required? always @(posedge BITSTRB or posedge CLEAR) begin if (CLEAR) begin CRC = 0; // Init before calculation end else begin CRC[7] = CRC[6]; CRC[6] = CRC[5]; CRC[5] = CRC[4]; CRC[4] = CRC[3] ^ inv; CRC[3] = CRC[2] ^ inv; CRC[2] = CRC[1] ^ inv; CRC[1] = CRC[0]; CRC[0] = inv; end end endmodule
A simple C implementation of the above polynom is shown in the following code. Again, you
can directly copy the source snippet to your code (distributed under LGPL):
// ========================================================================== // CRC Generation Unit - Linear Feedback Shift Register implementation // (c) Kay Gorontzi, GHSi.de, distributed under the terms of LGPL // ========================================================================== char *MakeCRC(char *BitString) { static char Res[9]; // CRC Result char CRC[8]; int i; char DoInvert; for (i=0; i<8; ++i) CRC[i] = 0; // Init before calculation for (i=0; i<strlen(BitString); ++i) { DoInvert = ('1'==BitString[i]) ^ CRC[7]; // XOR required? CRC[7] = CRC[6]; CRC[6] = CRC[5]; CRC[5] = CRC[4]; CRC[4] = CRC[3] ^ DoInvert; CRC[3] = CRC[2] ^ DoInvert; CRC[2] = CRC[1] ^ DoInvert; CRC[1] = CRC[0]; CRC[0] = DoInvert; } for (i=0; i<8; ++i) Res[7-i] = CRC[i] ? '1' : '0'; // Convert binary to ASCII Res[8] = 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=[100011101]\n", Data, Result); return(0); }
Of course, the software is provided here 'as is' with no expressed or implied warranties at all.
Do you consider this page somewhat useful? Please drop me a note via