Complex Multiply

I am trying to write a sunction for complex multiplication of 2 complex numbers

function complex_multiply(a : signed; b: signed; c : signed; d: signed) return signed; (a + bi)(c + di) = [ac - bd] + [ad + bc]i.

I am not sure on how I would return the real and imaginary part of the result. As per my understanding functions can return only one value. How do i represent the inputs and outputs? I want to write code in VHDL to be implemented on an FPGA.

Reply to
Ann
Loading thread data ...

Ann a écrit :

Hi Define your complex number as an array of two signed numbers

type complex is array(0 to 1) of signed(your_range);

function complex_multiply(a : complex; b : complex) return complex; (a(0) + a(1).i)(b(0) + b(0).i) = [a(0)b(0)-a(1)b(1)] + [a(0)b(1) + a(1)b(0)]i

You could even overload the '*' operator for type complex

Nicolas

Reply to
Nicolas Matringe

Define a new complex record type... type t_My_Complex_Type is record Real: signed; Imag: signed; end record;

Now your function would be defined as

function complex_multiply(a, b : t_My_Complex_Type) return t_My_Complex_Type is variable RetVal: t_My_Complex_Type; begin RetVal.Real :=3D a.real * b.real - a.imag * b.imag; RetVal.Imag :=3D a.real * b.imag + b.real * a.imag; return(RetVal); function complex_multiply;

If you're really feeling gutzy, you can instead call the function "*" (with the double quotes) and you'll be defining an override for the multiply operator so you could use your function like this...

C
Reply to
KJ

Right, that's cleaner (more readable) than my solution with an array.

Nicolas

Reply to
Nicolas Matringe

It gave me errors. The result would be twice as long as the lengths of a or b. So RetVal cannot be of type t_My_Complex_Type. I did the following and it is compiling fine.

type t_My_Complex_Type is record Real: signed(31 downto 0); Imag: signed(31 downto 0); end record;

type Result_Complex_Type is record Real: signed(63 downto 0); Imag: signed(63 downto 0); end record;

function complex_multiply(a, b : t_My_Complex_Type) return Result_Complex_Type is variable RetVal: Result_Complex_Type; begin RetVal.Real :=3D a.real * b.real - a.imag * b.imag; RetVal.Imag :=3D a.real * b.imag + b.real * a.imag; return(RetVal); end function complex_multiply;

How do i simulate this? What should be the type of a and b in the simulation file. Should they be 64 bit vectors each ?

Reply to
FPGA

Well it depends on just how much precision you think you need in the calculation. I'm guessing that 32 bits would've been enough. The range for each of the elements of the complex type should be made to be large enough to handle whatever range of complex numbers that you plan to be able to use. That being the case, all that is needed then is to strip off the lower bits of the result as shown below

RetVal.Real := (a.real * b.real - a.imag * b.imag)(a'range); RetVal.Imag := (a.real * b.imag + b.real * a.imag)(a'range);

a and b need to be whatever width you need them to be to give you whatever precision you need for your calculations. Whether that's 5 bits, 8 bits, 32 bits or something else I can't say since I don't know what precision you need for your application.

Kevin Jennings

Reply to
KJ

Note that you can save a multiplier: ac-bd = a(c-d) + d(a-b) ad+bc = b(c+d) + d(a-b) and if (c,d) is a constant, you can precompute (c-d) and (c+d).

Pontus

Reply to
pontus.stenstrom

Slight correction to previous post. Instead of

RetVal.Real := (a.real * b.real - a.imag * b.imag)(a'range); RetVal.Imag := (a.real * b.imag + b.real * a.imag)(a'range);

It should be

RetVal.Real := (a.real * b.real - a.imag * b.imag) (a.real'range); RetVal.Imag := (a.real * b.imag + b.real * a.imag) (a.imag'range);

KJ

Reply to
KJ

Thanks a bunch. I will try this out.

Reply to
Ann

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.