Revealing Untapped DSP Optimization Potentials for FPGA-Based Systolic Matrix Engines
Jindong Li Tenglong Li Guobin Shen Dongcheng Zhao Qian Zhang Yi Zeng


BSTcontrol





Revealing Untapped DSP Optimization Potentials for FPGA-Based Systolic Matrix Engines
    Jindong Li^1, 2, 4   Tenglong Li^1, 2, 4   Guobin Shen^1, 2, 3   Dongcheng Zhao^1,2    Qian Zhang^1, 2, 4   Yi Zeng^1, 2, 3, 4, 5

^1Brain-inspired Cognitive Intelligence Lab, Institute of Automation, Chinese Academy of Sciences
 
^2 Center for Long-term Artificial Intelligence 

^3 School of Future Technology, ^4 School of Artificial Intelligence, University of Chinese Academy of Sciences  
 
^5 Key Laboratory of Brain Cognition and Brain-inspired Intelligence Technology, Chinese Academy of Sciences
 
{lijindong2022, litenglong2023, shenguobin2021,zhaodongcheng2016, q.zhang, yi.zeng}@ia.ac.cn
Corresponding author: q.zhang@ia.ac.cn and yi.zeng@ia.ac.cn.

    
==========================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================



§ ABSTRACT 
Systolic architectures are widely embraced by neural network accelerators for their superior performance in highly parallelized computation. The DSP48E2s serve as dedicated arithmetic blocks in Xilinx Ultrascale series FPGAs and constitute a fundamental component in FPGA-based systolic matrix engines. Harnessing the full potential of DSP48E2s in architectural design can result in significant performance enhancements for systolic architectures on Ultrascale series FPGAs.
This paper unveils several previously untapped DSP optimization techniques capable of further enhancing FPGA-based systolic matrix engines.
We apply these techniques to two well-known systolic architectures: Google TPUv1 and Xilinx Vitis AI DPU.
With the proposed techniques, our design achieves substantial resource and power reduction compared to the open-source TPUv1 FPGA implementation and the Vitis AI DPU implementation in the same parallelism setting.
We also demonstrate the applicability of our techniques to neuromorphic hardware for supporting spiking neural network acceleration.



FPGA, DSP48E2, Accelerator, Systolic Array




§ INTRODUCTION

Recent years have witnessed the development of domain-specific hardware architectures tailored for deep learning.  Systolic architectures have demonstrated their effectiveness and efficiency in handling matrix multiplication during neural network inference.

In FPGA-oriented design, building a high-performance systolic matrix engine is a non-trivial endeavor. While a naive or high-level synthesis (HLS) implementation may function, it falls short of unlocking the maximum performance potential. Achieving the pinnacle of performance for a systolic matrix engine on an FPGA demands an in-depth understanding of the FPGA's resource characteristics. In the case of the UltraScale series FPGA, harnessing the full potential of the basic systolic array's building block, DSP48E2<cit.>, becomes as a paramount consideration.
A significant amount of research has concentrated on DSP-centric optimization to unlock the performance improvement potential<cit.><cit.><cit.><cit.><cit.>. Several techniques have already become common practices in contemporary neural network accelerator designs.

Keeping pace with the evolution of neural network algorithms, new domain-specific hardware architectures have been proposed rapidly. Yet, the systolic architecture continues to play a crucial role as the foundational computing backend.
We recognize the necessity to revisit the DSP48E2 functionalities to determine if further optimization of FPGA-based systolic engines is possible. Our findings in this paper confirm that there are indeed several untapped DSP optimization potentials for FPGA-based systolic engines that can be beneficial to the FPGA-based accelerator research society.

In this paper, we focus on two classic systolic-based neural network accelerators: the Google TPUv1<cit.> and Xilinx Vitis AI DPU<cit.>. We present pratical DSP48E2 techniques that can enhance the performance of the systolic matrix engine in these two accelerators. Our contributions are listed as follows:

1) We propose an in-DSP operand prefetching techniques applicable to the weight stationary (WS) systolic engine. With such technique, our implementation shows substantial resources reduction and frequency improvement compared to currently widely adopted open-source TPUv1-like design.

