Forum: FPGA, VHDL & Co. Verhalten mikroskopisch ok, makroskopisch komisch


von Gerald M. (gerald_m17)


Angehängte Dateien:

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;

von Gästchen (Gast)


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.

von J. S. (engineer) Benutzerseite


Lesenswert?

Wenn da ein 80Hz Filter hängt, kann es nicht so aussehen, meine ich.

Für mich sieht das verdächtig danach aus, daß dort irgendwelche Signale 
nicht sauber rausgetaktet werden und spike rausgehen. Gfs wird auch der 
Loopd nicht richtig eingetaktet oder es ist ein overflow.

von Bitwurschtler (Gast)


Lesenswert?

Jürgen S. schrieb:
> Wenn da ein 80Hz Filter hängt, kann es nicht so aussehen, meine ich.

Warum Nicht? Wenn da "Dreck" auf der Masse wg Schaltregler ist, dann 
schaut das genauso aus, da nutz kein 80Hz Filter an den FPGA-Ausgängen.

Miss mal mit kurzer Taskopfmasse.

von Gerald M. (gerald_m17)


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.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


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)

: Bearbeitet durch Moderator
von J. S. (engineer) Benutzerseite


Lesenswert?

Nun ja, im Prinzip ist die Messung damit ja richtig, denn sie zeigt, was 
aus den FPGA-Pins rauskommt. Allerdings sind die Spitzen ja im Pegel 
auch recht gering.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.