library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity flankentimer is port( clk : in std_logic; reset : in std_logic; ref_input_async : in std_logic; angle_input_async : in std_logic; counts_out : out integer range 0 to 50 := 0; new_data_out : out std_logic := '0'; first_index : in std_logic ); end flankentimer; architecture behave of flankentimer is -- synchronisierte Signale signal ref_input : std_logic := '0'; signal angle_input : std_logic := '0'; signal angle_inv_input : std_logic := '1'; signal counts_ref_angle_internal : integer range 0 to 50 := 0; signal counts_ref_angle_inv_internal : integer range 0 to 50 := 0; signal counts_summation : integer range 0 to 50 := 0; signal counts_summation_old : integer range 0 to 50 := 0; signal make_summation : std_logic := '0'; signal ref_old_state : std_logic := '0'; signal angle_old_state : std_logic := '0'; signal angle_inv_old_state : std_logic := '0'; signal timer_signal : std_logic := '0'; signal timer_signal_old_state : std_logic := '0'; signal timer_inv_signal : std_logic := '0'; signal timer_inv_signal_old_state : std_logic := '0'; signal switch : integer range 0 to 2 := 0; signal new_data : std_logic := '0'; -- Register für Vereinfachung der Kombinatorik signal calc_non_inv_sig : integer range 0 to 1 := 0; signal calc_inv_sig : integer range 0 to 2 := 0; --signal temp_counts_ref_angle_internal : integer range 0 to 50 := 0; --signal temp_counts_ref_angle_inv_internal_high : integer range 0 to 50 := 0; --signal temp_counts_ref_angle_inv_internal_low : integer range 0 to 50 := 0; signal temp_counts_internal : integer range 0 to 50 := 0; begin process(clk) begin if rising_edge(clk) then if reset = '0' and first_index = '1' then ref_old_state <= ref_input; angle_old_state <= angle_input; angle_inv_old_state <= angle_inv_input; timer_signal_old_state <= timer_signal; timer_inv_signal_old_state <= timer_inv_signal; ref_input <= ref_input_async; -- Einsynchronisieren neuer Signalpegel angle_input <= angle_input_async; -- Einsynchronisieren neuer Signalpegel angle_inv_input <= not angle_input_async; -- Einsynchronisieren neuer Signalpegel -- Timer starten if ref_input > ref_old_state then -- steigende Flanke an ref -> zählung starten timer_signal <= '1'; timer_inv_signal <= '1'; end if; -- Timer normales signal stoppen if angle_input > angle_old_state then -- steigende Flanke an Angle -> zählung stoppen timer_signal <= '0'; switch <= 0; end if; -- Timer normales signal weiterzählen if timer_signal = '1' then counts_ref_angle_internal <= counts_ref_angle_internal + 1; end if; -- Timer invertiertes signal stoppen if angle_inv_input > angle_inv_old_state then -- steigende Flanke an Angle_inv -> zählung stoppen timer_inv_signal <= '0'; switch <= 0; end if; -- Timer invertiertes signal weiterzählen if timer_inv_signal = '1' then counts_ref_angle_inv_internal <= counts_ref_angle_inv_internal + 1; end if; -- Signalauswahl und entsprechende Signalanpassung normales Signal if (((((timer_signal = '0') and (timer_signal_old_state = '1')) ) and switch = 0) or calc_non_inv_sig = 1) then if (counts_ref_angle_internal > 12 and counts_ref_angle_internal < 40 and calc_non_inv_sig = 0) then temp_counts_internal <= counts_ref_angle_internal; calc_non_inv_sig <= 1; switch <= 1; end if; -- normales Signal zur Auswertung verwenden if calc_non_inv_sig = 1 then -- counts_summation <= temp_counts_internal; new_data <= '1'; calc_non_inv_sig <= 0; end if; end if; -- Signalauswahl und entsprechende Signalanpassung invertiertes Signal if ((((timer_inv_signal = '0') and (timer_inv_signal_old_state = '1')) and switch = 0 ) or calc_inv_sig = 1) then if (counts_ref_angle_inv_internal > 12 and counts_ref_angle_inv_internal < 40 and calc_inv_sig = 0) then temp_counts_internal <= counts_ref_angle_inv_internal; calc_inv_sig <= 1; switch <= 2; end if; if temp_counts_internal > 12 and temp_counts_internal < 26 then temp_counts_internal <= temp_counts_internal + 25; calc_inv_sig <= 2; else temp_counts_internal <= temp_counts_internal - 25; calc_inv_sig <= 2; end if; -- invertiertes Signal zur Auswertung verwenden if calc_inv_sig = 2 then -- counts_summation <= temp_counts_internal; new_data <= '1'; calc_inv_sig <= 0; end if; end if; if (new_data = '1') then -- Ausgabewert ändern -- zähler stoppen timer_signal <= '0'; timer_inv_signal <= '0'; -- zählwert ausgeben if temp_counts_internal < 50 and temp_counts_internal >= 0 then -- nötig da es auch zu 50 Zählwerten kommt durch umschalten der PWM counts_out <= temp_counts_internal; end if; -- new_data Flag setzen new_data_out <= '1'; -- Zähler zurücksetzen counts_ref_angle_internal <= 0; counts_ref_angle_inv_internal <= 0; new_data <= '0'; else new_data_out <= '0'; end if; else --resetbedingung end if; end if; end process; end behave;