top of page
Hexagon Background

FPGA Serial Interfaces for Standard and Custom Protocols

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

  • Serial communication between devices, often over a distance traversed by a wire or cable (not a trace).

RS-485

Recommended Standard 485

  • Similar to RS-232 but implemented using balanced transmitters and differential receivers to reject common-mode interference, thereby enabling even longer transmission distances.

I2C

Inter-Integrated Circuit

  • Short distances, often traces, between integrated circuits (ASICs, FPGAs, HMIs, advanced sensors) designed onto a PCB assembly.

  • Cabled configurations are typical as well.

SPI

Serial Peripheral Interface

  • Synchronized data transfer between multiple circuits (microcontrollers, memory devices, sensors) on a board.

  • Configurations: 1 writer (master), 1-N readers (slaves) an

CAN

Controller Area Network

  • Common in industrial, automotive and medical environments with a robust physical layer and differential signaling for better noise immunity.

  • Built-in error checking

I2S

Inter-IC Sound

  • Used for transmitting digital audio signals between integrated circuits.

  • Requires three or more wires, so hardware setup is more complex than I2C.

Custom

-

  • Incorporate specialty triggering, timing, buffering, etc.


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.



SPI port configuration in LabVIEW FPGA
SPI port configuration and data communication in LabVIEW FPGA

The VI code snippet above executes the following steps:

  1. Initialize the port by creating a shared memory item on the FPGA.

  2. Configure the port, accounting for the number of bits to be transmitted, chip select (CS), and mode

  3. 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:        

  4. 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

  5. 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.



I2C interface states in a state machine
I2C bus states implemented in a LabVIEW FPGA state machine

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.



I2C port definition in LabVIEW FPGA
FPGA port definition and I2C "Configure" state

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.



I2C Arm state in a serial communication state machine
I2C "Arm" state



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.



RS-232 module and port configuration
RS-232 port configuration (baud rate, % error, start bit, data bits, stop bit)

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.


RS-232 Write
RS-232 interface "Write" loop in top-level VI
RS-232 Read
RS-232 interface "Read" loop in top-level VI

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

RS-232 port configuration
Top-level LabVIEW FPGA VI

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:

  1. Configure the FPGA I/O items (e.g., DIO0) and set the baud rate

  2. Write the start bit (pre-defined)

  3. Send data bits via FPGA I/O item (known number of bits)

  4. Send parity bit

  5. Send stop bit

  6. Continue looping...


The "Read" loop follows these steps:

  1. Wait for the start bit

  2. Read data from the FIFO data element (known number of data bits)

  3. Read the parity bit

  4. Read the stop bit

  5. 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:


FIFO buffer configuration in LabVIEW FPGA
LabVIEW FPGA FIFO configuration tool



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.


Serializer VI function prototype
Serializer VI prototype with an integer as input and bitstream as output
Deserializer VI function prototype
Deserializer VI prototype with a bitstream as an input and an integer as output

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

Serial data transformation
Serializer and Deserializer for serial interface data transformation
  • 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.



bottom of page