Verhalten mikroskopisch ok, makroskopisch komisch

#4536852
Lesenswert?

Hallo,

ich würde gerne einen Delta-Sigma DAC mit meinem FPGA "bauen".
Hierzu habe ich zunächst die einfache Version programmiert (im Code 
auskommentiert), bei dem einfach der Wert immer aufaddiert wird, und bei 
einem overflow der Port eine '1' ausgibt, ansonsten eine '0'.
Da ich dann niederfrequente (im Bereich von 10kHz) Rechtecke im 
gefilterten Signal hatte.
Also habe ich im Internet den Code für einen DAC zweiter Ordnung 
gefunden und eingebunden (und leicht verändert, damit ich einen 
clock-enable habe).
Das sah schon viel besser aus, doch erhalte ich immer Störungen auf dem 
Signal.
Für das Signal erzeuge ich ein Dreieck. Je nach Geschwindigkeit des 
clock-enables des DAC, erhalte ich öfter oder seltener rauschen.
Das Modulierte Signal sieht im Simulator und auf dem Oszi gut aus, das 
gefilterte (10kOhm und 0.2µF = 80Hz) Signal hat regelmäßig Störungen.
Erkennt jemand woran es liegen kann?

Danke schon einmal

Mein Code:
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use IEEE.NUMERIC_STD.ALL;
4

5
entity DAC_Test is
6

7
Port ( clock_50 : in  STD_LOGIC; 
8
       EX_IO  : out STD_LOGIC_vector(6 downto 0));
9
end DAC_Test;
10

11
architecture Behavioral of DAC_Test is
12

13

14
Signal accumulator : signed(24 downto 0);
15
signal counter_inc, counter_dac : integer;
16
signal inc_en, dac_en : std_logic;
17
signal up : std_logic := '0';
18
signal wert : signed(23 downto 0) := to_signed(0,24);
19
constant Wert_lower_limit : signed(23 downto 0) := to_signed(-83836,24);
20
constant Wert_upper_limit : signed(23 downto 0) := to_signed(83836,24);
21
constant inc_div : integer:=16;
22
constant dac_div : integer:=32;
23

24

25
 
26
component dac_dsm2
27
   generic (
28
     nbits : integer );
29
   port (
30
     din   : in  signed((nbits-1) downto 0);
31
     dout  : out std_logic;
32
     clk   : in  std_logic;
33
     clk_en   : in  std_logic;
34
     n_rst : in  std_logic);
35
 end component;
36

37

38

39
begin
40

41
dac1_2nd_order : dac_dsm2 generic map (nbits => 24) port map (wert, EX_IO(0), clock_50, dac_en, '1');
42

43
--dac_1st_order : process (clock_50)  --This is the DAC
44
--begin
45
--if rising_edge(clock_50) then
46
--  if dac_en = '1' then
47
--    accumulator <= ('0' & accumulator(23 downto 0)) + ('0' & wert); 
48
--  end if;
49
--end if;
50
--end process;
51

52

53

54
increment : process (clock_50)  --count up and down
55
begin
56
if rising_edge(clock_50) then
57
  if inc_en='1' then
58
    if up='1' then
59
      wert<= wert + 2;
60
      if wert+2 >= wert_upper_limit then
61
      up <= '0';
62
      end if;
63
    else 
64
      wert<= wert - 2;
65
      if wert-2 <= wert_lower_limit then
66
      up <= '1';
67
      end if;
68
    end if;
69
  end if;
70
end if;
71
end process;
72

73

74
count_inc : process (clock_50)  --speed control counter of triangular wave
75
begin
76
if rising_edge(clock_50) then
77
  if counter_inc = inc_div-1 then
78
    inc_en <= '1';
79
    counter_inc <= 0;
80
  else
81
    inc_en <= '0';
82
    counter_inc <= counter_inc +1;    
83
  end if;
84
end if;
85
end process;
86

87

88
count_dac : process (clock_50)  --speed control counter of dac
89
begin
90
if rising_edge(clock_50) then
91
  if counter_dac = dac_div-1 then
92
    dac_en <= '1';
93
    counter_dac <= 0;
94
  else
95
    dac_en <= '0';
96
    counter_dac <= counter_dac +1;    
97
  end if;
98
end if;
99
end process;
100

101

102
end architecture Behavioral;