2) We delve deeply into the systolic array implementation of the commercially encrypted Vitis AI DPU, identifying existing drawbacks in its design. Subsequently, we propose an in-DSP multiplexing technique and design a ring accumulator that can further reduce resource consumption and power consumption compared to the original official design.

3) We also demonstrate the application of our methods to neuromorphic hardware by offering enhanced implementations of the systolic-based spiking neural network (SNN) accelerators, FireFly<cit.>.



§ RELATED WORKS


DSP-based techniques play an important role in FPGA-based accelerators since DSP blocks serve as the fundamental computing hard blocks, yet being limited and scarce. Our focus in this paper is specifically on the UltraScale series FPGAs, which are widely favored in deep learning applications.

A common practice in neural network accelerator designs involves utilizing the wide input arithmetic unit within the DSP48E2 in UltraScale series FPGAs to enable SIMD low bit-width operations in quantized neural networks<cit.><cit.>.

Xilinx introduced a method that pack two 8-bit integer multiplications sharing a same operand into a single DSP48E2<cit.>. They further proposed another approach that pack the cross products between two pair of 4-bit operands into a single DSP48E2<cit.>. Zhang et al. proposed UInt-DSP6 packing and packed two more 4-bit multiplications into the DSP48E2 with appropriate overlaping in convolution application<cit.>. Sommer et al. generalized the multiplication packing technique and introduced an overpacking strategy<cit.>. FireFly<cit.> utilizes the SIMD mode of DSP48E2 to perform multiple synaptic operations for neuromorphic acceleration.


Another common practice in neural network accelerator designs involves leveraging the cascading paths in DSP48E2 for constructing systolic arrays. The DSP48E2 comprises three cascade paths: two to the input A and B ports and one to the output P port.
Xilinx's white paper suggests utilizing the partial sum cascaded chain at the output P port of the DSP48E2 for performing 8-bit integer dot product operations<cit.>.
Additionally, the Xilinx DSP48E2 datasheet recommends the adder-chain implementation over the adder-tree approach for FIR filter applications requiring high speed<cit.>.
Samajdar et al. optimally utilize the cascade chain at the input A and B ports in the DSP48E2 to support fixed-mode convolution<cit.>.

The DSP48E2's superior Fmax performance is also commonly utilized in neural network accelerator designs. The peak clock rate of DSP48E2 can exceed 700MHz for a device of the fastest speed grade<cit.>. To fully utilize its superior Fmax performance, the Xilinx DSP48E2 datasheet recommends employing the DSP48E2 in a time-multiplexed manner<cit.>. Following this guideline, Vitis AI DPUCZDX8G adopts a DSP double data rate (DDR) technique to enhance its systolic engine performance. FireFly v2<cit.> adopts the DDR technique on a neuromorphic SNN accelerator. Additionally, Wu et al. proposed a DSP supertile concept by utilizing the near DSP distributed RAM for fast operand fetching<cit.>.

While the potential for DSP48E2 optimization opportunities appears to have reached its end, this paper unveils several untapped tricks that can still greatly enhance performance.



§ DSP48E2 OVERVIEW




DSP48E2 serve as fundamental computing components in FPGAs, providing extensive parallelism opportunities for handling intensive computing workloads in neural network acceleration in Xilinx Ultrascale series FPGAs.

The DSP48E2 primarily comprises a 27-bit pre-adder, a 27× 18-bit multiplier, and an SIMD 48-bit accumulator, shown in Fig.<ref>. However, some circuits in the DSP48E2 do not directly contribute to arithmetic computations; instead, they play a crucial role as essential components for reconfigurable functionalities.
The flexible input pipelines inside the DSP48E2 feature two distinct pipeline registers with individual clock enables, along with a dynamic selector present on both the A and B input ports, enabling various input configurations.
The four wide-bus multiplexers route data from different ports to the four-input 48-bit ALU, enabling various dynamic user-controlled operating modes.
The dedicated cascade paths enable direct connections between adjacent DSP48E2s in the same column, enabling high-speed systolic-based applications.

In this paper, we uncover several DSP48E2 techniques by exploring these often-overlooked components in DSP48E2.



