Magnitude and phase angle of complex signal

expand all in page

## Description

The `dsphdl.ComplexToMagnitudeAngle`

System object™ computes the magnitude and phase angle of a complex signal. It provides hardware-friendly control signals. The System object uses a pipelined coordinate rotation digital computer (CORDIC) algorithm to achieve an HDL-optimized implementation.

To compute the magnitude and phase angle of a complex signal:

Create the

`dsphdl.ComplexToMagnitudeAngle`

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

### Syntax

`magAngle = dsphdl.ComplexToMagnitudeAngle`

`magAngle = dsphdl.ComplexToMagnitudeAngle(Name=Value)`

### Description

returns a `magAngle`

= dsphdl.ComplexToMagnitudeAngle`dsphdl.ComplexToMagnitudeAngle`

System object, `magAngle`

, that computes the magnitude and phase angle of a complex input signal.

example

sets properties of the `magAngle`

= dsphdl.ComplexToMagnitudeAngle(`Name=Value`

)`magAngle`

object using one or more name-value arguments.

**Example: **`magAngle = dsphdl.ComplexToMagnitudeAngle(AngleFormat='Radians')`

## Properties

expand all

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.

`OutputFormat`

— Type of values to return

`'Magnitude and angle'`

(default) | `'Magnitude'`

| `'Angle'`

Type of output values to return, specified as `'Magnitude and angle'`

, `'Magnitude'`

, or `'Angle'`

. You can choose for the object to return the magnitude of the input signal, or the phase angle of the input signal, or both.

`AngleFormat`

— Format of phase angle output value

`'Normalized'`

(default) | `'Radians'`

Format of the phase angle output value from the object, specified as:

`'Normalized'`

— Fixed-point format that normalizes the angle in the range [–1,1].`'Radians'`

— Fixed-point values in the range [π,−π].

`ScaleOutput`

— Scale output by inverse of CORDIC gain factor

`true`

(default) | `false`

Scale output by the inverse of the CORDIC gain factor, specified as `true`

or `false`

. The object implements this gain factor with either CSD logic or a multiplier, according to the `ScalingMethod`

property.

**Note**

If your design includes a gain factor later in the datapath, you can set `ScaleOutput`

to `false`

, and include the CORDIC gain factor in the later gain. For calculation of this gain factor, see Algorithm. The object replaces the first CORDIC iteration by mapping the input value onto the angle range [0,π/4]. Therefore, the initial rotation does not contribute a gain term.

`NumIterationsSource`

— Source of `NumIterations`

`'Auto'`

(default) | `'Property'`

Source of the `NumIterations`

property for the CORDIC algorithm, specified as:

`'Auto'`

— Sets the number of iterations to one less than the input word length. If the input is`double`

or`single`

, the number of iterations is 16.`'Property'`

— Uses the`NumIterations`

property.

For details of the CORDIC algorithm, see Algorithm.

`NumIterations`

— Number of CORDIC iterations

integer less than or equal to one less than the input word length

Number of CORDIC iterations that the object executes, specified as an integer. The number of iterations must be less than or equal to one less than the input word length.

For details of the CORDIC algorithm, see Algorithm.

#### Dependencies

To enable this property, set `NumIterationsSource`

to `'Property'`

.

`ScalingMethod`

— Implementation of CORDIC gain scaling

`'CSD'`

(default) | `'Multipliers'`

When you set this property to `'CSD'`

, the object implements the CORDIC gain scaling by using a shift-and-add architecture for the multiply operation. This implementation uses no multiplier resources and may increase the length of the critical path in your design. When you set this property to `'Multipliers'`

, the object implements the CORDIC gain scaling with a multiplier and increases the latency of the object by four cycles.

#### Dependencies

To enable this property, set the `ScaleOutput`

property to `true`

.

## Usage

### Syntax

`[mag,angle,validOut]= magAngle(X,validIn)`

`[mag,validOut]= magAngle(X,validIn)`

`[angle,validOut]= magAngle(X,validIn)`

### Description

example

