# function exp(z: complex)

Discussion in 'VHDL' started by Zhi, Sep 4, 2007.

1. ### ZhiGuest

I want to use the function exp(z: complex). And I added the
IEEE.MATH_COMPLEX.ALL. Firstly, I don't know how to use the function
if the the type of 'z' is complex. Shall I write it like
'exp(0.0,2.0)' to represent the expression exp(2j)? And even though I
added the MATH_COMPLEX package, there is error information 'No
feasible entries for subprogram "exp"'. What is the problemï¼Ÿ
I also saw another MATH_COMPLEX package ver. The function for the
complex exponential is 'CEXP'. I am a little confused about the
different function name.

Zhi, Sep 4, 2007

2. ### AndyGuest

On Sep 4, 3:16 pm, Zhi <> wrote:
> I want to use the function exp(z: complex). And I added the
> IEEE.MATH_COMPLEX.ALL. Firstly, I don't know how to use the function
> if the the type of 'z' is complex. Shall I write it like
> 'exp(0.0,2.0)' to represent the expression exp(2j)? And even though I
> added the MATH_COMPLEX package, there is error information 'No
> feasible entries for subprogram "exp"'. What is the problemï¼Ÿ
> I also saw another MATH_COMPLEX package ver. The function for the
> complex exponential is 'CEXP'. I am a little confused about the
> different function name.

The complex type should be defined in the same package.

Just guessing, but exp((0.0, 2.0)) is probably what you want. (one
argument that is an aggregate, not two arguments)

You may have to give it a hint: exp(complex(0.0, 2.0))

Andy

Andy, Sep 4, 2007

3. ### Jonathan BromleyGuest

On Tue, 04 Sep 2007 13:16:16 -0700, Zhi <>
wrote:

>I want to use the function exp(z: complex). And I added the
>IEEE.MATH_COMPLEX.ALL. Firstly, I don't know how to use the function
>if the the type of 'z' is complex. Shall I write it like
>'exp(0.0,2.0)' to represent the expression exp(2j)?

The prototype of EXP() is

function EXP(Z: in COMPLEX ) return COMPLEX;

and the definition of data type COMPLEX is

type COMPLEX is
record
RE: REAL; -- Real part
IM: REAL; -- Imaginary part
end record;

So it seems that you wish to write a constant of
type COMPLEX. You do so like this...

COMPLEX'(0.0, 2.0)

So your function call should look like