§ ENHANCING SYSTOLIC ENGINE OF TPUV1 ON FPGA


Google TPUv1<cit.> is a Tensor Processing Unit (TPU) designed for neural network machine learning. It incorporates a 256× 256 8-bit WS Multiply-Accumulate (MAC) matrix unit, delivering a peak throughput of 92 TOP/s.
In the classic WS systolic array design like TPUv1, weight data are fetched and cached near the PEs in advance, keeping stationary until the arrival of new sets of weight data. Input data flows horizontally into the systolic array staging into the next PE, while the partial sums flow vertically out of the array, accumulating along the way.
This architecture proves to be efficient for matrix multiplication, which is the computing backend for the widely used nn.Linear layer and nn.Conv2d layer.

tinyTPU<cit.> is the most widely adopted open-source FPGA-based TPUv1 design<cit.><cit.><cit.>. It large follows TPUv1 design but using a smaller systolic matrix size of five configurable choices ranges from 6× 6 to 14× 14 that can fit into edge FPGAs. 
Libano's systolic array generator represents a state-of-the-art FPGA-based TPUv1-like systolic array implementation, serving as the DUT for its matrix multiplication error detection research<cit.>.
Libano's implementation incorporates INT8 packing tricks and the DSP DDR technique, techniques that are absent in tinyTPU, thus resulting in a superior design with enhanced performance. Fig.<ref>A shows a TPUv1 like 4× 4 systolic matrix engine.



 §.§ Drawbacks in Existing Implementations




Despite the popularity of tinyTPU and the DSP-centric considerations in Libano's design, both implementations still fall short of achieving optimal performance.
tinyTPU does not employ the common INT8 packing techniques, resulting in half the computing density. Furthermore, activations at each row of the systolic array are broadcast to all columns of DSP48E2, instead of using pipelining registers. This approach leads to high fan-out and negatively impacts the frequency performance.
Libano's implementation fails to absorb the partial sums accumulating path into the DSP48E2, leading to excessive consumption of CLB resources.

In our implementation shown in Fig.<ref>B, we integrate a comprehensive set of techniques, including INT8 packing and in-DSP partial sums cascading. Furthermore, we have identified a critical yet often neglected aspect, the weight loading datapath, that could potentially become the performance bottleneck for the WS systolic array. Recognizing this, we introduce an innovative in-DSP operand prefetching technique designed to optimize the weight loading datapath. 



 §.§ Enhancement: In-DSP Operand Prefetching


In the WS systolic array, weights need to be preloaded into the array. To hide the preloading latency, each PE of the WS systolic array must instantiate two sets of registers. This setup enables the ping-pong update for loading the next set of weights.
In ASIC design, there's little room for optimizing register consumption. However, in FPGA design, it is possible to utilize existing resources for the ping-pong weight loading path rather than instantiate extra CLB flip-flops.

The DSP48E2 has two flexible input pipelines for input ports A and B, each comprising two registers with individual clock enables. These input pipelines can accept individual input from the general routing resources or share the same cascading path.
In this section, we demonstrate how to perform in-DSP operand prefetching by absorbing the weight ping-pong registers into the DSP48E2 pipelines, shown in Fig.<ref>.

In an FPGA-based WS systolic array, the accumulating datapath can be absorbed into the vertical DSP48E2 output cascading path.

The unused input cascaded path can be utilized for weight prefetching. Assuming the input pipeline for B is used for weight prefetching, Fig.<ref> illustrates the static configuration of the pipeline.
In this setup, B_1 registers serve as the operand prefetching path, while B_2 registers remain static across multiple computation rounds. New operands stream into the B_1 register chain until they reach the topmost DSP48E2. When operands cached in the B_2 registers expire, the clock enable signals trigger B_2 to accept new operands from the B_1 chain. The waveform of the clock enable signals for B_1 and B_2 registers is presented Fig.<ref>.
The entire operand prefetching process, along with the partial sums accumulating path, occurs entirely within the DSP, flowing vertically down the DSP48E2 column. This results in significant savings in CLB flip-flops.





 §.§ Experiments


