0
\$\begingroup\$

In my FPGA project we get a 100-bit wide vector on each 100 MHz clock cycle from a 10Gbps receiver. I can then compress it to 75-bit wide vector due to some particulars of the data.

I would like to pack this 75-bit data into some power-of-2 chunk so that it can be transferred on the USB FIFO (32-bit) or DDR memory FIFO (128-bit) with the best throughput.

My attempt: Assume packing into 125 bits is "good enough". So the input is 3x25 wide, and the output is 5x25 wide. So on each cycle, 3 chunks are fed into a big shift register where new chunks come in on the right, and old chunks are being shifted left. Then the output selects 5 chunks at the appropriate offset. Sometimes it has to skip a cycle until enough chunks are present. The shift register is sized so that it can fit all the combinations of offsets that have to be selected. enter image description here

So my question is basically, is this a common problem in FPGA designs? Does it have a name and a "proper" way to do it? Is there a generic way of solving this for all input and output sizes? Is there something obvious I'm missing where I don't have to waste 3 bits?

\$\endgroup\$
2
  • \$\begingroup\$ By the way changing the receiver so that it's 64-bits (compresses down to 48) into the fabric at 156.25 MHz is another possibility, but for now I'm hoping to keep the main clock at 100 MHz due to the convenience of a 10ns time resolution in our system. \$\endgroup\$
    – Keegan Jay
    Commented Apr 9, 2021 at 20:39
  • \$\begingroup\$ You can use the 3 extra bits for framing information and possibly a sanity check; accumulate enough that there's room for a CRC. \$\endgroup\$
    – user16324
    Commented Apr 9, 2021 at 21:13

1 Answer 1

3
\$\begingroup\$

I think the term for this is a "gearbox". They are used all the time when interfacing with serializers - converting between 66 and 64 bits, 66 and 16 bits, etc. Not sure about the proper way to do it aside from whatever gets the job done, although there may be more efficient techniques that I'm not currently aware of. Personally, I wouldn't worry too much about wasting 3 bits. It's a trade-off in logic complexity. To use those 3 bits, you would probably have to implement a rather large barrel shifter, which consumes a lot of logic resources. Another concern may be what's on the other end of the link, perhaps wasting a few bits as zero padding could be an advantage so you don't have to barrel-shift again when pulling things out of the FIFO.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Thanks for the response sounds like it's the right general approach. I recognize your name as creator of one of the big open source 10G ethernet projects. What a tremendous contribution that is. \$\endgroup\$
    – Keegan Jay
    Commented Apr 10, 2021 at 5:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.