library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_SIGNED.ALL; entity FIRFilt is Port ( clk : in std_logic; -- Systemtakt clk_en: in std_logic; -- Eingangswerten abhängiger Takt DIN : in std_logic_vector (7 downto 0); -- Eingang für ADW Werte Off : in std_logic_vector (7 downto 0); -- Variable Nullpunktsbestimmung (unbenutzt) Reset : in std_logic; -- Reset ONOFF : in std_logic; -- Filterung aktiviert/deaktivert switch: in std_logic; -- Filter umschalten (unbenutzt) DOUT : out std_logic_vector (7 downto 0); -- Ausgang für gefilterte Werte DONE : out std_logic); -- Übergabesignal (unbenutzt) end FIRFilt; architecture Behavioral of FIRFilt is -- Programmdurchlauf wird festgelegt type State is ( Didle, Deinlesen, DFIR1, DAdd, Dshift, Ddone); signal DNext : State; type Feld is array (0 to 29) of std_logic_vector (7 downto 0); -- Speicher berechnete Werte signal Wort : Feld :=( "00000000", --0 "00000000", "00000000", "00000000", "00000000", "00000000", "00000000", "00000000", "00000000", "00000000", "00000000", --10 "00000000", "00000000", "00000000", "00000000", "00000000", "00000000", "00000000", "00000000", "00000000", "00000000", --20 "00000000", "00000000", "00000000", "00000000", "00000000", "00000000", "00000000", "00000000", "00000000"); --29 type Feld2 is array (0 to 29) of std_logic_vector (7 downto 0); -- Speicher Eingangswerte signal Wert : Feld2 :=( "00000000", --0 "00000000", "00000000", "00000000", "00000000", "00000000", "00000000", "00000000", "00000000", "00000000", "00000000", --10 "00000000", "00000000", "00000000", "00000000", "00000000", "00000000", "00000000", "00000000", "00000000", "00000000", --20 "00000000", "00000000", "00000000", "00000000", "00000000", "00000000", "00000000", "00000000", "00000000"); --29 type Feld3 is array (0 to 29) of std_logic_vector (7 downto 0); -- Speicher Koeffizienten signal Koeff : Feld3 :=( "00000000", --Koeff0 "00000000", --Koeff1 "11111111", --Koeff2 "11111111", --Koeff3 "11111110", --Koeff4 "11111110", --Koeff5 "11111110", --Koeff6 "11111111", --Koeff7 "00000000", --Koeff8 "00000011", --Koeff9 "00000111", --Koeff10 "00001010", --Koeff11 "00001110", --Koeff12 "00010001", --Koeff13 "00010010", --Koeff14 "00010010", --Koeff15 "00010001", --Koeff16 "00001110", --Koeff17 "00001010", --Koeff18 "00000111", --Koeff19 "00000011", --Koeff20 "00000000", --Koeff21 "11111111", --Koeff22 "11111110", --Koeff23 "11111110", --Koeff24 "11111110", --Koeff25 "11111111", --Koeff26 "11111111", --Koeff27 "00000000", --Koeff28 "00000000"); --Koeff29 constant doneTime : std_logic_vector (3 downto 0) := "0110"; constant offwert : std_logic_vector (7 downto 0) := "01101001"; signal Ergebnis : std_logic_vector (7 downto 0) := "00000000"; signal doneSig : std_logic_vector (3 downto 0) := "0000"; signal i : integer range 0 to 29 := 0; ----------------------------------------------------------------------------------------------------- -- Hauptprogramm -- ----------------------------------------------------------------------------------------------------- begin DOUT <= Ergebnis; process (Reset, clk, Ergebnis) -- Das Hauptprogramm ist eine case-Struktur begin -- sie hat mehrere Zustände nach einem Reset if (Reset = '1') then -- ist der Zustand: Didle DNext <= Didle; elsif (clk = '1' and clk'Event) then case DNext is -- Start des FIR Filters -- ===================== when Didle => DONE <= '0'; if (clk_en = '1') then -- Start des FIR Filters DNext <= Deinlesen; else DNext <= Didle; end if; -- Einlesen und Nullpunktsverschiebung -- =================================== when Deinlesen => -- Der anliegende Wert des ADW wird eingelesen Wert(0) <= DIN - offwert; -- Der Offset von 127 wird abgezogen um eine -- Nullpunktsverschiebung zu erreichen DONE <= '0'; DNext <= DFIR1; -- Multiplizierer -- ============== when DFIR1 => Wort(i) <= SHR(Wert(i) * Koeff(i),"1000") (7 downto 0); i <= i + 1; DONE <= '0'; -- serieller Multiplikator aller Werte mit -- allen Koeffizienten if (i = 29) then DNext <= DAdd; i <= 0; else DNext <= DFIR1; end if; -- Addierer -- ======== when DAdd => -- Addition aller berechneten Werte if (ONOFF = '1') then Ergebnis <= offwert + Wort(0) + Wort(1) + Wort(2) + Wort(3) + Wort(4) + Wort(5) + Wort(6) + Wort(7) + Wort(8) + Wort(9) + Wort(10) + Wort(11) + Wort(12) + Wort(13) + Wort(14) + Wort(15) + Wort(16) + Wort(17) + Wort(18) + Wort(19) + Wort(20) + Wort(21) + Wort(22) + Wort(23) + Wort(24) + Wort(25) + Wort(26) + Wort(27) + Wort(28) + Wort(29); else Ergebnis <= Wert(0) + offwert; -- Abschaltfunktion des Filters (Übergabe des end if; -- original Wertes DONE <= '0'; DNext <= Dshift; -- Schieberegister -- =============== when Dshift => -- Schieberegister speichert das Eingangsregister um for l in 29 downto 1 loop Wert(l) <= Wert(l-1); end loop; DONE <= '0'; DNext <= Ddone; -- Übernahmesignal an DAW (evtl. weglassen) -- ====================== when Ddone => if (doneSig = DoneTime) then doneSig <= "0000"; DONE <= '0'; DNext <= Didle; else DONE <= '1'; doneSig <= doneSig + 1; DNext <= Ddone; end if; end case; end if; end process; end Behavioral;