Advertisement
Eifel

ComplexMult

Mar 14th, 2024
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
VHDL 7.60 KB | None | 0 0
  1. ---------------------------------------------------------------------------------------------------------------------------
  2. --------------------------------------------- Complex multiplication module. ----------------------------------------------
  3. -- This is part of 64-P FFT project.  This module performs the multiplication of two complex numbers and generates both
  4. -- the real and imaginary components of the result. The module utilizes a pipelined approach to efficiently compute
  5. -- the result.
  6. ----------------------------------------------------------------------------------------------------------------------------
  7. -- Complex multiply module
  8. -- (real_a + i imag_a) * (real_b + i imag_b) =
  9. -- = real_a * real_b + i*i * (image_a * imag_b) + i * (real_a * imag_b) + i * (imag_a * real_b) =
  10. -- = real_a * real_b - (imag_a * imag_b) + i * (real_a * imag_b + imag_a * real_b)
  11. ----------------------------------------------------------------------------------
  12. -- Two complex number multiplication:
  13. -- https://www.geeksforgeeks.org/product-of-complex-numbers-using-three-multiplication-operation/
  14. --(a + i b)*(c +id) = real ac -bd +
  15. --imag ad +  cb + ac -ac + bd -bd =  a(d+c) +b(d+c) -ac -bd = (a+b) * (d+c) - (a*c + b*d)
  16. -- prod1 = a * c;
  17. -- prod2 = b * d;
  18. -- prod3 = (a + b) * (c + d);
  19. -- real = prod1 - prod2;
  20. -- imag = prod3 - (prod1 + prod2);
  21. -- Last changes: 20.07.23.
  22. ----------------------------------------------------------------------------------
  23.  
  24. library IEEE;
  25. use IEEE.STD_LOGIC_1164.ALL;
  26. use IEEE.STD_LOGIC_SIGNED.ALL;
  27.  
  28. entity complex_mult is
  29.   generic (
  30.        DW1 : integer :=16;  -- for A
  31.        DW2 : integer :=17   -- for B
  32.       );
  33.   Port (
  34.       clk    : in std_logic;
  35. --      reset  : in std_logic;
  36.       data_in_valid : in std_logic;
  37.       a_real_in    : in std_logic_vector(DW1-1 downto 0); -- from Butterfly
  38.       a_imag_in    : in std_logic_vector(DW1-1 downto 0); -- from Butterfly
  39.       b_real_in    : in std_logic_vector(DW2-1 downto 0); -- from Twiddle
  40.       b_imag_in    : in std_logic_vector(DW2-1 downto 0); -- from Twiddle
  41.      
  42.       real_out    : out std_logic_vector((DW1+DW2) downto 0); -- 33 bits
  43.       imag_out    : out std_logic_vector((DW1+DW2) downto 0); -- 33 bits
  44.       data_out_valid : out std_logic
  45.       );
  46. end complex_mult;
  47.  
  48. architecture Behavioral of complex_mult is
  49.  
  50. signal prod1        : std_logic_vector((DW1+DW2)-1  downto 0); -- 32 bits
  51. signal prod2        : std_logic_vector((DW1+DW2)-1  downto 0); -- 32 bits
  52. signal prod1_d      : std_logic_vector((DW1+DW2)-1  downto 0); --32 bits
  53. signal prod2_d      : std_logic_vector((DW1+DW2)-1  downto 0); -- 32 bits
  54. signal prod3_sum_ab : std_logic_vector((DW1)  downto 0);        -- 17 bits
  55. signal prod3_sum_cd : std_logic_vector((DW2)  downto 0);        -- 18 bits
  56. signal prod3        : std_logic_vector((DW1+DW2)+1  downto 0);  -- 34 bits
  57. signal imag_sum     : std_logic_vector((DW1+DW2)  downto 0);    -- 33 bits
  58. signal imag_out_int    : std_logic_vector((DW1+DW2+2) downto 0); -- 35 bits
  59. signal data_valid_st1: std_logic :='0';
  60. signal data_valid_st2: std_logic :='0';
  61. signal data_valid_st3: std_logic :='0';
  62. begin
  63.  
  64. ---- stage 1 ------------------
  65. -- Stage 1 calculates prod1, prod2 and part of prod3
  66. -- prod1 = a * c
  67. -- prod2 = b * d
  68. process(clk)
  69. begin
  70. if (clk = '1' and clk'event) then
  71.    data_valid_st1 <= data_in_valid;
  72.    if (data_in_valid = '1') then
  73.        prod1 <= a_real_in * b_real_in;
  74.        prod2 <= a_imag_in * b_imag_in;
  75.        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));
  76.        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));
  77.    end if;
  78.    
  79.    data_valid_st2 <= data_valid_st1;
  80.    if (data_valid_st1 = '1') then
  81.        prod3 <= prod3_sum_ab * prod3_sum_cd;
  82.        prod1_d <= prod1;
  83.        prod2_d <= prod2;
  84.        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));
  85.    end if;
  86.      
  87. data_out_valid <= data_valid_st2;
  88.    if (data_valid_st2 = '1') then
  89.        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));
  90.        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)
  91.    end if;
  92.  end if;
  93. end process;
  94.  
  95. imag_out(DW1+DW2 downto 0) <= imag_out_int(DW1+DW2 downto 0);
  96.  
  97.  
  98. end Behavioral;
  99.  
  100.  
  101.  
  102.  
  103.  
  104.  
  105. --------------------------- OLD CODE. Uses two cycles and four multipliers--------------------------------
  106. --library IEEE;
  107. --use IEEE.STD_LOGIC_1164.ALL;
  108. --use IEEE.STD_LOGIC_SIGNED.ALL;
  109.  
  110. --entity complex_mult is
  111. --  generic (
  112. --       DW1 : integer :=16;  -- for input data width
  113. --       DW2 : integer :=17   -- for output data width
  114. --      );
  115. --  Port (
  116. --      clk    : in std_logic;
  117. --      reset  : in std_logic;
  118. --      data_in_valid : in std_logic;
  119. --      a_real_in    : in std_logic_vector(DW1-1 downto 0);
  120. --      a_imag_in    : in std_logic_vector(DW1-1 downto 0);
  121. --      b_real_in    : in std_logic_vector(DW2-1 downto 0);
  122. --      b_imag_in    : in std_logic_vector(DW2-1 downto 0);
  123.      
  124. --      real_out    : out std_logic_vector((DW1+DW2) downto 0); -- 33 bits
  125. --      imag_out    : out std_logic_vector((DW1+DW2) downto 0); -- 33 bits
  126. --      data_out_valid : out std_logic
  127. --      );
  128. --end complex_mult;
  129.  
  130. --architecture Behavioral of complex_mult is
  131. ---- multiplication intermediate results
  132. --signal mul_rr : std_logic_vector((DW1+DW2)-1  downto 0);    -- a_real * a_real
  133. --signal mul_ii : std_logic_vector((DW1+DW2)-1  downto 0);    -- b_real * b_real
  134. --signal mul_ri : std_logic_vector((DW1+DW2)-1  downto 0);    -- a_real * b_imag
  135. --signal mul_ir : std_logic_vector((DW1+DW2)-1  downto 0);    -- a_imag * b_real
  136. --signal data_valid_mul: std_logic;
  137. --begin
  138.  
  139. --process(clk, reset)
  140. --begin
  141. --  if (reset = '1') then
  142. --     mul_rr <= (others => '0');
  143. --     mul_ii <= (others => '0');
  144. --     mul_ri <= (others => '0');
  145. --     mul_ir <= (others => '0');
  146. --     data_valid_mul <= '0';
  147. --  elsif (clk = '1' and clk'event) then
  148. --     data_valid_mul <= data_in_valid;
  149. --     if (data_in_valid = '1') then
  150. --         mul_rr <= a_real_in * b_real_in;
  151. --         mul_ii <= a_imag_in * b_imag_in;
  152. --         mul_ri <= a_real_in * b_imag_in;
  153. --         mul_ir <= a_imag_in * b_real_in;
  154. --     else
  155. --         mul_rr <= (others => '0');
  156. --         mul_ii <= (others => '0');
  157. --         mul_ri <= (others => '0');
  158. --         mul_ir <= (others => '0');
  159. --     end if;
  160.      
  161. --  end if;  
  162. --end process;
  163.  
  164. --process(clk, reset)
  165. --begin
  166. --  if (reset = '1') then
  167. --     real_out <= (others => '0');
  168. --     imag_out <= (others => '0');
  169. --     data_out_valid <= '0';
  170. --  elsif (clk = '1' and clk'event) then
  171. --     data_out_valid <= data_valid_mul;
  172. --     if (data_valid_mul = '1') then
  173. --         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)
  174. --         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)
  175. --     else
  176. --         real_out <= (others => '0');
  177. --         imag_out <= (others => '0');
  178. --     end if;
  179. --  end if;  
  180.  
  181.  
  182. --end process;
  183.  
  184. --end Behavioral;
  185.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement