Diese Seite gehört zu einer Serie von Seiten über Timing.
Über diese Seite
Ohne Grundkenntnisse im Logikentwurf ist es unmöglich, das Timing korrekt hinzubekommen. Diese Seite erläutert einige grundlegende Konzepte, die die Basis für den Rest dieser Artikelserie bilden.
Alles, was unten steht, wird in akademischen Kursen zum Logikentwurf gelehrt. Aber nicht jeder, der mit FPGAs arbeitet, hat einen solchen Kurs belegt, und selbst wer einen belegt hat, erinnert sich nicht unbedingt an alles. Diese Seite soll etwaige Wissenslücken schließen.
Du kannst die Teile dieser Seite gerne überspringen, die du bereits kennst. Es ist aber trotzdem empfehlenswert, alles einmal durchzulesen, auch wenn das nur oberflächlich ist. Die letzten Abschnitte dieser Seite sind besonders wichtig, um die nachfolgenden Seiten dieser Serie zu verstehen.
Eine kurze Wiederholung
Bevor wir zu den Timing-Konzepten kommen, möchte ich einige relevante Begriffe aus dem Logikentwurf kurz wiederholen. Falls einer dieser Begriffe noch nicht bekannt ist, empfehle ich dir, dich damit vertraut zu machen, bevor du auf dieser Seite weitermachst.
Zunächst: kombinatorische Logik (combinatorial logic). Dieser Begriff beschreibt Elemente wie Logikgatter: UND-Gatter, ODER-Gatter, NICHT-Gatter usw. Diese Logikelemente zählen zur kombinatorischen Logik, weil sie kein Gedächtnis haben. Mit anderen Worten: Ihr Verhalten hängt nicht davon ab, was in der Vergangenheit passiert ist. Der Wert am Ausgang dieser Logikelemente hängt nur von den Werten an den Eingängen ab.
Ein wichtiger Typ kombinatorischer Logik ist die Look-up-Tabelle (LUT). Sie ist ein vielseitiges Logikelement, das jede beliebige Logikfunktion mit einer bestimmten Anzahl von Eingängen realisiert. Die LUT ist wichtig, weil fast die gesamte kombinatorische Logik in einem FPGA über LUTs umgesetzt wird. Die LUTs in einem FPGA sind als asynchrone ROMs implementiert (also ROMs ohne Takt): Die Eingänge dienen als Adresse für die Daten in der LUT. Der Ausgang besteht üblicherweise aus einem oder zwei Bits.
Fast alle FPGAs auf dem Markt besitzen LUTs mit 4 oder 6 Eingängen. Die Anzahl der Speicherzellen in jeder LUT ist daher entweder 16 oder 64.
Der nächste wichtige Begriff ist die sequentielle Logik. Dazu gehören Flip-Flops, synchrone RAMs und viele andere Bausteine, die einen Takt benötigen. Alle diese Logikelemente werden als Reaktion auf eine bestimmte Änderung des Takts aktiv. Zwischen diesen Aktivitätsmomenten ignorieren sequentielle Elemente ihre Eingänge, behalten ihren internen Zustand und ändern ihre Ausgänge nicht.
Zum Beispiel werden positiv flankengetriggerte Logikelemente aktiv, wenn der Takt von low auf high wechselt, also bei einer steigenden Taktflanke. Entsprechend werden negativ flankengetriggerte Logikelemente aktiv, wenn der Takt von high auf low wechselt, also bei einer fallenden Taktflanke. Es gibt auch Logikelemente, die bei beiden Taktflanken aktiv werden; diese verwendet man jedoch fast ausschließlich zum Abtasten (sampling) von I/O-Signalen oder zu deren Erzeugung.
Alle sequentiellen Elemente haben eine Form von Speicher. Das folgt unmittelbar daraus, dass sie ihren Ausgang erst ändern, wenn eine Taktflanke eintrifft. Einige sequentielle Elemente haben die minimale Speichermenge, nämlich genau ein Bit pro Ausgang. Andere haben mehr Speicher, zum Beispiel Schieberegister und RAMs.
Für die Diskussion über Timing sind nur zwei Tatsachen wichtig: Der Eingang wird nur im Zusammenhang mit einer Taktflanke abgetastet, und der Ausgang ändert sich fast ausschließlich als Folge einer Taktflanke. Es gibt genau eine Ausnahme: Einige sequentielle Elemente haben einen asynchronen Reset-Eingang (asynchronous reset). Wenn dieser Eingang aktiv ist (high oder low, je nach Logikelement), wechselt der interne Zustand des sequentiellen Elements sofort auf einen vorgegebenen Wert – unabhängig vom Takt. Dadurch wechseln auch einige oder alle Ausgänge sofort auf einen bekannten Wert.
In einem FPGA haben manche sequentielle Elemente einen asynchronen Reset, andere nicht. Der asynchrone Reset ist der einzige asynchrone Eingang, der bei fast allen sequentiellen Elementen auf einem FPGA vorkommt. Das gilt, obwohl die Theorie des Logikentwurfs durchaus Elemente mit mehreren asynchronen Eingängen kennt, z.B. das SR-Flip-Flop.
Ab jetzt spreche ich über Flip-Flops
Der Einfachheit halber nehme ich an, dass alle sequentiellen Elemente positiv flankengetriggerte Flip-Flops sind, also Flip-Flops, die auf eine steigende Taktflanke reagieren. Mit anderen Worten: Alle sequentiellen Elemente werden hier durch Flip-Flops repräsentiert. Diese Flip-Flops reagieren auf ihre Eingänge und aktualisieren ihre Ausgänge nur, wenn der Takt von low auf high wechselt.
So lässt sich das Timing leichter verstehen, und die Diskussion über Flip-Flops lässt sich problemlos auf jedes andere sequentielle Element verallgemeinern.
Setup- und Hold-Zeiten
Damit ein Flip-Flop korrekt und zuverlässig arbeitet, müssen seine Eingänge gemäß zwei Timing-Anforderungen stabil sein (d.h. ihren Wert nicht ändern):
- Der Eingang muss während einer Zeitspanne vor der Taktflanke stabil sein. Diese Zeitspanne nennt man die Setup-Zeit und bezeichnet sie mit tsu.
- Der Eingang muss während einer Zeitspanne nach der Taktflanke stabil sein. Diese Zeitspanne nennt man die Hold-Zeit und bezeichnet sie mit thold.
Das obige Diagramm zeigt die Bedeutung von tsu und thold: Der D-Eingang darf seinen Wert in der gelb markierten Zeitspanne nicht ändern. In diesem Beispiel wechselt D von high auf low mit zulässigem Timing, also außerhalb dieser gelben Zeitspanne.
Man kann sich diese beiden Timing-Parameter so veranschaulichen: Wenn ein Eingang eines Flip-Flops genau zusammen mit der Taktflanke wechselt, ist natürlich unklar, ob das Flip-Flop diesen Eingang als high oder low auswertet. Was soll es wählen? Den Zustand unmittelbar vor der Taktflanke oder den Zustand danach?
Dann kann man fragen, was es bedeutet, dass der Eingang „genau zusammen“ mit der Taktflanke gewechselt hat. Wie genau ist das? Die beiden Timing-Parameter tsu und thold legen fest, in welchem Abstand zur Taktflanke ein Wechsel des Eingangswerts zulässig ist. Diese Parameter sind für alle sequentiellen Elemente mit derselben Bedeutung definiert.
Wichtig ist: Wird diese Timing-Anforderung verletzt, können die Folgen viel schwerwiegender sein, als dass der Ausgang des Flip-Flops nach der Taktflanke einfach zufällig ist. Dafür gibt es zwei Hauptgründe:
- In manchen Fällen duplizieren die FPGA-Tools während der Implementierung des Projekts automatisch Flip-Flops aus dem Logikentwurf, insbesondere um den Fan-out (englisch: fan-out) zu verringern. Dabei wird ein Teil der Logik, der vom Wert dieses Flip-Flops abhängt, an das eine Flip-Flop angeschlossen, ein anderer Teil an das zweite. Das ist in Ordnung, solange beide Flip-Flops stets denselben Ausgangswert haben. Werden jedoch die Timing-Anforderungen (tsu und thold) verletzt, können die beiden Flip-Flops an ihren Ausgängen unterschiedliche Werte aufweisen.
- Ein Flip-Flop kann in einen Zustand der Metastabilität (metastability) geraten, wenn die Timing-Anforderungen verletzt werden. In diesem Zustand ist der Ausgang des Flip-Flops für kurze Zeit weder high noch low. Mehr über Metastabilität und ihre negativen Folgen findest du auf dieser Seite.
Clock-to-Output-Zeit
Der dritte Timing-Parameter, der für alle sequentiellen Elemente definiert ist, ist die Clock-to-Output-Zeit. Sie hat mehrere gebräuchliche Symbole, z.B. tcko, tco, tC_Q usw. Dieser Parameter ist keine Timing-Anforderung, sondern er gibt an, ab wann der Ausgang (Q) des sequentiellen Elements garantiert gültig ist. Genauer gesagt: Wie viel Zeit nach der Taktflanke vergeht, bis der Ausgang gültig ist (siehe das obige Zeitdiagramm).
Eigentlich gibt es dazu zwei Parameter:
- Die maximale Clock-to-Output-Zeit: Wie viel Zeit vergeht, bis der Ausgang nach einer Taktflanke gültig ist.
- Die minimale Clock-to-Output-Zeit: Wie lange der Ausgang nach einer Taktflanke garantiert unverändert bleibt.
Meistens ist nur die maximale Clock-to-Output-Zeit von Interesse. Wenn dieser Parameter in einem Datenblatt angegeben ist, handelt es sich also fast sicher um den Maximalwert.
Beachte: Werden die Timing-Anforderungen des Flip-Flops (tsu und thold) verletzt, gibt es keine Garantie dafür, wann der Ausgang stabil ist. In diesem Fall ist der Parameter der maximalen Clock-to-Output-Zeit ohne Bedeutung, weil das Flip-Flop möglicherweise kurz in einem undefinierten Zustand verharrt.
tsu und thold können negativ sein
Auch wenn das obige Diagramm positive tsu- und thold-Werte zeigt, kann einer dieser Parameter negativ sein. Tatsächlich kommt das bei Flip-Flops in FPGAs häufig vor.
Ein negatives tsu bedeutet zum Beispiel, dass die Daten nicht bereits stabil sein müssen, wenn die Taktflanke eintrifft. Vielmehr dürfen die Daten ihren stabilen Wert erst kurz nach der Taktflanke erreichen. tsu begrenzt dennoch, wie viel später das sein darf.
In ähnlicher Weise erlaubt ein negatives thold, dass sich die Daten vor der Taktflanke ändern. Auch hier gilt eine Grenze dafür, wie viel früher das zulässig ist; diese Grenze wird durch thold ausgedrückt.
Weil tsu und thold negativ sein können, ist es theoretisch möglich, Timing-Anforderungen zu definieren, die unsinnig sind.
Um das zu erklären, bezeichnen wir mit tsamp den tatsächlichen Zeitpunkt, zu dem das Flip-Flop seinen Eingang abtastet. tsamp ist nicht im Voraus bekannt, aber die Definition von tsu besagt, dass –tsu < tsamp ist. Mit anderen Worten: Das Flip-Flop tastet seinen Eingang ab, nachdem sich die Daten nach einem Wechsel stabilisiert haben – genau das stellt tsu sicher. Nach demselben Prinzip ist tsamp < thold: Die Abtastung muss erfolgen, bevor sich die Daten als Reaktion auf eine Taktflanke ändern können. Zusammengenommen ergibt sich –tsu < tsamp < thold, also einfach –tsu < thold. Das muss für jedes beliebige Paar aus tsu und thold gelten.
tsu und thold können also negativ sein, solange diese Bedingung erfüllt ist. Aber beide können nicht gleichzeitig negativ sein.
Der Clock-to-Output-Parameter ist immer positiv: Ein Flip-Flop kann unmöglich auf eine Taktflanke reagieren, bevor sie eingetroffen ist. Beachte dagegen: Ein negatives tsamp bedeutet nicht, dass die Abtastung vor der Taktflanke stattfand. Das kann vielmehr durch eine Verzögerung des Datensignals bedingt sein.
Signallaufzeit
Das obige Bild zeigt eine einfache Verbindung zwischen zwei Flip-Flops mit einer LUT in der Mitte. Der Einfachheit halber nehmen wir an, dass der Ausgang der LUT nur von I1 abhängt. Diese Logik könnte zum Beispiel das Ergebnis des folgenden Verilog-Codes sein, wobei die LUT ein NICHT-Gatter implementiert:
always @(posedge clk)
begin
foo_reg <= foo; // FF1 = foo_reg
bar <= !foo_reg; // FF2 = bar
end
Beachte, dass beide Flip-Flops an denselben Takt angeschlossen sind. Wie hoch ist die maximale Frequenz dieses Takts?
Um diese Frage zu beantworten, fehlt eine Information: Wie viel Zeit vergeht von dem Moment, in dem der Ausgang von FF1 einen stabilen Wert hat, bis der Eingang von FF2 einen stabilen Wert hat? Diese Zeit bezeichnen wir als tpd, also Signallaufzeit (propagation delay).
Beachte, dass sich der Begriff Signallaufzeit immer auf einen bestimmten Abschnitt der kombinatorischen Logik bezieht. Es ist wichtig, genau zu sagen, auf welchen Abschnitt er sich bezieht. Beispielsweise ließe sich auch die Zeit vom Eingang I1 der LUT bis zu ihrem Ausgang O (vom Eingang zum Ausgang) als Signallaufzeit bezeichnen. Diese Verzögerung unterscheidet sich wahrscheinlich von der obigen Definition von tpd.
Insbesondere gibt es auf einem FPGA eine Routing-Verzögerung zwischen dem Ausgang von FF1 und dem Eingang der LUT. In der Praxis liegt also zwischen FF1s Q und dem Eingang I1 der LUT noch ein Stück Weg, und das Signal benötigt eine gewisse Zeit, um dorthin zu gelangen.
Wegen dieser Mehrdeutigkeit sieht man das Symbol tpd in FPGA-Datenblättern selten. Und wenn in einem solchen Datenblatt eine Signallaufzeit angegeben ist, wird die genaue Bedeutung des Parameters meist ausdrücklich erklärt.
Auf die maximale Frequenz des Takts komme ich später zurück.
Der Pfad
Es ist schwierig, einen Pfad (path) knapp und präzise zu definieren, aber wir haben bereits ein Beispiel dafür gesehen. Oben habe ich tpd als die Signallaufzeit zwischen FF1s Q und FF2s D definiert. Dieses tpd bezieht sich auf ein konkretes Szenario: FF1 ändert seinen Wert; der aktualisierte Wert erreicht die LUT; die LUT ändert ihren Ausgang; schließlich erreicht der aktualisierte Wert FF2. Diese Ereigniskette beginnt mit der Änderung nur eines Signals (des Ausgangs von FF1) und endet, wenn das Signal an einem anderen Punkt (dem Eingang von FF2) stabil ist.
tpd ist also die Signallaufzeit des Pfads von FF1s Q zu FF2s D – kurz gesagt: des Pfads von FF1 zu FF2.
Ein Pfad besteht aus allen Elementen, die eine Verzögerung vom Anfang bis zum Ende dieser Ereigniskette verursachen. Dabei gibt es zwei Arten von Elementen:
- Elemente der kombinatorischen Logik: Sie tragen zur Verzögerung bei, weil elektronische Schaltungen eine gewisse Zeit benötigen, um die Signale an ihren Ausgängen zu aktualisieren. Das wird oft als Logikverzögerung bezeichnet. Im obigen Beispiel ist die LUT ein solches Element.
- Routing: also die Leitungen zwischen den Logikelementen. Diese Abschnitte verursachen eine Verzögerung, weil ein Signal Zeit braucht, um sich räumlich auszubreiten, und weil eine Spannungsänderung das Aufladen von Kondensatoren entlang des Wegs mit sich bringt.
Der Zweck eines Pfads ist die Berechnung seiner Signallaufzeit. Wie das Ergebnis dieser Berechnung verwendet wird, zeigt der nächste Abschnitt.
Oft steht ein Pfad für ein Gedankenexperiment, bei dem sich der Ausgang eines Flip-Flops ändert und wir einem bestimmten Weg bis zum Eingang eines anderen Flip-Flops folgen. In diesem Gedankenexperiment wird eine imaginäre Stoppuhr gestartet, sobald sich der Ausgang des ersten Flip-Flops ändert. Sie wird gestoppt, wenn sich der Eingang des zweiten Flip-Flops ändert.
Mit diesem Gedankenexperiment lässt sich feststellen, ob die von der Stoppuhr angezeigte Zeit zu lang ist, was eine Verletzung der tsu-Anforderung wäre. Die zweite Frage ist, ob diese Zeit zu kurz ist und thold verletzt wurde.
Beachte, dass der Weg eines Pfads nur Leitungen und kombinatorische Logik umfasst. Die Zeit bis zur Stabilisierung des Signals am Ziel hängt also nur von den Elementen der kombinatorischen Logik und den Leitungen entlang des Pfads ab. Es spielt keine Rolle, wann dieses Gedankenexperiment durchgeführt wird – das Ergebnis ist immer dasselbe.
In einem realen FPGA-Design hat jedes Flip-Flop normalerweise viele Pfade, die zu seinem Eingang führen, und viele Pfade, die an seinem Ausgang beginnen. Es kann zwischen zwei Flip-Flops sogar mehr als einen Pfad geben. Trotzdem basieren Timing-Berechnungen immer auf der Annahme, dass nur ein einziges Flip-Flop seinen Ausgang geändert hat und dass alles, was in der FPGA-Logik passiert, eine direkte Folge dieser Änderung ist. Die Zahl der Pfade, die in einem FPGA-Design berechnet wird, kann enorm sein; das erledigt aber selbstverständlich die Software.
Eine einfache statische Timing-Analyse
Zur Demonstration mache ich eine einfache Timing-Analyse des obigen Beispiels mit zwei Flip-Flops. Das Thema Timing-Constraints (englisch: timing constraints) wird später behandelt, aber für den Augenblick nehmen wir an, dass @clk eine Frequenz von 250 MHz (4 ns) hat und direkt mit der Logik verbunden ist (also ohne PLL – in einem realen Design nicht zu empfehlen, vereinfacht aber die Timing-Analyse). Die Timing-Constraint im SDC-Stil könnte etwa so aussehen:
create_clock -period 4.000 -name clk [get_ports clk]
Ein Beispiel für eine echte Timing-Analyse findest du auf der nächsten Seite dieser Serie. Diese Analyse ist jedoch präzise und enthält daher viele Details, die das Verständnis erschweren. Hier handelt es sich also um eine einfache Analyse, die nur das Prinzip veranschaulicht.
Die Analyse führt das oben erwähnte Gedankenexperiment durch: Eine imaginäre Stoppuhr startet mit der steigenden Flanke von @clk. Das ist die Ereigniskette mit den (fiktiven) Verzögerungen, die jedes Ereignis beiträgt.
- Clock-to-Output von FF1 (0,2 ns): Die Zeit, die vergeht, bis der Ausgang (Q) von FF1 mit dem Wert am Eingang (D) des Flip-Flops aktualisiert wird.
- Routing-Verzögerung zu I1 (0,3 ns): Die Zeit, die das Signal benötigt, um vom Ausgang von FF1 zum Eingang I1 der LUT zu gelangen.
- Signallaufzeit der LUT (0,3 ns): Die LUT braucht diese Zeit, um ihren Ausgang (O) zu aktualisieren, nachdem sich einer ihrer Eingänge (hier I1) geändert hat.
- Routing-Verzögerung zum Eingang von FF2 (0,4 ns): Die Zeit, die das Signal braucht, um vom Ausgang der LUT zum Eingang D von FF2 zu gelangen.
Die Signallaufzeit (tpd) dieses Pfads ist die Summe all dieser Verzögerungen: 0,2 + 0,3 + 0,3 + 0,4 = 1,2 ns. Für das Beispiel nehmen wir an, dass tsu von FF2 0,1 ns beträgt. Das bedeutet, dass der Eingang D von FF2 0,1 ns vor der nächsten steigenden Flanke von @clk stabil sein muss. Mit anderen Worten: Der maximal zulässige tpd beträgt 4 – 0,1 = 3,9 ns.
tpd ist aber nur 1,2 ns. Damit erfüllt der Pfad die Timing-Constraint mit großem Spielraum. Dieser Spielraum wird Slack (englisch: slack) genannt; in diesem Fall beträgt er 3,9 – 1,2 = 2,7 ns. Taucht diese Zahl in den Timing-Berechnungen der Software auf, zeigt sie an, ob die Tools Schwierigkeiten hatten, die Timing-Constraints zu erfüllen: Liegt der Slack nahe bei null, deutet das oft darauf hin, dass die Software hart arbeiten musste, um den Pfad innerhalb der Timing-Anforderungen unterzubringen.
Die Signallaufzeit erlaubt außerdem, die maximale Frequenz von @clk zu berechnen, mit der dieser Pfad das Timing einhalten kann. tpd beträgt 1,2 ns. Wegen der tsu-Anforderung muss die nächste steigende Flanke mindestens 0,1 ns nach dem Zeitpunkt kommen, an dem der Eingang von FF2 stabil ist. Zwischen den steigenden Flanken müssen also mindestens 1,3 ns liegen. Das entspricht einer Frequenz von etwa 769 MHz. Das ist eine sehr hohe Frequenz, aber ein realistisches Ergebnis, weil der Pfad nur eine einzige LUT enthält. Reale Logik ist meist komplizierter, und deshalb sind reale Frequenzen oft deutlich niedriger.
Eine echte statische Timing-Analyse rechnet genau diese Rechnung, aber das ist nur ein Teil der Geschichte. Der hier berechnete Pfad wird in einer echten Berechnung als Datenpfad bezeichnet. Eine echte statische Timing-Analyse berücksichtigt jedoch auch, dass die Taktflanke nicht an beiden Flip-Flops exakt zur gleichen Zeit ankommt. Das liegt daran, dass die Verzögerung vom Taktpuffer zu jedem dieser Flip-Flops geringfügig unterschiedlich ist. Diesen Unterschied nennt man Taktversatz (clock skew). Außerdem ist der Abstand zwischen zwei Taktflanken nicht exakt gleich, weil der Takt einen Jitter (englisch: jitter) aufweist. Diese Taktprobleme erschweren die genaue Berechnung, wie auf der nächsten Seite gezeigt wird.
Recovery- und Removal-Zeiten
Wenn ein Flip-Flop einen asynchronen Reset-Eingang hat (bist du dir sicher, dass du das willst?), gibt es Anforderungen daran, wann dieser Eingang wieder inaktiv wird. Es spielt keine Rolle, wann der Reset aktiv wird, denn das Flip-Flop geht so oder so in einen bekannten Zustand über.
Sobald der Reset jedoch inaktiv wird, ist das Flip-Flop wieder empfindlich für den Takt. Erfolgt diese Deaktivierung nahe an einer Taktflanke, ist nicht klar, ob das Flip-Flop darauf reagieren soll. Genau wie bei tsetup und thold muss der Reset während einer Zeitspanne um die Taktflanke herum stabil sein. Etwas konkreter:
- Der Reset darf während einer Zeitspanne vor der Taktflanke nicht von aktiv auf inaktiv wechseln. Diese Zeitspanne wird die Recovery-Zeit genannt. Sie ist die Zeit, die das Flip-Flop braucht, um sich vom Reset zu erholen und bereit für eine Taktflanke zu sein.
- Der Reset darf während einer Zeitspanne nach der Taktflanke nicht von aktiv auf inaktiv wechseln. Diese Zeitspanne wird die Removal-Zeit genannt.
Diese Definitionen ähneln denen von tsetup und thold. Das ist kein Zufall: Die Recovery-Zeit ist eine besondere Form der Setup-Zeit. Die Timing-Analyse funktioniert genauso. Der einzige Unterschied ist, dass die Setup-Zeit unabhängig vom Wert des Datensignals immer relevant ist. Die Recovery-Zeit dagegen greift nicht, wenn das asynchrone Reset-Signal gerade aktiv wird. Die Beziehung zwischen Removal-Zeit und Hold-Zeit ist analog dazu.
Wegen dieser Ähnlichkeit werden Recovery und Removal hier über diese Erwähnung hinaus nicht behandelt. Beachte außerdem, dass das oben Gesagte für alle asynchronen Eingänge gilt, nicht nur für asynchronen Reset.
Das RTL-Paradigma und das Timing
Das obige Beispiel mit zwei Flip-Flops ist einfach, aber es repräsentiert die gesamte Logik, die nach dem RTL-Paradigma entsteht: Jeder Pfad beginnt an einem Flip-Flop und endet an einem Flip-Flop, wobei die beteiligten Flip-Flops mit demselben Takt – oder mit zueinander verwandten Takten (related clocks) – arbeiten. Der Pfad selbst besteht aus kombinatorischer Logik und Routing. In diesem Beispiel ist die kombinatorische Logik nur eine einzige LUT; zwischen diesem Fall und einem Pfad mit mehreren Logikelementen gibt es keinen prinzipiellen Unterschied. Die Struktur ist dieselbe.
Warum ist das RTL-Paradigma so wichtig? Wenn man mit dieser Methode arbeitet, haben fast alle Datenpfade dieselbe einfache Struktur. Weil die Zahl der Pfade in einem Logikentwurf oft riesig ist, hilft die Einfachheit der Timing-Analyse, Fehler zu vermeiden. Unter anderem sorgt das feste Schema der Timing-Analyse dafür, dass man den Timing-Report lesen und hinterfragen kann, ob er plausibel ist.
Nach Möglichkeit sollte also alles an einem sequentiellen Element beginnen und an einem sequentiellen Element enden. Das ist eine nützliche Leitlinie sowohl beim Schreiben von Verilog-Code als auch allgemein bei der Planung der Logikstruktur.
Damit ist die kurze Einführung in die Theorie hinter Timing-Constraints abgeschlossen. Eine Taktperioden-Constraint und die zugehörigen Timing-Reports werden auf der nächsten Seite erklärt.


