Hallo Ich habe mal einen Einstieg in die FPGA-Welt gemacht und erst ein bisschen LED's blinken lassen und Zeug gezählt und habe jetzt einen Sende- und Empfangsbaustein für UART gebastelt. Der läuft in der Simulation prima, aber ich habe einfach keinen Ansprechpartner für die ganzen Stilfragen. Ich hätte also ganz gern, dass jemand das Design nach groben Schnitzern durchsucht. Vor allem habe ich in dem Design das erste Mal Tasks benutzt und mir über CDC Gedanken gemacht: -Zum Clockdomaincrossing wird ein UART-Bit beim Empfang mehrfach abgetastet, wie oft kann man mit Clock_Divide festlegen. In der Simulation hats mit ca. 10% Taktungenauigkeit noch funktioniert. Mit Synchroclocks_After_Begin und Synchroclocks_Before_End legt man den Bereich fest, in dem eine Flanke am RxD als Störung erkannt wird und wann diese Flanke zur Taktsynchronisierung genutzt wird. Kommt eine Flanke zum Empfangsbeginn oder nahe am Ende, ändert die Statemachine ihren Zustand so, dass FPGA und der andere Teilnehmer wieder synchronisiert sind. -Die Tasks XXX_Wait zählen beim Senden und beim Empfangen mit, wie weit das Senden oder Empfangen eines Bits schon ist. -Zum Reset werden ebenfalls Tasks benutzt -Das ganze läuft mit 8 Datenbits, einem Start- und einem Stopbit und ohne Parity Wie gesagt, in der Simulation läufts. Für einen richtigen Test habe ich leider noch kein Board. Ich wollte erst sehen, wie hart das von euch diskriminiert wird, was ich gemacht hab :D
Hallo, wie hoch ist die Eingangsclock und die Baudrate ? Danke.
Ich wollte es variabel machen: Die Baudrate ist dann Eingangstakt/Clock_Divide In der Testbench wars Eingangstakt = 500Mhz, ClockDivide = 10 => Baudrate von 50 Mhz
Für eine "richtige" UART ist das aber eine arge Einschränkung. Wie komme ich da von 50MHz auf 115kBd?
Wenn man CLock_Divide mit 435 wählt, bekommt man eine Baudrate von 114942,528736 und damit eine Abweichung von einem Prozent. Ich weiß, das ist hart an der Grenze aber ich dachte es reicht noch. Und es ist doch auch bei uCs so, dass der Systemtakt geteilt wird, um den UART-Takt zu kriegen und man ihn nunmal nur durch ganzzahlige Werte teilen kann?
Wie mache ich es denn richtig? Mein Ansatz war, dass man beim uC ja ebenfalls einen Zähler hat, der den UART Takt generiert. Also der Systemtakt wird runtergeteilt. In meinem Programm könnte man alternativ auch einen externen Takt zuführen, der ein genaues Vielfaches der Baudrate ist und mit Clock_Divide ein genaues zeitliches Verhalten und trotzdem die Mehrfachabtastung erzeugen könnte.
Joschua C. schrieb: > Mein Ansatz war, dass man beim uC ja ebenfalls einen Zähler hat, der den > UART Takt generiert. Also der Systemtakt wird runtergeteilt. Ja, das passt schon... Wenn man langfristig genau sein will, aber ein wenig Jitter erlauben kann, dann ist eine DDFS für das Erzeugen des Clock-Enables auch eine Möglichkeit. Damit lässt sich die Abweichung von der tatsächlichen Baudrate in Grenzen halten, weil der Fehler nicht "abgeschnitten", sondern über viele Zyklen hinweg aufsummiert wird. Joschua C. schrieb: > Wenn man CLock_Divide mit 435 wählt 434 wäre dann schon der bessere Vorteiler für 115200 Bit/s. Da ist der Fehler dann schon nur noch 6ppm und damit "besser" als die meisten Quarzoszillatoren...
Hab bei Google nicht allzu viel zur DDFS gefunden: Heißt das ich fenstere den Eingangstakt und setze ihn ganz kurz aus, wenn der UART gerade nix macht, um die Phasenverschiebung zum korrekten Takt aufzuheben? Hebt die Synchronisation durch das Startbit nicht diese Synchronisation auf?
Du verwendest nur die DDFS zum genauen Erzeugung der 16 fachen Baudrate für das Oversampling. Das Resynchronisieren auf die Flanke (so da eine kommt) passiert ja auf einer ganz anderen Ebene erst innerhalb des "Bitzählers"...
Aber um die DDFS zu erzeugen, brauche ich doch wieder einen Takt, der ein ganzzahliges Vielfaches dieser 16-fachen Baudrate ist, die ich erzeugen will? Wenn ich diesen Takt hätte, könnte ich ihn doch auch gleich direkt in den UART einspeisen und statt dem Aufbau der DDFS einfach Clock_Divide größer machen, um eine genaue Baudrate zu erhalten?
Joschua C. schrieb: > Aber um die DDFS zu erzeugen, brauche ich doch wieder einen Takt, der > ein ganzzahliges Vielfaches dieser 16-fachen Baudrate ist, die ich > erzeugen will? Nein, du kannst bei der DDFS den Akku breiter machen und mit quasi mit "Nachkommastellen" arbeiten. Du wirst aber wegen der "Nachkommastellen" eben ab&zu einen "Sprung" im Signalverlauf haben. Eine einfach Skizze hier:
1 | Vorteiler: 5 --> jeden 5. Takt ein Clock-Enable |
2 | - - - - - - - - - - - - - - - |
3 | ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- |
4 | |
5 | Vorteiler: 5.2 --> jeder 5. Puls dauert einen Puls länger |
6 | - - - - - - - - - - - - - - - |
7 | ---- ---- ---- ---- ----- ---- ---- ---- ---- ----- ---- ---- ---- ---- ----- --- |
Man sieht, dass die Frequenz über mehrerer Impulse betrachtet niedriger geworden ist. Aber es kommt eben zusätzlich ab&zu ein "Jitterimpuls" mit unterschiedlicher Länge rein. Der Jitter ist +-1/(2fclk), und damit bei 50MHz eben +-12,5ns.
:
Bearbeitet durch Moderator
Ah hey, danke für die Antwort. Habs gerafft :D Noch irgendwelche Stilfehler? Kann man Tasks so einsetzten? Und passen z.B. die non blocking assignments?
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.