Parallel CRC Generator (crc_parallel)
Cyclic redundancy check (CRC) generator.
Design
A CRC is an error-detecting algorithm commonly used to detect errors during the exchange of data.
The CRC value is the remainder of a polynomial division algorithm on the input data stream. The CRC calculation (modulo 2 divisions) can be easily performed by logical combinations of shift registers and XOR gates.
The linear feedback shift register (LFSR) is the most common approach for a serial CRC generator implementation (crc_serial). This parallel CRC generator design comprises N serial CRC operations, where N is equal to the input data width. An XOR logic tree generated at build time using the primitive’s generics calculates the next CRC from the current CRC output and the input data.
Implementation
The data input width is set at build time using the generic input_size_g.
The polynomial sets the divisor of the polynomial long division algorithm. The size of the polynomial multiplied by the data width gives the total number of shift registers used in the HDL implementation. The polynomial is defined at build time using the generic polynomial_g.
The initial CRC output can be set during run time using the seed input. When the reset signal, rst, is set high the CRC output becomes the value of seed on the next rising clock edge.
Depending on the application either the data input or CRC result may need to be reflected. Generics input_reflect_g and output_reflect_g provide the option to enable or disable this at build time.
Some applications require a final XOR on the CRC result. The final XOR value can be set during run time using the final_xor input.
This implementation can generate a new output every clock cycle. There is a one clock cycle latency before the CRC result is available after a valid input. A clock enable input, clk_en, is provided to control when an input is valid and therefore shifted into the LFSR. The CRC generator state will not advance when the clock enable is low.
Interface
Generics
input_size_g(integer): Input bit width of data.
polynomial_g(std_logic_vector): Polynomial value.
input_reflect_g(std_logic): Enable / disable input data reflection.
output_reflect_g(std_logic): Enable / disable output CRC reflection.
Ports
clk(std_logic), in: Clock. Inputs and outputs registered on rising edge.
rst(std_logic), in: Reset. Active high, synchronous with rising edge of clock.
clk_en(std_logic), in: Enable. Enables / disables data input when high.
data_in(std_logic_vector,input_size_gbits), in: Data input.
seed(std_logic_vector,polynomial_g'lengthbits), in: Seed. Initial CRC value.
final_xor(std_logic_vector,polynomial_g'lengthbits), in: Final XOR. Value to XOR CRC result with.
crc_out(std_logic_vector,polynomial_g'lengthbits), out: CRC. Available after one clock cycle delay.
Dependencies
The dependencies to other elements in OpenCPI are:
None.
There is also a dependency on:
ieee.std_logic_1164
Limitations
Limitations of crc_parallel are:
Although throughput is greater than
crc_serial’s this design utilises more resources.This primitive calculates the CRC in a single clock cycle. For larger CRC lengths this can require a lengthy logic path to evaluate within a single clock cycle, this may limit the maximum clock speed that a design can run at.