Datum:
hallo zusammen, ich steuere gerade den AD7401a mit FPGA an. Mit Sinc3-Filter, prinzipiell wie im Datenblatt, siehe bitte Seite 16 http://www.analog.com/static/imported-files/data_s...
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.Numeric_std.ALL; entity Sinc_filt is generic ( DECIMATOR_M_BIT_SIZE : natural := 8); -- M = 2^DECIMATOR_M_BIT_SIZE Port ( Mclk : in STD_LOGIC; Mdata : in STD_LOGIC; rst : in STD_LOGIC; DataRate_clk : out STD_LOGIC; -- in fifo abspeichern DataOut : out STD_LOGIC_VECTOR (15 downto 0)); end Sinc_filt; architecture Behavioral of Sinc_filt is constant DATA_BIT_SIZE : natural := 3*DECIMATOR_M_BIT_SIZE + 1; -- intern DatenBus Sinc3 ---------------------------------------------------------------------------------- -- signal ---------------------------------------------------------------------------------- -- integrator @ Mclk signal acc1 : signed (DATA_BIT_SIZE - 1 downto 0) := (others => '0'); signal acc2 : signed (DATA_BIT_SIZE - 1 downto 0) := (others => '0'); signal acc3 : signed (DATA_BIT_SIZE - 1 downto 0) := (others => '0'); -- diffirentiator @ Mclk/DECIMATOR_M signal diff_clk : std_logic := '0'; signal diff1 : signed (DATA_BIT_SIZE - 1 downto 0) := (others => '0'); signal diff2 : signed (DATA_BIT_SIZE - 1 downto 0) := (others => '0'); signal diff3 : signed (DATA_BIT_SIZE - 1 downto 0) := (others => '0'); signal acc3_d : signed (DATA_BIT_SIZE - 1 downto 0) := (others => '0'); signal diff1_d : signed (DATA_BIT_SIZE - 1 downto 0) := (others => '0'); signal diff2_d : signed (DATA_BIT_SIZE - 1 downto 0) := (others => '0'); -- clk divider ->> Mclk/DECIMATOR_M signal clk_div_cnt : std_logic_vector(DECIMATOR_M_BIT_SIZE-1 downto 0) := (others => '0'); begin ---------------------------------------------------------------------------------- -- Integrator @ Mclk ---------------------------------------------------------------------------------- Integ_pro: process begin wait until rising_edge(Mclk); -- falling Mclk ->> data valid if rst = '1' then acc1 <= (others => '0'); acc2 <= (others => '0'); acc3 <= (others => '0'); else if Mdata = '1' then acc1 <= acc1 + x"1"; end if; acc2 <= acc2 + acc1; acc3 <= acc3 + acc2; end if; end process Integ_pro; ---------------------------------------------------------------------------------- -- clk divider @ Mclk --> Mclk/DECIMATOR_M ---------------------------------------------------------------------------------- clk_div_pro: process begin wait until rising_edge(Mclk); if rst = '1' then clk_div_cnt <= (others => '0'); else clk_div_cnt <= std_logic_vector(unsigned(clk_div_cnt) + x"1"); end if; end process clk_div_pro; -- wired diff_clk <= clk_div_cnt(DECIMATOR_M_BIT_SIZE-1); -- MSB DataRate_clk <= diff_clk; ---------------------------------------------------------------------------------- -- differenciator @ falling diff_clk ---------------------------------------------------------------------------------- Diff_pro: process begin wait until falling_edge(diff_clk); -- Falling Edge! if rst = '1' then diff1 <= (others => '0'); diff2 <= (others => '0'); diff3 <= (others => '0'); acc3_d <= (others => '0'); diff1_d <= (others => '0'); diff2_d <= (others => '0'); else diff1 <= acc3 - acc3_d; diff2 <= diff1 - diff1_d; diff3 <= diff2 - diff2_d; acc3_d <= acc3; diff1_d <= diff1; diff2_d <= diff2; end if; end process Diff_pro; ---------------------------------------------------------------------------------- -- 16- bit DataOutput ---------------------------------------------------------------------------------- DataOut <= std_logic_vector(diff3(DATA_BIT_SIZE-1 downto DATA_BIT_SIZE-16)); -- 16-Bit DataOut end Behavioral; |
Mclk = 16MHz M = 256 = 2^8 ->> f_Data_rate = Mclk/M = 16MHz/256 = 62.5 kHz ~ 16µS. Ist das ein langsamer AD-Wandler? Auf dem Spartan 3a-Starerkit gibts 12-Bit, seriell DA-Wandler. Ich füttere den DA mit dem DataOut (16 downto 5) vom Sinc3-Filter, über ein asynchon-fifo. Mit einem Signal-Generator habe ich Reference-Sinus, und vergleiche das mit dem Ergebniss vom DA-Wandler. Bei großen Frequenz z.b. > 300Hz Sinus entsteht Phasenverschiebung zwischen beiden auf Ozsi, abhängig von Frequenz (> 15µS) wegen Tiefpassverhalten von Sinc3... Meine Frage ist: Wie muss man genau machen, damit man ein richtiges AD-Ergebniss vom Delta-Sigma AD-Wandler bekommt? Ich hab den Artikel [1] durchgelesen, aber mir nicht klar, ob man ein Halb-Band Filter hinter Sinc3 schalten muss, wenn ja dann wie genau? Ist das das Ziel, dass man Amplitude- Attenution wegen Sinc3 (s. 7-4 in [1]) kompensieren?... [1] http://www.numerix-dsp.com/appsnotes/APR8-sigma-delta.pdf vielen Dank im voraus! Lg Tomy
Datum:
tomy schrieb: > Mclk = 16MHz > M = 256 = 2^8 ->> f_Data_rate = Mclk/M = 16MHz/256 = 62.5 kHz ~ 16µS. > Ist das ein langsamer AD-Wandler? Ja. Es gibt inzwischen Wandler mit mehreren 100 MHz Samplerate. Duke
Datum:
danke für deine Antwort! kann jemand noch mir erklären, die Sache mir Sinc3-Filter, ob es ausreichend ist? vielen Dank im Voraus! Lg Tomy
Datum:
tomy schrieb:
clk_div_pro: process begin wait until rising_edge(Mclk); if rst = '1' then clk_div_cnt <= (others => '0'); else clk_div_cnt <= std_logic_vector(unsigned(clk_div_cnt) + x"1"); end if; end process clk_div_pro; -- wired diff_clk <= clk_div_cnt(DECIMATOR_M_BIT_SIZE-1); -- MSB DataRate_clk <= diff_clk; Diff_pro: process begin wait until falling_edge(diff_clk); -- Falling Edge! |
So erzeugt man in einem FPGA keine abgeleiteten Takte. Im Idealfall hast du sowieso nur 1 Takt und arbeitest dann mit Clock-Enables:
signal diff_enable : std_logic := '0'; -- clk divider ->> Mclk/DECIMATOR_M signal clk_div_cnt : integer range 0 to 2**DECIMATOR_M_BIT_SIZE-1 := 0; : : clk_div_pro: process begin wait until rising_edge(Mclk); if clk_div_cnt = 2**DECIMATOR_M_BIT_SIZE-1 then clk_div_cnt <= 0; diff_enable <= '1'; else clk_div_cnt <= clk_div_cnt+1; diff_enable <= '0'; end if; end process clk_div_pro; Diff_pro: process begin wait until rising_edge(Mclk); -- es kann nur EINEN geben! if (diff_enable='1') then : |
Datum:
danke Lothar für dein Tipp:-) kann jemand noch mir erklären, die Sache mir Sinc3-Filter, ob es ausreichend ist? gruß Tomy
Datum:
tomy schrieb: > kann jemand noch mir erklären, die Sache mir Sinc3-Filter, ob es > ausreichend ist? Das mußt Du wissen. Dafür macht man vorher eine Systembetrachtung und zur Prüfung dieser Btrachtung eine Modellsimulation. Dafür eignet sich z.B. ein Tool wie Matlab. Duke
Datum:
Duke Scarring schrieb: > Das mußt Du wissen. Dafür macht man vorher eine Systembetrachtung und > zur Prüfung dieser Btrachtung eine Modellsimulation. Dafür eignet sich > z.B. ein Tool wie Matlab. wie sieht das Systembetrachtung mit Matlab ungefähr aus? Ich hab noch nie einen Filter mit Matlab entworfen:( kannst du mir ein Beispeil-code für sinc3 geben? lg Tomy
Datum:
if Mdata = '1' then
acc1 <= acc1 + x"1";
end if;
kann mir jemand erklären warum hier x"1" geschrieben wurde?
und warum nicht wie hier:
if Mdata = '1' then
-- acc1 <= acc1 + x"1";
acc1 <= acc1 + acc1;
end if;
Datum:
sorry habe mich vertippt: > if Mdata = '1' then > -- acc1 <= acc1 + x"1"; acc1 <= acc1 + 1; > end if;
Datum:
cetec Ftec schrieb: >> if Mdata = '1' then >> -- acc1 <= acc1 + x"1"; > acc1 <= acc1 + 1; >> end if; so weit ich kenne: weil acc1 als std_locgic_vector deklariert wurde. Deine Variante wäre acc1 als integer.
Datum:
Danke zuerst, Tomy schrieb: > so weit ich kenne: > weil acc1 als std_locgic_vector deklariert wurde. du hast oben acc1 als unsigned deklariert. ist es möglich deine gesamte code mit verbesserten version zu sehen und die Testbenc? Gruß Ftec
Datum:
Angehängte Dateien:ich versuche nach dieser Muster (PDF) einen Sinc3filter zu erweitern, wie der Lothar oben erklärte. aber ich kriege error: No identifier "signed" in scope kann mir jemand, wie man es korrigiert. Gruß Ftec
Datum:
Angehängte Dateien:cetec Ftec schrieb: > du hast oben acc1 als unsigned deklariert. > ist es möglich deine gesamte code mit verbesserten version zu sehen und > die Testbenc? Hallo, hier ist meine Version im Anhang, für testbench hab ich kein echtes AD-Model, sondern nur data-streaming aus AD-Wandler...Ich würde sagen es reicht erstmal für Filter Testen...
Datum:
Hallo Tomy, danke sehr nett von dir. in "sinc_filt" hast du einen component drin für "edge detect", dafür wird auch die Code benötigt oder? Gruß Ftec
Datum:
cetec Ftec schrieb: > in "sinc_filt" hast du einen component drin für "edge detect", dafür > wird auch die Code benötigt oder? nein, du kannst auskommentieren lg Tomy
Datum:
Angehängte Dateien:ach doch, hier ist der im Anhang...das hab ich mir auch hier im forum geholt..
Datum:
Hallo Tomy, danke nocmals. ich versuche meine VHDL code zu simmulieren, aber ich kriege es nicht hin. kannst du mir dabei helfen? ich kann meine Code hochladen. Danke Ftec
Datum:
cetec Ftec schrieb: > kannst du mir dabei helfen? ich kann meine Code hochladen. ich würde versuchen....
Datum:
Angehängte Dateien:Hi, danke, hier ist die Code. Gruß Ftec
Datum:
Angehängte Dateien:Ich habe versucht anhand des Beispiels hier im Forum selbst ein Sync3 Filter zu schreiben. In Testbench hatte ich „0101010101….“ Reihenfolge generiert, was einem level von 0.5 entsprechen sollte. Leider bekomme ich lauter 0000 als Ausgabe. Kann mir jemand sagen woran es liegt? Danke im Voraus Student

