Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ---------------------------------------------------------------------------------------------------------------------------
- --------------------------------------------- Complex multiplication module. ----------------------------------------------
- -- This is part of 64-P FFT project. This module performs the multiplication of two complex numbers and generates both
- -- the real and imaginary components of the result. The module utilizes a pipelined approach to efficiently compute
- -- the result.
- ----------------------------------------------------------------------------------------------------------------------------
- -- Complex multiply module
- -- (real_a + i imag_a) * (real_b + i imag_b) =
- -- = real_a * real_b + i*i * (image_a * imag_b) + i * (real_a * imag_b) + i * (imag_a * real_b) =
- -- = real_a * real_b - (imag_a * imag_b) + i * (real_a * imag_b + imag_a * real_b)
- ----------------------------------------------------------------------------------
- -- Two complex number multiplication:
- -- https://www.geeksforgeeks.org/product-of-complex-numbers-using-three-multiplication-operation/
- --(a + i b)*(c +id) = real ac -bd +
- --imag ad + cb + ac -ac + bd -bd = a(d+c) +b(d+c) -ac -bd = (a+b) * (d+c) - (a*c + b*d)
- -- prod1 = a * c;
- -- prod2 = b * d;
- -- prod3 = (a + b) * (c + d);
- -- real = prod1 - prod2;
- -- imag = prod3 - (prod1 + prod2);
- -- Last changes: 20.07.23.
- ----------------------------------------------------------------------------------
- library IEEE;
- use IEEE.STD_LOGIC_1164.ALL;
- use IEEE.STD_LOGIC_SIGNED.ALL;
- entity complex_mult is
- generic (
- DW1 : integer :=16; -- for A
- DW2 : integer :=17 -- for B
- );
- Port (
- clk : in std_logic;
- -- reset : in std_logic;
- data_in_valid : in std_logic;
- a_real_in : in std_logic_vector(DW1-1 downto 0); -- from Butterfly
- a_imag_in : in std_logic_vector(DW1-1 downto 0); -- from Butterfly
- b_real_in : in std_logic_vector(DW2-1 downto 0); -- from Twiddle
- b_imag_in : in std_logic_vector(DW2-1 downto 0); -- from Twiddle
- real_out : out std_logic_vector((DW1+DW2) downto 0); -- 33 bits
- imag_out : out std_logic_vector((DW1+DW2) downto 0); -- 33 bits
- data_out_valid : out std_logic
- );
- end complex_mult;
- architecture Behavioral of complex_mult is
- signal prod1 : std_logic_vector((DW1+DW2)-1 downto 0); -- 32 bits
- signal prod2 : std_logic_vector((DW1+DW2)-1 downto 0); -- 32 bits
- signal prod1_d : std_logic_vector((DW1+DW2)-1 downto 0); --32 bits
- signal prod2_d : std_logic_vector((DW1+DW2)-1 downto 0); -- 32 bits
- signal prod3_sum_ab : std_logic_vector((DW1) downto 0); -- 17 bits
- signal prod3_sum_cd : std_logic_vector((DW2) downto 0); -- 18 bits
- signal prod3 : std_logic_vector((DW1+DW2)+1 downto 0); -- 34 bits
- signal imag_sum : std_logic_vector((DW1+DW2) downto 0); -- 33 bits
- signal imag_out_int : std_logic_vector((DW1+DW2+2) downto 0); -- 35 bits
- signal data_valid_st1: std_logic :='0';
- signal data_valid_st2: std_logic :='0';
- signal data_valid_st3: std_logic :='0';
- begin
- ---- stage 1 ------------------
- -- Stage 1 calculates prod1, prod2 and part of prod3
- -- prod1 = a * c
- -- prod2 = b * d
- process(clk)
- begin
- if (clk = '1' and clk'event) then
- data_valid_st1 <= data_in_valid;
- if (data_in_valid = '1') then
- prod1 <= a_real_in * b_real_in;
- prod2 <= a_imag_in * b_imag_in;
- prod3_sum_ab(DW1 downto 0) <= (a_real_in(DW1-1 downto DW1-1) & a_real_in(DW1-1 downto 0)) + (a_imag_in(DW1-1 downto DW1-1) & a_imag_in(DW1-1 downto 0));
- prod3_sum_cd(DW2 downto 0) <= (b_real_in(DW2-1 downto DW2-1) & b_real_in(DW2-1 downto 0)) + (b_imag_in(DW2-1 downto DW2-1) & b_imag_in(DW2-1 downto 0));
- end if;
- data_valid_st2 <= data_valid_st1;
- if (data_valid_st1 = '1') then
- prod3 <= prod3_sum_ab * prod3_sum_cd;
- prod1_d <= prod1;
- prod2_d <= prod2;
- imag_sum(DW1+DW2 downto 0) <= (prod1(DW1+DW2-1 downto DW1+DW2-1) & prod1(DW1+DW2-1 downto 0)) + (prod2(DW1+DW2-1 downto DW1+DW2-1) & prod2(DW1+DW2-1 downto 0));
- end if;
- data_out_valid <= data_valid_st2;
- if (data_valid_st2 = '1') then
- real_out(DW1+DW2 downto 0) <= (prod1_d(DW1+DW2-1 downto DW1+DW2-1) & prod1_d(DW1+DW2-1 downto 0)) - (prod2_D(DW1+DW2-1 downto DW1+DW2-1) & prod2_d(DW1+DW2-1 downto 0));
- imag_out_int(DW1+DW2+2 downto 0) <= (prod3(DW1+DW2+1 downto DW1+DW2+1) & prod3(DW1+DW2+1 downto 0)) - (imag_sum(DW1+DW2 downto DW1+DW2) & imag_sum(DW1+DW2 downto DW1+DW2) & imag_sum(DW1+DW2 downto 0)); --imag_out = (a_real_in * b_imag_in) + (a_imag_in * b_real_in)
- end if;
- end if;
- end process;
- imag_out(DW1+DW2 downto 0) <= imag_out_int(DW1+DW2 downto 0);
- end Behavioral;
- --------------------------- OLD CODE. Uses two cycles and four multipliers--------------------------------
- --library IEEE;
- --use IEEE.STD_LOGIC_1164.ALL;
- --use IEEE.STD_LOGIC_SIGNED.ALL;
- --entity complex_mult is
- -- generic (
- -- DW1 : integer :=16; -- for input data width
- -- DW2 : integer :=17 -- for output data width
- -- );
- -- Port (
- -- clk : in std_logic;
- -- reset : in std_logic;
- -- data_in_valid : in std_logic;
- -- a_real_in : in std_logic_vector(DW1-1 downto 0);
- -- a_imag_in : in std_logic_vector(DW1-1 downto 0);
- -- b_real_in : in std_logic_vector(DW2-1 downto 0);
- -- b_imag_in : in std_logic_vector(DW2-1 downto 0);
- -- real_out : out std_logic_vector((DW1+DW2) downto 0); -- 33 bits
- -- imag_out : out std_logic_vector((DW1+DW2) downto 0); -- 33 bits
- -- data_out_valid : out std_logic
- -- );
- --end complex_mult;
- --architecture Behavioral of complex_mult is
- ---- multiplication intermediate results
- --signal mul_rr : std_logic_vector((DW1+DW2)-1 downto 0); -- a_real * a_real
- --signal mul_ii : std_logic_vector((DW1+DW2)-1 downto 0); -- b_real * b_real
- --signal mul_ri : std_logic_vector((DW1+DW2)-1 downto 0); -- a_real * b_imag
- --signal mul_ir : std_logic_vector((DW1+DW2)-1 downto 0); -- a_imag * b_real
- --signal data_valid_mul: std_logic;
- --begin
- --process(clk, reset)
- --begin
- -- if (reset = '1') then
- -- mul_rr <= (others => '0');
- -- mul_ii <= (others => '0');
- -- mul_ri <= (others => '0');
- -- mul_ir <= (others => '0');
- -- data_valid_mul <= '0';
- -- elsif (clk = '1' and clk'event) then
- -- data_valid_mul <= data_in_valid;
- -- if (data_in_valid = '1') then
- -- mul_rr <= a_real_in * b_real_in;
- -- mul_ii <= a_imag_in * b_imag_in;
- -- mul_ri <= a_real_in * b_imag_in;
- -- mul_ir <= a_imag_in * b_real_in;
- -- else
- -- mul_rr <= (others => '0');
- -- mul_ii <= (others => '0');
- -- mul_ri <= (others => '0');
- -- mul_ir <= (others => '0');
- -- end if;
- -- end if;
- --end process;
- --process(clk, reset)
- --begin
- -- if (reset = '1') then
- -- real_out <= (others => '0');
- -- imag_out <= (others => '0');
- -- data_out_valid <= '0';
- -- elsif (clk = '1' and clk'event) then
- -- data_out_valid <= data_valid_mul;
- -- if (data_valid_mul = '1') then
- -- real_out <= (mul_rr(DW1+DW2-1)&mul_rr) - (mul_ii(DW1+DW2-1)&mul_ii); --real_out = (a_real_in * b_real_in) - (a_imag_in * b_imag_in)
- -- imag_out <= (mul_ri(DW1+DW2-1)&mul_ri) + (mul_ir(DW1+DW2-1)&mul_ir); --imag_out = (a_real_in * b_imag_in) + (a_imag_in * b_real_in)
- -- else
- -- real_out <= (others => '0');
- -- imag_out <= (others => '0');
- -- end if;
- -- end if;
- --end process;
- --end Behavioral;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement