Forum: FPGA, VHDL & Co. Spartan 3e - DAC


von Tobi (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

Ich bin blutiger Anfänger was das programmieren mit vhdl und Verwendung 
von FPGAs angeblangt und habe ein Problem bei dem ihr mir hoffentlich 
helfen könnt.
Ich möchte mit dem DAC des Spartan 3e (LTC2624 DAC) ein konstantes 
Signal ausgeben. Leider funktioniert das Ganze absolut nicht. Die 
verwendete .vhdl und .ucf habe ich angehängt.
Habt ihr vielleicht eine einfaches Beispiel wie die Ausgabe an den DACs 
funktioniert. Im Internet finde ich nur Programme bei denen noch viel 
Zeug
drumherum gemacht wird. Da schaue ich irgendwie nicht durch.

Es wäre nett, wenn ihr mir helfen könntet.

Grüße
Tobi

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


Lesenswert?

Tobi schrieb:
> Leider funktioniert das Ganze absolut nicht.
Funktioniert die Simulation?
Welche Taktfrequenz clk hast du?
Kann der DAC-SPI überhaupt so schnell?

BTW:
Das mit dem Taster sehe ich kritisch.
1
 if rising_edge(clk) then
2
   if btn = '1' then
3
   dacstate <= start;
4
   else 
5
  case dacstate is
6
   when  start =>
7
    dacstate <= sendbit;
8
          :
9
   when sendbit  =>
10
    SClk <= '0';
11
   :
Wenn der prellt, dann startest du bei aktiviertem CS blitzschnell z.B. 
10 mal hintereinander eine Übertragung...

Wozu eigentlich ein Taster?
Du startest doch sowieso sofort nach dem Ende der Übertragung wieder von 
vorn:
1
   when cshigh =>
2
    CS <= '1';
3
    dacstate <= start;

von Tobi (Gast)


Lesenswert?

Hallo,

Ich habe den Taster mal entfernt.
Die Taktfrequenz vom Clock sind 50 MHz. Bin nicht sicher wie schnell der 
DAC-SPI sein kann.
Bei der Simualtion passiert rein gar nichts. Also alle Signale bleiben 
während der gesamten Simulation gleich. Ich weiß aber auch nicht wie man 
ein
Testbench richtig anlegt. Habe sowas wie gesagt noch nie gemacht.

von Tobi (Gast)


Lesenswert?

Hallo,

Ich habe im Datasheet vom DAC nachgeschaut. Der sollte die 50 Mhz 
eigentlich schaffen.

http://www.datasheetcatalog.org/datasheet2/c/0g7ltueocowf5f04zxxzy5tgur3y.pdf

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


Lesenswert?

Tobi schrieb:
> Der sollte die 50 Mhz eigentlich schaffen.
Grenzwertig mit thi und tlo = min. 9ns.
Aber du hast bei 50MHz-FPGA-Takt sowieso jeweils 20ns.

> Bei der Simualtion passiert rein gar nichts.
Da würde ich mal ansetzen...

> Ich weiß aber auch nicht wie man ein
> Testbench richtig anlegt. Habe sowas wie gesagt noch nie gemacht.
Du kannst bei Xilinx ISE mit Add New Source --> VHDL Testbench einfach 
eine Testbench erzeugen. Dort müsstest du dann nur noch einen Takt 
erzeugen, der Rest läuft (ohne den Start-Knopf) von alleine.

von Christian R. (supachris)


Lesenswert?

Für den DAC auf dem Spartan 3e Board hatte ich mal einen schnellen Test 
zusammen geklöppelt damals:
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use IEEE.NUMERIC_STD.ALL;
4
5
library UNISIM;
6
use UNISIM.VComponents.all;
7
8
entity LTC2624_SPI_Master is
9
    Port ( CLK :         in  STD_LOGIC;
10
           RST :         in  STD_LOGIC;
11
           DAC_Data :     in  STD_LOGIC_VECTOR (11 downto 0);
12
           DAC_Channel :  in  STD_LOGIC_VECTOR (3 downto 0);
13
        DAC_Command :   in  STD_LOGIC_VECTOR (3 downto 0);
14
        DAC_Update :   in  STD_LOGIC;
15
           DAC_CS_n :     out  STD_LOGIC;
16
           DAC_SCK :     out  STD_LOGIC;
17
           DAC_SDI :     out  STD_LOGIC;
18
           DAC_CLR_n :     out  STD_LOGIC;
19
           DAC_Busy :     out  STD_LOGIC);
20
end LTC2624_SPI_Master;
21
22
architecture Behavioral of LTC2624_SPI_Master is
23
24
Signal ShiftReg, DAC_Value : std_logic_vector(23 downto 0) := (others => '0');
25
Signal BitCount : integer range 0 to 24 := 0;
26
Signal ShiftEn, Busy, Load, nCLK : std_logic := '0';
27
28
begin
29
  
30
  nCLK <= not CLK;
31
  
32
  ValueReg : Process(CLK)
33
  Begin
34
    if rising_edge(CLK)then
35
      if RST = '1' then DAC_Value <= (others => '0');
36
      elsif DAC_Update = '1' and Busy = '0' then DAC_Value <= DAC_Command & DAC_Channel & DAC_Data & "0000";
37
      end if;
38
    end if;
39
  End Process;
40
41
  SPICounter : Process(CLK)
42
  Begin
43
    if rising_edge(CLK)then
44
      if RST = '1' then BitCount <= 0;
45
      elsif Load = '1' then BitCount <= 24;
46
      elsif ShiftEn = '1' then BitCount <= BitCount - 1;
47
      end if;
48
    end if;
49
  End Process;
50
51
  ShiftEn <= '0' when BitCount = 0 else '1';
52
  
53
  LoadDelay : Process(CLK)
54
  Begin
55
    if rising_edge(CLK)then
56
      if RST = '1' then Load <= '0';
57
      elsif Busy = '0' then Load <= DAC_Update;
58
      end if;
59
    end if;
60
  End Process;
61
62
  SR24 : Process(CLK)
63
  Begin
64
    if rising_edge(CLK)then
65
      if Load = '1' then ShiftReg <= DAC_Value;
66
      elsif ShiftEn = '1' then ShiftReg <= ShiftReg(22 downto 0) & '1';
67
      end if;
68
    end if;
69
  End Process;
70
71
  Busy <= ShiftEn;
72
  
73
  DAC_Busy <= Busy;
74
  
75
  DAC_CLR_n <= not RST;
76
  DAC_CS_n <= not ShiftEn;
77
  DAC_SDI <= ShiftReg(23);
78
  
79
  SPI_ClockOut :  ODDR2  Port map(Q   => DAC_SCK, C0 => CLK, C1 => nCLK, CE => '1', D0 => '0', D1 => '1', R => '0', S => '0');
80
81
end Behavioral;

von Tobi (Gast)


Lesenswert?

Hallo,

Ich verstehe eben nicht warum in der Simulation nichts passiert.
Ich hatte zeitweise in jedem "state" meines Programms auch eine LED, 
welche
aufleuchten sollte, wenn das Programm an ihr vorbeikommt.
Und das haben alle Leds auch brav getan.
Wie baue ich denn die Clock richtig in mein Testbench ein?

(Sorry, wenn das hier wirklich ganz einfache Probleme sind, aber ich 
wurde
von meinem Chef in der Uni wirklich ohne jede Vorkenntnis in 
Programmieren oder Elektronik an diese Board gesetzt)

Grüße und Danke
Tobi

von Tobi (Gast)


Lesenswert?

@supachris

Danke für den Code. Hast du noch deine User Constraints File.
Ich habe teils Probleme in der entity-liste zuzuordnen, was was auf
dem FPGA Board ist.

von GastausHannover (Gast)


Lesenswert?

hallo,

ich steuere an grad auch den dac. Ich hab auch idee im forum gefunden 
und bisschen verändern. Hier ist der code für 4-kanale nacheinander 
gesteuert.
Es funktioniert super in Simulation, aber in hardware, starter kit 
spartan 3a, scheint problem meiner meinung nach beim "rst"-signal.

clk = 80Mh aus DCM-clkfx, dann meine meinung nach ist SPI-CLK(also 
SPI-SCK) = 80/2 = 40Mhz, also kleiner als maximal 50Mhz. Die 4 
Data-Eingänge sind jede 10Khz aktualisiert.

Problem ist: Manchmal muss ich mehrmals den rst-Taster drücken, damit 
die signals auf dem oszi sauber scheinen, sonst viel rausch. Wenn nur 
ein Kanal umgesetzt wird, beeinflusst der rst-taster weniger, abwohl ich 
NUR noch 1,2-mals den rst-taster drücken muss:D :-(

PS. Ich hab noch nicht Timing constraint ins projeckt reingebaut, weiss 
nicht, ob das auch problem sein kann.

kann jemand vorschlag geben?
1
----------------------------------------------------------------------------------
2
-- Company: 
3
-- Engineer: 
4
-- 
5
-- Create Date:    12:38:14 01/11/2010 
6
-- Design Name: 
7
-- Module Name:    dacAnsteuerung - Behavioral 
8
-- Project Name: 
9
-- Target Devices: 
10
-- Tool versions: 
11
-- Description: 
12
--
13
-- Dependencies: 
14
--
15
-- Revision: 
16
-- Revision 0.01 - File Created
17
-- Additional Comments: 
18
--
19
----------------------------------------------------------------------------------
20
library IEEE;
21
use IEEE.STD_LOGIC_1164.ALL;
22
use IEEE.NUMERIC_STD.ALL;
23
--use IEEE.STD_LOGIC_ARITH.ALL;
24
--use IEEE.STD_LOGIC_UNSIGNED.ALL;
25
26
---- Uncomment the following library declaration if instantiating
27
---- any Xilinx primitives in this code.
28
--library UNISIM;
29
--use UNISIM.VComponents.all;
30
31
entity dacAnsteuerung is
32
    Port ( clk : in  STD_LOGIC;
33
        rst : in STD_LOGIC;
34
        dataInA : in STD_LOGIC_VECTOR (11 downto 0);
35
        dataInB : in STD_LOGIC_VECTOR (11 downto 0); 
36
        dataInC : in STD_LOGIC_VECTOR (11 downto 0); 
37
        dataInD : in STD_LOGIC_VECTOR (11 downto 0);         
38
           SPI_MOSI : out  STD_LOGIC;
39
           SPI_CS : out  STD_LOGIC;
40
           SPI_CLR : out  STD_LOGIC;
41
           SPI_SCK : out  STD_LOGIC
42
       );
43
end dacAnsteuerung;
44
45
architecture Behavioral of dacAnsteuerung is
46
47
  -----DAC SPI Config
48
  type dacStateType is (idle, bitSammel, sendBit, spiClkHigh, csHigh);
49
  signal dacState : dacStateType := idle;
50
  signal dacCounter : integer range 0 to 31 := 31;
51
  signal dacConfig   : std_logic_vector (31 downto 0) := (others => '0');
52
  
53
54
  -----Data-In Auswählen
55
  signal dataIn    : STD_LOGIC_VECTOR (11 downto 0) := (others => '0');
56
  
57
  -----DAC Address Auswählen
58
  constant dacAddrA  : std_logic_vector (3 downto 0) := "0000";
59
  constant dacAddrB  : std_logic_vector (3 downto 0) := "0001";
60
  constant dacAddrC  : std_logic_vector (3 downto 0) := "0010";
61
  constant dacAddrD  : std_logic_vector (3 downto 0) := "0011";
62
  signal   dacAddr  : std_logic_vector (3 downto 0) := dacAddrA;
63
  
64
  ---Test
65
  signal stateTest  : integer range 0 to 4 := 0;
66
  type Konvertionschanel is (chA, chB, chC, chD);
67
  signal chanel : Konvertionschanel := chA;
68
  
69
begin
70
  
71
  
72
  dacAnsteureung: process (clk, rst)
73
              variable dataOldA, dataOldB,
74
                    dataOldC, dataOldD : std_logic_vector (11 downto 0) := (others => '0');
75
              begin          
76
                if rst = '0' then
77
                  SPI_MOSI <= '0';
78
                  SPI_CS <= '1';
79
                  SPI_SCK <= '0';
80
                  dacState <= idle;
81
                elsif rising_edge(clk) then
82
                
83
                      case dacState is
84
                        when idle => --idle state
85
                          dacCounter <= 31;
86
                          SPI_CS <= '0';
87
                          SPI_SCK <= '0';
88
                          
89
                          ---Konvertion when neue Data
90
                          if dataOldA /= dataInA then--new dataIn Chanel A?
91
                            dataIn <= dataInA;
92
                            dacAddr <= dacAddrA;
93
                            dacState <= bitSammel;
94
                            dataOldA := dataInA;
95
                            -----Test
96
                            chanel <= chA;
97
                          elsif dataOldB /= dataInB then--new dataIn Chanel B?
98
                            dataIn <= dataInB;
99
                            dacAddr <= dacAddrB;
100
                            dacState <= bitSammel;
101
                            dataOldB := dataInB;
102
                            -----Test
103
                            chanel <= chB;
104
                          elsif dataOldC /= dataInC then--new dataIn Chanel C?
105
                            dataIn <= dataInC;
106
                            dacAddr <= dacAddrC;
107
                            dacState <= bitSammel;
108
                            dataOldC := dataInC;
109
                            -----Test
110
                            chanel <= chC;
111
                          elsif dataOldD /= dataInD then--new dataIn Chanel D?
112
                            dataIn <= dataInD;
113
                            dacAddr <= dacAddrD;
114
                            dacState <= bitSammel;
115
                            dataOldD := dataInD;
116
                            -----Test
117
                            chanel <= chD;
118
119
                          
120
                          else 
121
                            dacState <= idle;
122
                          end if;
123
                    
124
                          ----Test
125
                          stateTest <= 0;
126
                        when bitSammel =>
127
                              -- 31 downto 0
128
                              -- 8 bits dont_care & Command & address & dataIn & 4 bits dont_care
129
                          dacConfig <= "00000000" & "0011" & dacAddr & dataIn & "0000";
130
                          dacState <= sendBit;
131
                          ----
132
                          stateTest <= 1;
133
                        when sendBit =>
134
                          SPI_SCK <= '0';
135
                          SPI_MOSI <= dacConfig (31);
136
                          dacConfig <= dacConfig (30 downto 0) & '0';
137
                          dacState <= spiClkHigh;
138
                          ----
139
                          stateTest <= 2;
140
                        when spiClkHigh =>
141
                          SPI_SCK <= '1';
142
                          if dacCounter = 0 then
143
                            dacState <= csHigh;
144
                          else 
145
                            dacCounter <= dacCounter - 1;
146
                            dacState <= sendBit;
147
                          end if;
148
                          ----
149
                          stateTest <= 3;
150
                        when csHigh =>
151
                          SPI_CS <= '1';
152
                          dacState <= idle;
153
                          ----
154
                          stateTest <= 4;
155
                        end case;
156
           
157
                end if;
158
               
159
          end process;
160
            
161
       
162
          SPI_CLR <= '1';--aktiv LOW        
163
end Behavioral;

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


Lesenswert?

GastausHannover schrieb:
> beeinflusst der rst-taster weniger, abwohl ich
> NUR noch 1,2-mals den rst-taster drücken muss:D :-(
Ein Dauerbrenner und immer der selbe :-/
Der Reset ist ein asynchrones Signal und muss einsynchronisiert 
werden.
1
                if rst = '0' then  -- Asynchrone Resets sind schlecht.
2
                  SPI_MOSI <= '0';
3
                  SPI_CS <= '1';
4
                  SPI_SCK <= '0';
5
                  dacState <= idle;
6
                elsif rising_edge(clk) then
7
                   ...
Das ist klar, dass der dir die ganze State-Machine zerhagelt.
Als Hintergrund: 
http://www.lothar-miller.de/s9y/categories/35-Einsynchronisieren
Das Signal inp dort im Beispiel, ist in diesem Fall hier dein Reset, 
der unterschiedliche Laufzeiten hat...

von Tobi (Gast)


Lesenswert?

Guten Abend,

Ok habe jetzt raus wie ich ein Testbench schreiben kann.
Melde mich im Laufe der nächsten Woche evtl. nochmal, wenn ich
das Problem eingegrenzt habe.

von GastausHannover (Gast)


Lesenswert?

Lothar Miller schrieb:
> Ein Dauerbrenner und immer der selbe :-/
> Der Reset ist ein asynchrones Signal und muss einsynchronisiert
> werden.                if rst = '0' then  -- Asynchrone Resets sind schlecht.
>                   SPI_MOSI <= '0';
>                   SPI_CS <= '1';
>                   SPI_SCK <= '0';
>                   dacState <= idle;
>                 elsif rising_edge(clk) then
>                    ...
> Das ist klar, dass der dir die ganze State-Machine zerhagelt.
> Als Hintergrund:
> http://www.lothar-miller.de/s9y/categories/35-Eins...
> Das Signal inp dort im Beispiel, ist in diesem Fall hier dein Reset,
> der unterschiedliche Laufzeiten hat...

hallo Lothar, vielen dank:-)
deine seite ist echt cool:-) great job^^

ich hab grad ausprobiert nach deiner rezept und mit der 
einsynchronisierung des rst-signals geht wie erwartet^^. Wobei ich hab 
den rst vom DAC-Ansteuerung weggenommen, also der DAC läuft immer mit 
80Mhz takt und den rst-signal von signalgenerator-block 
einsynchonisiert.

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


Lesenswert?

> ich hab grad ausprobiert nach deiner rezept und mit der
> einsynchronisierung des rst-signals geht wie erwartet^^.
QED  ;-)

