# dsphdl.IFFT

Compute inverse fast Fourier transform (IFFT)

## Description

The `dsphdl.IFFT`

System object™ provides two architectures to optimize either throughput or area. Use the
streaming Radix 2^2 architecture for high-throughput applications. This architecture supports
scalar or vector input data. You can achieve gigasamples-per-second (GSPS) throughput using
vector input. Use the burst Radix 2 architecture for a minimum resource implementation,
especially with large FFT sizes. Your system must be able to tolerate bursty data and higher
latency. This architecture supports only scalar input data. The object accepts real or complex
data, provides hardware-friendly control signals, and has optional output frame control
signals.

To calculate the inverse fast Fourier transform:

Create the

`dsphdl.IFFT`

object and set its properties.Call the object with arguments, as if it were a function.

To learn more about how System objects work, see What Are System Objects?

## Creation

### Description

returns an HDL IFFT
System object, `IFFT_N`

= dsphdl.IFFT`IFFT_N`

, that performs a fast Fourier transform.

sets
properties using one or more name-value arguments.`IFFT_N`

= dsphdl.IFFT(Name=Value)

**Example: **`ifft128 = dsphdl.IFFT(FFTLength=128)`

## Properties

Unless otherwise indicated, properties are *nontunable*, which means you cannot change their
values after calling the object. Objects lock when you call them, and the
`release`

function unlocks them.

If a property is *tunable*, you can change its value at
any time.

For more information on changing property values, see System Design in MATLAB Using System Objects.

`Architecture`

— Hardware implementation

`'Streaming Radix 2^2'`

(default) | `'Burst Radix 2'`

Hardware implementation, specified as either:

`'Streaming Radix 2^2'`

— Low-latency architecture. Supports gigasamples-per-second (GSPS) throughput when you use vector input.`'Burst Radix 2'`

— Minimum resource architecture. Vector input is not supported when you select this architecture. When you use this architecture, your input data must comply with the`ready`

backpressure signal.

`ComplexMultiplication`

— HDL implementation of complex multipliers

`'Use 4 multipliers and 2 adders'`

(default) | `'Use 3 multipliers and 5 adders'`

HDL implementation of complex multipliers, specified as either ```
'Use 4
multipliers and 2 adders'
```

or ```
'Use 3 multipliers and 5
adders'
```

. Depending on your synthesis tool and target device, one option may
be faster or smaller.

`BitReversedOutput`

— Order of the output data

`true`

(default) | `false`

Order of the output data, specified as either:

`true`

— The output channel elements are bit reversed relative to the input order.`false`

— The output channel elements are in linear order.

The IFFT algorithm calculates output in the reverse order to the input. When you request output in the same order as the input, the algorithm performs an extra reversal operation. For more information on ordering of the output, see Linear and Bit-Reversed Output Order.

`BitReversedInput`

— Expected order of the input data

`false`

(default) | `true`

Expected order of the input data, specified as either:

`true`

— The input channel elements are in bit-reversed order.`false`

— The input channel elements are in linear order.

The IFFT algorithm calculates output in the reverse order to the input. When you request output in the same order as the input, the algorithm performs an extra reversal operation. For more information on ordering of the output, see Linear and Bit-Reversed Output Order.

`Normalize`

— Output scaling

`true`

(default) | `false`

Output scaling, specified as either:

`true`

