Trends in Custom Peripheral Cores for Digital Sensor Interfaces

Building ever-smarter technology, we perpetually require more sensors to collect increasing amounts of data for our decision-making machines. Power and bandwidth constraints require signals from individual sensors to be aggregated, fused and condensed locally by sensor hubs before being passed to a local application processor or transmitted to the cloud.

FPGAs are often used for sensor hubs because they handle multiple parallel data paths in real time extremely well and can be very low power. ADC parallel interfaces and simple serial shift register interfaces are straightforward to implement in FPGA logic. However, interfacing FPGAs with more complex serial devices—which are becoming more common as analog and digital circuitry are integrated—or serializing collected data is often less straightforward. Typically, serial interfaces are implemented in FPGA fabric as a state machine where a set of registers represents the state of the serial interface, and each clock cycle, logic executes depending on the inputs and state registers. For anything but the most trivial serial interface, the HDL code for these state machines quickly balloons into a forest of parallel if-elseif-else trees that are difficult to understand or maintain and take large amounts of FPGA fabric to implement. Iterating the behavior of these state machines requires recompiling the HDL and reprogramming the FPGA for each change which is frustratingly time consuming.

Custom soft cores offer an alternate solution. Soft cores, sometimes known as IP cores, are not new in FPGA development, and most FPGA design tools include a library of cores that can be imported for free or purchased. Often these soft cores take the form of microcontrollers such as the Cortex M1, Microblaze, lowRISC, etc., which execute a program from memory and enable applications to be implemented as a combination of HDL (Verilog, VHDL, etc.) and procedural microcode (assembly, C, C++, etc.).

While off-the-shelf soft core microprocessors are overkill and too resource intensive for implementing single serial interfaces, we can easily create our own custom soft cores when we need them that use fewer resources and are easier to program than a state machine. For the purpose of this article, a custom soft core is a microcontroller with an instruction set, registers, and peripheral interfaces created specifically to efficiently accomplish a given task. The soft core executes a program from memory on the FPGA, which makes program iteration rapid because the memory can be reprogrammed without resynthesizing or reconfiguring the whole FPGA fabric. We program the soft core procedurally in assembly, which mentally maps to serial interface protocols more easily than HDL. Sensor data is made available to the FPGA fabric through register interfaces, which we also define according to the needs of our application.

