| Products & Services | Solutions | Academia | Support | User Community | Company |
| Download Product Updates | | | Get Pricing | | | Trial Software |
| Documentation → Simulink HDL Coder |
| Contents | Index |
| On this page… |
|---|
Conversion Between Complex and Real Signals Arithmetic Operations on Complex Numbers |
This section describes Embedded MATLAB Function block support for complex data types for HDL code generation. See also the eml_hdl_design_patterns library for numerous examples showing HDL related applications of complex arithmetic in Embedded MATLAB Function blocks.
The following Embedded MATLAB Function block code declares several local complex variables. x and y are declared by complex constant assignment; z is created using the using the complex() function.
function [x,y,z] = fcn % create 8 bit complex constants x = uint8(1 + 2i); y = uint8(3 + 4j); z = uint8(complex(5, 6));
The following code example shows VHDL code generated from the previous Embedded MATLAB Function block code.
ENTITY complex_decl IS
PORT (
clk : IN std_logic;
clk_enable : IN std_logic;
reset : IN std_logic;
x_re : OUT std_logic_vector(7 DOWNTO 0);
x_im : OUT std_logic_vector(7 DOWNTO 0);
y_re : OUT std_logic_vector(7 DOWNTO 0);
y_im : OUT std_logic_vector(7 DOWNTO 0);
z_re : OUT std_logic_vector(7 DOWNTO 0);
z_im : OUT std_logic_vector(7 DOWNTO 0));
END complex_decl;
ARCHITECTURE fsm_SFHDL OF complex_decl IS
BEGIN
x_re <= std_logic_vector(to_unsigned(1, 8));
x_im <= std_logic_vector(to_unsigned(2, 8));
y_re <= std_logic_vector(to_unsigned(3, 8));
y_im <= std_logic_vector(to_unsigned(4, 8));
z_re <= std_logic_vector(to_unsigned(5, 8));
z_im <= std_logic_vector(to_unsigned(6, 8));
END fsm_SFHDL;
As shown in the example, all complex inputs, outputs and local variables declared in Embedded MATLAB code expand into real and imaginary signals. The naming conventions for these derived signals are:
Real components have the same name as the original complex signal, suffixed with the default string '_re' (for example, x_re). To specify a different suffix, set the Complex real part postfix option (or the corresponding ComplexRealPostfix CLI property).
Imaginary components have the same name as the original complex signal, suffixed with the string '_im' (for example, x_im). To specify a different suffix, set the Complex imaginary part postfix option (or the corresponding ComplexImagPostfix CLI property).
A complex variable declared in an Embedded MATLAB Function block remains complex during the entire length of the program, following Embedded MATLAB Function block language rules.
The Embedded MATLAB Function block provides access to the fields of a complex signal via the real() and imag() functions, as shown in the following code.
function [Re_part, Im_part]= fcn(c) % Output real and imaginary parts of complex input signal Re_part = real(c); Im_part = imag(c);
The coder supports these constructs, accessing the corresponding real and imaginary signal components in generated HDL code. In the following Verilog code example, the Embedded MATLAB Function block complex signal variable c is flattened into the signals c_re and c_im. Each of these signals is assigned to the output variables Re_part and Im_part, respectively.
module Complex_To_Real_Imag (clk, clk_enable, reset, c_re, c_im, Re_part, Im_part );
input clk;
input clk_enable;
input reset;
input [3:0] c_re;
input [3:0] c_im;
output [3:0] Re_part;
output [3:0] Im_part;
// Output real and imaginary parts of complex input signal
assign Re_part = c_re;
assign Im_part = c_im;
When generating HDL code for the Embedded MATLAB Function Block, the coder supports the following arithmetic operators for complex numbers composed of all base types (integer, fixed-point, double):
Addition (+)
Subtraction (-)
Multiplication (*)
The coder supports division only for the Fixed-Point Toolbox divide function (see divide in the Fixed-Point Toolbox documentation). The divide function is supported only if the base type of both complex operands is fixed-point.
As shown in the following example, the default sum and product mode for fixed-point objects is FullPrecsion, and the CastBeforeSum property defaults to true.
fm = hdlfimath
fm =
RoundMode: floor
OverflowMode: wrap
ProductMode: FullPrecision
MaxProductWordLength: 128
SumMode: FullPrecision
MaxSumWordLength: 128
CastBeforeSum: trueGiven fixed-point operands, the coder follows full-precision cast before sum semantics. Each addition or subtraction increases the result width by one bit. Further casting is necessary to bring the results back to a smaller bit width.
In the following example function, two complex operands (with real and imaginary ufix4 components) are summed, with a complex result having real and imaginary ufix5 components. The result is then cast back to the original bit width.
function z = fcn(x, y) % addition of two complex numbers x,y of type 'ufix4' % x+y will have'ufix5' type z = x+y; % to cast the result back to 'ufix4' % z = fi(x + y, numerictype(x), fimath(x));
The following example shows VHDL code generated from this function.
ENTITY complex_add_entity IS
PORT (
clk : IN std_logic;
clk_enable : IN std_logic;
reset : IN std_logic;
x_re : IN std_logic_vector(3 DOWNTO 0);
x_im : IN std_logic_vector(3 DOWNTO 0);
y_re : IN std_logic_vector(3 DOWNTO 0);
y_im : IN std_logic_vector(3 DOWNTO 0);
z_re : OUT std_logic_vector(4 DOWNTO 0);
z_im : OUT std_logic_vector(4 DOWNTO 0));
END complex_add_entity;
ARCHITECTURE fsm_SFHDL OF complex_add_entity IS
BEGIN
-- addition of two complex numbers x,y of type 'ufix4'
-- x+y will have'ufix5' type
z_re <= std_logic_vector(resize(unsigned(x_re), 5) +
resize(unsigned(y_re), 5));
z_im <= std_logic_vector(resize(unsigned(x_im), 5) +
resize(unsigned(y_im), 5));
-- to cast the result back to 'ufix4' use
-- z = fi(x + y, numerictype(x), fimath(x));
END fsm_SFHDL;
Similarly, for the product operation in FullPrecision mode, the result bit width increases to the sum of the lengths of the individual operands. Further casting is necessary to bring the results back to a smaller bit width.
The following example function shows how the product of two complex operands (with real and imaginary ufix4 components) can be cast back to the original bit width.
function z = fcn(x, y) % Multiplication of two complex numbers x,y of type 'ufix4' % x*y will have'ufix8' type z = x * y; % to cast the result back to 'ufix4' % z = fi(x * y, numerictype(x), fimath(x));
The following example shows VHDL code generated from this function.
ENTITY complex_mul IS
PORT (
clk : IN std_logic;
clk_enable : IN std_logic;
reset : IN std_logic;
x_re : IN std_logic_vector(3 DOWNTO 0);
x_im : IN std_logic_vector(3 DOWNTO 0);
y_re : IN std_logic_vector(3 DOWNTO 0);
y_im : IN std_logic_vector(3 DOWNTO 0);
z_re : OUT std_logic_vector(8 DOWNTO 0);
z_im : OUT std_logic_vector(8 DOWNTO 0));
END complex_mul;
ARCHITECTURE fsm_SFHDL OF complex_mul IS
SIGNAL pr1 : unsigned(7 DOWNTO 0);
SIGNAL pr2 : unsigned(7 DOWNTO 0);
SIGNAL pr1in : unsigned(8 DOWNTO 0);
SIGNAL pr2in : unsigned(8 DOWNTO 0);
SIGNAL pre : unsigned(8 DOWNTO 0);
SIGNAL pi1 : unsigned(7 DOWNTO 0);
SIGNAL pi2 : unsigned(7 DOWNTO 0);
SIGNAL pi1in : unsigned(8 DOWNTO 0);
SIGNAL pi2in : unsigned(8 DOWNTO 0);
SIGNAL pim : unsigned(8 DOWNTO 0);
BEGIN
-- addition of two complex numbers x,y of type 'ufix4'
-- x*y will have'ufix8' type
pr1 <= unsigned(x_re) * unsigned(y_re);
pr2 <= unsigned(x_im) * unsigned(y_im);
pr1in <= resize(pr1, 9);
pr2in <= resize(pr2, 9);
pre <= pr1in - pr2in;
pi1 <= unsigned(x_re) * unsigned(y_im);
pi2 <= unsigned(x_im) * unsigned(y_re);
pi1in <= resize(pi1, 9);
pi2in <= resize(pi2, 9);
pim <= pi1in + pi2in;
z_re <= std_logic_vector(pre);
z_im <= std_logic_vector(pim);
-- to cast the result back to 'ufix4'
-- z = fi(x * y, numerictype(x), fimath(x));
END fsm_SFHDL;
Embedded MATLAB Function Block supports HDL code generation for vectors of complex numbers. Like scalar complex numbers, vectors of complex numbers are flattened down to vectors of real and imaginary parts in generated HDL code.
For example in the following script t is a complex vector variable of base type ufix4 and size [1,2].
function y = fcn(u1, u2) t = [u1 u2]; y = t+1;
In the generated HDL code the variable t is broken down into real and imaginary parts with the same two-element array. .
VARIABLE t_re : vector_of_unsigned4(0 TO 3); VARIABLE t_im : vector_of_unsigned4(0 TO 3);
The real and imaginary parts of the complex number have the same vector of type ufix4, as shown in the following code.
TYPE vector_of_unsigned4 IS ARRAY (NATURAL RANGE <>) OF unsigned(3 DOWNTO 0);
All complex vector-based operations (+,-,* etc.,) are similarly broken down to vectors of real and imaginary parts. Operations are performed independently on all the elements of such vectors, following Embedded MATLAB semantics for vectors of complex numbers.
In both VHDL and Verilog code generated for the Embedded MATLAB Function Block, complex vector ports are always flattened. If complex vector variables appear on inputs and outputs, real and imaginary vector components are further flattened to scalars.
In the following Embedded MATLAB Function Block code, u1 and u2 are scalar complex numbers and y is a vector of complex numbers.
function y = fcn(u1, u2) t = [u1 u2]; y = t+1;
This generates the following port declarations in a VHDL entity definition.
ENTITY Embedded_MATLAB_Function IS
PORT (
clk : IN std_logic;
clk_enable : IN std_logic;
reset : IN std_logic;
u1_re : IN vector_of_std_logic_vector4(0 TO 1);
u1_im : IN vector_of_std_logic_vector4(0 TO 1);
u2_re : IN vector_of_std_logic_vector4(0 TO 1);
u2_im : IN vector_of_std_logic_vector4(0 TO 1);
y_re : OUT vector_of_std_logic_vector32(0 TO 3);
y_im : OUT vector_of_std_logic_vector32(0 TO 3));
END Embedded_MATLAB_Function;The coder supports the following functions with complex operands:
complex
real
imag
conj
transpose
ctranspose
isnumeric
isreal
isscalar
The isreal function, which always returns 0 for complex numbers, is particularly useful for writing Embedded MATLAB algorithms that behave differently based on whether the input is a complex or real signal.
function y = fcn(u)
% output is same as input if 'u' is real
% output is conjugate of input if 'u' is complex
if isreal(u)
y = u;
else
y = conj(u);
end
For detailed information on these functions, see Supported Functions and Limitations of the Fixed-Point Embedded MATLAB Subset in the Fixed-Point Toolbox documentation.
![]() | Using Fixed-Point Bitwise Functions | Distributed Pipeline Insertion | ![]() |

Learn more about Simulink through this collection of videos, articles, technical literature and the Getting Started with Simulink Guide.
| © 1984-2009- The MathWorks, Inc. - Site Help - Patents - Trademarks - Privacy Policy - Preventing Piracy - RSS |