`[mag,angle,validOut]= magAngle(X,validIn)`

converts a scalar or vector of complex values `X`

into their component magnitude and phase angles. `validIn`

and `validOut`

are logical scalars that indicate the validity of the input and output signals, respectively.

`[mag,validOut]= magAngle(X,validIn)`

returns only the component magnitudes of `X`

.

To use this syntax, set OutputFormat to `'Magnitude'`

.

**Example: **`magAngle = dsphdl.ComplextoMagnitudeAngle(OutputFormat='Magnitude');`

`[angle,validOut]= magAngle(X,validIn)`

returns only the component phase angles of `X`

.

To use this syntax, set OutputFormat to `'Angle'`

.

**Example: **`magAngle = dsphdl.ComplextoMagnitudeAngle(OutputFormat='Angle');`

### Input Arguments

expand all

`X`

— Input signal

complex scalar or vector

Input signal, specified as a scalar, a column vector representing samples in time, or a row vector representing channels. Using vector input increases data throughput while using more hardware resources. The object implements the conversion logic in parallel for each element of the vector. The input vector can contain up to 64 elements.

The software supports `double`

and `single`

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

**Data Types: **`fi`

| `int8`

| `int16`

| `int32`

| `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`

### Output Arguments

expand all

`mag`

— Magnitude component of input signal

scalar | vector

Magnitude calculated from the complex input signal, returned as a scalar, a column vector representing samples in time, or a row vector representing channels. The dimensions and data type of this argument match the dimensions of the `dataIn`

argument.

#### Dependencies

To enable this argument, set the `OutputFormat`

property to `'Magnitude and Angle'`

or `'Magnitude'`

.

`angle`

— Phase angle component of input signal

scalar | vector

Angle calculated from the complex input signal, returned as a scalar, a column vector representing samples in time, or a row vector representing channels. The dimensions and data type of this argument match the dimensions of the `dataIn`

argument. The format of this value depends on the AngleFormat property.

#### Dependencies

To enable this argument, set the `OutputFormat`

property to `'Magnitude and Angle'`

or `'Angle'`

.