Der zweite Ordnung Sigma-Delta-DAC:
1
-------------------------------------------------------------------------------
2
-- Title      : DAC_DSM2 - sigma-delta DAC converter with double loop
3
-- Project    : 
4
-------------------------------------------------------------------------------
5
-- File       : dac_dsm2.vhd
6
-- Author     : Wojciech M. Zabolotny ( wzab[at]ise.pw.edu.pl )
7
-- Company    : 
8
-- Created    : 2009-04-28
9
-- Last update: 2009-04-29
10
-- Platform   : 
11
-- Standard   : VHDL'93c
12
-------------------------------------------------------------------------------
13
-- Description: Implementation without variables
14
-------------------------------------------------------------------------------
15
-- Copyright (c) 2009 - THIS IS PUBLIC DOMAIN CODE!!!
16
-------------------------------------------------------------------------------
17
-- Revisions  :
18
-- Date        Version  Author  Description
19
-- 2009-04-28  1.0      wzab    Created
20
-------------------------------------------------------------------------------
21

22
library ieee;
23
use ieee.std_logic_1164.all;
24
use ieee.numeric_std.all;
25

26
entity dac_dsm2 is
27
  
28
  generic (
29
    nbits : integer := 24);
30

31
  port (
32
    din    : in  signed((nbits-1) downto 0);
33
    dout   : out std_logic;
34
    clk    : in  std_logic;
35
   clk_en : in std_logic;
36
    n_rst  : in  std_logic);
37

38
end dac_dsm2;
39

40
architecture beh1 of dac_dsm2 is
41

42
  signal del1, del2, d_q : signed(nbits+2 downto 0) := (others => '0');
43
  constant c1            : signed(nbits+2 downto 0) := to_signed(1, nbits+3);
44
  constant c_1           : signed(nbits+2 downto 0) := to_signed(-1, nbits+3);
45
begin  -- beh1
46

47
  process (clk, n_rst)
48
  begin  -- process
49
    if n_rst = '0' then                 -- asynchronous reset (active low)
50
      del1 <= (others => '0');
51
      del2 <= (others => '0');
52
      dout <= '0';
53
    elsif clk'event and clk = '1' then  -- rising clock edge
54
    if clk_en= '1' then
55
      del1 <= din - d_q + del1;
56
      del2 <= din - d_q + del1 - d_q + del2;
57
      if din - d_q + del1 - d_q + del2 > 0 then
58
        d_q  <= shift_left(c1, nbits);
59
        dout <= '1';
60
      else
61
        d_q  <= shift_left(c_1, nbits);
62
        dout <= '0';
63
      end if;
64
    end if;
65
    end if;
66
  end process;
67
  
68

69
end beh1;
Angehängte Dateien:
Gast #4536871
Lesenswert?

Bin jetzt kein FPGA-Fuzzi, aber das sieht mir doch stark nach Messfehler 
aus. Insbesondere nach schlechter Masseverbindung und "Autoset-Infarkt".

Beachte doch mal den Maßstab. Du hast 20mVpp Signal am Ausgang des DAC. 
Bist du sicher, dass das das ist, was du ausgeben willst?

Fahr deinen DAC doch mal etwas aus, d.h. den Sinus/Dreieck auf 1Vpp oder 
mehr. Das was du da hast sind 20mVpp, da kann man nur raten, was das für 
eine Signalform hätte werden sollen.

Die "Haare" auf deinem Signal kommen vermutlich von irgendeinem 
Schaltregler. Der muss nicht mal auf deiner Platine sein. 20mV hat man 
gleich mal drin. Drum 1Vpp - da stören die 20mV kaum noch.

Du musst die Masse auch direk da abnehmen, wo das Signal drauf ist, dann 
wird es etwas besser.
#4543343
Lesenswert?

Noch kurz zur Auflösung.
Mir ist aufgefallen, dass als ich herangezoomt habe, das rauschen 
deutlich abgenommen hat. Nach kurzen Oszi-Check habe ich gesehen, dass 
die Bandbreite auf 20MHz begrenzt wurde.
Danach habe ich die Ausgabe nur mit 1MHz gemacht, und ich hatte 
immernoch diese Schwingungen drauf, die bei einer 20 MHz-Begrenzung 
deutlich besser wurden.
Das Ende vom Lied war, dass die Masse des FPGAs mit 50MHz quasi 
verseucht ist und durch den Steckbrettaufbau alles eingefangen wurde. 
Beim direkten auflöten des Filters auf die Pins war es noch einmal 
besser.
Moderator (Firma: Titel) Persönliche Seite #4543401
Lesenswert?

Gerald M. schrieb:
> Das Ende vom Lied war, dass die Masse des FPGAs mit 50MHz quasi
> verseucht ist
Das ist immer so.
Es gibt nicht "die eine Masse", sondern jedes Ende der Platine sieht 
seine "eigene" Masse. Und ein an eine FPGA-Platine angeschlossenes 
Steckbrett hat nochmal eine ganz "andere" Masse...

Stichworte dazu u.A.: Ground Bouncing und SSO (Simultaneously Switching 
Outputs)

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren