vhdl_einfuehrung/U4_FSM/fft_magnitude_calc.vhd

154 lines
5.9 KiB
VHDL
Raw Permalink Normal View History

2024-11-05 23:57:43 +01:00
------------------------------------------------------------------------
-- 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;