von maikh (Gast)


Lesenswert?

Guten Abend,
ich habe bei den Xilinx Spartan 3A und E Boards von Xilinx / Digilent 
die Erfahrung machen müssen, dass auf den Steurleitungen, die unter 
anderem den VGA (Variable Gain Amplifier) per SPI konfigurieren direkt 
beim Einschalten nach Start des FPGAs noch igendwelche Daten 
herumgeistern. (Ich glaube vom Platform Flash)
Wenn dann eine FSM diesen Verstärker per SPI konfigurieren soll, kommt 
das Steuerwort nicht korrekt an, da das FPGA schon läuft. Ich habe dann 
einfach ein paar Wartezyklen eingebaut...
Ist das Problem bekannt / was tut man da "professionell" gegen.

mfg Maik

von Tobi (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

Ich habe jetzt einen Testbench geschrieben und das ganze simuliert. Ich 
kann
aber auch dort keinen Fehler sehen. Bitte also nochmal um Hilfe.

Grüße
Tobi

von Tobi (Gast)


Lesenswert?

Hej,

Ich habe grade meinen Fehler gefunden.
Das Xilinx-Handbuch verschweigt, dass ich auf einen Pin des DAC noch
ein Signal geben muss, damit der DAC-Output nicht sofort wieder auf 0 
gesetzt wird.

Danke für eure Zeit
Tobi

von GastausHannover (Gast)


Lesenswert?

GastausHannover schrieb:
> ------------------------------------------------------------------------ 
----------
> -- Company:
> -- Engineer:
> --
> -- Create Date:    12:38:14 01/11/2010
> -- Design Name:
> -- Module Name:    dacAnsteuerung - Behavioral
> -- Project Name:
> -- Target Devices:
> -- Tool versions:
> -- Description:
> --
> -- Dependencies:
> --
> -- Revision:
> -- Revision 0.01 - File Created
> -- Additional Comments:
> --
> ------------------------------------------------------------------------ 
----------
> library IEEE;
> use IEEE.STD_LOGIC_1164.ALL;
> use IEEE.NUMERIC_STD.ALL;
> --use IEEE.STD_LOGIC_ARITH.ALL;
> --use IEEE.STD_LOGIC_UNSIGNED.ALL;
>
> ---- Uncomment the following library declaration if instantiating
> ---- any Xilinx primitives in this code.
> --library UNISIM;
> --use UNISIM.VComponents.all;
>
> entity dacAnsteuerung is
>     Port ( clk : in  STD_LOGIC;
>         rst : in STD_LOGIC;
>         dataInA : in STD_LOGIC_VECTOR (11 downto 0);
>         dataInB : in STD_LOGIC_VECTOR (11 downto 0);
>         dataInC : in STD_LOGIC_VECTOR (11 downto 0);
>         dataInD : in STD_LOGIC_VECTOR (11 downto 0);
>            SPI_MOSI : out  STD_LOGIC;
>            SPI_CS : out  STD_LOGIC;
>            SPI_CLR : out  STD_LOGIC;
>            SPI_SCK : out  STD_LOGIC
>        );
> end dacAnsteuerung;
>
> architecture Behavioral of dacAnsteuerung is
>
>   -----DAC SPI Config
>   type dacStateType is (idle, bitSammel, sendBit, spiClkHigh, csHigh);
>   signal dacState : dacStateType := idle;
>   signal dacCounter : integer range 0 to 31 := 31;
>   signal dacConfig   : std_logic_vector (31 downto 0) := (others => '0');
>
>
>   -----Data-In Auswählen
>   signal dataIn    : STD_LOGIC_VECTOR (11 downto 0) := (others => '0');
>
>   -----DAC Address Auswählen
>   constant dacAddrA  : std_logic_vector (3 downto 0) := "0000";
>   constant dacAddrB  : std_logic_vector (3 downto 0) := "0001";
>   constant dacAddrC  : std_logic_vector (3 downto 0) := "0010";
>   constant dacAddrD  : std_logic_vector (3 downto 0) := "0011";
>   signal   dacAddr  : std_logic_vector (3 downto 0) := dacAddrA;
>
>   ---Test
>   signal stateTest  : integer range 0 to 4 := 0;
>   type Konvertionschanel is (chA, chB, chC, chD);
>   signal chanel : Konvertionschanel := chA;
>
> begin
>
>
>   dacAnsteureung: process (clk, rst)
>               variable dataOldA, dataOldB,
>                     dataOldC, dataOldD : std_logic_vector (11 downto 0) := 
(others => '0');
>               begin
>                       if rising_edge(clk) then
>
>                       case dacState is
>                         when idle => --idle state
>                           dacCounter <= 31;
>                           SPI_CS <= '0';
>                           SPI_SCK <= '0';
>
>                           ---Konvertion when neue Data
>                           if dataOldA /= dataInA then--new dataIn Chanel A?
>                             dataIn <= dataInA;
>                             dacAddr <= dacAddrA;
>                             dacState <= bitSammel;
>                             dataOldA := dataInA;
>                             -----Test
>                             chanel <= chA;
>                           elsif dataOldB /= dataInB then--new dataIn Chanel B?
>                             dataIn <= dataInB;
>                             dacAddr <= dacAddrB;
>                             dacState <= bitSammel;
>                             dataOldB := dataInB;
>                             -----Test
>                             chanel <= chB;
>                           elsif dataOldC /= dataInC then--new dataIn Chanel C?
>                             dataIn <= dataInC;
>                             dacAddr <= dacAddrC;
>                             dacState <= bitSammel;
>                             dataOldC := dataInC;
>                             -----Test
>                             chanel <= chC;
>                           elsif dataOldD /= dataInD then--new dataIn Chanel D?
>                             dataIn <= dataInD;
>                             dacAddr <= dacAddrD;
>                             dacState <= bitSammel;
>                             dataOldD := dataInD;
>                             -----Test
>                             chanel <= chD;
>
>
>                           else
>                             dacState <= idle;
>                           end if;
>
>                           ----Test
>                           stateTest <= 0;
>                         when bitSammel =>
>                               -- 31 downto 0
>                               -- 8 bits dont_care & Command & address & dataIn & 
4 bits dont_care
>                           dacConfig <= "00000000" & "0011" & dacAddr & dataIn & 
"0000";
>                           dacState <= sendBit;
>                           ----
>                           stateTest <= 1;
>                         when sendBit =>
>                           SPI_SCK <= '0';
>                           SPI_MOSI <= dacConfig (31);
>                           dacConfig <= dacConfig (30 downto 0) & '0';
>                           dacState <= spiClkHigh;
>                           ----
>                           stateTest <= 2;
>                         when spiClkHigh =>
>                           SPI_SCK <= '1';
>                           if dacCounter = 0 then
>                             dacState <= csHigh;
>                           else
>                             dacCounter <= dacCounter - 1;
>                             dacState <= sendBit;
>                           end if;
>                           ----
>                           stateTest <= 3;
>                         when csHigh =>
>                           SPI_CS <= '1';
>                           dacState <= idle;
>                           ----
>                           stateTest <= 4;
>                         end case;
>
>                 end if;
>
>           end process;
>
>
>           SPI_CLR <= '1';--aktiv LOW
> end Behavioral;

hello,


ich hab mich mit diesem code für 4 kanal in spartan 3a, starter board 
gerade beschäftigt, vorher dachte ich dass es gut läuft, aber irgendwie 
läuft manchmal nicht wie erwartet, also mit viel rauschen:(

Die output Pin hab ich wie beschrieben in spartan 3a, starter kit user 
guide:

NET "SPI_MOSI" LOC = AB14;
NET "SPI_MOSI" DRIVE = 8;
NET "SPI_MOSI" SLEW = SLOW;
NET "SPI_CS" LOC = W7;
NET "SPI_MOSI" IOSTANDARD = "LVCMOS33";
NET "SPI_CS" IOSTANDARD = "LVCMOS33";
NET "SPI_CS" DRIVE = 8;
NET "SPI_CS" SLEW = SLOW;
NET "SPI_SCK" LOC = AA20;
NET "SPI_SCK" IOSTANDARD = "LVCMOS33";
NET "SPI_SCK" DRIVE = 8;
NET "SPI_SCK" SLEW = SLOW;
NET "SPI_CLR" LOC = AB13;
NET "SPI_CLR" IOSTANDARD = "LVCMOS33";
NET "SPI_CLR" DRIVE = 8;
NET "SPI_CLR" SLEW = SLOW;


clk sigal aus DCM ist 80Mhz, dann meine ich die SPI_SCK = 80/2 = 40Mhz.

die 4 Datain sollen jede 10khz gleichzeitig aktualisiert werden.

vielleicht liegt es an 4-else if für kanalauswahl? oder habt ihr anderen 
vorschlag für den ganzen code?

vielen dank im vorraus!

von Anguel S. (anguel)


Lesenswert?

Hallo!

Ich habe mal eine kurze Frage zu dem von Christian vorgestellten 
DAC-Code, der ODDR2 nutzt:

Christian R. schrieb:

> Für den DAC auf dem Spartan 3e Board hatte ich mal einen schnellen Test
> zusammen geklöppelt damals:
> ...
>   SR24 : Process(CLK)
>   Begin
>     if rising_edge(CLK)then
>       if Load = '1' then ShiftReg <= DAC_Value;
>       elsif ShiftEn = '1' then ShiftReg <= ShiftReg(22 downto 0) & '1';
>       end if;
>     end if;
>   End Process;
> ...
>   SPI_ClockOut :  ODDR2  Port map(Q   => DAC_SCK, C0 => CLK, C1 => nCLK,
> CE => '1', D0 => '0', D1 => '1', R => '0', S => '0');

Wenn ich das richtig verstehe, werden die Daten vom FPGA als SPI-Master 
auf rising_edge(clk) gecaptured. Dann müsste doch der ODDR2 Ausgang 
genau den Verlauf des CLK nachbilden. Warum ist dann das ODDR2 so 
konfiguriert, dass D0 auf '0' und D1 auf '1' gesetzt sind. Wird dadurch 
nicht der generierte SPI-Clock für den DAC verschoben? Müssten die Werte 
für D0 und D1 nicht vertauscht werden?

Grüße,
Anguel

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.