I need to set up networking (just a basic echo server) on an FPGA board (ZYNQ Ultrascale+) using only the PL side. The end goal is to DSP a large amount of data coming from a receiver through ethernet. I am aware that you can use LWIP on the PS side, but for now I need to evaulate the possibility of using only PL.

I've set up the AXI 1G/2.5G Ethernet Subsystem IP in Vivado, but reading through the user guide it seems that the IP doesn't handle the all of the needed logic. I haven't been able to find anything online about using PL for the entire networking. If someone has any insight on this, I would appreciate it.

  • \$\begingroup\$ How do you define networking? Do you want to implement RS-485 (simple) or ethernet with TCP/IP (complex)? You mention ethernet, but does it have to be ethernet? I don't know much about networking either, so I can't help with either, but I know that implementing TCP/IP is a lot more complex than RS-485 with an ad-hoc communications protocol. \$\endgroup\$
    – Hearth
    Commented Sep 30, 2022 at 4:17
  • \$\begingroup\$ SPEAD transfers huge amounts of data, usually for the FPGA to perform some DSP on it before sending it along. It uses UDP only, requires no "OS". \$\endgroup\$
    – tomnexus
    Commented Sep 30, 2022 at 6:43
  • \$\begingroup\$ If your design has the same Ethernet transceiver, you could try to port this on a Microblaze (No OS, Bare metal): docs.xilinx.com/v/u/en-US/xapp1026 \$\endgroup\$
    – user282292
    Commented Sep 30, 2022 at 14:32

4 Answers 4


If you are wanting to simply get proof-of-concept functionality on the bench, there are a lot of parts of the internet stack you can skip.

For example, if you have a closed-off network (ie, not your office network, just a cable or a switch on the bench) and can use fixed IP addresses (because it's on the bench)

Then the only things you need are UDP on IP

  • Omit ARP and either hardcode the ether addresses or use broadcasts
  • Omit DHCP/BOOTP and hardcode the IP addresses
  • Omit ICMP it's very fiddly

In these circumstances, all the packets are standalone, there aren't any timers or packet-to-packet dependencies. Specifically you're not waiting on DHCP states, you're not waiting on ARP replies, you're not expiring caches.

For outgoing packets you just build the UDP datagram, the IP packet, the ether frame and send it. For incoming packets you just check all the fields and accept it.

And concretely, you can implement something like RFC 862 Echo Service instead of ping over ICMP. Do status info on broadcast RFC 768 SYSLOG

Once you have that working, worry about the other parts

The other parts are for convenience and portability across networks; if you don't need that, you don't need them. Implement them when you do.

  • First is "idiot ARP" which is ARP without cache (yes it sends ARP request for every single outgoing packet)
  • Next is BOOTP to parameterise startup
  • Can do ARP cache with packets-sent counter instead of a timer
  • Up to this point there's no cache and no timers
  • Add timers and do ARP cache timeout
  • then DHCP if you actually need it

If you don't need ethernet in the beginning, consider using RFC 1055 SLIP over RS-232/RS-485. It's really easy to do and might help get you started.

Just to repeat: these are suggestions to get you started by greatly simplifying the problem How you progress from there depends on what you find out and what your exact needs are.

  • 1
    \$\begingroup\$ At my job we do this on an fpga to capture high bandwidth telemetry. We hard code all the packet hearers and use a broadcast ip to send udp packets. One direction only udp. No retries, but works great. \$\endgroup\$
    – poleguy
    Commented Jun 23, 2023 at 14:28

Sure, it's possible to implement the basic parts of a network stack on an FPGA.

Here are the basic protocols one would need to typically support...

  • ARP (You need this to find the MAC address to use when sending IPV4 packets).
  • IPV4 (Network layer)
  • UDP (For sending basic message packets)
  • ICMP (If you want to support things like ping)
  • BOOTP (DHCP is built on top of BOOTP)
  • DHCP (if you want non static IP addresses)

I have built two network stacks from scratch supporting the above protocols for different processor architectures, and one for a Xlinx FPGA. I would say that building it for the FPGA was more challenging compared to the software version, but it was certainly doable.

I am not aware of any pre-built libraries that would implement this for the PL side (but then again, I never looked for one). If you are thinking of implementing this yourself from scratch on the PL side, I would suggest going to the IETF website and getting a copy of the relevant RFC documents for each protocol (that's how I did it).

Unlike a lot of standards that are written today (which may be hundreds or thousands of pages) the relevant RFC documents for this stuff were written in the 70s, 80s, and 90s and are relatively short. I think UDP was only like 2 pages.


Yes it is. You can use lwIP in bare metal mode and it works fine (I did it for s small project a few years ago). You just need to make sure hook up the callbacks correctly and poll for incoming packets properly. It supports DHCPaswell which is nice. It took a bit of fiddling to get it going but worked in the end. I'd say this is going to be a lot easier than writing your own stack.

(Ultimately the fact that you are running on an embedded processor is no different from using a microcontroller with an ethernet interface, except that it is down to you to make sure you have the hardware configured and the driver available. But normally the Xilinx tools are pretty good at making that stuff happen.)


Absolutely - a network data stream is a data stream like any other. I have done an experiment where I made an FPGA reply to pings from a 100Mbps port.

There's a lot more stuff to consider, though, since it's not done for you. Starting from the physical interface to the PHY chip. I gather you have an IP block that handles that, but you still need to consider the physical interface to the IP block.

Then you need to identify the start and end of packets. Your IP block probably has signals like "start of packet" and "end of packet" so this is done for you.

Then you need to process the contents of packets. If you're using IP and Ethernet, each packet that you care about will have an Ethernet header followed by an IP header. However you also have to handle ARP packets which have an Ethernet header followed by an ARP header. You can start by making the FPGA recognize ARP request packets and then sending ARP replies. Then if you try to ping the FPGA's IP address, on Wireshark you should see the computer send an ARP request, receive an ARP reply, and send a ping request. Both ARP packets are fairly simple fixed-layout formats. If you can make this work, it proves that you have the ability to send and receive packets.

Oh, you do need an IP address and a MAC address. I suggest you start by just picking some reasonable ones and hard-coding them.

If your FPGA just replies to requests it gets, and doesn't send packets by itself, then you don't need "idiot ARP" as another answer suggested - you can just copy the MAC address from the request packet. If you can hardcode the IP address you don't need BOOTP or DHCP. This makes your FPGA design simpler.

For the actual protocol, I suggest using UDP, because TCP is rather complicated and tricky to get right. You can write a block that takes this stream of packet data from the network, replies to ARPs, and recognizes UDP packets and then puts the data from the UDP packet into a FIFO, where you can process it however you like. UDP on a local network isn't really unreliable, if the network isn't overloaded, so if losing the occasional block of data isn't the end of the world, you probably don't need a system to re-send missed packets.


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.