Fehler in DDS?

Gast #1272114
Lesenswert?
• ▲
▼
Hallo Freunde,

ich sitze nach wie vor an einer DDS, an der ich im Moment verzweifle und 
wäre für jede Hilfe echt dankbar.

Am Adressausgang (ADDR_OUT) des DDS-Moduls hängt die Lookup Table, in 
der eine viertel Sinusperiode gespeichert ist. Sie gibt nach einem Takt 
den entsprechenden Wert an den LUT_IN Eingang zurück (Werte von 512 bis 
1024) und wird dann über den kombinatorischen Prozess in der zweiten 
Hälfte der Periode subtrahiert, um Werte von 0 bis 1023 an den DAC zu 
geben.

Bei niedrigen Frequenzen und entsprechend niedrigen Phaseninkrementen 
funktioniert die Sache wunderbar. Bei höheren Frequenzen aber verschiebt 
sich die Adressierung zum Phasenregisterüberlauf so, dass im worst case 
die Amplitude des Signals kleiner wird. Das Resultat ist dann eine Art 
Amplitudenmodulation, die ich auch so im Spektrum sehe.

Es ist mein erstes "größeres" VHDL Projekt und langsam drängt die Zeit 
und ich finde meinen Fehler in meinem Vorgehen nicht. Wie gesagt, ich 
freue mich über jede Idee.

Viele Grüße, Max

Code:
1
library ieee;
2
use ieee.std_logic_1164.all;
3
use ieee.numeric_std.all;
4

5
entity DDS is
6
    port (
7
        RST      : in    std_logic;
8
        DDS_ON   : in    std_logic;
9
        ADDR_OUT : out   std_logic_vector(10 downto 0);
10
        LUT_IN   : in    std_logic_vector(8 downto 0);
11
        DDS_OUT  : out   std_logic_vector(8 downto 0);
12
        CLK      : in    std_logic
13
    );
14
end DDS;
15

16
architecture BEHAVE of DDS is
17

18

19
signal phaseaccu : unsigned(16-1 downto 0);
20
signal Delay_1: std_logic_vector(1 downto 0) := "00";
21
signal Delay_2: std_logic_vector(1 downto 0) := "00";
22

23
begin
24

25
     INCREMENT: process (CLK, RST)
26
     begin
27
          if RST = '1' then
28
             phaseaccu <= (others => '0');
29
             Delay_1 <= (others => '0');
30
             Delay_2 <= (others => '0');
31
          elsif CLK'event and CLK = '1' then
32
             if DDS_ON = '1' then phaseaccu <= phaseaccu+16000; end if;
33
             if (phaseaccu(16-1 downto 16-2) = "00") or (phaseaccu(16-1 downto 16-2) = "10") then
34
                ADDR_OUT <= std_logic_vector(phaseaccu(16-3 downto 16-2-10));
35
             else
36
                ADDR_OUT <= std_logic_vector(not phaseaccu(16-3 downto 16-2-10));
37
             end if;
38
             Delay_1 <= std_logic_vector (phaseaccu(16-1 downto 16-2));
39
             Delay_2 <= Delay_1;
40
          end if;
41
     end process INCREMENT;
42

43

44
     ADDRESSING: process (LUT_IN, Delay_2)
45
     begin
46
       case Delay_2 is
47
          when "00" => DDS_OUT <= LUT_IN;
48
          when "01" => DDS_OUT <= LUT_IN;
49
          when "10" => DDS_OUT <= std_logic_vector(2**10 - unsigned (LUT_IN));
50
          when "11" => DDS_OUT <= std_logic_vector(2**10 - unsigned (LUT_IN));
51
          when others => null;
52
       end case;
53
     end process ADDRESSING;
54

55
end;
Angehängte Dateien:
Gast #1272335
Lesenswert?
• ▲
▼
Hallo,

mein Vorredner hat völlig recht: du hast gerade mal noch vier 
Abtastwerte pro voller Sinusperiode. Da kann das Ausgangssignal nicht 
schöner aussehen, als das DDS_Out in deiner Simulation.

Ein analoger Tiefpass mit genau passender Grenzfrequenz könnte dir in 
der realen Schaltung vielleicht ein bisschen helfen. Aber wenn du einen 
"schönen" Sinus brauchst, wird dir nichts anderes übrigbleiben, als CLK 
deutlich schneller und dein Phaseninkrement dementsprechend deutlich 
kleiner zu machen.

schöne Grüße

Achim
Gast #1273577
Lesenswert?
• ▲
▼
Hallo Achim und Name,

vielen Dank für eure Antwort und sorry das ich selbst erst so spät 
antworte, ich konnte nicht in I-Net (unangenehm).

Mich "stört" nicht, dass der Sinus bei hohen Phaseninkrementen so fies 
aussieht - damit rechne ich ja. Ich habe nur noch nie davon 
gehört/gelesen, dass bei anderen DDS Systemen (z.B. Analog Devices) eine 
kleine Anzahl an Abtastwerten zu einer >periodischen< Änderung der 
Amplitude und damit zu einer Amplitudenmodulation führen!

Ich könnte jetzt bspw. mit egal welchem TP Filter kein sauberes 60kHz 
Signal bei einer CLK Frequenz von 480kHz erzeugen. Eigentlich sollte das 
kein Problem sein, aber diese periodische Amplitudenmodulation führt zu 
Spektrallinien bei 60kHz +/- ca. 5 kHz! Vor allem die bei 55kHz kann ich 
nicht filtern.

Die Abtastwerte im LUT sollten mehr als genug sein. Falls Ihr noch eine 
Idee habt oder vielleicht sogar mal ein ähnliches oder gleiches Problem 
freue ich mich über jede Info.

Vielen Dank und ein schönen Sonntag,

Max
Gast #1274328
Lesenswert?
• ▲
▼
> dass bei anderen DDS Systemen (z.B. Analog Devices) eine
> kleine Anzahl an Abtastwerten zu einer >periodischen< Änderung der
> Amplitude und damit zu einer Amplitudenmodulation führen!

Doch. Genau deswegen wird da auf die letzten Bits der LUT-Adresse noch 
ein Rauschen addiert. Stichwort: Phase Dithered DDS

Vielleicht kannst Du Dir auch folgendes Paper besorgen: Spur-Reduced 
Digital Sinusoid Generation Using Higher-Order Phase Dithering 
[Flanagan/ Zimmerman]

Duke

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.