We compare our implementation with tinyTPU and Libano's implementation under Vivado's out-of-context mode. This mode allows us to independently assess the performance of the systolic matrix engine without the interference of other components.
Table.<ref> shows that our proposed implementation with the in-DSP operand prefetching technique, significantly reduces the usage of LUTs and FFs compared to Libano's implementation, while also achieving a considerable improvement in clock frequency compared to the tinyTPU.





§ ENHANCING SYSTOLIC ENGINE OF XLINX DPU


       

Xilinx developed the Vitis AI DPU as a machine learning solution for FPGA<cit.>.
DPUCZDX8G is the DPU IP core of the Vitis AI for the Zynq UltraScale series FPGA platforms<cit.>.
We begin by providing a brief introduction to the systolic architecture of the DPUCZDX8G. Despite the encryption of the DPUCZDX8G IP core, the documentation for DPUCZDX8G contains ample information about its architecture. Furthermore, the utilization reports and the actual implementation layout obtained in Vivado IDE have verified the accuracy of the public documented description.

DPUCZDX8G employs an output stationary (OS) systolic engine with three levels of parallelism, involving input output channel and pixel parallelism. Fig.<ref>A shows the B1024 configuration of DPUCZDX8G.
Each PE shown in Fig.<ref>B comprises a group of DSP48E2 chains performing vector inner product computation. This PE design fully leverages the DSP48E2's dedicated cascaded path to reduce routing complexity.
Bundles of activations flow vertically into the systolic engine, bundles of weights flow horizontally into the systolic engine, and the products continually accumulate in the PE accumulator.

DPUCZDX8G also incorporates a DDR technique, allowing the DSP48E2s to operate at twice the clock rates of other logic components. CLB multiplexers switch between two data portions from a low-speed clock domain, delivering one portion at a time to the high-speed DSP48E2.
Dot products generated by the DSP chain are transferred back to the slow clock domain through a set of flip-flops that perform the serial-to-parallel conversion. These results are then accumulated by the low-speed accumulator.
This clock domain decoupling design maximizes the utilization of the DSP48E2's exceptional Fmax performance, eliminating any lag in the low-speed fabric.



 §.§ Drawbacks in DPUCZDX8G's Systolic Engine


While Xilinx's officially-developed systolic architecture of the DPUCZDX8G is already considered near-optimal and has demonstrated superior performance in Xilinx FPGA, it still exhibits several drawbacks as listed below:

1) The employment of CLB multiplexers inevitably consumes general routing resources and fabric logic. Furthermore, as CLB multiplexers span two clock domains, they impose stress on timing constraints. This may lead to a degradation of the clock frequency in the high-speed clock domain.

2) The cost associated with the DDR technique results in the harsh doubled bandwidth requirements for the weight data.

3) Each fast DSP48E2 chain requires two slow DSP48E2 accumulators in DPUCZDX8G. The Fmax performance of the DSP48E2 accumulator is underutilized, and the required number of accumulators in DPUCZDX8G is costly.

4) Extra LUTs and CARRY8s are required for the grouped partial sums combining and INT8 correction process.

In this section, we unveil several untapped DSP48E2 optimization potentials aimed at addressing these drawbacks.
We successfully absorb the CLB multiplexers introduced by DDR techniques into the DSP48E2, eliminating the need for excessive LUT usage.
We shift the burden of the doubled bandwidth requirement from the weight data to the output results, given that the output results' bandwidth is much smaller in the OS dataflow.
We move the DSP48E2 accumulator from the slow clock domain to the fast clock domain and halve the number of required accumulators without affecting the throughput, thereby significantly reducing DSP48E2 consumption.
We tackle these issues through two new DSP48E2 techniques outlined below and shown in Fig.<ref>C and Fig.<ref>D..



 §.§ Enhancement: In-DSP Multiplexing


In DPUCZDX8G, each row of the systolic matrix engine shares the same weights. Two portions of weights from the slow clock domain need to be multiplexed into the fast clock domain and streamed into the systolic engine, progressing through one flip-flop stage per processing element.
In our approach, the need for LUT multiplexing is eliminated, and the staging registers operate at the slow clock domain. This not only significantly alleviates timing closure pressure but also reduces power consumption.

