MicroZed Chronicles: DSP48 and Pattern Recognition
Over the last 13 years, I have written so many blog posts on a wide range of topics that sometimes I wonder if I am repeating myself.
However, this is something I have wanted to discuss for a while, and a search did not reveal that I had covered it previously.
When designing with FPGAs, we are always looking for the most efficient way to implement our requirements using the resources available within the device.
Combinational logic is implemented using LUTs, shift registers can leverage SRLs, arithmetic operations can use DSP slices, and storage can be implemented using registers, or BRAM.
What is interesting about these FPGA resources is that they often contain additional capabilities that designers either overlook or are unaware of. Understanding these features can provide alternative implementation approaches and help us achieve better resource utilisation and timing performance.
One of these less commonly discussed features is the pattern detection capability available within the DSP48 and DSP58 resources.
So let's take a look at how we can use DSP resources for pattern recognition. This capability is described in UG579 for the DSP48E2, but it is always useful to explore the functionality in a little more detail and walk through a practical example.
For this discussion, we will focus on the DSP48E2, which provides a 48-bit pattern detector.
Within the DSP48E2, the pattern detector compares the output of the arithmetic logic unit (ALU) against a specified 48-bit pattern. If the ALU output matches the configured pattern, the PATTERNDETECT output is asserted.
The comparison is performed on the DSP output P, rather than being a standalone comparator connected directly to arbitrary signals. However, the flexibility of the DSP datapath enables us to perform a range of comparisons.
Alongside the pattern register, there is also a 48-bit mask which allows individual bits to be excluded from the comparison. This is particularly useful when we are interested in only part of the output value, as we will see.
The mask operates such that a '1' indicates a bit should be ignored, while a '0' indicates that the corresponding bit must match the configured pattern.
For example, suppose we want to detect when the lower eight bits of P equal 0xA5, regardless of the upper 40 bits.
We could configure the pattern and mask as follows:
PATTERN = 48'h0000000000A5
MASK = 48'hFFFFFFFFFF00
With this configuration, the pattern detector will assert whenever the lower eight bits equal 0xA5, regardless of the values in the remaining bits.
Of course, if we wanted to compare the complete 48-bit value, we would set the mask to zero, ensuring that every bit participates in the comparison.
One important consideration is that the default DSP48E2 mask is configured for overflow and underflow detection rather than a full 48-bit equality comparison, so we need to select the mask appropriate to our application.
The DSP48E2 also provides a second output called PATTERNBDETECT, which performs a comparison against the complement of the configured pattern.
This is not simply the inverse of PATTERNDETECT. Depending on the mask, the output could match neither the original pattern nor its complement.
Another useful capability is that the comparison pattern does not have to be fixed at implementation time.
The pattern can be supplied using either the PATTERN attribute or the C input, selected through SEL_PATTERN. This enables us to implement either a fixed comparison or one in which the comparison value can change during operation.
When using the C input as a dynamic pattern, we must consider the datapath configuration and any registers enabled on the C input. UG579 also specifies that the Z multiplexer should select zero when C is being used as the comparison pattern.
This provides considerable flexibility, especially when the comparison threshold or value needs to change during operation.
One of the more common applications of pattern detection is identifying overflow and underflow conditions when performing arithmetic operations.
This is particularly useful when working with accumulators, where we need to know when the accumulated result exceeds the permitted numerical range.
The DSP48E2 provides dedicated OVERFLOW and UNDERFLOW outputs that use the pattern detection logic and the previous pattern detection state to determine when the result moves outside the permitted range.
An important distinction is that the pattern detector itself does not add an additional clock cycle of latency relative to the P output. The pattern detection result is available in the same cycle as the corresponding P value.
However, the overflow and underflow functions use the previous comparison state to detect the transition outside the permitted range. This means the previous value is important to the detection process, rather than the pattern detector simply delaying the comparison by one cycle.
It would be easy to consider the pattern detector only as an overflow and underflow feature. However, it is much more versatile than that.
The ability to perform a masked 48-bit equality comparison directly within the DSP opens up several other potential applications, including terminal-count detection, counter wrap-around, selected range and bit-field checks, saturation support, rounding operations, and comparisons against run-time values.
As always, the decision about which approach to use depends on the requirements of the design and the FPGA resources available.
There are several potential benefits to implementing pattern detection within a DSP48 rather than using programmable logic, one of the most interesting is timing.
If we implement a wide counter or accumulator in the FPGA fabric, we may have to consider the arithmetic carry chain, a comparison implemented using LUTs, and the routing between these elements.
For a counter with terminal-count detection, the comparison and associated control logic may become part of the critical path, depending on the implementation.
Within the DSP48E2, the pattern detector is implemented using dedicated hardware connected directly to the ALU output. The pattern detection result is registered alongside P, so the comparison result is aligned with the value it describes.
This removes the need for a separate fabric comparator and its associated routing when the comparison can be performed within the DSP.
However, this does not mean that pattern detection has no timing cost. UG579 identifies a moderate reduction in speed on the pattern detection path when this feature is enabled.
As with any FPGA implementation, we should verify the achieved timing rather than assuming that one approach will always outperform another.
Another consideration is resource utilisation, implementing the arithmetic and comparison within a DSP can reduce the number of LUTs and registers required in the programmable logic. This is particularly attractive when the DSP is already being used to perform the arithmetic operation.
Of course, using an entire DSP48 just to implement a counter or comparator may not always be the most efficient approach. If DSP resources are heavily utilised, implementing the same function in the CLBs may be preferable.
The most efficient solution depends on the balance of resources available within the device and the timing requirements of the application.
One interesting application of the DSP48 pattern detector is the implementation of large counters with automatic reset when a terminal count is reached.
A counter is a simple accumulator which adds one to its previous value every clock cycle. If we want the counter to wrap at a specific value, we also need to detect that value and reset the counter.
The DSP48E2 provides the necessary functionality to implement both the arithmetic operation and terminal-count detection within the DSP slice.
To implement the counter, we configure the ALU to perform an addition using the registered P output fed back through the X multiplexer. By selecting zero for the other arithmetic operands and setting the carry input to '1', the ALU increments the previous P value on each enabled clock cycle.
The P output register must be enabled for this feedback arrangement.
We can then configure the pattern detector to recognise the required terminal count.
For example, if we want a counter which counts from 0 to 999, we can configure the pattern detector to recognise the value 999 and enable the automatic reset functionality.
The key pattern detection settings are:
PATTERN = 48'h0000000003E7
MASK = 48'h000000000000
SEL_PATTERN = "PATTERN"
USE_PATTERN_DETECT = "PATDET"
AUTORESET_PATDET = "RESET_MATCH"
With these settings, the pattern detector asserts when P reaches 999, the automatic reset functionality then resets the P register on the following clock edge.
The counter therefore progresses through the terminal value before returning to zero, giving us the required counting sequence.

