Electrical – How to divide complex number in VHDL

arithmetic-divisionvhdlxilinx

I know how to divide numbers in VHDL (or using one of the Xilinx IP core generators) but I do not know how to do it in the case the numbers are complex.

In my case I have defined a complex number as this:

type complex12 is record
    re  : std_logic_vector (11 downto 0);
    im  : std_logic_vector (11 downto 0);
end record;

So my complex number it is just two vectors of 12 bits, one for the real part an other for the imaginary part.

Let say that now I have a and b complex numbers:

signal A : complex12 := (re => (others=>'0'), im => (others=>'0'));
signal B : complex12 := (re => (others=>'0'), im => (others=>'0'));

I know that the theory for dividing to complex numbers tell us two approaches for doing a division:

$$
c = \frac{a_r + j\cdot a_i}{b_r + j\cdot b_i} = \frac{(a_r + j\cdot a_i) \cdot (b_r – j\cdot b_i)}{b_r^2 + b_i^2}
$$

Alternatively:
$$
c = \frac{|a|}{|b|} \cdot e^{j (\angle a – \angle b)}
$$

But both approaches seem very difficult to implement in VHDL. What would be the preferred approach? Is there an easy way to divide complex numbers? Is there any Xilinx block that can save the day? I am bit lost on how to approach this.

Best Answer

You've got the right idea with that first equation. You've just got to do some more algebra:

$$ c = \frac{a_r + j a_i}{b_r + j b_i} = \frac{(a_r + j a_i) (b_r - j b_i)}{b_r^2 + b_i^2} $$

$$ c = \frac{a_r b_r + a_i b_i + j a_i b_r - j a_r b_i}{b_r^2 + b_i^2} $$

$$ c = \frac{(a_r b_r + a_i b_i) + j (a_i b_r - a_r b_i)}{b_r^2 + b_i^2} $$

$$ c = \frac{a_r b_r + a_i b_i}{b_r^2 + b_i^2} + j \frac{a_i b_r - a_r b_i}{b_r^2 + b_i^2} $$

Yes, there are a lot of operations required. Looks like 6 multiplies, two additions, one subtraction, and two divisions. Yes, implementing this in Verilog/VHDL will be rather complex. If you don't need maximum throughput, then you can probably get away with one multiplier and one divider and then sequence the operations with a state machine. Compute the denominator first, store it, then do the numerators, computing the second one while the divider is working on the real part of the output.