We make use of the two flexible input pipelines to perform in-DSP multiplexing. In the DSP48E2's input pipelines, the pathway from the input port to the multiplier can be configured statically through attribute settings or dynamically switched using a multiplexer.
For simplification in the illustration, we focus on the multiplication between input port A and input port B without any data packing process.
While data stream into the DSP48E2 from the slow clock domain, the DSP48E2 itself operates at a doubled data rate. We designate the slow clock as Clk_× 1 and the fast clock as Clk_× 2.
As shown in Fig.<ref>, input port A is set up with a simple 2-stage pipeline. Activations are streamed into the A_1 and A_2 registers. The clock enable pins for A_1 and A_2 are consistently high, and new data updates A_1 and A_2 every Clk_× 1 cycle.
Conversely, input port B is configured with a ping-pong datapath. Weights are streamed into B_1 and B_2 registers in a ping-pong manner, controlled by the independent clock enable pins for B_1 and B_2. New data updates B_1 or B_2 every two Clk_× 1 cycles.



The multiplexer in the input port B pipeline plays a crucial role: it switches between B_1 and B_2 registers at the speed of Clk_× 2. This enables the multiplier to execute the cross product between activations a_t, a_t+1 and weights w_t, w_t+1 in adjacent Clk_× 1 cycles. As a result, it yields a_tw_t, a_tw_t+1, a_t+1w_t, a_t+1w_t+1, four results every two Clk_× 1 cycles, achieving DDR multiplication.
The streaming activations and weights can be pre-arranged in such interleaved manner in advance.
All the aforementioned signals are depicted in the waveform in Fig.<ref> to provide a clearer illustration.

INT8 packing technique can also be applied in combination with the proposed in-DSP multiplexing techniques. Since the A plus D pre-adder datapath, which is also a 2-stage pipeline, has no effect on the ping-pong datapath of the B input port.
Furthermore, cascading is applicable. Cascading N DSP48E2 units with such settings, combined with INT8 packing, results in a processing element capable of performing matrix multiplication between 4× N activations and N× 2 weights every two Clk_× 1 cycles.
Our proposed DSP48E2 chain achieves an equivalent computing density to the DSP48E2 chain in DPUCZDX8G, but eliminating the need for LUT multiplexing and halving the weight data bandwidth at the same time.



 §.§ Enhancement: Ring Accumulator


In DPUCZDX8G, each DSP48E2 chain generates two pair of independent INT18 partial sums every Clk_× 2 cycle. The partial sums are transferred back to Clk_× 1 domain by serial-to-parallel conversion.
The official implementation, where products generated by DSP48E2 chains in the same group are combined using LUT adder-tree and each combined partial sum is processed by an SIMD=ONE48 DSP48E2 accumulator (which adds an INT26 bias using the DSP pre-adder and produce 29-bit final results), is not optimal.
Dealing with INT18 partial sums, INT26 bias, and INT29 final results leads to underutilization of the 48-bit DSP48E2 accumulator.
Our implementation reduce both the bias precision and the precision of the accumulator to INT24. This adjustment results in only a minor loss in precision but allows for an efficient alignment with the SIMD=TWO24 feature of the DSP48E2.

In our in-DSP multiplexing method, each DSP48E2 chain produces four pairs of INT18 partial sums every four Clk_× 2 cycles.
Rather than transferring the partial sums back to the Clk_× 1 domain and utilizing LUT adders for group combining, we design a ring accumulator composed of only two cascaded DSP48E2s that also operate at Clk_× 2, handling the combining of partial sums, the addition of bias, and the accumulation process altogether, as depicted in Fig.<ref>.
The two groups, four pairs of partial sums sending to the ring accumulator are accumulated sequentially. The accumulator introduces a latency of two, and the outputs of the accumulator undergo a delay using two registers. The delayed outputs are connected back to the DSP48E2, aligning with the next iteration of accumulation. By adopting this approach, the number of DSP48E2 accumulators is effectively reduced by half.

It's noteworthy that the correction required by the INT8 packing does not demand extra LUTs or CARRY8 logic. We leverage the rounding constant at the W multiplexer inside the DSP48E2 to handle the compensation. It is also worth noting that the delay registers in the ring accumulator loop can be repurposed for the serial-to-parallel conversion to transfer the accumulated results back to Clk_× 1 domain, shown in Fig.<ref>.