EXP( COMPLEX'(0.0, 2.0) )

but of course the function's result is also of type COMPLEX,
so you probably need a COMPLEX variable to store it:

variable exp2j: complex;
...
exp2j := EXP( COMPLEX'(0.0, 2.0) );
...

Note that there are also some useful predefined
constants in MATH_COMPLEX:

MATH_CBASE_1 = COMPLEX'(1.0, 0.0) -- 1+0j
MATH_CBASE_J = COMPLEX'(0.0, 1,0) -- 0+1j
MATH_CZERO = COMPLEX'(0.0, 0.0) -- 0+0j

and all the obvious sensible arithmetic operations
are supported, so you could also write

exp2j := EXP( 2.0 * MATH_CBASE_J );

hth
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK

http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.

Jonathan Bromley, Sep 4, 2007
4. ### Jonathan BromleyGuest

On Tue, 04 Sep 2007 13:33:06 -0700, Andy <>
wrote:

>The complex type should be defined in the same package.

It is.

>Just guessing, but exp((0.0, 2.0)) is probably what you want. (one
>argument that is an aggregate, not two arguments)

Yes, but it's ambiguous because there is also a COMPLEX_POLAR
type, and EXP is defined over that too.

>You may have to give it a hint: exp(complex(0.0, 2.0))

nope, it needs a type qualification - see my other post.
The conversion can't work because the aggregate is still
ambiguous.
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK

http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.

Jonathan Bromley, Sep 4, 2007
5. ### ZhiGuest

On 4 Sep, 21:40, Jonathan Bromley <>
wrote:
> On Tue, 04 Sep 2007 13:33:06 -0700, Andy <>
> wrote:
>
> >The complex type should be defined in the same package.

>
> It is.
>
> >Just guessing, but exp((0.0, 2.0)) is probably what you want. (one
> >argument that is an aggregate, not two arguments)

>
> Yes, but it's ambiguous because there is also a COMPLEX_POLAR
> type, and EXP is defined over that too.
>
> >You may have to give it a hint: exp(complex(0.0, 2.0))

>
> nope, it needs a type qualification - see my other post.
> The conversion can't work because the aggregate is still
> ambiguous.
> --
> Jonathan Bromley, Consultant
>
> DOULOS - Developing Design Know-how
> VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services
>
> Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
> ://www.MYCOMPANY.com
>
> The contents of this message may contain personal views which
> are not the views of Doulos Ltd., unless specifically stated.

Thanks Jonathan Bromley and Andy. My problem is solved.

Zhi, Sep 5, 2007
6. ### ZhiGuest

I pop-up again, sorry.
The problem is not easy as what I expected. Now I want to ask about
the EXP function implementation skills in FPGA board. I've known that
FPGA board only deals with the fixed point values. If my design needs
the result of EXP as temparary coefficient for the
other caculation. How to deals with the floating things then? I used
to manage the simple floating problem to fixed point value, e.g 2**{-
A}, A is an integer. I don't know how to convert the 'e**' to the
fixed point value. Any body has been experienced the simlar thing to
design EXP implementation? Please give me some tip on this. Thank you
very much.

Zhi, Sep 5, 2007
7. ### TrickyGuest

On Sep 5, 12:16 pm, Zhi <> wrote:
> I pop-up again, sorry.
> The problem is not easy as what I expected. Now I want to ask about
> the EXP function implementation skills in FPGA board. I've known that
> FPGA board only deals with the fixed point values. If my design needs
> the result of EXP as temparary coefficient for the
> other caculation. How to deals with the floating things then? I used
> to manage the simple floating problem to fixed point value, e.g 2**{-
> A}, A is an integer. I don't know how to convert the 'e**' to the
> fixed point value. Any body has been experienced the simlar thing to
> design EXP implementation? Please give me some tip on this. Thank you
> very much.

Unfortunatly, pretty much everything from the math_real and
math_complex are completly unsynthesizable. You should NOT use them in
FPGA designs because they will NOT work. They are only there for
system modelling and testbenching. They can only be used for generics
to set up your design, Otherwise they need converting to fixed point
values.

If you are handling floating point numbers, you may have to find
floating point libraries that use std_logic_vectors in the standard
32/64 bit IEEE float standard. I know Xilinx offer floating point
libraries (developed by QinetiQ) that include things likefloating
point adder/multiplier/divider/square root etc. Handing of floating
point in VHDL is non trivial in synthesizable designs.

You will have to stick with fixed point values throughout the design.

I have a function that converts reals to slv's, but these must be
elaborated as setup parameters only and cannot be used inside a
functioning design:

--casts a real to an integer, with or without rounding
function real_to_int( x : real; round : boolean := false) return
integer is
variable ret : integer;
variable temp : integer;
begin
if round then
ret := integer(x);
else
temp := integer(x);

--always round towards 0
if temp >= 0 then
--rounds positive numbers down
if real(temp) > x then
ret := temp - 1;
else
ret := temp;
end if;
else
--rounds -ve numbers up
if real(temp) < x then
ret := temp + 1;
else
ret := temp;
end if;
end if;
end if;

return ret;
end function;

function real_to_slv(x : real; m, f : natural; s, round : boolean :=
false ) return std_logic_vector is

variable ret_slv : std_logic_vector(m+f-1 downto 0);
variable size_int : integer := 1;
begin

--this loop determins the multiplcation that happens on the real
number, to give it a meaningful value in an integer range
size_loop : for i in 0 to f-1 loop --extra loop to account for
size_int starting at 1
size_int := size_int * 2;
end loop;

--real to integer conversion
if s then
ret_slv := std_logic_vector(to_signed( real_to_int( x *
real(size_int), round) , ret_slv'length));
else
ret_slv := std_logic_vector(to_unsigned( abs( real_to_int( x *
real(size_int), round )) , ret_slv'length));
end if;

return ret_slv;
end function real_to_slv;

Tricky, Sep 5, 2007
8. ### Duane ClarkGuest

Zhi wrote:
> I pop-up again, sorry.
> The problem is not easy as what I expected. Now I want to ask about
> the EXP function implementation skills in FPGA board. I've known that
> FPGA board only deals with the fixed point values. If my design needs
> the result of EXP as temparary coefficient for the
> other caculation. How to deals with the floating things then? I used
> to manage the simple floating problem to fixed point value, e.g 2**{-
> A}, A is an integer. I don't know how to convert the 'e**' to the
> fixed point value. Any body has been experienced the simlar thing to
> design EXP implementation? Please give me some tip on this. Thank you
> very much.

e**a can be computed with a cordic function. Or if the range of the
fixed point values is limited, it could be computed with a lookup table.
Or you could use a lookup table, and do a linear interpolation between
the lookup values.

Duane Clark, Sep 5, 2007
9. ### ZhiGuest

On 5 Sep, 15:01, Tricky <> wrote:
> On Sep 5, 12:16 pm, Zhi <> wrote:
>
> > I pop-up again, sorry.
> > The problem is not easy as what I expected. Now I want to ask about
> > the EXP function implementation skills in FPGA board. I've known that
> > FPGA board only deals with the fixed point values. If my design needs
> > the result of EXP as temparary coefficient for the
> > other caculation. How to deals with the floating things then? I used
> > to manage the simple floating problem to fixed point value, e.g 2**{-
> > A}, A is an integer. I don't know how to convert the 'e**' to the
> > fixed point value. Any body has been experienced the simlar thing to
> > design EXP implementation? Please give me some tip on this. Thank you
> > very much.

>
> Unfortunatly, pretty much everything from the math_real and
> math_complex are completly unsynthesizable. You should NOT use them in
> FPGA designs because they will NOT work. They are only there for
> system modelling and testbenching. They can only be used for generics
> to set up your design, Otherwise they need converting to fixed point
> values.
>
> If you are handling floating point numbers, you may have to find
> floating point libraries that use std_logic_vectors in the standard
> 32/64 bit IEEE float standard. I know Xilinx offer floating point
> libraries (developed by QinetiQ) that include things likefloating
> point adder/multiplier/divider/square root etc. Handing of floating
> point in VHDL is non trivial in synthesizable designs.
>
> You will have to stick with fixed point values throughout the design.
>
> I have a function that converts reals to slv's, but these must be
> elaborated as setup parameters only and cannot be used inside a
> functioning design:
>
> --casts a real to an integer, with or without rounding
> function real_to_int( x : real; round : boolean := false) return
> integer is
> variable ret : integer;
> variable temp : integer;
> begin
> if round then
> ret := integer(x);
> else
> temp := integer(x);
>
> --always round towards 0
> if temp >= 0 then
> --rounds positive numbers down
> if real(temp) > x then
> ret := temp - 1;
> else
> ret := temp;
> end if;
> else
> --rounds -ve numbers up
> if real(temp) < x then
> ret := temp + 1;
> else
> ret := temp;
> end if;
> end if;
> end if;
>
> return ret;
> end function;
>
> function real_to_slv(x : real; m, f : natural; s, round : boolean :=
> false ) return std_logic_vector is
>
> variable ret_slv : std_logic_vector(m+f-1 downto 0);
> variable size_int : integer := 1;
> begin
>
> --this loop determins the multiplcation that happens on the real
> number, to give it a meaningful value in an integer range
> size_loop : for i in 0 to f-1 loop --extra loop to account for
> size_int starting at 1
> size_int := size_int * 2;
> end loop;
>
> --real to integer conversion
> if s then
> ret_slv := std_logic_vector(to_signed( real_to_int( x *
> real(size_int), round) , ret_slv'length));
> else
> ret_slv := std_logic_vector(to_unsigned( abs( real_to_int( x *
> real(size_int), round )) , ret_slv'length));
> end if;
>
> return ret_slv;
> end function real_to_slv;

Thanks. It is really tough to implement it into board.

Zhi, Sep 5, 2007