FPGA Horizons Journal Issue 4

(This article is from Issue 4 of the FPGA Horizons Journal. If you’d like to read more FPGA-related articles, you can download a PDF of the issue right now.)

Designing for portability with open-source FPGA libraries

Oliver Bründler, Maintainer of Open Logic

FPGA developers face many productivity challenges, but two stand out as particularly common: vendor IP libraries that lock designs to a single silicon supplier, and the endless reimplementation of standard building blocks every project needs. The first resembles a Trojan Horse: it looks like a gift until you need to migrate. The second is reinventing the wheel, implementing something that many others have done before. Open-source FPGA libraries can address both, so let’s explore how.

The FPGA ecosystem is dominated by vendor toolchains that bundle their own IP libraries. Whether named macros, primitives, megafunctions or IP-cores, they are all convenient…until you need to migrate to a different device. At that point, the true cost of a free library becomes visible: you potentially have to rewrite large parts of a design you architected around the library of a specific vendor.

The alternative – writing everything from scratch in HDL – carries its own cost. Every developer who’s implemented (and debugged) yet another synchronous FIFO or CDC synchronizer from first principles knows the feeling. It’s time invested that simply doesn’t advance your application.

Open-source libraries offer a different path. Projects like Open Logic, along with hdl-modules, Taxi, and Pile of Cores, provide battle-tested, reusable components that aren’t tied to any vendor toolchain. That independence matters beyond the obvious technical argument. The immediate case is cost flexibility: if a cheaper or more capable device emerges from a competing vendor, a portable codebase lets you move without directly re-investing the saved money into the porting effort.

Long-term product maintenance becomes cheaper for the same reason. And in today’s geopolitical climate, supply chain resilience has moved from theoretical concern to practical reality. Which devices are available, which face tariffs, and which fall under export restrictions can change faster than a product lifecycle. A design tightly coupled to one vendor’s library carries a risk that rarely appears on any project plan.

 

Making FPGA code truly portable

Even code written in pure HDL without vendor primitives or macros doesn’t automatically synthesize across different vendors. There are HDL dialect differences, with each vendor supporting a slightly different subset of VHDL and Verilog. Similarly, synthesis attributes vary, as does inference behavior. There are also corner cases, especially around reset handling, that consistently surface when porting between vendors.

To address this, every element in Open Logic is regularly synthesized with every supported toolchain. This ensures no unsupported language constructs slip in and all elements synthesize efficiently across all targets. The correct synthesis attributes for every supported device vendor are also applied consistently, so that double-stage synchronizers work safely, regardless of the target device.

Open Logic is also transferable between languages. While it’s written in VHDL, the interfaces have been designed so that every element can also be used from Verilog, and corresponding examples are provided.

In contrast, most proprietary codebases are only ever synthesized for the current target device, and any portability issues remain hidden. By using truly portable code from the start, you avoid this entirely.

 

Full portability

How Open Logic makes designs portable
Fig 1. How Open Logic makes designs portable across vendors and devices

Balancing portability with resource and timing efficiency

FPGA libraries that support vendor-independent code can’t take advantage of every device-specific option or feature to save resources or optimize timing. This is the trade off in portable design which works across toolchains and device families. Highly tuned logic often depends on vendor specific primitives or attributes, so the focus instead is on providing standard design elements that cover the majority of use-cases.

This allows engineers to concentrate on implementing the highly optimized – and potentially device-specific – logic for the smaller portion where it really matters. Maximum optimization isn’t the goal. Saving effort on the default case is.

That said, Open Logic has been designed with resources and timing in mind. Where applicable, you can select the level of pipelining or the target resource type (e.g. RAM resources), so the portable baseline doesn’t prevent you from guiding implementation where needed.

Open Logic also follows the principle of providing default values for all optional configuration parameters and ports. You only need to understand them if you use them. Here’s a FIFO example to illustrate how the default case looks in practice.

Instantiating a FIFO can be as simple as this – which is probably as simple as you could imagine a FIFO:

FIFO code example 1
The FIFO actually has significantly more configuration options, like controlling the RAM resource, defining almost-empty and almost-full signals and more. All of them are optional, so you can omit anything you don’t need and keep the default, portable behavior.

If you want to constrain your FIFO to use UltraRAMs on an AMD UltraScale+ device, you can do that too. This does to some extent break portability because the resource selection will be ignored on other devices, but it shows that you can still control resource selection where optimization matters. The instantiation below shows how to set the RAM style explicitly.

FIFO example code 2

The examples above are in VHDL, but every Open Logic element can also be instantiated from Verilog. 

 

Providing the building blocks you need

