mikrocontroller.net

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


Autor: Tobi (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.
 if rising_edge(clk) then
   if btn = '1' then
   dacstate <= start;
   else 
  case dacstate is
   when  start =>
    dacstate <= sendbit;
          :
   when sendbit  =>
    SClk <= '0';
   :
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:
   when cshigh =>
    CS <= '1';
    dacstate <= start;

Autor: Tobi (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Tobi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

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

http://www.datasheetcatalog.org/datasheet2/c/0g7lt...

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Christian R. (supachris)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Für den DAC auf dem Spartan 3e Board hatte ich mal einen schnellen Test 
zusammen geklöppelt damals:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

library UNISIM;
use UNISIM.VComponents.all;

entity LTC2624_SPI_Master is
    Port ( CLK :         in  STD_LOGIC;
           RST :         in  STD_LOGIC;
           DAC_Data :     in  STD_LOGIC_VECTOR (11 downto 0);
           DAC_Channel :  in  STD_LOGIC_VECTOR (3 downto 0);
        DAC_Command :   in  STD_LOGIC_VECTOR (3 downto 0);
        DAC_Update :   in  STD_LOGIC;
           DAC_CS_n :     out  STD_LOGIC;
           DAC_SCK :     out  STD_LOGIC;
           DAC_SDI :     out  STD_LOGIC;
           DAC_CLR_n :     out  STD_LOGIC;
           DAC_Busy :     out  STD_LOGIC);
end LTC2624_SPI_Master;

architecture Behavioral of LTC2624_SPI_Master is

Signal ShiftReg, DAC_Value : std_logic_vector(23 downto 0) := (others => '0');
Signal BitCount : integer range 0 to 24 := 0;
Signal ShiftEn, Busy, Load, nCLK : std_logic := '0';

begin
  
  nCLK <= not CLK;
  
  ValueReg : Process(CLK)
  Begin
    if rising_edge(CLK)then
      if RST = '1' then DAC_Value <= (others => '0');
      elsif DAC_Update = '1' and Busy = '0' then DAC_Value <= DAC_Command & DAC_Channel & DAC_Data & "0000";
      end if;
    end if;
  End Process;

  SPICounter : Process(CLK)
  Begin
    if rising_edge(CLK)then
      if RST = '1' then BitCount <= 0;
      elsif Load = '1' then BitCount <= 24;
      elsif ShiftEn = '1' then BitCount <= BitCount - 1;
      end if;
    end if;
  End Process;

  ShiftEn <= '0' when BitCount = 0 else '1';
  
  LoadDelay : Process(CLK)
  Begin
    if rising_edge(CLK)then
      if RST = '1' then Load <= '0';
      elsif Busy = '0' then Load <= DAC_Update;
      end if;
    end if;
  End Process;

  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;

  Busy <= ShiftEn;
  
  DAC_Busy <= Busy;
  
  DAC_CLR_n <= not RST;
  DAC_CS_n <= not ShiftEn;
  DAC_SDI <= ShiftReg(23);
  
  SPI_ClockOut :  ODDR2  Port map(Q   => DAC_SCK, C0 => CLK, C1 => nCLK, CE => '1', D0 => '0', D1 => '1', R => '0', S => '0');

end Behavioral;

Autor: Tobi (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Tobi (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: GastausHannover (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?
----------------------------------------------------------------------------------
-- 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 rst = '0' then
                  SPI_MOSI <= '0';
                  SPI_CS <= '1';
                  SPI_SCK <= '0';
                  dacState <= idle;
                elsif 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;


Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.
                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...

Autor: Tobi (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: GastausHannover (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

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

Autor: maikh (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Tobi (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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

Autor: Tobi (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: GastausHannover (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: Anguel S. (anguel)
Datum:

Bewertung
0 lesenswert
nicht 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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
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.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.