Abtastrate des UART-Empfängers

Ich versuche, einen UART-Empfänger in Verilog für mein FPGA zu erstellen. Ich habe diese Anleitung http://www.fpga4fun.com/SerialInterface4.html befolgt

Demnach besteht die Standardpraxis für asynchrone Kommunikation darin, das Signal mit der 16-fachen BAUD-Rate zu überabtasten. Dies macht für mich Sinn, da ich dies tun müsste, um den ersten Tropfen schnell zu erkennen und mit dem Sendetakt zu synchronisieren.

Was ich mich frage, ist, warum nicht einfach mit der gleichen Frequenz wie der Takt auf meinem FPGA abgetastet wird, der viel schneller ist als das 16-fache des BAUD (mein Takt beträgt 100 MHz). Kann es schaden, dies zu tun? Ich weiß, dass es wahrscheinlich nur mehr Strom verbrauchen würde, aber würde es funktionieren oder gibt es etwas, das ich vermisse?

Antworten (5)

Ich habe bei einem Job 8 Mal gesampelt und es war in Ordnung, also gibt es keine Regel, die vorschreibt, dass 16 die magische Zahl ist, also ist das Sampling höher als das kein Problem in etwas anderem als dem Umgang mit größeren Zahlen in der Hardware. Hier ist eine Idee für den 16x-Zähler: -

Geben Sie hier die Bildbeschreibung ein

Von der fallenden Flanke des Startbits "finden" Sie die "Mitte" des Startbits, indem Sie bis 8 zählen, dann "abtasten" Sie bei jeder Zählung von 16 die von UART empfangenen Daten, um das übertragene Byte (oder die übertragenen Bytes) wiederherzustellen. Wenn Sie einen 32-fachen Zähler hätten, würden Sie den Mittelpunkt des Bits eindeutig etwas genauer bestimmen, und das Zählen mit einer höheren Rate wird funktionieren, aber die Zahlen werden größer und der Stromverbrauch steigt.

Ich dachte nur, dass es einfacher ist, nur mit dem 100-MHz-Takt zu sampeln, den ich bereits habe, als ein Modul zu erstellen, um es aufzuteilen.
Ich verstehe, aber Sie müssen Hardware-Sachen abwägen wie - ist es effizienter, auf eine niedrigere Frequenz zu unterteilen und kleinere Zählungen mit weniger Hardware und weniger Stromverbrauch zu verwenden.
Nehmen wir an, Ihr UART arbeitet mit 9600 Baud. Dann ist eine Datenzelle 104 usec. Ein 100-MHz-Takt benötigt 104.000 Taktzyklen, um die UART-Daten zu verarbeiten, und dies wiederum benötigt einen 17-Bit-Zähler. Sie finden dies vielleicht etwas verschwenderisch, und die Durchführung der erforderlichen Logik bei 100 MHz kann mühsam sein, aber Sie haben die Wahl. Diese Art von Kompromiss (zusätzliche FPGA-Ressourcen vs. langsamer externer Taktgeber) ist genau das, womit Designingenieure ihren Lebensunterhalt verdienen. Und natürlich hindert Sie nichts daran, Ihre 100 MHz intern herunterzuteilen, um die UART-Logik kompakter zu machen.

Für einen sehr einfachen UART-Empfänger spielt es wirklich keine Rolle, welchen Weg Sie gehen.

Viele UART-Designs müssen jedoch sowohl robust als auch flexibel sein, und das treibt das Design dazu, ein 16-faches Taktsignal (oder Taktaktivierungssignal) zu erzeugen.

Aus Gründen der Robustheit ist es vorteilhaft, jedes Bit mehrere Male nahe der Mitte des Bits abzutasten und dann eine Abstimmung unter den mehreren Abtastwerten vorzunehmen, um die Auswirkungen von Rauschen zu minimieren. Beispielsweise ist es üblich, Proben bei 7/16, 8/16 und 9/16 durch das Bit zu nehmen und den Wert zu nehmen, der am häufigsten vorkommt. Wenn Sie versucht haben, drei benachbarte Samples bei 100 MHz zu nehmen, haben sie fast garantiert den gleichen Wert, selbst wenn es sich um einen Fehler handelt, also möchten Sie, dass sie weiter voneinander entfernt sind.

Aus Gründen der Flexibilität – zum Beispiel müssen viele verschiedene mögliche Baudraten unterstützt werden – möchten Sie nur einen Parameter haben, der die Baudrate steuert. Wenn Sie mehrere verschiedene interne Verzögerungen haben, die von der Baudrate abhängen (dh 1-Bit-Periode, 1/2-Bit-Periode, 7/16-Bit-Periode usw.), wird die Logik komplexer, als wenn Sie eine Zustandsmaschine haben, die läuft bei, sagen wir, 1/16 der Bitperiode. In diesem Fall skalieren alle unterschiedlichen Verzögerungen automatisch mit dem einen Parameter.