As a vendor-independent FPGA component library, Open Logic provides the following foundational and reusable building blocks for portable designs:

  • Clock Domain Crossing
  • Vendor-independent RAM implementations
  • FIFOs (synchronous, asynchronous, and packet-FIFO)
  • Width converters
  • Arbiters
  • Timing control (strobe generators, delay, latency compensation, etc.)
  • CRC handling
  • Content addressable memory (CAM)
  • AXI master and slave implementations
  • Standard interfaces like I2C, SPI, and UART
  • Fixed-point mathematics including a bit-exact modelling framework in Python

This provides the basic building blocks that can be integrated into your own custom logic, and they can be combined with other libraries when you need higher-level functionality. For example, you might use an open-source Ethernet stack, along with vendor IP for the AXI infrastructure. 

 

Conclusion

Open-source FPGA libraries like Open Logic are a practical tool for reducing development time and avoiding vendor lock-in, particularly in greenfield projects. In these cases, it significantly improves development efficiency by removing the need to implement basic building blocks, rely on vendor-supplied components, or on an internal, unmaintained library.

If you’re curious, the easiest way to get started is to follow the tutorial for your device vendor at https://github.com/open-logic/open-logic. Once you’re comfortable, start replacing the components you’d normally write from scratch with Open Logic equivalents in your real projects.

The wheel has been invented. You don’t need to build it again. And the horse? At least check what’s inside before you bring it into your FPGA design.

Rene Brglez, FPGA developer at Aviat Networks, is also a contributor to Open-Logic. If you’d like to join him, visit https://github.com/open-logic/open-logic/blob/main/Contributing.md for more details.

Case Study: Building a QoS subsystem with Open Logic

A good example of Open Logic in practice is a Quality of Service (QoS) subsystem developed for a network processing platform. The project required components that could control how bandwidth is shared, how congestion is handled, and how traffic bursts are smoothed. The goal was not to build a complete QoS system, but to provide reusable, modular components that system architects could select and combine as needed.

The main motivation was cost optimization. Instead of relying on expensive switches with built-in QoS support, the QoS subsystem was implemented in an FPGA placed after a simpler, lower-cost switch. Since the FPGA was already present in the device for other processing tasks, the approach did not significantly increase overall system cost.

 

Queue arbitration

The starting point was queue arbitration – scheduling multiple ingress AXI-Stream channels onto a single egress path. The initial implementation used a Round Robin component from Open Logic. While simple and effective, it does not support prioritization of individual streams, which is essential for QoS. It did, however, give the engineers a basis for developing a Weighted Round Robin (WRR) component which enables proportional bandwidth allocation across streams and forms the core of the arbitration stage in the QoS pipeline. A Deficit Round Robin (DRR) component was also developed for scenarios requiring more precise control over bursty traffic.

QoS Implementation

Fig 2. QoS implementation and related Open Logic components

Congestion management

The next stage in the QoS pipeline was congestion management. When multiple streams are merged into a single output, available bandwidth may be insufficient to forward all incoming traffic. At this point, packets may need to be dropped.

Rather than implementing frame-aware buffering from scratch, the design used the olo_base_fifo_packet component from Open Logic. This provides a store-and-forward packet buffer and allows the dropping, skipping and repeating of packets, and only the dropping capability was required. With a simple control FSM on top, entire frames can be dropped cleanly, preventing partial-frame corruption.

The design was extended further with Weighted Random Early Detection (WRED), which probabilistically drops lower-priority frames based on buffer occupancy before the buffer is actually full. The approach also improved behavior for Transmission Control Protocol (TCP) traffic, as early packet loss signals congestion to the sender, prompting it to reduce its transmission rate and helping to prevent buffer overflow.

 

Traffic shaping

The final stage in the QoS pipeline was traffic shaping, which smooths traffic bursts into a controlled bandwidth profile using the token-bucket algorithm. This prevents short term rate spikes from propagating downstream, reducing queue buildup and avoiding unnecessary packet loss.

The olo_base_rate_limit component from Open Logic provided the token‑bucket mechanism, enforcing a defined output rate and ensuring that downstream links and buffers receive traffic at a predictable pace. By regulating burst size and sustained throughput, it avoids overwhelming slower downstream interfaces and keeps protocol behavior stable.

 

Running on real hardware

The complete QoS system was verified on an Alinx AXKU5 development board featuring an AMD Kintex UltraScale+ FPGA, connected to a Quad SFP28 FMC card from Opsero for 10 Gigabit Ethernet connectivity. The QoS module was configured with four ingress streams, each with its own congestion management, feeding into WRR arbitration and traffic shaping. All components were configured at runtime via a register bank accessible over UART, using the UART implementation provided by Open Logic. The system worked as expected, and no issues related to Open Logic components were encountered on hardware.

Fig 1. Schematic view of an FPGA

Journal Issue 4

This article is from Issue 4 of the FPGA Horizons Journal. If you’d like to read more FPGA-related articles written by FPGA engineers for FPGA engineers, why not go ahead and download a PDF of the issue right now?

Download the pdf