function exp(z: complex)

Z

Zhi

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.
 
A

Andy

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
 
J

Jonathan Bromley

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
(e-mail address removed)
http://www.MYCOMPANY.com

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

Jonathan Bromley

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
(e-mail address removed)
http://www.MYCOMPANY.com

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

Zhi

It is.


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


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
(e-mail address removed)://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.
 
Z

Zhi

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.
 
T

Tricky

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;
 
D

Duane Clark

Zhi said:
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.
 
Z

Zhi

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top