1 | --
|
2 | --Implementierung der Direktform eines FIR - Tiefpasses
|
3 | --Kennwerte: Abtastrate: 50 kHz
|
4 | --f_Durchlass = 0,8kHz
|
5 | --f_stopp: 5kHz bei delta_s = 20dB Absenkung
|
6 | --passband Ripple = 0,1db
|
7 |
|
8 | library IEEE;
|
9 | use IEEE.Std_logic_1164.all;
|
10 | use IEEE.Numeric_Std.all;
|
11 | use IEEE.math_real.all;
|
12 |
|
13 |
|
14 | entity FIR_Test is
|
15 | generic(N : integer := 10); --(Anzahl der Koeffizienten - 1)
|
16 | port
|
17 | (
|
18 | x_in : in std_logic_vector(11 downto 0); --Input 12 Bit vom AD Wandler
|
19 | clk : in std_logic; --Input Clk mit hoher Frequenz
|
20 | rst : in std_logic; --Reset Active Low
|
21 | enable_data : in std_logic; --next Sample von ADC
|
22 | data_acknowledged : in std_logic; --DA hat Daten erhalten
|
23 |
|
24 | filter_rdy : out std_logic; --Signalisiere dem DA ready.
|
25 | y : out std_logic_vector(11 downto 0) --Output 12 Bit an den DA - Wandler
|
26 | );
|
27 | end FIR_Test;
|
28 |
|
29 | architecture FIR_Test_arch of FIR_Test is
|
30 |
|
31 | type tap_line is array(0 to (N - 1)) of std_logic_vector(12 downto 0); --Typenerklärung: Array zum Verschieben
|
32 | -- =(Zeitverzögern) des Inputs
|
33 |
|
34 | type table is array(0 to N) of signed(12 downto 0); --Typenerklärung: Array aus Filterkoeffizienten,
|
35 |
|
36 |
|
37 | --States
|
38 | type states is (
|
39 | waitForADC,
|
40 | readData,
|
41 | filter,
|
42 | shiftToDA
|
43 | );
|
44 |
|
45 | signal x : tap_line;
|
46 | constant coeff : table:= (
|
47 | "0" & X"085",
|
48 | "0" & X"07F",
|
49 | "0" & X"0A9",
|
50 | "0" & X"0CD",
|
51 | "0" & X"0E6",
|
52 | "0" & X"0EE",
|
53 | "0" & X"0E6",
|
54 | "0" & X"0CD",
|
55 | "0" & X"0A9",
|
56 | "0" & X"07F",
|
57 | "0" & X"085"
|
58 | ); --Koeffiziententabelle, von a_10 bis a_0
|
59 | --Darstellung: signed 1.12
|
60 |
|
61 | signal current_state : states := waitForADC; --Enthält den aktuellen Status, initialisiert mit "waitForADC"
|
62 | signal filter_rdy_intern : std_logic := '0'; --Internes Signal für die fertige Filteroperation
|
63 | signal data_read_ready : std_logic := '0'; --Daten einlesen fertig
|
64 | signal DA_acknowledged : std_logic := '0'; --DA hat Daten erhalten
|
65 | -- signal counter_filter : integer range 0 to 50;
|
66 |
|
67 | begin
|
68 |
|
69 | --Schreiben der Statemachine
|
70 | write_statemachine : process(clk, rst)
|
71 | begin
|
72 | --Reset aktiv low
|
73 | if (rst = '0') then
|
74 | current_state <= waitForADC;
|
75 | --Signaländerung bei steigender Flanke des 125MHz Clocks
|
76 | elsif (rising_edge(clk)) then
|
77 | if (enable_data = '1' and data_read_ready = '0' ) then --Nur 1x lesen
|
78 | current_state <= readData;
|
79 | elsif (data_read_ready = '1') then
|
80 | current_state <= filter;
|
81 | elsif (filter_rdy_intern = '1') then
|
82 | current_state <= shiftToDA;
|
83 | elsif (data_acknowledged = '1') then
|
84 | current_state <= waitForADC;
|
85 | else
|
86 | NULL;
|
87 | end if;
|
88 | end if;
|
89 | end process write_statemachine;
|
90 |
|
91 | --Durchführen der Operationen abhängig vom State
|
92 | statemachine : process(clk)
|
93 | variable sop : signed(25 downto 0); --Variable für Zwischenergebnis der Multiplikation, Darstellung 2.22
|
94 | variable counter_filter : integer range 0 to 20;
|
95 | begin
|
96 | if (rising_edge(clk)) then
|
97 | case (current_state) is
|
98 | when waitForADC =>
|
99 | filter_rdy_intern <= '0';
|
100 | data_read_ready <= '0';
|
101 | sop := (others => '0');
|
102 | counter_filter := 0;
|
103 | when readData =>
|
104 | x(0) <= "0" & x_in; --Neues Datum einlesen
|
105 | data_read_ready <= '1';
|
106 | when filter =>
|
107 | if (counter_filter < 12) then
|
108 | sop := sop + coeff(counter_filter - 1) * signed(x(counter_filter - 1)); --Durchführung einer Multiplikation und einer Addition
|
109 | x(counter_filter) <= x(counter_filter - 1); --Zeitverschiebung
|
110 | else
|
111 | filter_rdy_intern <= '1';
|
112 | end if;
|
113 | counter_filter := counter_filter + 1;
|
114 | when shiftToDA =>
|
115 | y <= std_logic_vector(sop(22 downto 11));
|
116 | filter_rdy <= '1';
|
117 | end case;
|
118 | else
|
119 | NULL;
|
120 | end if;
|
121 |
|
122 | end process statemachine;
|
123 |
|
124 | end FIR_Test_arch;
|