Hallo Zusammen, seit geraumer Zeit treibt mich ein Problem so langsam in den Wahnsinn :-) Vorab sei gesagt das ich zwar beruflich Software entwickele und vor einigen Jahren auch grundlegende Kenntnisse in der Elektrotechnik gelernt habe, ich jedoch kein Profi in Sachen FPGA+Verilog bin. Zur Zeit versuche ich mittels FPGA mit einem externen µC zu kommunizieren. Das ganze kann man sich so vorstellen das beide FPGA und µC zwei gemeinsame Datenleitungen, eine Resetleitung und ein Takt Signal besitzen. Hier ein kleines Schaubild: -----+ +---------------- | <==> | D0 FPGA | <==> | D1 | <=== | Reset | <=== | Takt (~3,5Mhz) -----+ +----------------- Der µC gibt hierbei den Takt vor. Der FPGA reagiert mittels "always @(posedge clk) begin" auf die Daten die an D0 bzw. D1 anliegen. Beide Systeme sind so ausgelegt das diese in nach einer Bestimmten Anzahl von Takten Daten über die Datenleitungen austauschen und diese dann mit einem Referenzwert abgleichen. Kommen beiden Systeme aus dem Takt, merkt der µC das anhand der Fehlerhaften Daten und löst einen Reset aus. Mein Problem hat zeigt sich nun wie folgt: Nach einer gewissen Zeit (~1 Sekunde) laufen beide Systeme nicht mehr synchron und der FPGA erhält ein Reset Signal. Verlängere ich die Takt-Leitung um ~15cm (sehr grob 1ns) dann läuft alles. (>10 Minuten). Dazu sollte man vielleicht wissend s das Takt-Signal nicht besonders "eckig" ist, sondern eher wie eine gestauchte Sinuskurve aussieht. Ich tippe darauf das zu dem Zeitpunkt wenn der FPGA die Steigende Flanke erkennt, die daten an D0/D1 noch nicht stabil anliegen. Wobei das nur geraten ist. Ich verwende aktuell das Entwickler Board von Lattice für MachXO3LF FPGA mit dem IC LCMXO3LF-6900C. Hat vielleicht jemand einen Tipp für mich wie ich das Problem vielleicht direkt in Verilog lösen kann? Programmiertechnisch oder über Optionen im Lattice Diamond Studio. Für andere Optionen bin ich natürlich auch offen. Ich vermute mal das ich schlichtweg irgend einen "dummen" Anfängerfehler gemacht habe.
D0, D1, RESET und CLK mit dem internen FPGA-Clock in ein Schieberegister einsynchronisieren. http://www.lothar-miller.de/s9y/categories/35-Einsynchronisieren Oder Verilog: http://www.fpga4fun.com/SPI2.html Prinzip ist dasselbe
:
Bearbeitet durch User
Andre F. schrieb: > Mein Problem hat zeigt sich nun wie folgt: > Nach einer gewissen Zeit (~1 Sekunde) laufen beide Systeme nicht mehr > synchron und der FPGA erhält ein Reset Signal. Es ist eh' schlecht, keinen Sync-Mechanismus einzubauen. Was, wenn dein Nachbar die Leuchtstoffröhre einschaltet und die Lampe alt ist und hundertmal vor sich hinblitzt? Oder wenn der Handwerker seine alte Hilti mit mächtig Bürstenfeuer nebenan anwirft? Ein klitzekleiner Störspike und du bist ausser Tritt ohne Hoffnung auf Besserung. Nicht umsonst gibt es beim SPI den Slaveselect, der den Beginn und das Ende einer Übertragung markiert. > Dazu sollte man vielleicht wissend s das Takt-Signal nicht besonders > "eckig" ist, sondern eher wie eine gestauchte Sinuskurve aussieht. Am Besten noch mit hübschem Klingeln und Überschwingen... Wie gesagt: Weil der Takt so schnarchlangsam ist: takte dein FPGA mit 50MHz und betrachte den µC Takt als ein einzulesendes asynchrones Signal, das einsynchronisiert und entprellt werden muss. Dann eine Flankenerkennung und dann kannst du die Daten einlesen.
:
Bearbeitet durch Moderator
Andre F. schrieb: > Der µC gibt hierbei den Takt vor. > Der FPGA reagiert mittels "always @(posedge clk) begin" auf die Daten > die an D0 bzw. D1 anliegen. Ich nehme jetzt mal an, dass du mit clk den Takt der Übertragung und nicht den Takt des FPGA meinst. Ich kenne mich in Verilog nicht besonders aus, aber generiert das nicht üble Schaltungen (Stichwort Clock Domain crossing) mit unterschiedlichen Clocks innerhalb des FPGA? Sofern das überhaupt geroutet werden kann. Zu 99.99% wird die Lösung in deinem Problem das einsynchronisieren ALLER Übertragungsleitungen: Lothar M. schrieb: > Wie gesagt: > Weil der Takt so schnarchlangsam ist: takte dein FPGA mit 50MHz und > betrachte den µC Takt als ein einzulesendes asynchrones Signal, das > einsynchronisiert und entprellt werden muss. Dann eine Flankenerkennung > und dann kannst du die Daten einlesen. Ansonsten, sie dir Lothars Seite doch an. Da sind viele nützliche Infos enthalten...
Wie liegen Takt, Daten und Reset zeitlich zueinander? Ein Zeitdiagram ist da hilfreich.
Andre F. schrieb: > Ich tippe darauf das zu dem Zeitpunkt wenn der FPGA die Steigende Flanke > erkennt, die daten an D0/D1 noch nicht stabil anliegen. Wobei das nur > geraten ist. Das solltest du mit einem Oszilloskop herausfinden können. Wenn der FPGA die Daten auf steigender Flanke übernimmt, sollest du dafür sorgen, dass der uC die Daten auf der vorherigen fallenden Flanke anlegt. Wenn der uC die Daten auf steigender Flanke ändert, muss der FPGA eben auf deer nächsten fallenden Flanke die Daten übernehmen. Ist denn D0/D1 bi-direktional? Wie ist da geregelt, welche Seite die Leitungen treiben darf? Warum verwendet ihr nicht einfach eine Standardschnittstelle? Mit 4 Leitungen kann man ganz prima SPI implementieren. Eine Datenleitung geht vom uC zum FPGA (MOSI), die zweite in umgekehrter Richtung (MISO). CLK wird vom uC getrieben, und "Reset" könnte man als "Chip Select" umdefinieren. Über Chip-Selekt findet bei SPI eine ziemlich zuverlässige Synchronisation statt, so dass die zu erwartende Fehlerrate gering ist. Zu guter letzt: über welche Geschwindigkeit reden wir (Frequenz von CLK)?
:
Bearbeitet durch User
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.