Da UART asynchron ist, kann es nur durch Oversampling abgetastet werden.

Es gibt eine untere Grenze für die Überabtastung, die durch den möglichen Fehler definiert ist, der durch das Verpassen der abfallenden Flanke des Startbits verursacht wird. Bei einem 8-fachen Oversampling führt also eine mögliche Fehlanpassung der fallenden Flanke zu einem max. Fehler von 12,5 %. 16x Oversampling reduziert den Fehler auf 6 %.

Die Obergrenze wird durch Ihre Investition in Hardware-Ressourcen begrenzt. Niemand möchte einen 32-Bit-Zähler verwenden :).

Wenn Sie den Verilog-Code des von Ihnen bereitgestellten Links analysieren, gibt es ein Behauptungssegment:

generieren if(ClkFrequency<Baud*8 && (ClkFrequency % Baud!=0)) ASSERTION_ERROR PARAMETER_OUT_OF_RANGE("Frequenz nicht kompatibel mit angeforderter Baudrate"); Ende erzeugen

Wenn Sie sich den Code erneut ansehen, gibt es zwei konstante Parameter für die Taktfrequenz und die Baudrate:

Parameter ClkFrequency = 25000000; // 25 MHz Parameter Baud = 115200;

Nun, zuerst wird der Code mit diesen Konstanten Assertion auslösen! Denn 25_000_000 lässt sich nicht ohne Rest durch 115200 teilen. Sie benötigen also einige seltsame Taktfrequenzen, um eine solche UART-Logik mit Ihrem FPGA zu implementieren.

Ich möchte eine Frage an x8- oder x16-Unterstützer stellen. Können Sie mit einem Gerät kommunizieren, das UART mit einer Baudrate von 1_843_200 bps verwendet, selbst mit einer hohen Taktfrequenz wie 100 MHz? Nun, beim x16-Sampling benötigen Sie 1/(BAUDx16) Sekunden-Tick, was 33,908 ns entspricht. Bei einer Taktfrequenz von 100 MHz beträgt Ihre Auflösung jedoch 10 ns. Wenn Sie also bis 3 zählen, erhalten Sie 30 ns. Sie erzeugen also einen Baud-Tick von 30 ns statt 33,908 ns, wobei die Fehlerrate 33,908/30 = 13 % beträgt !!!

Okay, für diesen Fall kann man gut sagen, dass ich x8-Oversampling verwenden kann. Also muss ich 1/(BAUDx8) Sekunden-Tick generieren, was 67,81 ns entspricht. Diesmal beträgt die Fehlerquote 67.817/70 = 3 %. Dann werde ich fragen, was, wenn Sie 50 MHz statt 100 MHz haben?

IMHO, da UART ein altes Protokoll ist, war es zu dieser Zeit entscheidend, weniger Ressourcen für die Schaltung zu verwenden. Heutzutage mit Tausenden von Gattern in einem FPGA ist jedoch die Anpassung an neuere Anforderungen meistens schnell und Modularität gewinnt an Bedeutung, insbesondere für kleine Low-End-Protokolle wie UART, SPI, I2C usw. Daher ergibt sich jedes Mal eine Abtastung des RX-Signals Sie haben die Möglichkeit, mit wenig zusätzlichen Ressourcen höhere Baudraten zu kommunizieren, über die Sie heutzutage in FPGAs eine riesige Menge verfügen.

Übrigens, ob Sie es glauben oder nicht, aber x8- oder x16-Tick-Erzeugungsschaltkreise verbrauchten auch Ressourcen von FPGAs! Es ist kein kostenloses Tick-Signal.

Also meine Antwort auf die Frage "Schadet das?" ist NEIN, auch Sie werden mehr Flexibilität haben und höhere Baudraten erreichen.

Grüße,

Ist dies für Demozwecke, ein Produktionsdesign oder ein wiederverwendbarer IP-Block? Wenn Sie zu Demozwecken arbeiten, tun Sie einfach alles, was Sie zum Laufen bringen können. Wenn Sie für die Produktion über reichlich FPGA-Ressourcen verfügen, verwenden Sie einfach die 100 MHz und riesige Zähler und viel Logik. Für wiederverwendbares IP (oder Produktionsdesign mit begrenzten Ressourcen) sollten Sie die Verwendung eines FPGA PLL/DLL/ClockMgr annehmen, um einen viel langsameren Takt für die UART-Logik zu erzeugen und die FPGA-Ressourcennutzung zu reduzieren. Das kritische funktionale Anliegen ist, dass Ihre Empfangslogik die Drift zwischen Sende- und Empfangstaktdomänen (Delta im ungünstigsten Fall zwischen Frequenz der Taktquelle + ppm) über die gesamte Dauer jeder möglichen Nachrichtenlänge tolerieren und dennoch jedes Bit genau abtasten kann.