Hallo, habe das DE0-Nano Cyclone IV Eval-Board. (Von mir ist dann auch der aktuelle Beitrag "Clock teilen oder Clock-Enable?") Das Board hat einen ADC128S022, den ich seit geraumer Zeit zu steuern versuche, bzw. ein Modul in VHDL dafür zu entwerfen. Datenblatt des ADC128S022: http://www.google.de/url?sa=t&rct=j&q=&esrc=s&source=web&cd=2&ved=0CC8QFjAB&url=http%3A%2F%2Fwww.ti.com%2Flit%2Fds%2Fsymlink%2Fadc128s022.pdf&ei=nrNhUMjEKsaQswan6oG4AQ&usg=AFQjCNFc66MAyUeuvsc3GqSMtDGBNhZlWg&cad=rja Das Timing-Modell habe ich der Seite 8 des Datenblattes entnommen. Der SCLK kann, so wie ich das verstanden habe, von 1,8MHz bis 3,2 MHz betragen? Aus diesem Grund habe ich geplant den ADC mit 3,125MHz anzusteuern (ergibt sich so aus dem Teilerverhältnis ganz gut, denn das DE0-Nano stellt einen "Main-Clock" von 50MHz zu Verfügung. Ich habe gedacht, das ganze modular aufzubauen. (Ich wollte das endlich mal ordentlicher angehen ;) ). Da im Datenblatt immer mit der fallenden FLanke gearbeitet wird, frage ich hier auch immer die fallende Flanke ab! Ich habe nun also folgende vhd-Dateien mit den zugehörigen Entities: "CLKDIV.vhd" --> enthält einen einfachen generischen Taktteiler, der mir ein 3,125MHz Signal ableiten soll (aus den 50MHz) "CLKENGEN.vhd" --> enthält einen Taktteiler, wobei hier nur ein enable Signal erzeugt wird ebenfalls 3,125MHz "ADC_ADDR_CODER.vhd" --> enthält ein Modul, das an den ADC die Adressdaten (an DIN) senden soll, also können hier parallel 3Bit Adressdaten seriell an den ADC geschickt werden, auf diese Weise kann ein bestimmter der 8 ADC Kanäle des ADC128S022 abgefragt werden. Des Weiteren wird das /CS also Chip Select Signal durchgeschleift, so dass später die Analog digital wandlung per Signal an oder ausgeschaltet werden kann. "DATA-RECEIVE.vhd" --> enthält eine entity, die die vom ADC gesendeten Daten empfangen soll, dabei wird abgefragt, ob 4 mal low an "DOUT" angelegen hat..... Nun das Problem: Ich habe jedes Modul einzeln mit Modelsim simuliert und entsprechend existiert zu jedem Modul eine Test Bench. Nach meiner Auffassung scheinen die einzelnen Test funktional in Ordnung zu sein. Dann wollte ich alle Module gemäß bild1.jpg vernetzten das übergeordnete Modul befindet sich in "ADC128S022.vhd" dazu habe ich ebenfalls eine Test Bench "gebastelt" leider funktionieren die einzelnen Module nun nicht mehr??? ich kann mir nicht erklären warum? Da ich sonst nicht so viel mit Komponenten gearbeitet habe könnte was mit der Komponenteneinbindung schief gegangen sein??
Ich hatte noch nicht die Zeit, das Ganze anzusehen, aber das gibt mir zu denken:
1 | use IEEE.STD_LOGIC_ARITH.ALL; |
2 | use IEEE.STD_LOGIC_UNSIGNED.ALL; |
3 | use IEEE.NUMERIC_STD.ALL; |
Zuviel des Guten! Siehe den Beitrag "IEEE.STD_LOGIC_ARITH.ALL obsolete" > Das Timing-Modell habe ich der Seite 8 des Datenblattes entnommen. Aha, simples SPI... Ich mach das so: http://www.lothar-miller.de/s9y/categories/45-SPI-Master > Ich habe nun also folgende vhd-Dateien mit den zugehörigen Entities: Warum jeden Dreizeiler mit 200% Overhead in ein eigenes Modul stecken? > leider funktionieren die einzelnen Module nun nicht mehr??? Was funktioniert nicht mehr?
Lothar Miller schrieb: >> Das Timing-Modell habe ich der Seite 8 des Datenblattes entnommen. > Aha, simples SPI... > Ich mach das so: > http://www.lothar-miller.de/s9y/categories/45-SPI-Master Ok ich denke mit einigen Inspiration von deinem SPI werde ich das jetzt auch etwas klarer hinbekommen.... ich hatte das jetzt irgendwie zu sehr "modularisieren" wollen!!! Aber ein Bestätigen, dass Senden oder Empfang fertig ist, gibt der ADC nicht, sowie dein SPI drauf wartet also "tx_done" z.B.?
Gerd M. schrieb: > Aber ein Bestätigen, dass Senden oder Empfang fertig ist, gibt der ADC > nicht, Nein. Denn der ADC ist ein Slave. Er wird also genau dann fertig sein, wenn dein Master fertig ist. Das ist nach 16 SCLK Takten der Fall, denn SPI sind ja nur zwei gekoppelte Schieberegister: http://www.lothar-miller.de/s9y/categories/17-SPI Um die Sache zu vereinfachen, empfehle ich dir den Modus im Bild 2 auf Seite 8. Dort wird mit CS nach jedem Frame neu synchronisiert. > sowie dein SPI drauf wartet also "tx_done" z.B.? Mein SPI generiert das tx_done für die Ansteuerung durch ein übergeordnetes Modul. Das ieht dann am tx_done, dass die nächste Übertragung gestartet werden darf. Und eine unangenehme Sache ist an diesem ADC: mit der ersten Übertragung sendest du die Adresse für die Kanalauswahl der zweiten Wandlung. Bei der zweiten Wandlung sendest du die Kanalauswahl für die dritte Wandlung. Du weißt also vorher schon (bzw. du musst wissen), was als Nächstes gewandelt wird. Aber umgekehrt ist die Sache wesentlich unangenehmer: bei der zweite Wandlung bekommst du das Ergebnis des Kanals, den du in der ersten Wandlung ausgewählt hast. Und du siehst an diesem Ergebnis nicht mehr, welcher das war! Du musst dir also merken, welches der zuvor ausgewählte Kanal war. Ist doch nicht so schlimm, sagst du jetzt. Aber, glaub mir, du wirst noch ein paar mal drüber stolpern... :-/ Der AD7490 macht das besser: er sendet in jedem Paket sowohl die Kanaladresse wie auch das zugehörige Wandlungsergebins zurück. Bei diesem ADC musst du dir also nichts merken.
Hallo, ich hab mich jetzt an deinem SPI orientiert.... allerdings "hau'" ich die Daten direkt raus bzw. empfange sie. Das Empfangen scheint zu funktionieren aber die TX_DATA packt der nicht seriell auf den MOSI...... alles weitere, wie welche Kanal wurde gelesen etc. kommt dann später... hier scheint was nicht zu gehen: -- transmitting shift register transmit_reg: process (CLK) begin if (CLK'event and CLK = '1') then if TX_ENABLE = '1' then if (SPICLK ='1' and SPICLKLAST = '0') then TX_REG <= TX_REG(TX_REG'left-1 downto 0) & TX_REG(0); end if; end if; end if; end process transmit_reg; SCLK <= SPICLK; MOSI <= TX_REG(TX_REG'left); RX_DATA <= RX_REG_VALID; dieser Befehl TX_REG'left gibt doch nur den größten Index...?
hmmmh wenn ich das Senden wie folgt mit nem Zähler CNT machen klappt's!! transmit_reg: process (CLK) begin if (CLK'event and CLK = '1') then if TX_ENABLE = '1' then if (SPICLK ='1' and SPICLKLAST = '0') then MOSI_TEMP <= TX_REG(CNT); CNT <= CNT -1; --TX_REG <= TX_REG(TX_REG'left-1 downto 0) & TX_REG(0); end if; else CNT <= 15; end if; end if; end process transmit_reg; SCLK <= SPICLK; MOSI <= MOSI_TEMP; --MOSI <= TX_REG(TX_REG'left); RX_DATA <= RX_REG_VALID; Zeit für die Synthese?
Gerd M. schrieb: > dieser Befehl TX_REG'left gibt doch nur den größten Index...? Ja, das MSB... Gerd M. schrieb: > hmmmh wenn ich das Senden wie folgt mit nem Zähler CNT machen klappt's!! Ändert sich wenigstens das Schieberegister: TX_REG <= TX_REG(TX_REG'left-1 downto 0) & TX_REG(0); > hmmmh wenn ich das Senden wie folgt mit nem Zähler CNT machen klappt's!! Multipexer sind eher aufwendiger in FPGAs, weil viel Logik gebraucht wird...
Lothar Miller schrieb: > Ändert sich wenigstens das Schieberegister: > TX_REG <= TX_REG(TX_REG'left-1 downto 0) & TX_REG(0); als das gibt mir Quartus 2 dazu als Meldung heraus: Error (10028): Can't resolve multiple constant drivers for net "TX_REG[15]" at ADC_SPI.vhd(111) Error (10029): Constant driver at ADC_SPI.vhd(51) Error (10028): Can't resolve multiple constant drivers for net "TX_REG[14]" at ADC_SPI.vhd(111) Error (10028): Can't resolve multiple constant drivers for net "TX_REG[13]" at ADC_SPI.vhd(111) Error (10028): Can't resolve multiple constant drivers for net "TX_REG[12]" at ADC_SPI.vhd(111) Error (10028): Can't resolve multiple constant drivers for net "TX_REG[11]" at ADC_SPI.vhd(111) Error (10028): Can't resolve multiple constant drivers for net "TX_REG[10]" at ADC_SPI.vhd(111) Error (10028): Can't resolve multiple constant drivers for net "TX_REG[9]" at ADC_SPI.vhd(111) Error (10028): Can't resolve multiple constant drivers for net "TX_REG[8]" at ADC_SPI.vhd(111) Error (10028): Can't resolve multiple constant drivers for net "TX_REG[7]" at ADC_SPI.vhd(111) Error (10028): Can't resolve multiple constant drivers for net "TX_REG[6]" at ADC_SPI.vhd(111) Error (10028): Can't resolve multiple constant drivers for net "TX_REG[5]" at ADC_SPI.vhd(111) Error (10028): Can't resolve multiple constant drivers for net "TX_REG[4]" at ADC_SPI.vhd(111) Error (10028): Can't resolve multiple constant drivers for net "TX_REG[3]" at ADC_SPI.vhd(111) Error (10028): Can't resolve multiple constant drivers for net "TX_REG[2]" at ADC_SPI.vhd(111) Error (10028): Can't resolve multiple constant drivers for net "TX_REG[1]" at ADC_SPI.vhd(111) Error (12153): Can't elaborate top-level user hierarchy Error: Quartus II 32-bit Analysis & Synthesis was unsuccessful. 17 errors, 3 warnings Error: Peak virtual memory: 366 megabytes Error: Processing ended: Wed Sep 26 16:09:10 2012 Error: Elapsed time: 00:00:01 Error: Total CPU time (on all processors): 00:00:01 Error (293001): Quartus II Full Compilation was unsuccessful. 19 errors, 3 warnings Also zumiindest klappt die "testweise" Adressierung über TX_DATA <= "0111000000000000"; obwohl es eigentlich so sein müsste: TX_DATA <= "0011100000000000"; um Channel7 anzusprechen!??! Ich hoffe, ich hab hier nicht zu sehr genervt! Also Vielen Dank soweit jetzt klappt das auch so langsam mit dem SPI (zumindest ein wenig). hätte nicht gedacht, dass das so "unkritisch" ist... lief nach erfolgreicher Simu auch auf dem FPGA!!
Fehlerursache: du treibst tx_reg gleichzeitig aus 2 Prozessen.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.