Diese Seite ist die erste von drei Seiten in einer Serie über Taktdomänen.
Einführung
Abgesehen von sehr trivialen FPGA-Entwürfen werden für die synchronen Elemente (Flip-Flops, Block-RAMs, Schieberegister usw.) mehr als ein Takt verwendet. Die meisten Funktionseinheiten in einem Logikentwurf basieren jedoch auf genau einem Takt, sodass das Thema mehrerer Takte meist keine besondere Aufmerksamkeit erfordert. Schwieriger wird es, wenn Logik, die auf einem Takt basiert, mit Logik verbunden wird, die von einem anderen Takt abhängt. Diese Serie von Seiten behandelt, wie man mit mehreren Takten in einem Entwurf arbeitet.
Beim Verbinden von Logik, die von verschiedenen Takten abhängt, ist die erste und wichtigste Frage, ob eine Resynchronisationslogik erforderlich ist. Das ist gleichbedeutend mit der Frage, ob die beiden Takte verwandte Takte sind oder nicht. Diese Seite erklärt diese Frage und wie man sie beantwortet, dazu weitere damit zusammenhängende Themen. Ein Großteil der folgenden Ausführungen betrifft Timing-Constraints und die Möglichkeit, sie auf bestimmte Logikelemente anzuwenden. Deshalb beginne ich mit einer kurzen Wiederholung zum Thema Timing.
Die Diskussion in dieser Serie beschränkt sich auf Flip-Flops mit positiver Flanke, also Flip-Flops, die auf steigende Flanken ihres Takteingangs reagieren. Natürlich gibt es auch andere synchrone Elemente, also Logikelemente, die Signale auf der Grundlage eines Takts abtasten und erzeugen: Schieberegister, Block-RAMs und viele andere funktionale Elemente. Manche dieser Elemente reagieren auf die fallende Flanke oder sogar auf beide. Das lasse ich hier der Einfachheit halber außer Acht.
Außerdem verwende ich den Ausdruck „X ist synchron mit Y“, um auszudrücken, dass der Takteingang des synchronen Elements X mit dem Takt Y verbunden ist. Dieses synchrone Element tastet also seine Eingänge mit diesem Takt ab und aktualisiert auch seine Ausgänge mit ihm.
Kurz zu den Timing-Grundlagen
Das ist eine kurze Zusammenfassung der Timing-Theorie. Eine ausführlichere Erklärung gibt es auf einer separaten Seite.
Betrachten wir die folgende Zeichnung, die den Signalpfad von einem Flip-Flop zu einem anderen durch eine LUT zeigt:
Die LUT (Look-Up-Tabelle) in dieser Zeichnung steht stellvertretend für eine beliebige Gruppe kombinatorischer Logik (combinatorial logic): Jede Änderung an I1, I2, I3 oder I4 bewirkt eine unmittelbare Änderung am Ausgang O, und zwar mit einer Ausbreitungsverzögerung (propagation delay).
Der Signalpfad verläuft also folgendermaßen: Der Q-Ausgang des linken Flip-Flops, der mit @foo bezeichnet ist, ändert sich nach einer steigenden Flanke seines Takteingangs @clk1. Da dieser Ausgang mit I1 verbunden ist, kann sich der Ausgang O der LUT nach einer kurzen Verzögerung ändern. Dieses Signal geht in den Dateneingang D des rechten Flip-Flops. Nach einer steigenden Flanke auf @clk2 kopiert das Flip-Flop D nach Q, das mit @bar bezeichnet ist.
Aber so einfach ist es nicht. Alle Flip-Flops haben Timing-Anforderungen: Der Dateneingang D muss vor der steigenden Flanke von @clk2 für die Zeit tsu (die Setup-Zeit) stabil sein und nach dieser Flanke für die Zeit thold (die Hold-Zeit) stabil bleiben.
Die überwiegende Mehrheit der Signalpfade in einem FPGA hängt mit einem einzigen Takt zusammen, sodass @clk1 und @clk2 genau dasselbe Taktsignal sind (wir ignorieren den Taktversatz, clock skew). Für solche Pfade lässt sich berechnen, ob diese beiden Timing-Anforderungen garantiert werden können.
Betrachten wir zum Beispiel die Zeichnung oben und die Timing-Anforderung für tsu: Es geht darum herauszufinden, wie viel Zeit von der steigenden Flanke von @clk1 vergeht, bis der D-Eingang des rechten Flip-Flops aktualisiert und stabil ist. Das ist die Summe aller Verzögerungen auf diesem Pfad (path): Sie beginnt mit der Verzögerung von der steigenden Flanke von @clk1 bis @foo aktualisiert ist (Clock-to-Output) und setzt sich mit allen Verzögerungen bis zum D-Eingang des rechten Flip-Flops fort. Dazu gehören die Verzögerung der LUT sowie die Verdrahtungsverzögerungen zwischen den Logikelementen (Routing-Verzögerungen).
Da @clk1 und @clk2 derselbe Takt sind, wissen wir, wann die nächste steigende Flanke an beiden Flip-Flops auftritt: eine Taktperiode später (z. B. 10 ns bei einem 100-MHz-Takt). Die Gesamtverzögerung des Pfads muss also kleiner als die Taktperiode sein, und zwar mit einer Reserve von tsu. Wenn das garantiert werden kann, ist die Anforderung von tsu erfüllt: Der D-Eingang des rechten Flip-Flops ist vor der steigenden Flanke von @clk2 während der Zeit tsu stabil. Ein Zahlenbeispiel finden Sie auf der Seite zur Timing-Theorie.
Eine ähnliche Berechnung lässt sich für thold durchführen. Im Gegensatz zu tsu verlangt die Anforderung, dass der D-Eingang des rechten Flip-Flops nach einer steigenden Flanke von @clk2 für eine bestimmte Zeit (thold) stabil bleibt. Die Taktperiode ist daher irrelevant und wird nicht berücksichtigt (wenn @clk1 und @clk2 gleich sind). Entscheidend ist, was im selben Taktzyklus passiert, nicht im nächsten.
Beachten Sie, dass solche Berechnungen nur möglich sind, weil wir den Zeitunterschied zwischen der steigenden Flanke von @clk1 und der steigenden Flanke von @clk2 kennen. Wenn @clk1 und @clk2 derselbe Takt sind, ist der für die Berechnung von tsu verwendete Zeitunterschied insbesondere die Taktperiode dieses Takts. Ist der Zeitunterschied zwischen den beiden Takten jedoch unbekannt, lassen sich weder tsu noch thold garantieren.
Beide Anforderungen, tsu und thold, gelten für jedes Flip-Flop. Das betrifft natürlich alle Flip-Flops im FPGA, aber auch Flip-Flops in externen Bausteinen, etwa wenn ein Ausgangspin des FPGAs mit einem externen Baustein verbunden ist, der das Signal mit einem Takt abtastet. Für jedes Flip-Flop im System müssen wir uns also fragen, ob wir die Erfüllung dieser beiden Anforderungen garantiert haben. Bei Flip-Flops, bei denen das nicht zu garantieren ist, müssen wir einen Mechanismus vorsehen, der trotzdem einen zuverlässigen Betrieb gewährleistet – also Resynchronisationslogik. Das ist im Kern das Thema des Wechsels zwischen Taktdomänen.
Also nochmal: Wann ist das Timing garantiert?
Falls Sie im vorigen Abschnitt den Faden verloren haben, hier die wichtigsten Punkte:
Zur Erinnerung: Ein FPGA-Entwurf enthält immer Timing-Constraints, die den Entwurfswerkzeugen die Frequenzen der Takte mitteilen. Auf dieser Grundlage stellen die Werkzeuge sicher, dass die beiden Timing-Anforderungen (tsu und thold) erfüllt sind. Falls die Werkzeuge diese Anforderungen nicht erreichen, melden sie das.
Wie bereits erwähnt, ist es nur möglich, tsu und thold zu garantieren, wenn der Zeitunterschied zwischen den steigenden Flanken des Takts am Anfang des Pfads und des Takts am Ende des Pfads bekannt ist. Das ist meist der Fall, denn der größte Teil eines Logikentwurfs besteht aus Registern, die von anderen Registern abhängen, welche mit demselben Takt synchron sind.
Aber was, wenn zwei verschiedene Takte verwendet werden? Wenn ein Takt mit dem Flip-Flop am Anfang des Pfads verbunden ist und ein anderer Takt mit dem Flip-Flop am Ende? Anders gesagt: Was, wenn @clk1 nicht dasselbe wie @clk2 ist? Ist dann immer noch eine Timing-Berechnung möglich und lassen sich die Timing-Anforderungen sicherstellen? Nun, das hängt davon ab. Genau darum geht es auf dem Rest dieser Seite.
Taktdomänen und Taktdomänenwechsel
Eine Taktdomäne (clock domain) besteht aus allen synchronen Elementen (also Flip-Flops und Ähnlichem), die mit einem bestimmten Taktsignal synchron sind.
Betrachten Sie diesen einfachen Verilog-Codeausschnitt:
reg foo, bar;
always @(posedge clk1)
foo <= !foo;
always @(posedge clk2)
bar <= foo;
In diesem Beispiel ist @foo synchron mit @clk1, und @bar ist synchron mit @clk2. @foo und @bar gehören also eindeutig zu verschiedenen Taktdomänen, nämlich zu denen von @clk1 bzw. @clk2.
An @foo gibt es nichts zu beanstanden: Es hängt nur von sich selbst ab. @bar jedoch ist synchron mit @clk2 und hängt von @foo ab, das synchron mit @clk1 ist. Kann @bar also wie jedes Register verwendet werden? Können wir annehmen, dass @bar den Wert von @foo immer mit korrektem Timing übernimmt, sodass sein Verhalten bekannt und reproduzierbar ist?
Bevor wir versuchen, diese Frage zu beantworten, geben wir dem, was hier passiert, einen Namen: Es handelt sich um einen Taktdomänenwechsel (clock domain crossing): @foo und @bar sind als zwei Flip-Flops implementiert, die mit verschiedenen Takten synchron sind. Der Pfad von @foo nach @bar führt also von einer Taktdomäne in eine andere.
Allgemeiner bezeichnet Taktdomänenwechsel die Situation, in der der Ausgang eines synchronen Elements aus einer Taktdomäne am Eingang eines synchronen Elements aus einer anderen Taktdomäne landet. Dazwischen liegt oft kombinatorische Logik.
Selbst wenn @bar folgendermaßen definiert wäre:
always @(posedge clk2)
bar <= !foo || !bar;
läge immer noch ein Taktdomänenwechsel vor. In diesem Fall würde er bei @foo beginnen, durch die LUT, die die logische Funktion implementiert, verlaufen und bei @bar enden – genau wie in der Zeichnung oben.
Verwandte Takte vs. nicht verwandte Takte
Der Begriff verwandte Takte (related clocks) bezeichnet Takte, die von demselben Referenztakt abgeleitet sind, und zwar so, dass die Zeitabstände zwischen ihren steigenden und fallenden Flanken vorhersagbar sind – abgesehen von bekannten Ungenauigkeiten und Jitter.
Statt von „related clocks“ (verwandten Takten) spricht man oft von „synchronous clocks“. Ebenso verwendet man statt „unrelated clocks“ (nicht verwandten Takten) häufig „asynchronous clocks“.
Ein häufiges Beispiel für verwandte Takte ist, wenn eine einzelne FPGA-PLL verwendet wird, um mehrere Takte mit bekannten Frequenzbeziehungen zu erzeugen. In diesem Szenario arrangieren die FPGA-Tools die Taktpuffer normalerweise so, dass die Taktflanken so weit wie möglich ausgerichtet sind.
Wenn ein Referenztakt beispielsweise mit 2 und mit 3 multipliziert wird:
In diesem Beispiel sind x1 clk, x2 clk und x3 clk verwandte Takte, denn der zeitliche Abstand zwischen jedem Paar dieser Takte ist vorhersagbar.
Im allgemeinen Fall ist der Referenztakt in Bezug auf jeden dieser anderen Takte ein nicht verwandter Takt: Das zeitliche Verhältnis zwischen den Flanken des Referenztakts und denen der anderen Takte kann sich mit der Temperatur und anderen Faktoren ändern. Wenn die PLL jedoch so konfiguriert ist, dass sie eine vorhersagbare Ausrichtung zwischen dem Referenztakt und den PLL-Ausgängen sicherstellt, ist auch der Referenztakt ein verwandter Takt.
Das Wissen über die Zeitbeziehungen zwischen Takten ermöglicht Timing-Berechnungen für Pfade, die zwischen ihren Taktdomänen verlaufen. So wird beispielsweise das Timing eines Pfads zwischen den Domänen von x1 clk und x2 clk mit denselben Anforderungen berechnet wie bei einem Pfad, der vollständig in der Domäne von x2 clk liegt. Der kürzeste Zeitabstand zwischen diesen beiden Takten ist nämlich derselbe wie die Zeit zwischen zwei steigenden Flanken von x2 clk.
Ebenso lässt sich ein Pfad zwischen x2 clk und x3 clk berechnen, aber der kürzeste Zeitabstand beträgt nur ein Sechstel der Periode von x1 clk. Der ungünstigste Timing-Fall entspricht daher einem imaginären x6 clk. Der Grund ist der Zeitabstand zwischen der zweiten steigenden Flanke von x2 clk und der dritten steigenden Flanke von x3 clk.
Eine ausführlichere Diskussion zur Berechnung des Timings finden Sie auf dieser Seite.
Der Punkt dieses Beispiels ist eine Aussage, die auch allgemein gilt: Bei verwandten Takten ist es möglich, das Timing zu garantieren, indem man Timing-Constraints auf den Pfaden zwischen diesen Takten durchsetzt, genauso wie bei Pfaden innerhalb derselben Taktdomäne. Das funktioniert, wenn die FPGA-Tools bewusst dafür sorgen, dass die Taktflanken ausgerichtet sind. Wie das Beispiel zeigt, sind die Timing-Anforderungen oft strenger als für jeden der Takte einzeln, manchmal sogar deutlich strenger.
Beachten Sie jedoch, dass die Tatsache, dass zwei Takte von demselben Referenztakt abgeleitet sind, sie nicht zwangsläufig zu verwandten Takten macht. Wenn insbesondere der Taktversatz zwischen diesen Takten unkontrolliert oder unbekannt ist – was der Fall ist, wenn die Entwurfswerkzeuge nicht ausdrücklich Taktverteilungsressourcen mit gleichen Verzögerungen verwendet haben –, sollten sie als nicht verwandte Takte behandelt werden.
Und selbst der Takt x1 ist nicht unbedingt mit seinem Referenztakt verwandt, auch wenn sie exakt dieselbe Frequenz haben. Sofern diese Takte nicht bewusst zueinander ausgerichtet werden, ist ihre Phasenbeziehung unbekannt.
Wegen dieses Themas der Phase habe ich oben in der Definition der Taktdomäne von einem bestimmten Taktsignal geschrieben und nicht einfach von einem bestimmten Takt. „Ein bestimmter Takt“ könnte beispielsweise derselbe Takt auf der Platine sein, der an zwei verschiedene Eingangspins des FPGAs angeschlossen ist. „Ein bestimmtes Taktsignal“ dagegen bezieht sich auf eine Leitung im Verilog-Entwurf oder in der Netzliste, die ein Taktsignal repräsentiert, etwa @clk1 und @clk2 im obigen Beispiel. Es wird im Verilog-Entwurf durch Portverbindungen bei Instanziierungen (instantiations) oder durch einfache assign-Anweisungen verteilt.
Dass es sich in Verilog um exakt dasselbe Taktsignal handelt, bedeutet, dass die Werkzeuge dafür sorgen, auf der Hardware Ressourcen mit geringem Taktversatz zu verwenden. Das hat auch Auswirkungen darauf, ob die Werkzeuge die Takte als verwandte Takte betrachten (dazu weiter unten mehr).
Verwandte Takte, Timing-Constraints und Resynchronisationslogik
Kommen wir zur ursprünglichen Frage zurück: Kann @bar im obigen Beispiel wie jedes Register verwendet werden? Oder allgemeiner: Wenn ein Flip-Flop das Ziel eines Pfads ist, der von einer Taktdomäne in eine andere führt, kann man seinen Ausgang dann genauso zuverlässig verwenden wie den Ausgang eines beliebigen Flip-Flops? Das ist dieselbe Frage wie die, ob sich Setup-Zeit und Hold-Zeit dieses Flip-Flops sicherstellen lassen, wenn mindestens ein Pfad, der seinen Dateneingang erreicht, mit einem anderen Takt synchron ist.
Die Antwort ist einfach und kurz: Wenn die Takte auf beiden Seiten (@clk1 und @clk2 im Beispiel) verwandte Takte sind, dann ist der Ausgang des Flip-Flops am Ziel völlig in Ordnung und kann wie jedes Register verwendet werden – vorausgesetzt, die passende Timing-Constraint für diesen Pfad wird erfüllt. Andernfalls kann das Timing am Ziel nicht sichergestellt werden, und es muss Resynchronisationslogik hinzugefügt werden, um dieser Tatsache zu begegnen.
Diese Seite zeigt eine vollständige Timing-Analyse eines Pfads zwischen zwei verwandten Takten.
Nach der langen Diskussion oben ist es an der Zeit, das in ein paar einfache Regeln zusammenzufassen:
- Auf Pfaden zwischen Taktdomänen, die zu nicht verwandten Takten gehören, lassen sich keine Timing-Constraints durchsetzen.
- Wenn auf allen Pfaden zwischen zwei Taktdomänen Resynchronisationslogik vorhanden ist, müssen auf diesen Pfaden keine Timing-Constraints durchgesetzt werden.
- Wenn auf einem Pfad zwischen zwei Taktdomänen keine Resynchronisationslogik vorhanden ist, müssen auf diesem Pfad Timing-Constraints durchgesetzt werden.
Die erste Regel ist die einfachste: Wenn Sie nicht sicher sein können, dass zwei Takte verwandte Takte sind, sorgen Sie dafür, dass auf allen Pfaden zwischen den Taktdomänen Resynchronisationslogik liegt (die nächste Seite erklärt, wie das geht). Stellen Sie außerdem sicher, dass auf diesen Pfaden keine Timing-Constraints durchgesetzt werden; das ist nach der zweiten Regel in Ordnung. Unnötige Timing-Constraints machen die Arbeit der FPGA-Tools nur schwerer.
Ein weiteres Ergebnis dieser Regeln ist, dass es auch bei verwandten Takten in Ordnung ist, sie wie nicht verwandte Takte zu behandeln. Wie gerade erwähnt, geschieht das, indem man auf allen Pfaden Resynchronisationslogik vorsieht und die Durchsetzung von Timing-Constraints abschaltet (dazu weiter unten mehr).
Und schließlich: Wenn Sie sicher sind, dass die Takte verwandte Takte sind, ist keine Resynchronisationslogik nötig, aber es müssen Timing-Constraints vorhanden sein, die auf allen Pfaden zwischen den Taktdomänen korrekt durchgesetzt werden.
Die folgende Tabelle fasst diesen Abschnitt zusammen. Die Zeilen der Tabelle geben an, ob am Ende des Pfads Resynchronisationslogik angewendet wird; die Spalten geben an, ob die Takte verwandte Takte sind oder nicht. In der Mitte steht, ob der Pfad Timing-Constraints benötigt.
| Die Takte sind | |||
| verwandte Takte | nicht verwandte Takte | ||
|
Resynchronisations- |
Nicht angewendet | Timing-Constraints sind auf dem Pfad erforderlich | Das ist ein Fehler |
| angewendet | Auf dem Pfad sind keine Timing-Constraints erforderlich | ||
Häufige Fehler
In einem komplexen Entwurf, in dem Signale zwischen verschiedenen Modulen verdrahtet sind, übersieht man leicht, welches Signal synchron zu welchem Takt ist, und wechselt dadurch unbemerkt von einer Taktdomäne in eine andere.
Es gibt zwei Möglichkeiten für folgenschwere Fehler: Die erste ist, einen Pfad zwischen Taktdomänen nicht verwandter Takte ohne Resynchronisationslogik anzulegen. Das bedeutet, dass das Timing am Ziel dieser Pfade gelegentlich verletzt sein kann. Wie bei allen Timing-Fehlern kann das sichtbare Problem sehr irreführend sein. Die Werkzeuge können zur Verwirrung beitragen, wenn sie aus den Timing-Constraints ableiten, dass die beiden Takte verwandte Takte sind, und deshalb unnötigerweise Timing-Constraints auf die Pfade anwenden. Diese Timing-Constraints haben auf Pfaden zwischen nicht verwandten Takten keine Bedeutung, aber die Pfade erscheinen in den Berichten, als wären sie ordnungsgemäß behandelt worden. Ein menschlicher Leser der Timing-Berichte kann dadurch zu der Annahme verleitet werden, dass alles in Ordnung ist – oder vielleicht sogar, dass die Takte wirklich verwandte Takte sind.
Der zweite folgenschwere Fehler ist, wenn zwei Takte verwandte Takte sind und von der Logik auch als solche behandelt werden, die Tools sie aber nicht als solche betrachten. Infolgedessen werden auf den Pfaden zwischen den Taktdomänen keine Timing-Constraints durchgesetzt. Damit ist nicht garantiert, dass die Timing-Anforderungen am Ziel eingehalten werden. Auch das kann zu unzuverlässigem Verhalten führen. Ein solcher Fehler lässt sich allerdings bei einer Timing-Validierungsprüfung des Entwurfs erkennen.
Die einzige Situation, in der ein unbemerkter Taktdomänenwechsel wirklich harmlos ist, ist zwischen verwandten Takten, wenn die FPGA-Tools sie ebenfalls als solche betrachten (und daher Timing-Constraints auf die betreffenden Pfade anwenden). Es kann trotzdem funktionale Fehler geben, wenn die Takte unterschiedliche Frequenzen haben und die Logik das nicht berücksichtigt; das ist dann aber wie jeder andere Logikfehler.
Unnötige Constraints vermeiden
Nicht selten wird eine einzelne PLL verwendet, um Takte mit verschiedenen Frequenzen zu erzeugen, die für unterschiedliche Funktionseinheiten gedacht sind. Aus Sicht des Entwicklers sind das nicht verwandte Takte, in Wirklichkeit sind es aber verwandte Takte, und die Tools betrachten sie meist auch als solche.
Angenommen, eine PLL erzeugt aus einem Referenztakt von 10 MHz zwei Takte. Der eine Takt hat 90 MHz, der zweite 100 MHz. Die Absicht ist, diese Takte für verschiedene Teile des Projekts zu verwenden, also sind sie konzeptionell nicht verwandt. Was aber, wenn eine Verbindung zwischen zwei Flip-Flops besteht, wobei das eine Flip-Flop synchron mit dem einen Takt und das zweite Flip-Flop synchron mit dem anderen Takt ist?
Weil die Periode des ersten Takts 11,11 ns und die des zweiten Takts 10 ns beträgt, ist der Zeitabstand zwischen den steigenden Flanken im ungünstigsten Fall 1,11 ns (unter Berücksichtigung aller möglichen Phasenkombinationen). Das entspricht einer Taktperiode von 900 MHz. Das Timing des Pfads zwischen diesen beiden Flip-Flops ist also eng; selbst wenn diese Anforderung erfüllbar ist, bereitet sie den Tools Schwierigkeiten, besonders wenn es viele solcher Pfade gibt.
Das ist kein theoretischer Fall: Eine häufige Falle ist, einen Dual-Clock-FIFO zum Übergang zwischen Taktdomänen zu verwenden, ohne darauf zu achten, ob die Takte verwandt sind oder nicht. Funktional ist dieser Fehler unproblematisch, aber da Dual-Clock-FIFOs immer Resynchronisationslogik enthalten, ist es sinnlos, die Tools zu zwingen, Timing-Constraints auf den Pfaden zwischen den beiden Taktdomänen durchzusetzen. Die Tools können sich dann ohne Nutzen mit diesen Timing-Constraints abmühen.
Es ist daher wichtig, auf verwandte Takte zu achten, die nicht als solche verwendet werden – insbesondere auf Takte aus derselben PLL: Sehr wahrscheinlich werden Timing-Constraints auf Pfaden von einer Taktdomäne in die andere durchgesetzt. Das hat keinen Nutzen, weil die Resynchronisationslogik vor Timing-Verletzungen schützt. Andererseits kann die Mühe der Tools, diese Timing-Constraints zu erfüllen, dazu führen, dass die Timing-Constraints für den gesamten Entwurf schwerer zu erfüllen sind.
Zur Lösung fügt man Timing-Constraints hinzu, die die Takte als nicht verwandte Takte deklarieren. Alternativ definiert man falsche Pfade (false paths) oder maximale Verzögerungen für diese Pfade. In manchen Fällen ist das allerdings nicht nötig; es lohnt sich also, vorher den Timing-Bericht für diese Pfade zu prüfen. Wenn man zum Beispiel einen Dual-Clock-FIFO verwendet, der von den FPGA-Tools bereitgestellt wird, werden für die Pfade zwischen den Taktdomänen oft automatisch passende Timing-Constraints hinzugefügt.
Irreführende Timing-Constraints
Es ist wichtig zu betonen, dass die FPGA-Tools Timing-Constraints zwischen nicht verwandten Takten normalerweise akzeptieren und durchsetzen. Solche Constraints sind sinnlos und verwirrend, insbesondere weil die betreffenden Pfade im Timing-Bericht erscheinen, als wären ihre Timing-Anforderungen garantiert. Wie bereits besprochen, ist es unmöglich, das Timing eines Pfads zwischen Taktdomänen zu garantieren, die zu nicht verwandten Takten gehören.
Man darf nicht vergessen, dass Timing-Constraints nur eine Möglichkeit sind, den FPGA-Tools Informationen über den Entwurf zu geben. Wenn ein Entwurf die Timing-Constraints erfüllt, bedeutet das nur dann etwas, wenn die Timing-Constraints korrekt sind. Versuchen Sie also nicht, einen Taktdomänenwechsel durch das bloße Hinzufügen einer Timing-Constraint zu lösen, wenn Sie nicht sicher sind, dass die Takte verwandte Takte sind.
Und noch einmal: Wenn es relevant ist, ist es eine gute Idee, Timing-Constraints hinzuzufügen, die Takte als nicht verwandt definieren, oder falsche Pfade (false paths) zu definieren. Das erleichtert nicht nur die Arbeit der FPGA-Tools, sondern vermeidet auch Verwirrung.
Sicherstellen, dass die Tools korrekt informiert sind
Aus allen oben genannten Gründen ist es entscheidend, dass die FPGA-Entwurfswerkzeuge die richtigen Informationen darüber haben, welche Takte verwandte Takte sind und welche nicht. Oder genauer: dass die FPGA-Tools Timing-Constraints auf alle Pfade anwenden, die nicht durch Resynchronisationslogik geschützt sind (das schließt Pfade innerhalb von Taktdomänen ein, ist hier aber nicht von Bedeutung).
Es kann jedoch schwierig sein sicherzustellen, dass die Tools dieselbe Auffassung haben wie der Logikentwurf: Jede FPGA-Entwurfssoftware hat ihre eigene Art, automatische Annahmen über Beziehungen zwischen Takten zu treffen. Das Einzige, was alle Tools gemein zu haben scheinen, ist: Wenn die eigens dafür vorgesehene Clocking-IP des Tools verwendet wird, um mit derselben PLL zwei oder mehr Takte zu erzeugen, betrachtet das Tool diese Takte als verwandte Takte. Dementsprechend werden Pfade zwischen den betreffenden Taktdomänen zeitlich analysiert und die Timing-Constraints auf diesen Pfaden durchgesetzt. Diese Durchsetzung basiert normalerweise auf der Timing-Constraint, die für den Referenztakt angegeben ist. Aber nicht einmal das sollte man als selbstverständlich hinnehmen.
Abgesehen davon hat jedes Tool seine eigene Art, die Beziehung zwischen Takten abzuleiten, und selbst verschiedene Tools desselben FPGA-Herstellers können in bestimmten Situationen unterschiedlich entscheiden. Besonders auffällig ist, dass Xilinx’ Vivado eher dazu neigt, Takte als verwandte Takte anzunehmen, als Xilinx’ bisheriges Flaggschiff-Tool ISE.
Es gibt also kein allgemeines Prinzip für alle FPGA-Entwurfswerkzeuge, und selbst ein bestimmtes Tool kann überraschende Entscheidungen treffen. Der einzige Weg, dieses Thema wirklich anzugehen, besteht darin, die Timing-Berichte zu prüfen und für bestimmte Pfadgruppen gezielt Timing-Berichte zu erzeugen. So stellt man sicher, dass die Timing-Anforderungen dort vorhanden sind, wo sie notwendig sind, und dort fehlen, wo sie unnötig sind. Das ist eine anspruchsvolle Aufgabe, aber die Mühe lohnt sich.
Damit endet die erste Seite in dieser Serie. Die nächste Seite behandelt die Grundlagen des Taktdomänenwechsels.

