154 lines
5.9 KiB
VHDL
154 lines
5.9 KiB
VHDL
------------------------------------------------------------------------
|
|
-- fft_magnitude_calc
|
|
--
|
|
-- calculation of FFT magnitude sqrt(real_part²+im_part²)
|
|
-- Inputs:
|
|
-- input_re in: +-1 signed Fixpoint (0.5=0x40000000, -0.5=0xC0000000 (negative numbers in 2K)
|
|
-- input_im in: +-1 signed Fixpoint (0.5=0x40000000, -0.5=0xC0000000 (negative numbers in 2K)
|
|
-- input_valid: high = inputs are valid for data processing
|
|
-- Outputs
|
|
-- output_magnitude: Fixpoint 0.5=0x40000000 (always positive)
|
|
-- output_valid: high = magnitude data is valid
|
|
-----------------------------------------------------------------------
|
|
|
|
library ieee;
|
|
use ieee.std_logic_1164.all;
|
|
use ieee.numeric_std.all;
|
|
|
|
entity fft_magnitude_calc is
|
|
port (
|
|
clk : in std_logic; -- Takt
|
|
reset : in std_logic; -- Reset
|
|
input_valid: in std_logic; -- Eingangsdaten gueltig
|
|
input_re : in std_logic_vector( 31 downto 0 ); -- Realteil in Fixpoint
|
|
input_im : in std_logic_vector( 31 downto 0 ); -- Imaginaerteil in Fixpoint
|
|
output_valid : out std_logic; -- Ausgangsdaten gueltig
|
|
output_magnitude : out std_logic_vector( 31 downto 0 ) -- Berechnete magnitude
|
|
);
|
|
end entity fft_magnitude_calc;
|
|
|
|
architecture rtl of fft_magnitude_calc is
|
|
|
|
|
|
-- Zustaende fuer die Zustandsmaschine fuer die Berechnung
|
|
type CalcState is (
|
|
CALC_IDLE, -- Zustand Leerlauf
|
|
CALC_MULTIPLY, -- Zustand Berechnung real_part² und im_part²
|
|
CALC_ADD, -- Zustand Berecnung Addition real_part²+im_part²
|
|
CALC_SQRT, -- Zustand Berechnung der sqrt(real_part²+im_part²)
|
|
CALC_STORE_RESULT -- Zustand Setzen von output_valid und output_magnitude
|
|
);
|
|
|
|
-- Legen Sie die Signale current_calc_state und next_calc_state fuer die Zustandsmaschine CalcState an
|
|
|
|
-- Legen Sie die Signale re_multiply_re und im_multiply_im als signed (63 downto 0) an
|
|
|
|
-- Legen Sie die Signal re2_add_im2 als signed (63 downto 0) an
|
|
|
|
-- Legen Sie die Signal output_sqrt als std_logic_vector (31 downto 0) an
|
|
|
|
-- Legen Sie die Signal output_sqrt als std_logic_vector (15 downto 0) an
|
|
|
|
-- Legen Sie das Signal start_sqrt_calc als std_logic an
|
|
|
|
-- Legen Sie das Signal sqrt_out_valid_flag als std_logic an
|
|
|
|
|
|
begin
|
|
|
|
-- uebergangsschaltnetz der Zustandsmaschine fuer die Berechnung (Strukturvariante 2 Process Zustandsmaschine)
|
|
-- Beschreiben Sie den Prozess fuer das uebergangsschaltnetz (Case-Anweisung)
|
|
-- CALC_IDLE -> CALC_MULTIPLY wenn input_valid = 1
|
|
-- CALC_MULTIPLY -> CALC_ADD
|
|
-- CALC_ADD -> CALC_SQRT
|
|
-- CALC_SQRT -> CALC_STORE_RESULT wenn sqrt_out_valid_flag = 1
|
|
-- CALC_STORE_RESULT -> CALC_IDLE
|
|
calc_state_transitions : process ( all ) is
|
|
begin
|
|
|
|
end process calc_state_transitions;
|
|
|
|
-- Zustandsspeicher und Ausgangsschaltnetz zu der Steuerung der Berechnung (Strukturvariante 2 Process Zustandsmaschine)
|
|
sync : process ( clk, reset ) is
|
|
begin
|
|
-- Der Prozess steuert folgende Signale setzen Sie fuer alle passende Resetwerte
|
|
-- current_calc_state
|
|
-- re_multiply_re
|
|
-- im_multiply_im
|
|
-- re2_add_im2
|
|
-- input_sqrt
|
|
-- start_sqrt_calc
|
|
-- output_valid
|
|
-- output_magnitude
|
|
if ( reset = '1' ) then
|
|
|
|
elsif ( rising_edge( clk ) ) then
|
|
|
|
-- Machen Sie Anweisungen um start_sqrt_calc und output_valid auf 0 zu setzen
|
|
|
|
-- Realisieren Sie den Zustandsspeicher current_calc_state
|
|
|
|
-- Vervollstaendigen Sie das Ausgangsschaltnetz
|
|
case next_calc_state is
|
|
when CALC_IDLE=> null;
|
|
|
|
-- calculation of real_part² and im_part²
|
|
-- Anweisung fuer die Berechnung von re_multiply_re = input_re² (Datentypen beachten)
|
|
-- Anweisung fuer die Berechnung von im_multiply_im = input_im² (Datentypen beachten)
|
|
when CALC_MULTIPLY =>
|
|
|
|
-- calculation of real_part²*+im_part²
|
|
-- Anweisung fuer die Berechnung von re2_add_im2 = re_multiply_re + im_multiply_im
|
|
when CALC_ADD =>
|
|
|
|
-- calculation of sqrt(real_part²+im_part²)
|
|
-- Anweisung um input_sqrt mit den obersten 32-Bit von re2_add_im2 zu belegen (Datentypen beachten)
|
|
-- Anweisung um start_sqrt_calc mit 1 zu setzen
|
|
when CALC_SQRT =>
|
|
|
|
-- Setzen der Entity-Ausgaenge
|
|
-- Anweisung um die obersten 16 bit von output_magnitude mit output_sqrt zu setzen und die untern 16 Bit mit 0
|
|
-- Anweisung um output_valid mit 1 zu setzen
|
|
when CALC_STORE_RESULT =>
|
|
|
|
when others => NUll;
|
|
end case;
|
|
end if;
|
|
end process sync;
|
|
|
|
|
|
-- Instanziierung des SQRT Moduls fuer die Berechnung der Quardratwurzel
|
|
-- Weisen Sie die Signale output_sqrt, reset, input_sqrt und clk richtig zu
|
|
sqrt_module : entity work.squareRoot_pipe
|
|
generic map (
|
|
G_DATA_W => 32
|
|
)
|
|
port map (
|
|
clk => ,
|
|
rst => ,
|
|
iv_data => ,
|
|
ov_res =>
|
|
);
|
|
|
|
-- Dieser Prozess sorgt dafuer, dass 16 Takte nachdem start_sqrt_calc 1 geworden ist sqrt_out_valid_flag zu 1 wird
|
|
-- Wird benoetigt um die Berechnungsdauer des sqrt_module anzueigen
|
|
-- Hier muss nichts veraendert werden
|
|
p_sqrt_out_valid_flag: process ( clk, reset ) is
|
|
variable delay_sqrt_out_valid_flag : std_logic_vector(14 downto 0);
|
|
begin
|
|
if ( reset = '1' ) then
|
|
sqrt_out_valid_flag <= '0';
|
|
delay_sqrt_out_valid_flag := (others => '0');
|
|
elsif ( rising_edge( clk ) ) then
|
|
sqrt_out_valid_flag <= delay_sqrt_out_valid_flag(14);
|
|
delay_sqrt_out_valid_flag := delay_sqrt_out_valid_flag(13 downto 0) & start_sqrt_calc;
|
|
if sqrt_out_valid_flag = '1' then
|
|
delay_sqrt_out_valid_flag := (others => '0');
|
|
end if;
|
|
end if;
|
|
end process p_sqrt_out_valid_flag;
|
|
|
|
|
|
end architecture rtl;
|
|
|