DSP on FPGA
How signal processing maps onto an FPGA, from Q-format fixed-point arithmetic and DSP slices through FIR, IIR, CIC, FFT and CORDIC, to the choice between model-based tools and hand RTL.
Overview
Digital signal processing is the workload FPGAs were made for. A filter that needs a multiply and an add on every sample at 500 MHz is a loop a processor cannot keep up with, and a few dozen dedicated multipliers running in parallel can. This hub is for engineers who know some DSP theory and want to see how it becomes hardware, and for RTL engineers who have been handed a filter specification.
The craft is in the arithmetic. Floating point is rare in FPGA DSP because it is large and slow. Nearly everything is fixed point, and the work is choosing word widths, deciding where to round and where to saturate, and proving that the result is close enough to the ideal.
Key ideas
Fixed-point arithmetic and bit growth
A fixed-point number is an integer with an implied binary point. Q1.15 means one integer bit (the sign) and fifteen fractional bits, so the value is the integer divided by 32,768. Adding two Qm.n numbers can grow the result by one bit. Multiplying a Qa.b by a Qc.d gives a Q(a+c).(b+d) result, so a 16 by 16 multiply yields 32 bits. A filter that sums many products grows further, by roughly log2 of the number of taps. Every stage therefore either widens its output or rounds it back down, and rounding introduces noise. Truncation is cheap and biased. Round-half-up is one adder. Convergent rounding removes the bias. Saturation costs a comparator but prevents wrap-around, which turns a loud input into a catastrophic one. Tools such as MATLAB Fixed-Point Designer, Python’s numpy with explicit scaling, or the arbitrary-precision types in HLS let you model the quantisation before you commit to RTL.
The DSP slice
Every mid-range FPGA has columns of hard arithmetic blocks. AMD’s DSP48E2 contains a 27 by 18 bit signed multiplier, a pre-adder, a 48-bit ALU and accumulator, and pipeline registers at each stage. Altera’s variable-precision DSP block does 18 by 19 or 27 by 27 multiplies and has native floating-point modes on Arria 10 and later. Lattice, Microchip, Gowin and Efinix have 18 by 18 multipliers with accumulators. Using these blocks well means matching the pipeline registers the block provides, so that the multiplier runs at its full rated clock, and chaining accumulators through the dedicated cascade paths so that a long FIR does not need fabric routing between taps.
Filters, transforms and rotations
A FIR filter is a sum of delayed samples weighted by coefficients. A fully parallel FIR uses one DSP slice per tap and produces one output per clock. A symmetric FIR halves that with the pre-adder. A time-multiplexed FIR shares a few slices across many taps when the sample rate is well below the clock rate. IIR filters use feedback and are harder to pipeline, so they are usually kept to second-order sections. CIC filters decimate or interpolate by large factors with no multipliers at all, using only integrators and combs, and are the standard first stage after an ADC. FFTs are built from butterflies in a pipelined or burst architecture, and every vendor ships a generator. CORDIC computes sine, cosine, magnitude, phase and rotations with shifts and adds, and is how you build an NCO or a polar-to-rectangular converter without a multiplier. Multirate design, which changes sample rate between stages, is what keeps the arithmetic cheap: run the hard filters at the lowest rate that still satisfies the sampling theorem.
Model-based design versus hand RTL
AMD’s System Generator for DSP (now part of Model Composer) and Altera’s DSP Builder let you draw a signal flow in Simulink with bit-true blocks and generate RTL. They are fast for exploring word widths and good for teams who live in MATLAB. The generated RTL is hard to maintain outside the tool, licences are expensive and the blocks sometimes lag the latest devices. Hand RTL, or HLS with fixed-point types, produces designs that any engineer can read and that fit in a normal version-controlled flow. Many teams model in Python or MATLAB, then hand-write the RTL and verify it bit-true against the model.
Where to start
- /learn/beginner/03-combinational-logic-and-luts/ and /learn/beginner/04-registers-clocks-and-state/ give you adders and pipelines.
- /learn/beginner/08-counters-timers-and-debouncing/ builds the accumulator that becomes an NCO.
- /learn/beginner/09-memories-block-ram-and-fifos/ covers the delay lines and coefficient memories in every filter.
Intermediate lessons on a fixed-point FIR with a Python golden model, a CIC decimator and a CORDIC NCO are coming.
Tools and vendors
| Vendor | Hard multiplier | Filter and FFT IP | Model-based tool | Hub |
|---|---|---|---|---|
| AMD | DSP48E2 (27x18), DSP58 (27x24, Versal) | FIR Compiler, FFT, CORDIC, DDS | Model Composer, Vitis HLS | /vendors/amd/ |
| Altera | Variable precision, native FP32 | FIR II, FFT, CORDIC | DSP Builder | /vendors/altera/ |
| Microchip | Math block 18x18 | CoreFIR, CoreFFT | None | /vendors/microchip/ |
| Lattice | sysDSP 18x18 | FIR, FFT in IP catalogue | None | /vendors/lattice/ |
| Open source | Inferred by Yosys | Hand RTL, Amaranth, SpinalHDL libraries | Python models | /vendors/opensource/ |
Common mistakes
- Picking word widths by guesswork instead of simulating the quantisation noise against the model.
- Truncating a long accumulation and then wondering about the DC offset.
- Letting the synthesiser infer a multiplier without the pipeline registers, so the DSP slice runs at half its rated clock.
- Writing an IIR filter with a long combinational feedback path that cannot be pipelined.
- Running a filter at the ADC rate when a CIC and a decimation would let it run ten times slower.
- Using floating point because the model used it.
Going deeper
- AMD UG579, UltraScale Architecture DSP Slice: the full DSP48E2 description, including cascade and rounding modes.
- AMD PG149, FIR Compiler: shows every FIR architecture choice the generator makes.
- Hogenauer, “An Economical Class of Digital Filters for Decimation and Interpolation”: the 1981 CIC paper.
- Andraka, “A Survey of CORDIC Algorithms for FPGA Based Computers”: the FPGA CORDIC reference.
- Harris, Multirate Signal Processing for Communication Systems: the standard book on multirate design with hardware in mind.