Loesung des Praktikums Systementwurf - Bjarne Hoesch - Bernhard Schoeffel
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

fft_magnitude_calc.vhd 6.6KB

1 year ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. ------------------------------------------------------------------------
  2. -- fft_magnitude_calc
  3. --
  4. -- calculation of FFT magnitude sqrt(real_part²+im_part²)
  5. -- Inputs:
  6. -- input_re in: +-1 signed Fixpoint (0.5=0x40000000, -0.5=0xC0000000 (negative numbers in 2K)
  7. -- input_im in: +-1 signed Fixpoint (0.5=0x40000000, -0.5=0xC0000000 (negative numbers in 2K)
  8. -- input_valid: high = inputs are valid for data processing
  9. -- Outputs
  10. -- output_magnitude: Fixpoint 0.5=0x40000000 (always positive)
  11. -- output_valid: high = magnitude data is valid
  12. -----------------------------------------------------------------------
  13. library ieee;
  14. use ieee.std_logic_1164.all;
  15. use ieee.numeric_std.all;
  16. library work;
  17. use work.task.all;
  18. use work.float.all;
  19. entity fft_magnitude_calc is
  20. port (
  21. clk : in std_logic;
  22. reset : in std_logic;
  23. input_valid: in std_logic;
  24. input_re : in std_logic_vector( 31 downto 0 ); -- in Fixpoint
  25. input_im : in std_logic_vector( 31 downto 0 ); -- in Fixpoint
  26. output_valid : out std_logic;
  27. output_magnitude : out std_logic_vector( 31 downto 0 )
  28. );
  29. end entity fft_magnitude_calc;
  30. architecture rtl of fft_magnitude_calc is
  31. subtype Word_64 is std_logic_vector( 63 downto 0 );
  32. type Array_64 is array ( natural range <> ) of Word_64;
  33. subtype Word_32 is std_logic_vector( 31 downto 0 );
  34. type Array_32 is array ( natural range <> ) of Word_32;
  35. subtype Word_16 is std_logic_vector( 15 downto 0 );
  36. type Array_16 is array ( natural range <> ) of Word_16;
  37. signal input_valid_stage1 : std_logic;
  38. signal re_multiply_re_stage1 : signed(63 downto 0);
  39. signal im_multiply_re_stage1 : signed(63 downto 0);
  40. signal input_valid_stage2 : std_logic;
  41. signal re2_add_im2 : signed(63 downto 0);
  42. signal input_valid_stage3 : std_logic;
  43. signal input_sqrt : Array_32( 0 to 16 );
  44. signal output_sqrt: Array_16( 0 to 16 );
  45. signal output_delay_sqrt: std_logic_vector(15 downto 0);
  46. signal data_memory : work.reg32.RegArray( 0 to 1023 );
  47. signal index_sqrt : integer range 0 to 16;
  48. begin
  49. -- calculation of real_part² and im_part²
  50. p_pow2_stage1: process ( clk, reset ) is
  51. begin
  52. if ( reset = '1' ) then
  53. input_valid_stage1 <= '0';
  54. re_multiply_re_stage1 <= (others => '0');
  55. im_multiply_re_stage1 <= (others => '0');
  56. elsif ( rising_edge( clk ) ) then
  57. input_valid_stage1 <= input_valid;
  58. if input_valid = '1' then
  59. re_multiply_re_stage1 <= signed(input_re) * signed(input_re);
  60. im_multiply_re_stage1 <= signed(input_im) * signed(input_im);
  61. end if;
  62. end if;
  63. end process p_pow2_stage1;
  64. -- calculation of real_part²*+im_part²
  65. p_add_stage2: process ( clk, reset ) is
  66. begin
  67. if ( reset = '1' ) then
  68. input_valid_stage2 <= '0';
  69. re2_add_im2 <= (others => '0');
  70. elsif ( rising_edge( clk ) ) then
  71. input_valid_stage2 <= input_valid_stage1;
  72. re2_add_im2 <= re_multiply_re_stage1 + im_multiply_re_stage1;
  73. end if;
  74. end process p_add_stage2;
  75. -- calculation of sqrt (one sqrt caluation needs 16 clks with G_DATA_W => 32
  76. -- for continous stream 17 sqrt instances are needed
  77. p_sqrt_stage3: process ( clk, reset ) is
  78. begin
  79. if ( reset = '1' ) then
  80. input_valid_stage3 <= '0';
  81. index_sqrt <= 0;
  82. input_sqrt(0) <= (others => '0');
  83. input_sqrt(1) <= (others => '0');
  84. input_sqrt(2) <= (others => '0');
  85. input_sqrt(3) <= (others => '0');
  86. input_sqrt(4) <= (others => '0');
  87. input_sqrt(5) <= (others => '0');
  88. input_sqrt(6) <= (others => '0');
  89. input_sqrt(7) <= (others => '0');
  90. input_sqrt(8) <= (others => '0');
  91. input_sqrt(9) <= (others => '0');
  92. input_sqrt(10) <= (others => '0');
  93. input_sqrt(11) <= (others => '0');
  94. input_sqrt(12) <= (others => '0');
  95. input_sqrt(13) <= (others => '0');
  96. input_sqrt(14) <= (others => '0');
  97. input_sqrt(15) <= (others => '0');
  98. input_sqrt(16) <= (others => '0');
  99. elsif ( rising_edge( clk ) ) then
  100. input_valid_stage3 <= input_valid_stage2;
  101. if input_valid_stage2 = '1' then
  102. if index_sqrt = 16 then
  103. index_sqrt <= 0;
  104. else
  105. index_sqrt <= index_sqrt +1;
  106. end if;
  107. end if;
  108. case index_sqrt is
  109. when 16 => input_sqrt(16) <= std_logic_vector(re2_add_im2(63 downto 32));
  110. when 15 => input_sqrt(15) <= std_logic_vector(re2_add_im2(63 downto 32));
  111. when 14 => input_sqrt(14) <= std_logic_vector(re2_add_im2(63 downto 32));
  112. when 13 => input_sqrt(13) <= std_logic_vector(re2_add_im2(63 downto 32));
  113. when 12 => input_sqrt(12) <= std_logic_vector(re2_add_im2(63 downto 32));
  114. when 11 => input_sqrt(11) <= std_logic_vector(re2_add_im2(63 downto 32));
  115. when 10 => input_sqrt(10) <= std_logic_vector(re2_add_im2(63 downto 32));
  116. when 9 => input_sqrt(9) <= std_logic_vector(re2_add_im2(63 downto 32));
  117. when 8 => input_sqrt(8) <= std_logic_vector(re2_add_im2(63 downto 32));
  118. when 7 => input_sqrt(7) <= std_logic_vector(re2_add_im2(63 downto 32));
  119. when 6 => input_sqrt(6) <= std_logic_vector(re2_add_im2(63 downto 32));
  120. when 5 => input_sqrt(5) <= std_logic_vector(re2_add_im2(63 downto 32));
  121. when 4 => input_sqrt(4) <= std_logic_vector(re2_add_im2(63 downto 32));
  122. when 3 => input_sqrt(3) <= std_logic_vector(re2_add_im2(63 downto 32));
  123. when 2 => input_sqrt(2) <= std_logic_vector(re2_add_im2(63 downto 32));
  124. when 1 => input_sqrt(1) <= std_logic_vector(re2_add_im2(63 downto 32));
  125. when 0 => input_sqrt(0) <= std_logic_vector(re2_add_im2(63 downto 32));
  126. when others => null;
  127. end case;
  128. end if;
  129. end process p_sqrt_stage3;
  130. -- generate sqrt instances for continous data stream
  131. gen_sqrt_array: for i in 0 to 16 generate
  132. sqrt_module : entity work.squareRoot_pipe
  133. generic map (
  134. G_DATA_W => 32
  135. )
  136. port map (
  137. clk => clk,
  138. rst => reset,
  139. iv_data => input_sqrt(i),
  140. ov_res => output_sqrt(i)
  141. );
  142. end generate gen_sqrt_array;
  143. -- output assignment
  144. p_output_stage4: process ( clk, reset ) is
  145. begin
  146. if ( reset = '1' ) then
  147. output_valid <= '0';
  148. output_magnitude <= (others => '0');
  149. output_delay_sqrt <= (others => '0');
  150. elsif ( rising_edge( clk ) ) then
  151. output_delay_sqrt <= output_delay_sqrt(14 downto 0) & input_valid_stage3;
  152. output_valid <= output_delay_sqrt(15);
  153. output_magnitude <= std_logic_vector(output_sqrt(index_sqrt)) & x"0000";
  154. end if;
  155. end process p_output_stage4;
  156. end architecture rtl;