3

I have generated an Ethernet 10GE MAC design in VHDL. Now I am trying to implement CRC. I have a 64-bit parallel CRC-32 generator in VHDL.

Specification:
- Data bus is of 64-bits
- Control bus is of 8-bits (which validates the data bytes)

Issue:
Let's say, my incoming packet length is 14-bytes, (assuming no padding).

The CRC is calculated for the first 8 bytes in one clock cycle, but when I try to calculate the CRC over the remaining 6 bytes the results are wrong due to zeros being appended.

Is there a way I can generate the CRC for any length of bytes packet length using a 64-bit parallel CRC generator?

What I've tried:
I used different parallel CRC generators (8-bit parallel CRC, 16-bit parallel CRC generator and so on). But that consumes a lot of FPGA resources. I want to conserve resources using just 64-bit parallel CRC generators.

Tushar
  • 415
  • 2
  • 16
  • See comp.lang.vhdl [Ethernet CRC-32](https://groups.google.com/forum/#!topic/comp.lang.vhdl/WHsU0PxD28E) on Google Groups. –  Jan 19 '17 at 14:18
  • Just to clarify, are you receiving the entire packet, storing it, and then calculating the CRC? Or are you trying (/want) to incrementally calculate the CRC from every 64-bit block received? – gsm Jan 20 '17 at 00:11
  • @gsm I am not storing the entire packet. I am trying to calculate the CRC32 over the incoming packet on every clock cycle. – Tushar Jan 20 '17 at 04:59

2 Answers2

1

Start with a constant 64-bit data word that brings the effective CRC register to all zeros. Then prepend the message with zero bytes, instead of appending them, putting those zeros on the end of the 64-bit word that is processed first. (You did not provide the CRC definition, so this depends on whether the CRC is reflected or not. If the CRC is reflected, then put the zero bytes in the least-significant bit positions. If the CRC is not reflected, then put them in the most-significant bit positions.) Then exclusive-or the result with a 32-bit constant.

So for the example, you would first feed a 64-bit constant to the parallel CRC generator, then feed two zero bytes and six bytes of message in the first word, and then eight message bytes in the second word. Then exclusive-or the result with the 32-bit constant.

For the standard PKZIP CRC, the 64-bit constant is 0x00000000ffffffff, the 32-bit constant is 0x2e448638, and the prepended zero bytes go in the bottom of the 64-bit word.

If you are in control of the implementation of the CRC generator, then you can probably modify it to initialize the effective CRC register to all zeros when you reset the generator, avoiding the need to feed the 64-bit constant.

Mark Adler
  • 101,978
  • 13
  • 118
  • 158
  • >> So for the example, you would first feed a 64-bit constant to the parallel CRC generator, then feed two zero bytes and six bytes of message in the first word, and then eight message bytes in the second word. Then exclusive-or the result with the 32-bit constant. << Does that mean, I have to send the data backward? Like, first the remaining 6-bytes and then 8-bytes? Another thing is, How would you get this 32 and 64-bit constant values for standard Ethernet CRC32 (polynomial 0x04C11DB7) – Tushar Jan 20 '17 at 04:56
  • No, you would not send the data backwards. The first byte of the message comes after the pre-pended zero bytes. The PKZIP CRC is the Ethernet CRC. – Mark Adler Jan 20 '17 at 05:23
0

I can't speak for certain, but if you can pad zeros at the start of your packet instead of at the end, then you should get the right answer. It does depend on the polynomial and the initializer...

See this answer here Best way to generate CRC8/16 when input is odd number of BITS (not byte)? C or Python

Community
  • 1
  • 1
Mark Lakata
  • 19,989
  • 5
  • 106
  • 123
  • It may work for CRC8/16 but it does NOT work for CRC32 for sure. I am initializing the logic with all-1s and using the standard ethernet CRC32 polynomial, 0x04C11DB7 – Tushar Jan 19 '17 at 06:56
  • The trick is initializing the crc with the correct value. The end of the answer I referenced shows the trick he used. You would probably have to calculate 8 different crc initializations, for each (packetLen MOD 8). You are just priming the crc pump to get the answer you want. – Mark Lakata Jan 19 '17 at 15:27