An important consideration is that automatic reset takes effect on the following clock edge, rather than immediately when the pattern is detected.
The AUTORESET_PRIORITY attribute also allows us to determine how the automatic reset interacts with the P register clock enable. This needs to be considered if the counter can be paused or disabled.
We should also take care when simulating the initial reset sequence. UG579 describes a transient assertion of PATTERNDETECT following reset, which is worth understanding when implementing counter control.
The simulation results demonstrate the counter incrementing, detecting the terminal value, and returning to zero using the DSP's automatic reset capability.

Of course, this approach may not always be the most efficient use of a DSP48. However, it is a useful technique to have up your sleeve if you need a wide counter, particularly when DSP resources are available and fabric resources or timing are constrained.
A single DSP48E2 provides a 48-bit result, so counters requiring more than 48 bits would need a wider implementation using additional resources.
There is also scope to adapt the example for other applications by changing the configured pattern, adjusting the mask, or introducing a dynamic pattern using the C input.
The example code provided in the GitHub repository demonstrates how we can use the DSP48E2 ALU and pattern detector together to implement a simple counter.
The objective of the example is not to claim that a DSP-based counter will always be better than one implemented in the fabric, but to demonstrate another capability available within the FPGA architecture.
Once we understand how the pattern detector operates, it becomes easier to see how the same technique can be applied to other functions, including terminal-count detection, accumulator monitoring, and dynamically configurable comparisons.
The DSP48 pattern detector is another example of a feature which is easy to overlook when concentrating on the primary purpose of an FPGA resource.
While we may not use it in every design, understanding how arithmetic, pattern comparison, and automatic reset can be combined within a single hardened resource gives us another implementation option.
And ultimately, that is one of the interesting aspects of FPGA design, the more we understand about the resources available within the device, the more options we have for implementing efficient solutions.
FPGA Journal
Read about cutting edge FPGA developments, in the FPGA Horizons Journal or contribute an article.
Workshops and Webinars:
If you enjoyed the blog why not take a look at the free webinars, workshops and training courses we have created over the years. Highlights include:
Upcoming Webinars Timing, RTL Creation, FPGA Math and Mixed Signal
Professional PYNQ Learn how to use PYNQ in your developments
Introduction to Vivado learn how to use AMD Vivado
Ultra96, MiniZed & ZU1 three day course looking at HW, SW and PetaLinux
Arty Z7-20 Class looking at HW, SW and PetaLinux
Mastering MicroBlaze learn how to create MicroBlaze solutions
HLS Hero Workshop learn how to create High Level Synthesis based solutions
Perfecting Petalinux learn how to create and work with PetaLinux OS
Boards
Get an Adiuvo development board:
Adiuvo Embedded System Development board - Embedded System Development Board
Adiuvo Embedded System Tile - Low Risk way to add a FPGA to your design.
SpaceWire CODEC - SpaceWire CODEC, digital download, AXIS Interfaces
SpaceWire RMAP Initiator - SpaceWire RMAP Initiator, digital download, AXIS & AXI4 Interfaces
SpaceWire RMAP Target - SpaceWire Target, digital download, AXI4 and AXIS Interfaces
Embedded System Book
Do you want to know more about designing embedded systems from scratch? Check out our book on creating embedded systems. This book will walk you through all the stages of requirements, architecture, component selection, schematics, layout, and FPGA / software design. We designed and manufactured the board at the heart of the book! The schematics and layout are available in Altium here. Learn more about the board (see previous blogs on Bring up, DDR validation, USB, Sensors) and view the schematics here.
All words in this blog were written by a human.




