Hallo, Ich muss euch leider nochmal mit einem ziemlichen Anfängerproblem stören. Nachdem ich jetzt den DAC auf dem Spartan3E unter Kontrolle bekommen habe, möchte ich über den ADC ein Signal einlesen, im FPGA verdoppeln und über den DAC wieder ausgeben. Leider scheitere ich schon bei der Simulation von meinem Programm. Sie läuft nicht bis zum Ende durch, sondern bricht bei 4000ns einfach ab. Das hängt wohl damit zusammen, dass ISim eine Endlosschleife findet. Aber ich sehe nicht warum ich eine solche generiert haben sollte. Ich habe einfach alle wichtigen Dateien angehängt. Könnt ihr mir helfen und aufzeigen wo mein Fehler liegt? Vielen Dank Tobias
1 | $ vlib work |
2 | $ vcom *.vhd |
3 | |
4 | ** Warning: [4] adc_test.vhd(106): (vcom-1207) An abstract literal and an identi |
5 | fier must have a separator between them. |
Da muss noch ein Leerzeichen zwischen 100 und ms.
1 | $ vsim -gui adc_test |
2 | > add wave -r /* |
3 | > run -all |
4 | |
5 | # ** Fatal: (vsim-3734) Index value 14 is out of range 13 downto 0. |
6 | # Time: 3970 ns Iteration: 1 Process: /adc_test/uut/main File: adc.vhd |
7 | # Fatal error in Process main at adc.vhd line 104 |
Da wird Dein adccounter zu groß, obwohl nur 14 Bit (13 downto 0) in adcdata1 deklariert sind. Genau für solche Sachen ist eine Simulation Gold wert. Duke
1 | :
|
2 | if reset = '0' and rising_edge(clk) then |
3 | if counter = 2 then |
4 | newclk <= not newclk; |
5 | counter <= 0; |
6 | else
|
7 | counter <= counter + 1; |
8 | end if; |
9 | end if; |
10 | end process clkdiv; |
11 | |
12 | main: process (newclk,reset) -- hier ist reset unnötig, der taucht sowieso nicht auf... |
13 | variable temp:integer; |
14 | begin
|
15 | if rising_edge(newclk) then -- sehr unschön... |
16 | :
|
Du machst hier einen Gated Clock newclk (über reset), der vom Synthesetool so nur lokal (also nicht als Tektnetz) realisiert werden kann. Dafür gabs früher mal die Warnung "this is no good design-practice" :-o Zudem führen asynchrone Resets des öfteren zu eigenartigem Verhalten... Besser wäre es etwa so:
1 | clkdiv : process(clk) begin |
2 | if rising_edge(clk) then |
3 | clkenable <= '0'; -- wir arbeiten mit Clock-Enable |
4 | if reset = '0' then -- synchroner Reset |
5 | if counter = 2 then |
6 | clkenable <= '1'; |
7 | counter <= 0; |
8 | else
|
9 | counter <= counter + 1; |
10 | end if; |
11 | end if; |
12 | end if; |
13 | end process; |
14 | |
15 | main: process (clk) |
16 | variable temp:integer; |
17 | begin
|
18 | if rising_edge(clk) then -- Der Takt: es kann (sollte) nur einen geben. |
19 | if clkenable = '1' then |
20 | case adcstate is |
21 | :
|
Oder dann sogar noch so:
1 | if rising_edge(clk) and clkenable = '1' then |
2 | case adcstate is |
3 | :
|
Diese Beschreibung für ein Clokc-Enable kapiert das Synthesetool dann schon... ;-)
Dieser Teil sieht etwas wild aus: clkdiv : process(clk) begin if rising_edge(clk) then clkenable <= '0'; -- wir arbeiten mit Clock-Enable if reset = '0' then -- synchroner Reset if counter = 2 then clkenable <= '1'; counter <= 0; else counter <= counter + 1; end if; end if; end if; end process; Ich würde es besser machen: clkdiv : process(clk) begin if rising_edge(clk) then if(reset = '0')then -- synchroner Reset clkenable <= '0'; -- wir arbeiten mit Clock-Enable counter <= 0; else if(counter = 2)then clkenable <= '1'; counter <= 0; else counter <= counter + 1; end if; end if; end process; Mal ganz neben bei Bei DEINEM CODE blick ja keiner mehr durch. Dies ist ein riesen Wollkneul.
> Ich würde es besser machen: Das ist doch genau der selbe Code, nur eben ohne Tabs... Ich selber arbeite ohne Tabs, dann gibt es dieses Gewölle i.A. nicht. Vor dem Senden hat das gut ausgesehen... :-/ > Mal ganz neben bei Bei DEINEM CODE blick ja keiner mehr durch. Mir kam es darauf an, zu zeigen, dass dieses Design ohne Aufwand zu einem synchronen Design mit nur 1 Takt umgebaut werden kann. Als Tipp: mit den Tags [/vhdl] und [vhdl] (in umgekehrter Reihenfolge) kannst du hier im Forum vhdl-Code formatieren.
Hallo, Also ich danke euch schon mal für eure Beiträge. Ich habe jetzt die Fehler beseitigt und die Simulation läuft auch durch. Leider funktioniert das Ganze im realen Leben immer noch nicht. Also es kommt keine Spannung aus dem DAC. Alle Programmteile, die aber direkt mit DAC zu tun haben, scheinen zu funktionieren, da ich eine Spannung erhalte, wenn ich einfach ein "festes" DAC-Signal im Programm erzeuge. Ich wäre euch also nochmal sehr verbunden, wenn ihr nochmal drüber schauen könntet und evtl. noch Fehler findet. @Duke Komisch. Bei ISim kam keine Fehlermeldung bzgl. des adccounters. Muss man das irgendwo einstellen? Grüße und Danke Tobi
1. Bilde Dir ADC und DAC richtig in der Testbench nach (mit den entsprechenden timing-Bedingungen) und schaue ob das geht. Die ADC-Werte kann man sich z.B. aus einer Datei holen und die DAC-Werte in eine andere speichern. 2. Erzeuge doch mal testweise eine Rampe über den DAC. (Das ist aber eher debugging by trying.) Duke
> wenn ich einfach ein "festes" DAC-Signal im Programm erzeuge.
Wo? In dacdata?
Funktioniert das Einlesen in adcdata1?
Also in der Simulation geht das einlesen von adcdata1. Ein Signal erhalte ich allerdings nur, wenn ich ein wert in dacdata fest vorgebe.
> Ein Signal erhalte ich allerdings nur, wenn ich ein wert in dacdata fest > vorgebe. Dann hast du das Problem doch eher auf der ADC-Seite. Leg doch mal den ADC-Wert adcdata1 auf LEDs und sieh nach, ob du da was anders als 0 bekommst...
Danke. Die Idee mit den LEDs ist richtig gut. Werde ich mal machen, wenn ich das nächste Mal arbeiten gehe. Bis dahin an alle ein großes Danke.
Hallo, Ich habe die LED-Idee einmal umgesetzt. Die LEDs bleiben dunkel unabhängig davon welchen logischen Wert ich am Anfang für sie vorgebe. Scheinbar schickt der ADC nur logisch Null zum FPGA. Bitte helft mir noch etwas weiter. Ich bin ziemlich ratlos. Liebe Grüße Tobias
Hab dir mal hier n ADC-Beispielt reingestellt. Kanns grad nicht direkt testen, aber sollte eig. funtkionieren. Du stellst dir den Talkthrew trotzdem noch ein wenig zu einfach vor. Du musst z.b. beachten, dass ADC & DAC die selben Leitungen verwenden. D.h. du kannst die Daten nicht direkt rüberschicken. Du musst einen Zwischenspeicher machen (FIFO). Nochdazu Timingmäßig die nötigen Leitungen Aktivieren, Deaktivieren, Umschalten. Fragen zum Programm an mich..
Hallo Vielen Dank. Aber habe das Problem inzwischen gelöst und alles läuft wunderbar. Hatte den Thread schon vergessen und habe mich daher nicht mehr gemeldet. Grüße und nochmal Danke an alle Tobi
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.