www.mikrocontroller.net

Forum: FPGA, VHDL & Co. Frage zum Theta Delta-Sigma AD


Important announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
Autor: tomy (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
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

Autor: Duke Scarring (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
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

Autor: Tomy (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
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

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite Flattr this
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
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
        :

Autor: tomy (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
danke Lothar für dein Tipp:-)

kann jemand noch mir erklären, die Sache mir Sinc3-Filter, ob es
ausreichend ist?

gruß Tomy

Autor: Duke Scarring (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
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

Autor: tomy (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
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

Autor: cetec Ftec (ftec)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
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;

Autor: cetec Ftec (ftec)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
sorry habe mich vertippt:

>       if Mdata = '1' then
>       --  acc1 <= acc1 + x"1";
      acc1 <= acc1 + 1;
>       end if;

Autor: Tomy (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
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.

Autor: cetec Ftec (ftec)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
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

Autor: cetec Ftec (ftec)
Datum:
Angehängte Dateien:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
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

Autor: Tomy (Gast)
Datum:
Angehängte Dateien:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
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...

Autor: cetec Ftec (ftec)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
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

Autor: Tomy (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
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

Autor: Tomy (Gast)
Datum:
Angehängte Dateien:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
ach doch, hier ist der im Anhang...das hab ich mir auch hier im forum 
geholt..

Autor: cetec Ftec (ftec)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
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

Autor: Tomy (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
cetec Ftec schrieb:
> kannst du mir dabei helfen? ich kann meine Code hochladen.

ich würde versuchen....

Autor: cetec Ftec (ftec)
Datum:
Angehängte Dateien:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Hi,

danke, hier ist die Code.

Gruß
Ftec

Autor: Student (Gast)
Datum:
Angehängte Dateien:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel




Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder GIF-Format hochladen.
Siehe Bildformate

Mit dem Abschicken erkennst du die Nutzungsbedingungen an.

webmaster@mikrocontroller.netImpressumNutzungsbedingungenWerbung auf Mikrocontroller.net