library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity Takterkennung is Port ( CLK: in std_logic; In_Takt: in std_logic; Input: in std_logic; CD: in std_logic; Out_Takt: out std_logic; Output: out std_logic; Error: out std_logic ); end Takterkennung; architecture Behavioral of Takterkennung is signal Input_Buffer : std_logic; signal In_Takt_Buffer : std_logic; signal lock : std_logic := '0'; signal CD_helper : std_logic; signal counter : POSITIVE := 1; begin process(CLK) variable CD_positiv : NATURAL := 0; variable CD_negativ : NATURAL := 0; variable Out_Takt_helper : std_logic; begin -- 1 2 3 4 |--> 5 6 <--| 7 8 9 10 -- 5 6 sollten gleich sein, da sie in der Signalmitte liegen und damit den Signalwert möglichst ideal repräsentieren -- Wenn dort stattdessen eine Flanke ist, wird direkt zu 2 gesprungen, da man dann wohl völlig falsch gestartet ist. -- Wenn sich im Bereich 1 bis 5 eine Flanke befindet, dann wird der Signalfluß quasi verzögert -- Wenn sie hingegen im Bereich 7 bis 10 ist, dann wir der Signalfluß quasi beschleunigt. if (CLK'event and (CLK='1')) then -- CD in Bewertung einfließen lassen if (CD_helper = '1') then CD_positiv := CD_positiv + 1; else CD_negativ := CD_negativ + 1; end if; CD_helper <= CD; if (CD_positiv > 1000) then -- 1 ms (Einschwingzeit) CD_negativ := 0; -- Reseten des Konkurrenzzählers CD_positiv := 501; -- Zurück auf halbe Höhe end if; if (CD_negativ > 100) then -- In der Zeit müßte ein Bit wechsel gewesen sein, also auch ein CD CD_positiv := 0; -- Reseten des Konkurrenzzählers CD_negativ := 51; -- Zurück auf halbe Höhe end if; -- Wenn es wieder was zu tun gib (In_Takt_Buffer Flanke...) if (In_Takt_Buffer /= In_Takt) AND (CD_positiv > 500) AND (CD_helper = '1') then -- Träger muß also mind. 0,5 ms vorhanden gewesen sein... -- Automat Anfang if (counter = 6) then -- Abtasten an den mittleren zwei Segmenten Out_Takt_helper := not Out_Takt_helper; Out_Takt <= Out_Takt_helper; if (Input_Buffer = Input) then Output <= Input; Error <= '0'; counter <= 7; -- Dann kann es ja munter weitergehen... else Error <= '1'; counter <= 2; -- Dann ist hier ja eine Flanke... end if; elsif (counter > 9) then if (Input = Input_Buffer) then -- Normaler Reset auf 1 counter <= 1; else -- Flanke zwischen 9 und 10 => Beschleunigen. counter <= 2 - CONV_INTEGER(lock); -- lock muß ja auch hier berücksichtigt werden... end if; elsif (Input /= Input_Buffer) and (lock = '0') and (counter /= 1) then -- Flanke, wo keine sein sollte... if (counter = 7) OR (counter = 8) then counter <= counter + 2; elsif (counter = 9) then counter <= 1; end if; lock <= '1'; -- sorgt für moderate Reaktion auf Schwankungen... else counter <= counter + 1; lock <= '0'; end if; -- zwischen 10 und 1 muß nicht zwingend eine Flanke sein. Es können auch zwei gleiche Bits aufeinander folgen. Input_Buffer <= Input; -- Automat Ende end if; In_Takt_Buffer <= In_Takt; end if; end process; end Behavioral;