In contrast to DPUCZDX8G's accumulator, our accumulator generates four pairs of sums instead of two. This difference is due to the burden of doubled weight bandwidth in DPUCZDX8G's implementation, now placed on the output. This is not expected to become a performance bottleneck as the output bandwidth, amortized over time, is generally small in OS dataflow, particularly considering that accumulation cycles are typically large in convolutional neural networks.



 §.§ Experiments


DPUCZDX8G is a commercially encrypted IP, making it impossible to access its original module-level breakdown design directly for experimentation.

Although the module hierarchy of the encrypted DPUCZDX8G is explicitly hidden, it can still be obtained from the Vivado resource utilization report.
While the netlists of the encrypted DPUCZDX8G are also explicitly hidden, they remain implicitly visible in the Vivado implementation device view GUI when selecting the physical routing wire, shown in Fig.<ref>. Additionally, we can still use the Vivado find function to count cells or nets with the same naming prefix.
Through these methods and existing public documentation of the DPUCZDX8G, we were able to unravel the intricate design of the Vitis AI DPU. We obtain the resource utilization breakdown of the DPUCZDX8G systolic engine in B1024 configuration, shown in Table.<ref>.

To ensure a fair assessment solely on the systolic architecture, we recreate a one-to-one systolic matrix engine of the DPUCZDX8G B1024 to compare with our proposed implementation under Vivado's out-of-context mode.
Our replication closely adheres to the resource utilization breakdown of the critical systolic array component of B1024, removing other non-critical components to simplify the comparison and align with our proposed implementation, ensuring a fair comparison.
As shown in Table.<ref>, our proposed implementation achieves a substantial 85% and 20% reduction in total LUTs and FFs compared to the official B1024 replicate. We have also managed to halve the number of DSP48E2 accumulators. Moreover, under the same frequency, we have achieved a 20% reduction in power and gained much more timing margin.







§ APPLICABILITY ON SNN ACCELERATOR


In this section, we show that aforementioned techniques can seamlessly be applied to systolic-array-based SNN accelerators.
FireFly<cit.> represents a state-of-the-art SNN accelerator, employing a typical WS systolic array design. It leverages the wide-bus multiplexers in DSP48E2 units for spike-based computation.
In FireFly's implementation, two sets of synaptic weights are presented on the A B port and the C port, respectively, with the weights on the A B port being concatenated within the DSP48E2, as illustrated in Fig.<ref>. Utilizing the SIMD=FOUR12 mode of the DSP48E2 allows a single DSP48E2 unit to function as a 2× 4 synaptic crossbar.

Our in-DSP operand prefetching technique can use both the A and B input pipelines along with their cascaded paths for synaptic weight prefetching, shown in Fig.<ref>.
While the use of CLB flip-flops is unavoidable for weights presented on the C port due to the absence of C cascaded paths in DSP48E2, the overall requirement for weight ping-pong CLB registers is still greatly reduced. 
As indicated in Table.<ref>, the total flip-flops consumption is reduced by half compared to the original implementation, accompanied by a noticeable drop in power consumption.







§ CONCLUSION


In this paper, we revisit the functionalities of the DSP48E2, exploring its optimization potential and uncovering several underutilized techniques that can enhance the performance of systolic matrix engines on UltraScale series FPGAs. We discuss the in-DSP operand prefetching technique, in-DSP multiplexing technique, and the ring accumulator technique, which can be broadly applied to both WS and OS systolic arrays, including those used for neuromorphic SNN computing. We believe that our contibutions offer insights for researchers and developers aiming to build DSP-optimized hardware.



§ ACKNOWLEDGEMENT


This work is supported by the Chinese Academy of Sciences Foundation Frontier Scientific Research Program (ZDBS-LY- JSC013). 
This work is part of the software-hardware codesigns research of the Brain-inspired Cognitive Engine (BrainCog)<cit.><cit.>.
We would also like to express our gratitude to Niansong Zhang from Cornell University for providing valuable suggestions on the paper.

IEEEtran


