

FPGA Serial Interfaces for Standard and Custom Protocols

Whether you’re designing a test system or building an embedded controls or monitoring system, one very common task in FPGA-based applications is communicating with peripheral devices over serial buses. Serial buses communicate data over a bitstream, where specific protocols define “metadata” that account for access control, start & stop bits, clocking, etc. When compared to a parallel bus, a generalized serial bus has the following advantages:
Lower complexity – Fewer wires and simpler hardware configuration lowers material costs and simplifies manufacturing builds.
Higher scalability – Flexible to different data rates and communication distances, supporting code reuse and data integrity.
Reliability over longer transmission lengths – Lower crosstalk from multi-path interference providing for better data integrity
Lower power consumption – Mitigates stress on power budgets and is more optimal for battery-powered devices where battery life is a top concern.
Different serial protocols use different serial bus scheme that vary by:
The number of writer and readers (masters and slaves) allowed in a configuration
The overhead bit scheme (start, stop, parity) required to orchestrate efficient communication
The number of wires required for digital signals carrying data
For system design and integration, sometimes a developer has a choice of which communciation bus to use, but oftentimes there will be a peripheral device that uses a specific protocol. There can be numerous different protocols used throughout a signle system dpeending on the overall design and various subsystems. Here are some common examples of serial protocols.
Common Serial Communication Standards
Protocol | Description | Common Use Cases |
RS-232 | Recommended Standard 232 |
|
RS-485 | Recommended Standard 485 |
|
I2C | Inter-Integrated Circuit |
|
SPI | Serial Peripheral Interface |
|
CAN | Controller Area Network |
|
I2S | Inter-IC Sound |
|
Custom | - |
|
There are many resources that further explore the tradeoffs between serial and parallel data communication as well as the nuances of specific serial protocols. The purpose of this post is to outline how serial protocols can be implemented in NI FPGA hardware and the LabVIEW FPGA design language.
FPGA Benefits for Serial Communication
While fundamentals concepts of FPGA application development in LabVIEW are covered in this article, it’s worth noting some of the benefits as they relate to digital communication.
Device integration: Many FPGA-based test, control, and monitoring systems require integration of tasks with peripheral devices, such as sensors, electrotechnical systems, ICs, etc. These devices provide 1-N interfaces used for device control and data communication. Oftentimes the FPGA acts as part of the central control system through which various devices are integrated into the end application, which is feasible even if different devices have different interfaces.
Timing control through clock domains: FPGAs give the developer significant flexibility in controlling timing for communication, data processing, and other tasks. If the overall system timing diagram necessitates communication with different devices at different rates, this can easily be implemented in the FPGA code.
Customization: Regardless of tasks, FPGAs enable significant customization at the hardware-level. This could apply to triggering, inline data processing, and data storage, such that performance can be optimized for a given set of FPGA resources.
Thus, it becomes critical to have an API to for the digital communications protocols present in your application. While NI provides a SPI and I2C driver which can be used in LabVIEW Real-Time and FPGA applications, your application may have different requirements.
Need application support for your FPGA project? We're here to help.
Application Example: SPI Communication
Let’s look at how a SPI interface can be configured in LabVIEW FPGA. The following code snippet implements a write/transmit action to a configured SPI port on a digital I/O line available on an NI CompactRIO, Single-board RIO, or R Series card.