`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 `mag`

and/or `angle`

arguments. When `validOut`

is `0`

(`false`

), values from the `mag`

and/or `angle`

arguments 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)

expand all

### Common to All System Objects

step | Run System object algorithm |

release | Release resources and allow changes to System object property values and input characteristics |

reset | Reset internal states of System object |

## Examples

collapse all

### Compute Magnitude and Phase Angle of Complex Signal

Open Script

Use the `dsphdl.ComplextoMagnitudeAngle`

object to compute the magnitude and phase angle of a complex signal. The object uses a CORDIC algorithm for an efficient hardware implementation.

Choose word lengths and create random complex input signal. Then, convert the input signal to fixed-point.

a = -4;b = 4;inputWL = 16;inputFL = 12;numSamples = 10;reData = ((b-a).*rand(numSamples,1)+a);imData = ((b-a).*rand(numSamples,1)+a);dataIn = (fi(reData+imData*1i,1,inputWL,inputFL));figureplot(dataIn)title('Random Complex Input Data')xlabel('Real')ylabel('Imaginary')

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

function [mag,angle,validOut] = Complex2MagAngle(yIn,validIn)%Complex2MagAngle % Converts one sample of complex data to magnitude and angle data.% yIn is a fixed-point complex number.% validIn is a logical scalar value.% You can generate HDL code from this function. persistent cma; if isempty(cma) cma = dsphdl.ComplexToMagnitudeAngle(AngleFormat='Radians'); end [mag,angle,validOut] = cma(yIn,validIn);end% Copyright 2021-2023 The MathWorks, Inc.

The number of CORDIC iterations determines the latency that the object takes to compute the answer for each input sample. The latency is `NumIterations+4`

. In this example, `NumIterationsSource`

is set to the default, `'Auto'`

, so the object uses `inputWL-1`

iterations. The latency is `inputWL+3`

.

latency = inputWL+3;mag = zeros(1,numSamples+latency);ang = zeros(1,numSamples+latency);validOut = false(1,numSamples+latency);

Call the function to convert each sample. After you apply all input samples, continue calling the function with invalid input to flush remaining output samples.

for ii = 1:1:numSamples [mag(ii),ang(ii),validOut] = Complex2MagAngle(dataIn(ii),true);endfor ii = (numSamples+1):1:(numSamples+latency) [mag(ii),ang(ii),validOut(ii)] = Complex2MagAngle(fi(0+0*1i,1,inputWL,inputFL),false);end% Remove invalid output valuesmag = mag(validOut == 1);ang = ang(validOut == 1);figurepolar(ang,mag,'--r') % Red is output from System objecttitle('Output from dsphdl.ComplexToMagnitudeAngle')magD = abs(dataIn);angD = angle(dataIn);figurepolar(angD,magD,'--b') % Blue is output from abs and angle functionstitle('Output from abs and angle Functions')

## Algorithms

expand all

### CORDIC Algorithm

The CORDIC algorithm is a hardware-friendly method for performing trigonometric functions. It is an iterative algorithm that approximates the solution by converging toward the ideal point. The object uses CORDIC vectoring mode to iteratively rotate the input onto the real axis.

The Givens method for rotating a complex number *x*+*iy* by an angle *θ* is as follows. The direction of rotation, *d*, is +1 for counterclockwise and −1 for clockwise.

$$\begin{array}{l}{x}_{r}=x\mathrm{cos}\theta -dy\mathrm{sin}\theta \\ {y}_{r}=y\mathrm{cos}\theta \text{}+dx\mathrm{sin}\theta \end{array}$$

For a hardware implementation, factor out the cos*θ* to leave a tan*θ* term.

$$\begin{array}{l}{x}_{r}=\mathrm{cos}\theta \left(x-dy\mathrm{tan}\theta \right)\\ {y}_{r}=\mathrm{cos}\theta \left(y+dx\mathrm{tan}\theta \right)\end{array}$$

To rotate the vector onto the real axis, choose a series of rotations of *θ _{n}* so that $$\mathrm{tan}{\theta}_{n}={2}^{-n}$$. Remove the cos

*θ*term so each iterative rotation uses only shift and add operations.

$$\begin{array}{l}R{x}_{n}={x}_{n-1}-{d}_{n}{y}_{n-1}{2}^{-n}\\ R{y}_{n}={y}_{n-1}+{d}_{n}{x}_{n-1}{2}^{-n}\end{array}$$

Combine the missing cos*θ* terms from each iteration into a constant, and apply it with a single multiplier to the result of the final rotation. The output magnitude is the scaled final value of *x*. The output angle, *z*, is the sum of the rotation angles.

$$\begin{array}{l}{x}_{r}=\left(\mathrm{cos}{\theta}_{0}\mathrm{cos}{\theta}_{1}\mathrm{...}\mathrm{cos}{\theta}_{n}\right)R{x}_{N}\\ z={\displaystyle \sum _{0}^{N}{d}_{n}{\theta}_{n}}\end{array}$$

### Modified CORDIC Algorithm

The convergence region for the standard CORDIC rotation is ≈±99.7°. To work around this limitation, before doing any rotation, the object maps the input into the [0,π/4] range using the following algorithm.

if abs(x) > abs(y) input_mapped = [abs(x), abs(y)];else input_mapped = [abs(y), abs(x)];end

At each iteration, the object rotates the vector towards the real axis. The rotation is counterclockwise when *y* is negative, and clockwise when *y* is positive.

Quadrant mapping saves hardware resources and reduces latency by reducing the number of CORDIC pipeline stages by one. The CORDIC gain factor, *Kn*, therefore does not include the n=0, or cos(π/4) term.

$${K}_{n}=cos{\theta}_{1}\mathrm{...}\mathrm{cos}{\theta}_{n}=\text{cos}(26.565)\cdot \text{cos}(14.036)\cdot \text{cos}(7.125)\cdot \text{cos}(3.576)$$

After the CORDIC iterations are complete, the object corrects the angle back to its original location. First it adjusts the angle to the correct side of π/4.

if abs(x) > abs(y) angle_unmapped = CORDIC_out;else angle_unmapped = (pi/2) - CORDIC_out;end

Then it flips the angle to the original quadrant.

if (x < 0) if (y < 0) output_angle = - pi + angle_unmapped;e else output_angle = pi - angle_unmapped;else if (y<0) output_angle = -angle_unmapped;

### Architecture

The object generates a pipelined HDL architecture to maximize throughput. Each CORDIC iteration is done in one pipeline stage. The gain multiplier, if enabled, is implemented with Canonical Signed Digit (CSD) logic.

If you use vector input, this object replicates this architecture in parallel for each element of the vector.

Input Word Length | Output Magnitude Word Length |
---|---|

fixdt(0,WL,FL) | fixdt(0,WL+2,FL) |

fixdt(1,WL,FL) | fixdt(1,WL+1,FL) |

Input Word Length | Output Angle Word Length | |
---|---|---|

fixdt([ ],WL,FL) | Radians | fixdt(1,WL+3,WL) |

Normalized | fixdt(1,WL+3,WL+2) |

The CORDIC logic at each pipeline stage implements one iteration. For each pipeline stage, the shift and angle rotation are constants.

When you set `OutputFormat`

to `'Magnitude'`

, the object does not generate HDL code for the angle accumulation and quadrant correction logic.

### Normalized Angle Format

This format normalizes the fixed-point radian angle values around the unit circle. This is a more efficient use of bits than a range of [0,2π] radians. Normalized angle format also enables wraparound at 0/2π without additional detect and correct logic.

For example, representing the angle with 3 bits results in the following normalized values.

Using the mapping described in Modified CORDIC Algorithm, the object normalizes the angles across [0,π/4] and maps them to the correct octant at the end of the calculation.

### Delay

The latency is NumIterations + 4 cycles from input to output. Each call to the object models one clock cycle.

When you set NumIterationsSource to `'Auto'`

, the number of iterations is one less than the input word length and the latency is three more than the input word length. If the data type of the input is `double`

or `single`

, the number of iterations is 16 and the latency is 20.

**Note**

When you set the `ScalingMethod`

property to `'Multipliers'`

, the object latency increases by four cycles.

### Performance

Performance was measured for the default configuration, with output scaling disabled and `fixdt(1,16,12)`

input. When the generated HDL code is synthesized into a Xilinx^{®} ZC706 (XC7Z045FFG900-2) FPGA, the design achieves 350 MHz clock frequency. It uses the following resources.

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

LUT | 891 |

FFS | 899 |

Xilinx LogiCORE | 0 |

Block RAM (16K) | 0 |

Critical path | 2.792 ns |

When you use a multiplier for the CORDIC gain scaling, the design uses one DSP block and has a shorter critical path. The critical path difference is not significant at this number of bits, but as the size of the data increases, the critical path of the CSD implementation rises faster than the critical path of the multiplier.

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

LUT | 808 |

FFS | 956 |

Xilinx LogiCORE DSP48 | 1 |

Block RAM (16K) | 0 |

Critical path | 2.574 ns |

Performance of the synthesized HDL code varies depending on your target and synthesis options. When you use vector input, the resource usage is about *VectorSize* times the scalar resource usage.

## 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**

expand all

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

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

and was part of the DSP System Toolbox™ product.

### R2022a: Option to use multiplier for scale factor

In previous releases, the System object implemented the CORDIC gain for hardware by using shift-and-add logic. To use a multiplier, set the `ScalingMethod`

property to `'Multipliers'`

. To use shift-and-add logic, set this property to `'CSD'`

.

### R2021b: High-throughput interface

The System object accepts and returns a column vector of elements that represent samples in time. The input vector can contain up to 64 samples.

## See Also

### Blocks

- Complex to Magnitude-Angle

### Functions

- cordicangle | cordiccart2pol | cordicabs | angle

## 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:

### 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
- Deutsch
- English
- Français

- United Kingdom (English)

Contact your local office