Having implemented custom soft cores many times in FPGA applications, I am presently developing an open-source example/template soft core that is posted on GitHub ( For this example, I am interfacing with a Linear Technology LTC2991 sensor that has internal configuration, status, and data registers, which must be set and read over I2C (which is notoriously difficult to implement in HDL). The soft core has 16-bit instructions defined specifically for this application and executes from block ram. The serial program is written in assembly and compiled by a Python script. I hope that this example will demonstrate how straightforward and beneficial creating custom soft cores can be.

While I have been discussing soft cores for FPGAs in this article, an interesting related trend in microprocessors is the inclusion of minion cores, sometimes also called programmable real-time units (PRUs) or programmable peripherals. While not fully customizable as in FPGA fabric, these cores are very similar to the soft cores discussed, as they have limited instruction sets optimized for serial interfaces and are intended to have simple programs that execute independently of the application to interface with sensors and other peripherals. By freeing the main processor core of direct interface requirements, they can improve performance and often simplify development. In the future, I would expect more and more MCUs to include minion cores among their peripherals.

As the amount of data to be processed and efficiently requirements increase, we should expect to see heterogeneous processing in FPGAs and microcontrollers increasing and be ready to shift our mental programming models to take advantage of the many different paradigms available.

Daniel Casner is a robotics engineer at Anki, co-founder of Robot Garden, hardware start-up adviser, and embedded systems consultant. He is passionate about building clever consumer devices, adding intelligence to objects, and smart buildings or any other cyber-physical system. His specialties include: design for manufacture and salable production; cyber-physical security; reverse engineering; electronics and firmware; signal processing; and prototype development.

This essay appears in Circuit Cellar 301.

Bit Banging

Shlomo Engelberg, an associate professor in the electronics department of the Jerusalem College of Technology, is well-versed in signal processing. As an instructor and the author of several books, including Digital Signal Processing: An Experimental Approach (Springer, 2008), he is a skilled guide to how to use the UART “protocol” to implement systems that transmit and receive data without a built-in peripheral.

Implementing serial communications using software rather than hardware is called bit-banging, the topic of his article in Circuit Cellar’s June issue.

“There is no better way to understand a protocol than to implement it yourself from scratch,” Engelberg says. “If you write code similar to what I describe in this article, you’ll have a good understanding of how signals are transmitted and received by a UART. Additionally, sometimes relatively powerful microprocessors do not have a built-in UART, and knowing how to implement one in software can save you from needing to add an external UART to your system. It can also reduce your parts count.”

In the excerpt below, he explains some UART fundamentals:

UART stands for universal asynchronous receiver/transmitter. The last three words in the acronym are easy enough to understand. “Asynchronous” means that the transmitter and the receiver run on their own clocks. There is no need to run a wire between the transmitter and the receiver to enable them to “share” a clock (as required by certain other protocols). The receiver/transmitter part of the acronym means just what it says: the protocol tells you what signals you need to send from the transmitter and what signals you should expect to acquire at the receiver.

The first term of the acronym, “universal,” is a bit more puzzling. According to Wikipedia, the term “universal” refers to the fact that the data format and the speed of transmission are variable. My feeling has always been that the term “universal” is basically hype; someone probably figured a “universal asynchronous receiver/transmitter” would sell better than a simple “asynchronous receiver/transmitter.”

Figure 1: The waveform output by a microprocessor’s UART is shown. While “at rest,” the UART’s output is in the high state. The transmission begins with a start bit in which the UART’s output is low. The start bit is followed by eight data bits. Finally, there is a stop bit in which the UART’s output is high.


Before you can use a UART to transfer information from device to device, the transmitter and receiver have to agree on a few things. First, they must agree on a transmission speed. They must agree that each transmitted bit will have a certain (fixed) duration, denoted TBIT. A 1/9,600-s duration is a typical choice, related to a commonly used crystal’s clock speed, but there are many other possibilities. Additionally, the transmitter and receiver have to agree about the number of data bits to be transmitted each time, the number of stop bits to be used, and the flow control (if any).

When I speak of the transmitter and receiver “agreeing” about these points, I mean that the people programming the transmitting and receiving systems must agree to use a certain data rate, for example. There is no “chicken and egg” problem here. You do not need to have an operational UART before you can use your UART; you only need a bit of teamwork.

Using a UART is considered the simplest way of transmitting information. Figure 1 shows the form the transmissions must always make. The line along which the signal is transmitted is initially “high.” The transmissions begin with a single start bit during which the line is pulled low (as all UART transmissions must). They have eight data bits (neither more nor less) and a single stop bit (and not one and a half or two stop bits) during which the line is once again held high. (Flow control is not used throughout this article.)

Why must this protocol include start and stop bits? The transmitter and the receiver do not share a common clock, so how does the receiver know when a transmission has begun? It knows by realizing that the wire connecting them is held high while a transmission is not taking place, “watching” the wire connecting them, and waiting for the voltage level to transition from high to low, which it does by watching and waiting for a start bit. When the wire leaves its “rest state” and goes low, the receiver knows that a transmission has begun. The stop bit guarantees that the line returns to its “high” level at the end of each transmission.

Transmissions have a start and a stop bit, so the UART knows how to read the two words even if one transmits that data word 11111111 and follows it with 11111111. Because of the start and stop bits, when the UART is “looking at” a line on which a transmission is beginning, it sees an initial low level (the start bit), the high level repeated eight times, a ninth high level (the stop bit), and then the pattern repeats. The start bit’s presence enables the UART to determine what’s happening. If the data word being transmitted were 00000000 followed by 00000000, then the stop bit would save the day.

The type of UART connection I describe in this article only requires three wires. One wire is for transmission, one is for reception, and one connects the two systems’ grounds.

The receiver and transmitter both know that each bit in the transmission takes TBIT seconds. After seeing a voltage drop on the line, the receiver waits for TBIT/2 s and re-examines the line. If it is still low, the receiver assumes it is in the middle of the start bit. It waits TBIT seconds and resamples the line. The value it sees is then used to determine data bit 0’s value. The receiver then samples every TBIT seconds until it has sampled all the data bits and the stop bit.

Engelberg’s full article, which you can find in Circuit Cellar’s June issue, goes on to explain UART connections and how he implemented a simple transmitter and receiver. For the projects outlined in his article, he used the evaluation kit for Analog Devices’s ADuC841.

“The transmitter and the receiver are both fairly simple to write. I enjoyed writing them,” Engelberg says in wrapping up his article. “If you like playing with microprocessors and understanding the protocols with which they work, you will probably enjoy writing a transmitter and receiver too. If you do not have time to write the code yourself but you’d like to examine it, feel free to e-mail me at I’ll be happy to e-mail the code to you.”

Project Spotlight: “3D-Printed Mouse” Circuitry & Design




Check out the mouse strapped to a hand.

The mouse in hand (Source: D. Mellis)

Mellis writes:



Rhino: mouse.3dm
STLs: mouse-shell.stl, mouse-base.stl

Circuit board
Eagle files: mouse.brd, mouse.sch
Schematic: mouse.pdf

Component Datasheets

Button: SS-P_1110.pdf
Mouse Chip: ADNS2620.pdf




Click here to access the project site.