The VI code snippet above executes the following steps:
Initialize the port by creating a shared memory item on the FPGA.
Configure the port, accounting for the number of bits to be transmitted, chip select (CS), and mode
Map the digital I/O channels to the SPI diagram. In this example, digital lines 5-8 on the hardware are used for the following SPI signals:
Read SPI data from the port. This is an iterative action based on the Single-Cycle Timed Loop configured to execute based on a 40MHz clock
Write SPI data to the port. As this subVI is also called in the Single-Cycle Timed Loop, it also executes at 40MHz. The case structure enables data write control based on the previous read action. It implements some basic decision-making logic which can occur in the FPGA clock domain.
Signal | Acronym | Purpose |
SCLK | Serial Clock | Specifies the clock signals defined by the leader (master) |
MISO | Master In Slave Out (Leader In Follower Out) | Serial data output from the follower (slave) |
MOSI | Master Out Slave In (Leader Out Follower In) | Serial data output from the leader (master) |
CS | Chip Select | Important when you have multiple followers interfacing with a single master. When the chip select pin on the follower is active, it will be “listening” for communication. When it is inactive, it will be “deaf” This provides flexible control over the communication topology. |
This VI is implemented in such a way that the FPGA will execute without sharing data up to a host running on a Linux Real-Time controller or a Windows machine. Other communication paradigms can be used to pipe data up to a higher level for additional processing and visibility, though closed loop control will be fastest if wholly implemented on the FPGA.
Application Example: I2C State Machine
The following code snippets show different states of an I2C interface as implemented in a state machine. State machines are common design patterns which provide the developer with flexibility for implementing functionality and using current conditions and logic to transition between states.
In LabVIEW, state machines are typically implemented with a case structure embedded in a while loop, where state logic is passed between successive iterations of the loop using shift registers. For this particular example, the following states are defined in the state machine, each representing a different action (or idleness) of the I2C bus.

In the VI block diagram below, the I/O port is defined on the FPGA, again referencing the 40MHz onboard clock as the time base to be derived from.

After the port is configured, the master can then arm and write data to the line. Given the state machine architecture in place, you could easily add some functionality for data processing on the FPGA or sharing to a host VI.

Application Example: Maximizing RS-232 and RS-485 Baud Rates
Using LabVIEW FPGA gives access to high-speed transmission rates over 102.4 kbaud as well as the ability to rapidly analyze and deterministically act on communication. The baud rate is the number of symbols transmitted per unit time, often expressed as bits per second (bps).
The image below shows the configuration tool for an RS232 interface, accounting for baud rate and assignments for parity, data, and stop bits on a per-port basis. This provides the user with wide flexibility for the various serial-based peripherals they want to communicate with.

The VI snippets below, show a simplified example of how RS-232 communication can be implemented on an FPGA target in LabVIEW.
The top-level VI also provides a UI for defining data to be written and showing data which has been read. Commonly, this data would be further synchronized up to a host.


The top-level FPGA VI calls the FPGA Read Write VI (lower level) which runs in the background.

In the lower level VI, which directly interfaces with the FPGA DIO lines configured as serial ports, there are two loops running in parallel, one handling reading from a FIFO, the other handling writing to a FIFO.
The "Write" loop follows these steps:
Configure the FPGA I/O items (e.g., DIO0) and set the baud rate
Write the start bit (pre-defined)
Send data bits via FPGA I/O item (known number of bits)
Send parity bit
Send stop bit
Continue looping...
The "Read" loop follows these steps:
Wait for the start bit
Read data from the FIFO data element (known number of data bits)
Read the parity bit
Read the stop bit
Continue looping...
In order for this lower-level VI to run effectively, the FIFO on the FPGA buffering the bit stream must be configured. LabVIEW FPGA provides an elegant configuration tool for configuring this FIFO:

Serializing and Deserializing Data
The sections above show how different types of serial interfaces can be configured on an FPGA using LabVIEW. This section outlines the usefulness of an API that can perform serializing and deserializing actions regardless of which serial interface is being used.
Serial communication protocols transfer data through bitstreams (0’s and 1’s). However, it is often not the case that the data to be transferred is already in a bitstream format, meaning the application must convert the numeric data to a bitstream.
To make the code more modular and reusable across different protocols and devices, using a serializer/deserializer API can save significant time and troubleshooting effort. The serializer is utilized on the transmit side where an integer is converted to bits, and the deserializer does the reverse – takes a bitstream and converts it into a numeric datatype for more intuitive display and datalogging.


The following code snippet shows how this FPGA can be called:

Take an input word (in this case, it’s an unsigned 16-bit integer)
Serialize the data (integer → bitstream)
Deserialize the data (bitstream → integer)
Process the generated data array
Plot on a waveform graph for testing and troubleshooting
Conclusion
FPGAs provide developers significant flexibility and resource access for high-performance control and monitoring applications, which commonly involve interfacing with peripheral systems via serial standards. The intent of this article was to provide context on different serial interfaces and how their protocols can be designed into larger LabVIEW FPGA applications.
While there are various toolchains and APIs available, we at Cyth have decades of experience designing and developing LabVIEW FPGA applications and are interested in helping you develop or upgrade your future systems.