Why Is FPGA FIFO Execution Slower Than Expected Despite Timeout?

Updated Aug 5, 2025

Reported In

Hardware

  • cRIO-9055
  • PXIe-7821
  • cRIO-9053

Software

  • LabVIEW
  • LabVIEW FPGA Module

Issue Details

I have an FPGA code that performs a read operation from one FIFO and then writes to another. When both the read and write operations are executed, the average execution time is around some microseconds.

However, if I skip the write and only attempt the read an empty FIFO — with a specific ms timeout set —the execution time unexpectedly increases to the order of several ms over the timeout specified.

This isn’t the expected behavior, given the simplicity of the code. The FPGA should wait for expected timeout and then discard the operation if it cannot proceed.

Solution

The unexpected ms delay you're observing when skipping the FIFO read and only performing a write with an specific ms timeout is likely due to how certain NI Linux Real-Time (NI Linux RT) cRIO targets—particularly those based on x86_64 architecture—handle FIFO operations. These targets use interrupts instead of polling to wait for data transfers. While interrupts reduce CPU usage, they introduce additional setup overhead, which contributes to the increased execution time.

Additionally, the timeout mechanism on these devices is based on the system's "Jiffies", which have a 10 ms resolution as defined in the Linux kernel configuration. This causes timeout values to round up to the next 10 ms tick. For example:

  • A timeout of 1–10 ms results in an actual delay of ~30 ms.
  • A timeout of 11–20 ms results in ~40 ms, and so on.

This behavior explains why you're seeing a bigger ms delay even with a small ms timeout.

To achieve lower and more consistent latency, it's recommended to set the timeout to 0, which avoids the interrupt setup and instead performs a single poll of the FIFO. This approach is particularly effective for low-latency operations.

Additional notes:

  • All x86_64 NI Linux RT targets share this 10 ms Jiffie resolution, as defined in the kernel configuration.
    • The configuration file is publicly available here.
    • Advanced users can rebuild the kernel with a smaller Jiffie period (e.g., 1 ms) by enabling CONFIG_HZ_1000=y.
  • ARM-based targets may behave differently, as they often use a default Jiffie value not explicitly defined in the config file.

Keep in mind that DMA FIFOs are optimized for high throughput and low CPU overhead, not necessarily for low latency. If your application requires minimal latency for small data transfers, consider using Host Memory Buffer or other communication mechanisms designed for that purpose.

An easier and fast workaround, you can also implement logic in your code to avoid triggering these delays unnecessarily, such as checking FIFO status and time before attempting a write. Here you can see an example on the Real Time controller code: