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;
|