Continuing on from my earlier Ask Adam columns (see Ask Adam VHDL: Sensitivity Lists & Simulation and Ask Adam VHDL: Coding Styles), in this article I've decided to take a look at the way in which we code for registers and latches.
As our fearless leader, Max, has touched on in his Ask Max blogs (see Ask Max: What's Inside a Simple FPGA? and Ask Max: Look Out for Lookup Tables!), the fundamental programmable fabric in an FPGA consists of programmable blocks (also known as "slices") linked by programmable interconnect.
Along with other simple logic functions like multiplexers, the programmable blocks primarily consist of lookup tables (LUTs) and registers (flip-flops). Registers are the storage elements within the FPGA that we use to form the cores of things like counters, shift registers, state machines, and DSP functions -- basically anything that requires us to store a value between clock edges.
A register's contents are updated on the active edge of the clock signal ("clk" in the diagram below), at which time whatever value is present on the register's data input ("a" in the diagram below) is loaded into the register and stored until the next clock edge. (These discussions assume that any required setup and hold times are met. If not, a metastable state may ensue. This will be the topic of a future column.) Some registers are triggered by a rising (or positive) edge on the clock, others are triggered by a falling (or negative) clock edge. The following illustration reflects a positive-edge-triggered register:
Register symbol and waveform (positive-edge triggered clock).
Excluding any blocks of on-chip memory, there is another type of storage element that may be used in a design -- the transparent latch. Transparent latches differ from registers in that registers are edge-triggered while latches are level-sensitive. When the enable signal ("en" in the diagram below) is in its active state, whatever value is presented to the latches' data input ("a" in the diagram below) is transparently passed through the latch to its output.
If the value on the data input changes while the enable is in its active state, then this new value will be passed through to the output. When the enable returns to its inactive state, the current data value is stored in the latch. If the enable signal is in its inactive state, any changes on the data input will have no effect. Some latches have active-high enables, others have active-low enables. The following illustration reflects a transparent latch with an active-high enable:
Latch symbol and waveform (active-high enable).
In some FPGA architectures, a register element in a programmable block may be explicitly configured to act as a latch. In other cases, the latch may be implemented using combinatorial logic (in the form of LUTs) with feedback. Designers may explicitly decide to create their VHDL code in such a way that one or more latches will result. More commonly, however, a designer doesn't actually mean to use a latch, but the synthesis engine infers a latch based on the way the code is captured.
Generally speaking, the use of latches within an FPGA is frowned upon. As we previously noted, the fundamental programmable fabric in an FPGA is based around a LUT and a register. These devices are designed to have local and global clock networks with low skew. FPGA architectures are not intended to have enable signals replacing clock signals.
This means that if the VHDL code implies the use of a latches, the synthesis tool will be forced to implement those latches in a non-preferred way, which will vary depending on the targeted device architecture. In addition to unwanted race conditions, the use of latches can cause downstream issues in the verification phase with regard to things like static timing analysis and formal equivalence checking. For this reason, most FPGA designers agree that latches are best avoided and registers should be used wherever local storage elements are required.
Latches are generally created when the engineer accidentally forgets to cover all assignment conditions within a combinatorial process, therefore implying storage as illustrated in the following VHDL code example:
VHDL code for an asynchronous latch.
The IF statement does not check all conditions on the "en" signal, which means that storage is implied and a latch will be inferred for the "op" output signal. In fact, when this code was synthesised, the tool issued the following warning:
WARNING:Xst:737 -- Found 1-bit latch for signal <op>. Latches may be generated from incomplete case or if statements. We do not recommend the use of latches in FPGA/CPLD designs, as they may lead to timing problems.
So, how do we correct for this error? Well, in this case we can make the process synchronous as illustrated in the following VHDL code example:
VHDL code for a synchronous latch.
This code will not result in latch generation. It is important to note, however, that only the design engineers know exactly what it is they are trying to achieve, so it is up to them to decide whether they do require storage (in which case they can use a synchronous process and an enable signal) or whether a purely combinatorial process is desired.
Have you had any experiences with unwanted latches being inferred by the synthesis engine? Alternatively, have you created any FPGA designs in which you decided latches were a necessary evil? If so, please explain.
Click here to download a ZIP file containing the code examples presented in this article.