Complex Data Type Support

Declaring Complex Signals

The following MATLAB® 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 MATLAB 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, complex inputs, outputs and local variables declared in 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 MATLAB code remains complex during the entire length of the program.

Conversion Between Complex and Real Signals

The MATLAB code 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);

HDL Coder™ supports these constructs, accessing the corresponding real and imaginary signal components in generated HDL code. In the following Verilog® code example, the MATLAB 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;

Support for Vectors of Complex Numbers

You can generate HDL code 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);

Complex vector-based operations (+,-,* etc.,) are similarly broken down to vectors of real and imaginary parts. Operations are performed independently on the elements of such vectors, following MATLAB semantics for vectors of complex numbers.

In both VHDL and Verilog code generated from MATLAB code, 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 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 _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 _MATLAB_Function;