# Complex Multiplier Examples (VHDL) - 2022.1 English

## Vivado Design Suite User Guide: Synthesis (UG901)

Document ID
UG901
Release Date
2022-06-06
Version
2022.1 English

Fully pipelined complex multiplier using three DSP blocks.

Filename: cmult.vhd

-- Complex Multiplier (pr+i.pi) = (ar+i.ai)*(br+i.bi)

--

--

-- cumult.vhd

--

library ieee;

use ieee.std_logic_1164.all;

use ieee.numeric_std.all;

entity cmult is

generic(AWIDTH : natural := 16;

BWIDTH : natural := 16);

port(clk    : in  std_logic;

ar, ai : in  std_logic_vector(AWIDTH - 1 downto 0);

br, bi : in  std_logic_vector(BWIDTH - 1 downto 0);

pr, pi : out std_logic_vector(AWIDTH + BWIDTH downto 0));

end cmult;

architecture rtl of cmult is

signal ai_d, ai_dd, ai_ddd, ai_dddd             : signed(AWIDTH - 1 downto 0);

signal ar_d, ar_dd, ar_ddd, ar_dddd             : signed(AWIDTH - 1 downto 0);

signal bi_d, bi_dd, bi_ddd, br_d, br_dd, br_ddd : signed(BWIDTH - 1 downto 0);

signal addcommon                                : signed(AWIDTH downto 0);

signal addr, addi                               : signed(BWIDTH downto 0);

signal mult0, multr, multi, pr_int, pi_int      : signed(AWIDTH + BWIDTH downto 0);

signal common, commonr1, commonr2               : signed(AWIDTH + BWIDTH downto 0);

begin

process(clk)

begin

if rising_edge(clk) then

ar_d   <= signed(ar);

ar_dd  <= signed(ar_d);

ai_d   <= signed(ai);

ai_dd  <= signed(ai_d);

br_d   <= signed(br);

br_dd  <= signed(br_d);

br_ddd <= signed(br_dd);

bi_d   <= signed(bi);

bi_dd  <= signed(bi_d);

bi_ddd <= signed(bi_dd);

end if;

end process;

-- Common factor (ar - ai) x bi, shared for the calculations

-- of the real and imaginary final products.

--

process(clk)

begin

if rising_edge(clk) then

addcommon <= resize(ar_d, AWIDTH + 1) - resize(ai_d, AWIDTH + 1);

mult0     <= addcommon * bi_dd;

common    <= mult0;

end if;

end process;

-- Real product

--

process(clk)

begin

if rising_edge(clk) then

ar_ddd   <= ar_dd;

ar_dddd  <= ar_ddd;

addr     <= resize(br_ddd, BWIDTH + 1) - resize(bi_ddd, BWIDTH + 1);

multr    <= addr * ar_dddd;

commonr1 <= common;

pr_int   <= multr + commonr1;

end if;

end process;

-- Imaginary product

--

process(clk)

begin

if rising_edge(clk) then

ai_ddd   <= ai_dd;

ai_dddd  <= ai_ddd;

addi     <= resize(br_ddd, BWIDTH + 1) + resize(bi_ddd, BWIDTH + 1);

multi    <= addi * ai_dddd;

commonr2 <= common;

pi_int   <= multi + commonr2;

end if;

end process;

--

-- VHDL type conversion for output

--

pr <= std_logic_vector(pr_int);

pi <= std_logic_vector(pi_int);

end rtl;