I did some research looking for existing TCP/IP FPGA Cores. There are two basic types – 10 Gigabit and non-10 Gigabit. There is also a range of free and commercial solutions out there, and I’m sure the usual caveats apply. Free = no documentation or support, Commercial = super expensive. Anyway, here is what I discovered:
The most important thing is that data comes in using an AXI4-Lite or similar interface. What is an AXI4-Lite interface? Here is the official Xilinx documentation:
https://www.xilinx.com/products/intellectual-property/axi_lite_ipif.html
You can also simply think of it like this, on each clock cycle your FPGA reads the following signals:
For receiving data:
- New Data is Available
- New Data in the form of 64 bits or 8 bits
For sending data, the opposite:
- I have new data
- Here is the new data
No packet sizes, no lengths, nothing else. You have 8 bytes of new data on each cycle for 10 Gigabit connections, or 1 byte of new data on each cycle for the rest.
Here is a picture to make things easier to understand:
Of course, what if you are trying to send data and the TCP Core is not ready to send data for whatever reason? Be it busy, has no space in its send buffer or does not have a valid connection/place to send the data? Well, there is a ‘Ready’ signal that you have to read before sending data as described above.
As for reading data, you have to do the complementary operation by telling the TCP Core that you are ready to read data, and then the TCP Core sends you the data.
Anyway, here is a closed-source TCP FPGA core that is non-10 Gigabit:
https://www.fpga-cores.com/cores/fc1002_mii/
And here is a commercial 10 Gigabit TCP FPGA Core from some company called Design Gateway in Bangkok, Thailand:
https://www.dgway.com/TOE10G-IP_X_E.html
In summary:
- Each core provides 1 TCP session
- If you want multiple sessions you have to instantiate multiple copies of the core
- You set the parameters of your TCP connection by using registers
- You send and receive data through a FIFO / AXI4-Lite interface
Up Next
so this looks quite simple. I can take some data like a FIX or ITCH message, convert the date string, which in the FIX protocol is 20-something ASCII characters, convert them into a binary representation, and send out this data using a similar FIFO / AXI4-Lite interface. Where this outgoing FIFO goes is not of concern right now, however, keep in mind that it can be any of the following:
- Operating System/kernel TCP/IP
- User-mode application
- Another portion of the FPGA
- A user-mode application running on an embedded processor which is housing the FPGA.