— The object implements an overall 1/*N*scale factor by dividing the output of each butterfly multiplication by 2. This adjustment keeps the output of the IFFT in the same amplitude range as its input.`false`

— The object avoids overflow by increasing the word length by one bit after each butterfly multiplication. The bit growth is the same for both architectures.

`FFTLength`

— Number of data points used for one FFT calculation

1024 (default) | integer power of 2 between 2^{2} and
2^{16}

Number of data points used for one FFT calculation, specified as an integer power of
2 between 2^{2} and 2^{16}. The object
accepts FFT lengths outside this range, but they are not supported for HDL code
generation.

`ResetInputPort`

— Enable reset argument

`false`

(default) | `true`

Enable `reset`

input argument to the object. When
`reset`

is `1`

(true), the object stops the current
calculation and clears internal states. When the `reset`

is
`0`

(false) and the input `valid`

is
`1`

(true), the object captures data for processing.

`StartOutputPort`

— Enable start output argument

`false`

(default) | `true`

Enable `startOut`

output argument of the object. When enabled, the
object returns an additional output signal that is `true`

on the first
cycle of each valid output frame.

`EndOutputPort`

— Enable end output argument

`false`

(default) | `true`

Enable `endOut`

output argument of the object. When enabled, the
object returns an additional output signal that is `true`

on the first
cycle of each valid output frame.

`RoundingMethod`

— Rounding mode used for fixed-point operations

`'Floor'`

(default) | `'Ceiling'`

| `'Convergent'`

| `'Nearest'`

| `'Round'`

| `'Zero'`

Rounding mode used for fixed-point operations. When the input is any integer or fixed-point data type, the IFFT algorithm uses fixed-point arithmetic for internal calculations. This option does not apply when the input is single or double type. Rounding applies to twiddle factor multiplication and scaling operations.

## Usage

### Syntax

### Description

`[`

returns the inverse fast Fourier transform (IFFT) when using the burst Radix 2
architecture. The `Y`

,`validOut`

,`ready`

]
= IFFT_N(`X`

,`validIn`

)`ready`

signal indicates when the object has memory
available to accept new input samples. You must apply input `data`

and
`valid`

signals only when `ready`

is
`1`

(true). The object ignores the input `data`

and
`valid`

signals when `ready`

is
`0`

(false).

To use this syntax, set the `Architecture`

property to `'Burst Radix 2'`

. For example:

IFFT_N = dsphdl.IFFT(___,Architecture='Burst Radix 2'); ... [y,validOut,ready] = IFFT_N(x,validIn)

`[`

also returns frame control signals `Y`

,`startOut`

,`endOut`

,`validOut`

]
= IFFT_N(`X`

,`validIn`

)`startOut`

and
`endOut`

. `startOut`

is `true`

on
the first sample of a frame of output data. `endOut`

is
`true`

for the last sample of a frame of output data.

To use this syntax, set the `StartOutputPort`

and `EndOutputPort`

properties to `true`

. For example:

```
IFFT_N = dsphdl.IFFT(___,StartOutputPort=true,EndOutputPort=true);
...
[y,startOut,endOut,validOut] = IFFT_N(x,validIn)
```

`[`

returns the IFFT, `Y`

,`validOut`

]
= IFFT_N(`X`

,`validIn`

,`resetIn`

)`Y`

, when `validIn`

is
`true`

and `resetIn`

is `false`

.
When `resetIn`

is `true`

, the object stops the current
calculation and clears all internal state.

To use this syntax, set the `ResetInputPort`

property to `true`

. For example:

```
IFFT_N = dsphdl.IFFT(___,ResetInputPort=true);
...
[y,validOut] = IFFT_N(x,validIn,resetIn)
```

### Input Arguments

`X`

— Input data

scalar or column vector of real or complex values

Input data, specified as a scalar or column vector of real or complex values, in
fixed-point or integer format. Vector input is supported with ```
'Streaming
Radix 2^2'
```

architecture only. The vector size must be a power of 2 between
1 and 64 that is not greater than the FFT length.

The software supports `double`

and
`single`

data types for simulation, but not for HDL code generation.

**Data Types: **`fi`

| `int8`

| `int16`

| `int32`

| `int64`

| `uint8`

| `uint16`

| `uint32`

| `single`

| `double`

**Complex Number Support: **Yes

`validIn`

— Indicates valid input data

scalar

Control signal that indicates if the input data is valid. When
`validIn`

is `1`

(`true`

), the
object captures the values from the `dataIn`

argument. When
`validIn`

is `0`

(`false`

), the
object ignores the values from the `dataIn`

argument.

**Data Types: **`logical`

`resetIn`

— Clears internal states

logical scalar

Control signal that clears internal states. When `reset`

is
`1`

(`true`

), the object stops the current
calculation and clears internal states. When the `reset`

is
`0`

(`false`

) and the input
`valid`

is `1`

(`true`

), the
block captures data for processing.

For more reset considerations, see the Reset Signal section on the Hardware Control Signals page.

#### Dependencies

To enable this argument, set `ResetInputPort`

to `true`

.

**Data Types: **`logical`

### Output Arguments

`Y`

— Output data

scalar or column vector of real or complex values

Output data, returned as a scalar or column vector of real or complex values. The output format matches the format of the input data.

`ready`

— Indicates object is ready for new input data

logical scalar

Control signal that indicates that the object is ready for new input data sample
on the next cycle. When `ready`

is `1`

(`true`

), you can specify the `data`

and `valid `

inputs for the next time step. When
`ready`

is `0`

(`false`

), the object ignores any input data in the next time step.
This output is returned when you select `'Burst Radix 2'`

architecture.

**Data Types: **`logical`

`startOut`

— First sample of output frame

logical scalar

First sample of output frame, returned as a logical scalar. To enable this
argument, set the `StartOutputPort`

property to `true`

.

**Data Types: **`logical`

`endOut`

— Last sample of output frame

logical scalar

Last sample of output frame, returned as a logical scalar. To enable this
argument, set the EndOutputPort property to `true`

.

**Data Types: **`logical`

`validOut`

— Indicates valid output data

scalar

Control signal that indicates if the output data is valid. When
`validOut`

is `1`

(`true`

), the
object returns valid data from the `dataOut`

argument. When
`validOut`

is `0`

(`false`

),
values from the `dataOut`

argument are not valid.

**Data Types: **`logical`

## Object Functions

To use an object function, specify the
System object as the first input argument. For
example, to release system resources of a System object named `obj`

, use
this syntax:

release(obj)

### Specific to dsphdl.IFFT

`getLatency` | Latency of FFT calculation |

## Examples

### Create IFFT for HDL Code Generation

Create the specifications and input signal. This example uses a 128-point FFT.

```
N = 128;
Fs = 40;
t = (0:N-1)'/Fs;
x = sin(2*pi*15*t) + 0.75*cos(2*pi*10*t);
y = x + .25*randn(size(x));
y_fixed = sfi(y,32,16);
noOp = zeros(1,'like',y_fixed);
```

Compute the FFT of the signal to use as the input to the IFFT object.

hdlfft = dsphdl.FFT(FFTLength=N,BitReversedOutput=false); Yf = zeros(1,4*N); validOut = false(1,4*N); for loop = 1:1:N [Yf(loop),validOut(loop)] = hdlfft(complex(y_fixed(loop)),true); end for loop = N+1:1:4*N [Yf(loop),validOut(loop)] = hdlfft(complex(noOp),false); end Yf = Yf(validOut == 1);

Plot the single-sided amplitude spectrum.

plot(Fs/2*linspace(0,1,N/2),2*abs(Yf(1:N/2)/N)) title('Single-Sided Amplitude Spectrum of Noisy Signal y(t)') xlabel('Frequency (Hz)') ylabel('Output of FFT (f)')

Select frequencies that hold the majority of the energy in the signal. The `cumsum`

function does not accept fixed-point arguments, so convert the data back to `double`

.

[Ysort,i] = sort(abs(double(transpose(Yf(1:N)))),1,'descend'); Ysort_d = double(Ysort); CumEnergy = sqrt(cumsum(Ysort_d.^2))/norm(Ysort_d); j = find(CumEnergy > 0.9, 1); disp(['Number of FFT coefficients that represent 90% of the ', ... 'total energy in the sequence: ', num2str(j)]) Yin = zeros(N,1); Yin(i(1:j)) = Yf(i(1:j));

Number of FFT coefficients that represent 90% of the total energy in the sequence: 4

Write a function that creates and calls the IFFT System object™. You can generate HDL from this function.

function [yOut,validOut] = HDLIFFT128(yIn,validIn) %HDLIFFT128 % Processes one sample of data using the dsphdl.IFFT System object(TM) % yIn is a fixed-point scalar or column vector. % validIn is a logical scalar. % You can generate HDL code from this function. persistent ifft128; if isempty(ifft128) ifft128 = dsphdl.IFFT(FFTLength=128); end [yOut,validOut] = ifft128(yIn,validIn); end % Copyright 2012-2023 The MathWorks, Inc.

Compute the IFFT by calling the function for each data sample.

Xt = zeros(1,3*N); validOut = false(1,3*N); for loop = 1:1:N [Xt(loop),validOut(loop)] = HDLIFFT128(complex(Yin(loop)),true); end for loop = N+1:1:3*N [Xt(loop),validOut(loop)] = HDLIFFT128(complex(0),false); end

Discard invalid output samples. Then inspect the output and compare it with the input signal. The original input is in green.

```
Xt = Xt(validOut==1);
Xt = bitrevorder(Xt);
norm(x-transpose(Xt(1:N)))
figure
stem(real(Xt))
figure
stem(real(x),'--g')
```

ans = 0.7863

### Create a Vector-Input IFFT for HDL Code Generation

Create the specifications and input signal. This example uses a 128-point FFT and computes the transform over 16 samples at a time.

N = 128; V = 16; Fs = 40; t = (0:N-1)'/Fs; x = sin(2*pi*15*t) + 0.75*cos(2*pi*10*t); y = x + .25*randn(size(x)); y_fixed = sfi(y,32,24); y_vect = reshape(y_fixed,V,N/V);

Compute the FFT of the signal, to use as the input to the IFFT object.

hdlfft = dsphdl.FFT('FFTLength',N); loopCount = getLatency(hdlfft,N,V)+N/V; Yf = zeros(V,loopCount); validOut = false(V,loopCount); for loop = 1:1:loopCount if ( mod(loop,N/V) == 0 ) i = N/V; else i = mod(loop,N/V); end [Yf(:,loop),validOut(loop)] = hdlfft(complex(y_vect(:,i)),(loop<=N/V)); end

Plot the single-sided amplitude spectrum.

C = Yf(:,validOut==1); Yf_flat = C(:); Yr = bitrevorder(Yf_flat); plot(Fs/2*linspace(0,1,N/2),2*abs(Yr(1:N/2)/N)) title('Single-Sided Amplitude Spectrum of Noisy Signal y(t)') xlabel('Frequency (Hz)') ylabel('Output of FFT(f)')

Select frequencies that hold the majority of the energy in the signal. The `cumsum`

function doesn't accept fixed-point arguments, so convert the data back to `double`

.

[Ysort,i] = sort(abs(double(Yr(1:N))),1,'descend'); CumEnergy = sqrt(cumsum(Ysort.^2))/norm(Ysort); j = find(CumEnergy > 0.9, 1); disp(['Number of FFT coefficients that represent 90% of the ', ... 'total energy in the sequence: ', num2str(j)]) Yin = zeros(N,1); Yin(i(1:j)) = Yr(i(1:j)); YinVect = reshape(Yin,V,N/V);

Number of FFT coefficients that represent 90% of the total energy in the sequence: 4

Write a function that creates and calls the IFFT System object™. You can generate HDL from this function.

function [yOut,validOut] = HDLIFFT128V16(yIn,validIn) %HDLFFT128V16 % Processes 16-sample vectors of FFT data % yIn is a fixed-point column vector. % validIn is a logical scalar value. % You can generate HDL code from this function. persistent ifft128v16; if isempty(ifft128v16) ifft128v16 = dsphdl.IFFT(FFTLength=128) end [yOut,validOut] = ifft128v16(yIn,validIn); end % Copyright 2012-2023 The MathWorks, Inc.

Compute the IFFT by calling the function for each data sample.

Xt = zeros(V,loopCount); validOut = false(V,loopCount); for loop = 1:1:loopCount if ( mod(loop,N/V) == 0 ) i = N/V; else i = mod(loop,N/V); end [Xt(:,loop),validOut(loop)] = HDLIFFT128V16(complex(YinVect(:,i)),(loop<=N/V)); end

ifft128v16 = dsphdl.IFFT with properties: FFTLength: 128 Architecture: 'Streaming Radix 2^2' ComplexMultiplication: 'Use 4 multipliers and 2 adders' BitReversedOutput: true BitReversedInput: false Normalize: true Use get to show all properties

Discard invalid output samples. Then inspect the output and compare it with the input signal. The original input is in green.

```
C = Xt(:,validOut==1);
Xt = C(:);
Xt = bitrevorder(Xt);
norm(x-Xt(1:N))
figure
stem(real(Xt))
figure
stem(real(x),'--g')
```

ans = 0.7863

### Explore Latency of HDL IFFT Object

The latency of the object varies with the FFT length and the vector size. Use the `getLatency`

function to find the latency of a particular configuration. The latency is the number of cycles between the first valid input and the first valid output, assuming that the input is contiguous.

Create a new `dsphdl.IFFT`

object and request the latency.

hdlifft = dsphdl.IFFT(FFTLength=512); L512 = getLatency(hdlifft)

L512 = 599

Request hypothetical latency information about a similar object with a different FFT length. The properties of the original object do not change. When you do not specify a vector length, the function assumes scalar input data.

L256 = getLatency(hdlifft,256)

L256 = 329

N = hdlifft.FFTLength

N = 512

Request hypothetical latency information of a similar object that accepts eight-sample vector input.

L256v8 = getLatency(hdlifft,256,8)

L256v8 = 93

Enable scaling at each stage of the IFFT. The latency does not change.

hdlifft.Normalize = true; L512n = getLatency(hdlifft)

L512n = 599

Request the same output order as the input order. This setting increases the latency because the object must collect the output before reordering.

hdlifft.BitReversedOutput = false; L512r = getLatency(hdlifft)

L512r = 1078

## Algorithms

### Streaming Radix 2^2

The streaming Radix 2^2 architecture implements a low-latency architecture. It saves resources compared to a streaming Radix 2 implementation by factoring and grouping the FFT equation. The architecture has log_{4}(*N*) stages. Each stage contains two single-path delay feedback (SDF) butterflies with memory controllers. When you use vector input, each stage operates on fewer input samples, so some stages reduce to a simple butterfly, without SDF.

The first SDF stage is a regular butterfly. The second stage multiplies the outputs of the
first stage by *–j*. To avoid a hardware multiplier, the block
swaps the real and imaginary parts of the inputs, and again swaps the imaginary
parts of the resulting outputs. Each stage rounds the result of the twiddle factor
multiplication to the input word length. The twiddle factors have two integer bits,
and the rest of the bits are used for fractional bits. The twiddle factors have the
same bit width as the input data, *WL*. The twiddle factors have
two integer bits, and *WL*-2 fractional bits.

If you enable scaling, the algorithm divides the result of each butterfly stage by 2. Scaling
at each stage avoids overflow, keeps the word length the same as the input, and results in
an overall scale factor of 1/*N*. If scaling is disabled, the algorithm
avoids overflow by increasing the word length by 1 bit at each stage. The diagram shows the
butterflies and internal word lengths of each stage, not including the memory.

### Burst Radix 2

The burst Radix 2 architecture implements the FFT by using a single complex butterfly
multiplier. The algorithm cannot start until it has stored the entire input frame,
and it cannot accept the next frame until computations are complete. The output
**ready** port indicates when the algorithm is ready for
new data. The diagram shows the burst architecture, with pipeline registers.

When you use this architecture, your input
data must comply with the **ready** backpressure signal.

### Control Signals

The algorithm processes input data only when the input **valid** port
is 1. Output data is valid only when the output **valid** port is
1.

When the optional input **reset** port is 1, the algorithm stops the
current calculation and clears all internal states. The algorithm begins new
calculations when **reset** port is 0 and the input
**valid** port starts a new frame.

**Timing Diagram**

This diagram shows the input and output **valid** port values for contiguous
scalar input data, streaming Radix 2^2 architecture, an FFT length of 1024, and a vector
size of 16.

The diagram also shows the optional **start** and **end**
port values that indicate frame boundaries. If you enable the **start**
port, the **start** port value pulses for one cycle with the first valid
output of the frame. If you enable the **end** port, the
**start** port value pulses for one cycle with the last valid output of
the frame.

If you apply continuous input frames, the output will also be continuous after the initial latency.

The input **valid** port can be noncontiguous.
Data accompanied by an input **valid** port is processed as it arrives, and
the resulting data is stored until a frame is filled. Then the algorithm returns contiguous
output samples in a frame of *N* (**FFT length**) cycles.
This diagram shows noncontiguous input and contiguous output for an FFT length of 512 and a
vector size of 16.

When you use the burst architecture, you cannot provide the next frame of input data until
memory space is available. The **ready** signal indicates when the
algorithm can accept new input data. You must apply input **data** and
**valid** signals only when **ready** is
`1`

(true). The algorithm ignores any input **data**
and **valid** signals when **ready** is
`0`

(false).

### Latency

The latency varies with the FFT length and the vector size. Use the `getLatency`

function to find the latency of a particular configuration. The latency is the number of
cycles between the first valid input and the first valid output, assuming that the input is
contiguous.

When using the burst architecture with a contiguous input, if your design waits for
**ready** to output `0`

before de-asserting the input
**valid**, then one extra cycle of data arrives at the input. This data
sample is the first sample of the next frame. The algorithm can save one sample while
processing the current frame. Due to this one sample advance, the observed latency of the
later frames (from input **valid** to output **valid**) is
one cycle shorter than the reported latency. The latency is measured from the first cycle,
when input **valid** is 1 to the first cycle when output
**valid** is 1. The number of cycles between when
**ready** port is 0 and the output **valid** port is 1
is always *latency* – *FFTLength*.

### Performance

This resource and performance data is the synthesis result from the generated HDL targeted to
a Xilinx^{®}
Virtex^{®}-6 (XC6VLX75T-1FF484) FPGA. The examples in the tables have this configuration:

1024 FFT length (default)

Complex multiplication using 4 multipliers, 2 adders

Output scaling enabled

Natural order input, Bit-reversed output

16-bit complex input data

Clock enables minimized (HDL Coder™ parameter)

Performance of the synthesized HDL code varies with your target and synthesis options. For instance, reordering for a natural-order output uses more RAM than the default bit-reversed output, and real input uses less RAM than complex input.

For a scalar input Radix 2^2 configuration, the design achieves 326 MHz clock frequency. The latency is 1116 cycles. The design uses these resources.

Resource | Number Used |
---|---|

LUT | 4597 |

FFS | 5353 |

Xilinx LogiCORE | 12 |

Block RAM (16K) | 6 |

When you vectorize the same Radix 2^2 implementation to process two 16-bit input samples in parallel, the design achieves 316 MHz clock frequency. The latency is 600 cycles. The design uses these resources.

Resource | Number Used |
---|---|

LUT | 7653 |

FFS | 9322 |

Xilinx LogiCORE DSP48 | 24 |

Block RAM (16K) | 8 |

The block supports scalar input data only when implementing burst Radix 2 architecture. The burst design achieves 309 MHz clock frequency. The latency is 5811 cycles. The design uses these resources.

Resource | Number Used |
---|---|

LUT | 971 |

FFS | 1254 |

Xilinx LogiCORE DSP48 | 3 |

Block RAM (16K) | 6 |

## Extended Capabilities

### C/C++ Code Generation

Generate C and C++ code using MATLAB® Coder™.

This System object supports C/C++ code generation for accelerating MATLAB^{®} simulations, and for DPI component generation.

### HDL Code Generation

Generate VHDL, Verilog and SystemVerilog code for FPGA and ASIC designs using HDL Coder™.

The software supports `double`

and
`single`

data types for simulation, but not for HDL code generation.

To generate HDL code from predefined System objects, see HDL Code Generation from Viterbi Decoder System Object (HDL Coder).

## Version History

**Introduced in R2014b**

### R2022a: Moved to DSP HDL Toolbox from DSP System Toolbox

Before R2022a, this System object was named `dsp.HDLIFFT`

and was part of the DSP System Toolbox™ product.

### R2022a: FFT length of 4

You can now set the FFT length to 4 (2^{2}). In previous
releases the FFT length had to be a power of 2 from 8 (2^{3}) to
2^{16}.

## Open Example

You have a modified version of this example. Do you want to open this example with your edits?

## MATLAB Command

You clicked a link that corresponds to this MATLAB command:

Run the command by entering it in the MATLAB Command Window. Web browsers do not support MATLAB commands.

Select a Web Site

Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .

You can also select a web site from the following list:

## How to Get Best Site Performance

Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.

### Americas

- América Latina (Español)
- Canada (English)
- United States (English)

### Europe

- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)

- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)