Compute magnitude and phase angle of complex signal – optimized for HDL code generation using the CORDIC algorithm
DSP System Toolbox HDL Support / Math Functions
The Complex to Magnitude-Angle HDL Optimized block computes the magnitude and phase angle of a complex signal and provides hardware-friendly control signals. To achieve an efficient HDL implementation, the block uses a pipelined Coordinate Rotation Digital Computer (CORDIC) algorithm.
You can use this block to implement operations such as atan2
in hardware.
dataIn
— Complex input signalComplex 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 block implements the conversion logic in parallel for each element of the vector. The input vector can contain up to 64 elements.
double
and single
data
types are supported for simulation, but not for HDL code generation.
Data Types: single
| double
| int8
| int16
| int32
| int64
| uint8
| uint16
| uint32
| uint64
| fixed point
validIn
— Validity of input dataBoolean
scalarWhen validIn is true
, the block captures
the data from the dataIn input port. The
validIn signal applies to all samples in a vector input
signal.
Data Types: Boolean
Magnitude
— Magnitude of the input signalMagnitude of the input signal, returned as a scalar, a column vector representing samples in time, or a row vector representing channels. The dimensions of this port match the dimensions of the dataIn port.
To enable this port, set the Output format parameter to
Magnitude and Angle
or Magnitude
.
Data Types: single
| double
| int8
| int16
| int32
| int64
| uint8
| uint16
| uint32
| uint64
| fixdt([],N,0)
Angle
— Angle of the input signalAngle of the input signal, returned as a scalar, a column vector representing samples in time, or a row vector representing channels. The dimensions of this port match the dimensions of the dataIn port.
To enable this port, set the Output format parameter to
Magnitude and Angle
or Angle
.
Data Types: single
| double
| int8
| int16
| int32
| int64
| uint8
| uint16
| uint32
| uint64
| fixdt([],N,0)
validOut
— Validity of output dataBoolean
scalarThe block sets validOut to true
with each
valid data returned on the Magnitude or
Angle output ports. The validOut signal
applies to all samples in a vector output signal.
Data Types: Boolean
Number of iterations source
— Source of number of iterationsAuto
(default) | Property
To set the number of iterations to input WL − 1, select
Auto
. If the input is of data type double
or
single
, the number of iterations is set to 16, by
default.
To specify the number of iterations by using Number of
iterations parameter, select Property
.
Number of iterations
— Number of CORDIC iterationsThe number of iterations must be less than or equal to input WL − 1. The latency of the block depends on the number of iterations performed. For information about latency, see Latency.
To enable this parameter, set Number of iterations source to
Property
.
Output format
— Output signal formatMagnitude and Angle
(default) | Magnitude
| Angle
Use this parameter to specify which output ports are enabled.
To enable the Magnitude and Angle
output ports, select Magnitude and Angle
(default).
To enable the Magnitude output port and disable the
Angle output port, select
Magnitude
.
To enable the Angle output port and disable the
Magnitude output port, select Angle
.
Angle format
— Output angle formatNormalized
(default) | Radians
To return the Angle output as a fixed-point value that
normalizes the angles in the range [–1,1], select Normalized
. For
more information see Normalized Angle Format.
To return the Angle output as a fixed-point value in the
range [-π, π], select Radians
. When using this block to implement
the atan2
function, set this parameter to
Radians
.
Scale output
— Scales outputon
(default) | off
Select this parameter to multiply the Angle output by the inverse of the CORDIC gain factor.
Note
If you clear this parameter and apply the CORDIC gain elsewhere in your design, you must exclude the π/4 term. Because the quadrant mapping algorithm replaces the first CORDIC iteration by mapping inputs onto the angle range [0, π/4], the initial rotation does not contribute a gain term.
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 block uses CORDIC vectoring mode to iteratively rotate the input onto the real axis.
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.
For a hardware implementation, factor out the cosθ to leave a tanθ term.
To rotate the vector onto the real axis, choose a series of rotations of θn so that . Remove the cosθ term so each iterative rotation uses only shift and add operations.
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.
The convergence region for the standard CORDIC rotation is ≈±99.7°. To work around this limitation, before doing any rotation, the block maps the input into the [0, π/4] range using this algorithm.
if abs(x) > abs(y) input_mapped = [abs(x), abs(y)]; else input_mapped = [abs(y), abs(x)]; end
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.
After the CORDIC iterations are complete, the block adjusts 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
if (x < 0) if (y < 0) output_angle = - pi + angle_unmapped; else output_angle = pi - angle_unmapped; else if (y<0) output_angle = -angle_unmapped;
The block 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 block replicates this architecture in parallel for each element of the vector.
The following table shows Magnitude and Angle output word length (WL), for particular input word length (WL). FL stands for fractional length used in fixed-point representation.
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 Output format to Magnitude
,
the block does not generate HDL code for the angle accumulation and quadrant correction
logic.
This format normalizes the fixed-point radian angle values around the unit circle. This use of bits can be more efficient than the use of the range [0, 2π] radians. Also this normalized angle format enables wraparound of angle at 0 or 2π without additional detect and correct logic.
For example, representing the angle with 3 bits results in these normalized values.
The block normalizes the angles across [0, π/4] and maps them to the correct octant at the end of the calculation.
When the valid input is applied, the valid output comes after Number of iterations + 4 cycles.
When you set the Number of iterations source parameter to
Property
, the block shows the latency immediately. When you set
Number of iterations source to Auto
, the block
calculates the latency based on the input port data type and displays the latency when you
update the model.
When you set the Number of iterations source parameter to
Auto
, the number of iterations is input WL − 1, and
the latency is input WL + 3. If the input is of data type
double
or single
, the number of iterations is 16,
and the latency is 20.
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®
Virtex®-6 (XC6VLX240T-1FFG1156) FPGA, the design achieves 260 MHz clock frequency. It
uses the following resources.
Resource | Number Used |
---|---|
LUT | 882 |
FFS | 792 |
Xilinx LogiCORE® DSP48 | 0 |
Block RAM (16K) | 0 |
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.
This block supports C/C++ code generation for Simulink® accelerator and rapid accelerator modes and for DPI component generation.
HDL Coder™ provides additional configuration option that affect HDL implementation and synthesized logic.
This block has a single, default HDL architecture.
ConstrainedOutputPipeline | Number of registers to place at
the outputs by moving existing delays within your design. Distributed
pipelining does not redistribute these registers. The default is
|
InputPipeline | Number of input pipeline stages
to insert in the generated code. Distributed pipelining and constrained
output pipelining can move these registers. The default is
|
OutputPipeline | Number of output pipeline stages
to insert in the generated code. Distributed pipelining and constrained
output pipelining can move these registers. The default is
|
This block supports code generation for complex signals.
atan2
| dsp.HDLComplexToMagnitudeAngle
| Complex to Magnitude-Angle (Simulink)