CRC Generator (crc_generator_c)
Appends a trailing cyclic redundancy check (CRC) to sample data between two flush or discontinuity messages.
Design
On reception of a flush or discontinuity opcode message, a CRC will be generated for any sample data received since the last flush or discontinuity messages.
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.
An example of a common CRC type is CRC-8-WCDMA. This is used for error detection in mobile networks. It has a polynomial shown by (21), which can also be defined as 0x9B.
Using the CRC-8-WCDMA example the following output is produced from the provided input. Note the input is an entire message that is four bytes in length. Also the left most byte is input into the CRC generator component first.
Input: 0x01, 0x02, 0x03, 0x04
Output: 0x01, 0x02, 0x03, 0x04, 0xD6
Compared to the input the output message size has increased by one byte to five bytes due to the addition of a trailing CRC. The appended CRC is 0xD6.
The polynomial_taps property sets the divisor of the polynomial long division algorithm. It is set at build time. The size of the polynomial multiplied by the data width, eight, gives the total number of shift registers used in the HDL implementation.
The seed property defines the initial value of the CRC at the start of a message. It is settable during run time.
Depending on the application the input data or CRC result may need to be reflected for a different endianness. Properties input_reflect and output_reflect provide the option to enable or disable this. They are set at build time.
Some CRC’s require a final XOR on the CRC result. The final XOR value is set by the property final_xor. It is settable during run time.
Interface
<?xml version="1.0"?>
<componentspec>
<property name="polynomial_taps" type="uchar" arraylength="64" writable="false" parameter="true" default="16,15,2"
description="Polynomial taps of the CRC used."/>
<property name="input_reflect" type="bool" writable="false" parameter="true" default="false"
description="True reverses the bit order of the input data, False keeps the order the same."/>
<property name="output_reflect" type="bool" writable="false" parameter="true" default="false"
description="False is CRC most significant bit first and true is CRC least significant bit first."/>
<property name="seed" type="ulonglong" writable="true" default="0" description="Initial seed in CRC generator."/>
<property name="final_xor" type="ulonglong" writable="true" default="0" description="Value to XOR the CRC result with."/>
<port name="input" producer="false" protocol="char_timed_sample-prot"/>
<port name="output" producer="true" protocol="char_timed_sample-prot"/>
</componentspec>
Ports
Inputs:
input: Primary input samples port.Protocol:
char_timed_sample-protOptional:
False
Outputs:
output: Primary output samples port.Protocol:
char_timed_sample-protOptional:
False
Opcode Handling
Discontinuity and flush opcode messages mark the end of a message and cause the component to append a CRC to any sample data received since the previous discontinuity or flush message. The component applies backpressure whilst outputting the CRC. When the component has finished generating the CRC it is reset, the discontinuity or flush opcode is forwarded to the output, and backpressure is removed.
All other message opcode types are passed through this component without any effect.
Properties
polynomial_taps: Polynomial taps of the CRC used. An array of up to 64 unsigned characters, meaning a maximum of 64 taps can be specified. If the polynomial is \(x^8+x^2+x+1\) thenpolynomial_tapsshould be set to “8,2,1”. There is no need to specify the \(x^0\) term, this is implied.Type:
ucharArray dimensions:
['64']
Access:
Parameter:
TrueWritable:
FalseInitial:
FalseVolatile:
False
Default value:
16,15,2
input_reflect: True reverses the bit order of the input data, False keeps the order the same.Type:
boolAccess:
Parameter:
TrueWritable:
FalseInitial:
FalseVolatile:
False
Default value:
false
output_reflect: False is CRC most significant bit first and true is CRC least significant bit first.Type:
boolAccess:
Parameter:
TrueWritable:
FalseInitial:
FalseVolatile:
False
Default value:
false
seed: Initial seed in CRC generator.Type:
ulonglongAccess:
Parameter:
FalseWritable:
TrueInitial:
FalseVolatile:
False
Default value:
0
final_xor: Value to XOR the CRC result with.Type:
ulonglongAccess:
Parameter:
FalseWritable:
TrueInitial:
FalseVolatile:
False
Default value:
0
A table listing the default polynomials the component is built for is shown below.
Polynomial |
|
|
|---|---|---|
\(x^8 + x^2 + x + 1\) |
|
true andfalse |
\(x^8 + x^4 + x^3 + x^2 + 1\) |
|
true andfalse |
\(x^8 + x^5 + x^3 + x^2 + x + 1\) |
|
|
\(x^8 + x^5 + x^4 + 1\) |
|
|
\(x^8 + x^5 + x^4 + x^3 + 1\) |
|
|
\(x^8 + x^7 + x^4 + x^3 + x + 1\) |
|
|
\(x^8 + x^7 + x^6 + x^4 + x^2 + 1\) |
|
|
\(x^{16} + x^{10} + x^8 + x^7 + x^3 + 1\) |
|
|
\(x^{16} + x^{12} + x^5 + 1\) |
|
true andfalse |
\(x^{16} + x^{13} + x^{12} + x^{11} + x^{10} + x^8 +\)
\(x^6 + x^5 + x^2 + 1\)
|
16,13,12,11,10,8,6,5,2 |
true andfalse |
\(x^{16} + x^{15} + x^2 + 1\) |
|
true andfalse |
\(x^{16} + x^{15} + x^{11} + x^9 + x^8 + x^7 +\)
\(x^5 + x^4 + x^2 + x + 1\)
|
16,15,11,9,8,7,5,4,2,1 |
|
\(x^{16} + x^{15} + x^{13} + x^7 + x^4 + x^2 +\)
\(x + 1\)
|
16,15,13,7,4,2,1 |
|
\(x^{16} + x^{15} + x^{14} + x^{11} + x^6 + x^5 +\)
\(x^2 + x + 1\)
|
16,15,14,11,6,5,2,1 |
|
\(x^{32} + x ^7 + x^5 + x^3 + x^2 + x + 1\) |
|
|
\(x^{32} + x^{26} + x^{23} + x^{22} + x^{16} + x^{12} +\)
\(x^{11} + x^{10} + x^8 + x^7 + x^5 + x^4 +\)
\(x^2 + x + 1\)
|
32,26,23,22,16,12,11,10,8,7,5,4,2,1 |
true andfalse |
\(x^{32} + x^{28} + x^{27} + x^{26} + x^{25} + x^{23} +\)
\(x^{22} + x^{20} + x^{19} + x^{18} + x^{14} + x^{13} +\)
\(x^{11} + x^{10} + x^9 + x^8 + x^6 + 1\)
|
32,28,27,26,25,23,22,20,19,18,14,13,11,10,9,8,6 |
|
\(x^{32} + x^{31} + x^{24} + x^{22} + x^{16} + x^{14} +\)
\(+ x^8 + x^7 + x^5 + x^3 + x + 1\)
|
32,31,24,22,16,14,8,7,5,3,1 |
|
\(x^{32} + x^{31} + x^{29} + x^{27} + x^{21} + x^{20} +\)
\(x^{17} + x^{16} + x^{15} + x^{12} + x^{11} + x^5 +\)
\(x^3 + x + 1\)
|
32,31,29,27,21,20,17,16,15,12,11,5,3,1 |
|
\(x^{64} + x^4 + x^3 + x + 1\) |
|
|
\(x^{64} + x^{62} + x^{57} + x^{55} + x^{54} + x^{53} +\)
\(x^{52} + x^{47} + x^{46} + x^{45} + x^{40} + x^{39} +\)
\(x^{38} + x^{37} + x^{35} + x^{33} + x^{32} + x^{31} +\)
\(x^{29} + x^{27} + x^{24} + x^{23} + x^{22} + x^{21} +\)
\(x^{19} + x^{17} + x^{13} + x^{12} + x^{10} + x^9 +\)
\(x^7 + x^4 + x + 1\)
|
64,62,57,55,54,53,52,47,46,45,40,39,38,37,35,33,32,31,29,27,24,23,22,21,19,17,13,12,10,9,7,4,1 |
true andfalse |
Implementations
Example Application
<?xml version="1.0"?>
<application done="file_write">
<instance component="ocpi.core.file_read" connect="crc_generator_c">
<property name="filename" value="input.bin"/>
</instance>
<instance component="ocpi.comp.sdr.communication.crc_generator_c" connect="file_write">
<property name="polynomial_taps" value="16,15,2"/>
<property name="seed" value="0"/>
<property name="input_reflect" value="false"/>
<property name="output_reflect" value="false"/>
<property name="final_xor" value="0"/>
</instance>
<instance component="ocpi.core.file_write">
<property name="filename" value="output.bin"/>
</instance>
</application>
Dependencies
The dependencies to other elements in OpenCPI are:
There is also a dependency on:
ieee.std_logic_1164
ieee.numeric_std
ieee.math_real
Limitations
Limitations of crc_generator_c are:
Only CRC sizes of 8, 16, 24, 32, 40, 48, 56, and 64 are supported.
The component uses the
crc_parallelprimitive which 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.
Testing
Tested platforms: None
Component testing not completed.