Diese Seite gehört zu einer Serie von Seiten über Timing. Die vorherigen Seiten haben die Theorie hinter Timing-Berechnungen erklärt, die Taktperioden-Vorgabe besprochen, die Prinzipien des Timing-Closure vorgestellt und einige wichtige Tcl-Befehle eingeführt. Diese Seite erklärt, wie man Timing-Vorgaben für bestimmte Pfade definiert.
Einführung
Das Ziel beim Schreiben von Timing-Vorgaben ist, dass sie kurz, prägnant und leicht verständlich sein sollten. Das verringert das Risiko von Verwirrung und Fehlern. Wenn möglich, sollten die Timing-Vorgaben für die internen Pfade des FPGAs nur aus zwei Arten bestehen: Taktperioden-Vorgaben (z.B. create_clock) und Taktgruppen-Vorgaben (z.B. set_clock_groups).
Aber oft benötigen bestimmte Pfade eigene Regeln. Diese speziellen Regeln nennt man Timing-Ausnahmen (englisch: timing exceptions). Wie der Name andeutet, dienen diese Timing-Vorgaben in erster Linie dazu, die vorhandenen Timing-Vorgaben zu übersteuern. Sie können auch verwendet werden, um Timing-Anforderungen für Pfade festzulegen, die sonst keine solchen Anforderungen hätten.
Die Befehle für diese Zwecke in der SDC-Syntax sind hauptsächlich diese:
- set_false_path: Teilt den Tools mit, dass auf den ausgewählten Pfaden keine Timing-Anforderungen durchgesetzt werden sollen.
- set_max_delay: Definiert die Anforderung zur Durchsetzung von tsetup.
- set_min_delay: Definiert die Anforderung zur Durchsetzung von thold.
- set_multicycle_path: Lockert die Anforderungen für Logik, die von einem Clock-Enable-Signal gesteuert wird.
Tools, die eine andere Syntax verwenden, haben wahrscheinlich ähnliche Befehle.
Die Argumente dieser Befehle definieren unter anderem, welche Pfade betroffen sein sollen. Das wird weiter unten erklärt.
Es gibt zwei verwandte Themen, die auf anderen Seiten behandelt werden:
- Für I/O-Timing-Vorgaben gibt es eine eigene Seite. Die folgende Diskussion beschränkt sich daher auf die Verwendung dieser Befehle mit internen Pfaden (also Pfaden, die von einem sequentiellen Logikelement in der Logikstruktur ausgehen und an einem solchen enden).
- set_multicycle_path wird auf einer eigenen Separaten Seite behandelt.
False Paths
Ein False Path (falscher Pfad) ist ein Pfad, den die Tools aufgrund einer Timing-Vorgabe, die das anfordert, ignorieren. Mit anderen Worten: Die Tools setzen auf einem False Path bewusst keine Timing-Anforderungen durch, weil wir ihnen das so gesagt haben.
Das darf nicht mit unconstrained paths (Pfaden ohne Timing-Vorgabe) verwechselt werden: Das sind Pfade, für die die Tools keine Timing-Vorgabe haben. Wie bei False Paths setzen die Tools auf diesen Pfaden keine Timing-Anforderungen durch, aber der Grund ist ein anderer: Dieses Nichtt Durchsetzen ist keine Absicht, sondern die Tools wissen nicht, welche Anforderung sie anwenden sollen.
In einem FPGA-Design sollte es keine Pfade ohne Timing-Vorgabe (unconstrained paths) geben. Allerdings gibt es oft Pfade, die wir von den Tools ignorieren lassen wollen. Diese Pfade sollten mit Timing-Vorgaben als False Paths markiert werden. Die Begründung: Wenn wir den Timing-Report lesen, sollten wir immer sehen, dass die Anzahl der Pfade ohne Timing-Vorgabe null ist. Wenn diese Anzahl nicht null ist, sollten wir nach einem Fehler suchen. Wenn wir uns daran gewöhnen, eine Anzahl ungleich null zu akzeptieren, übersehen wir leichter Probleme mit Timing-Vorgaben.
Es gibt also zwei mögliche Gründe, False Paths zu deklarieren:
- Wenn die Tools sonst Timing-Anforderungen auf dem Pfad durchsetzen würden, weist ein False Path die Tools an, den Pfad stattdessen zu ignorieren.
- Wenn es keine Timing-Vorgabe für den Pfad gibt. In diesem Fall dient der False Path nur dazu, die Anzahl der Pfade ohne Timing-Vorgabe auf null zu halten.
Praktisch spielt es keine Rolle, welches dieser Szenarien zutrifft. Wenn auf einem Pfad keine Timing-Anforderungen nötig sind, sollte er als False Path deklariert werden.
Ein häufiger Fehler ist die Verwendung von set_false_path im Zusammenhang mit Taktdomänenübergängen (clock domain crossings). Dieses Thema wird später genauer besprochen. Tatsächlich gibt es nicht viele Situationen, in denen die Verwendung von set_false_path richtig ist, abgesehen von I/O-Ports.
Auswahl von Pfaden für set_false_path
Es gibt viele Möglichkeiten auszuwählen, auf welche Pfade sich der Befehl bezieht. Trotz der großen Auswahl wird die Auswahl der Pfade meist mit zwei Argumenten durchgeführt: -from und -to. Zum Beispiel:
set_false_path -from [get_cells source_reg] -to [get_cells dest_reg]
In diesem Beispiel wird der Befehl set_false_path auf den Pfad angewendet, der an einem @source-Register beginnt und am @dest-Register endet.
Beachten Sie, dass get_cells für -from und -to Objekte liefert, die Logikelemente repräsentieren. Die anderen Befehle, die auf der vorherigen Seite besprochen wurden, können ebenfalls verwendet werden: get_pins, get_nets, get_ports und get_clocks. Jedes FPGA-Tool hat jedoch seine eigenen Regeln, was für -from und -to zulässig ist.
Beachten Sie, dass die Tools den Bezug auf Objekte möglicherweise nicht so interpretieren, wie man es natürlich erwarten würde. Die Tools können auch einige oder alle Objekte ignorieren, ohne eine Warnung auszugeben. Wenn tatsächlich keine Objekte vom get_*-Befehl gefunden werden (z.B. wegen eines Fehlers im Suchmuster), wird kein Pfad in die Timing-Ausnahme einbezogen. Auch das kann ohne Warnung geschehen.
Es ist daher wichtig, den Timing-Report zu verwenden, um zu überprüfen, ob die Timing-Ausnahmen wie beabsichtigt angewendet werden. Das bedeutet, dass die richtigen Pfade betroffen sind und dass die Timing-Analyse ihren genauen Zweck erfüllt (keine Durchsetzung von Timing-Anforderungen).
Es gibt ein weiteres nützliches Argument zur Auswahl von Pfaden: -through. Wie der Name andeutet, wählt dieses Argument Pfade aus, die durch die bestimmten Logikelemente führen.
Es lohnt sich, die offizielle Dokumentation zu lesen, um alle Funktionen zu kennen. Zum Beispiel ist es auch möglich, die Wirkung des Befehls nur auf steigende oder nur auf fallende Taktflanken zu beschränken. Eine weitere Möglichkeit besteht darin, den Befehl auf die Analyse nur von tsetup oder nur von thold zu beschränken.
Der Befehl set_false_path benötigt mindestens eines von -from, -to oder -through als Argument (oder ein anderes Argument mit ähnlicher Bedeutung). Wenn mehr als ein Argument vorhanden ist, gilt die Timing-Ausnahme nur für die Pfade, die die Bedingungen aller Argumente erfüllen.
Die Gefahr bei set_false_path
Das Problem bei False Paths ist, wie leicht man Fehler machen kann. Insbesondere besteht das Risiko, mehr Pfade einzubeziehen als beabsichtigt. Wenn das passiert, gibt es sequentielle Elemente, die möglicherweise nicht ordnungsgemäß arbeiten: Wir erwarten fälschlicherweise, dass die Tools ihre Anforderungen für tsu und thold garantieren. In Wirklichkeit verhalten sich die Tools aber so, als wären die Pfade zu diesen sequentiellen Elementen False Paths. Die Tools bemühen sich also nicht um eine Timing-Analyse für sie. Das ist eine gefährliche Situation, weil sie die Illusion erzeugt, dass alles in Ordnung ist, wenn die Tools sagen, dass die Timing-Vorgaben erreicht wurden. In Wirklichkeit gibt es Flipflops und andere sequentielle Elemente, die Timing-Verletzungen ohne jeden Schutz ausgesetzt sind.
Erschwerend kommt hinzu: Wenn ein Pfad als False Path deklariert ist, hat diese Deklaration normalerweise höchste Priorität. Wenn also ein Pfad versehentlich als False Path deklariert wird, übersteuert das wahrscheinlich andere Timing-Vorgaben, die das Gegenteil verlangen. Das gilt in der Regel auch dann, wenn set_false_path vor der anderen Timing-Vorgabe steht. set_false_path wird also interpretiert als „das sind False Paths, egal was ich vorher oder später verlangt habe.“
set_min_delay und set_max_delay
Ich habe mit False Paths begonnen, die die Timing-Anforderungen für eine Gruppe ausgewählter Pfade beseitigen. Oft ist es aber nötig, Timing-Anforderungen festzulegen, statt sie aufzuheben. Das geschieht mit set_min_delay und set_max_delay. Betrachten wir zum Beispiel diesen Verilog-Code:
reg x, y;
always @(posedge clk)
y <= x;
Und die Timing-Vorgaben:
set_max_delay -from [get_cells x_reg] -to [get_cells y_reg] 3 set_min_delay -from [get_cells x_reg] -to [get_cells y_reg] 1
Was bedeutet das nun? Beginnen wir mit set_max_delay. Die kurze Erklärung für diese Timing-Ausnahme ist, dass sie einer Taktperioden-Vorgabe (create_clock) ähnelt, die nur für bestimmte Pfade gedacht ist.
Zur Erinnerung: Wenn eine Taktperioden-Vorgabe definiert ist, setzen die Tools automatisch die notwendigen Timing-Anforderungen durch: Die maximalen Verzögerungen der betreffenden Pfade werden beschränkt, um die tsetup-Anforderung zu erfüllen. Ebenso werden die minimalen Verzögerungen im Hinblick auf thold beschränkt.
Im obigen Beispiel beträgt der Wert im Befehl set_max_delay 3. Das entspricht einem create_clock-Befehl für eine Taktperiode von 3 ns. Aber der Einfluss von set_max_delay ist auf eine bestimmte Gruppe von Pfaden begrenzt. Das ist der Unterschied.
Was set_min_delay betrifft, so ist es etwas komplizierter, dazu weiter unten mehr.
Beachten Sie, dass der Name des Befehls set_max_delay irreführend ist: Dieser Befehl definiert nicht direkt die maximale Verzögerung des Pfads selbst. Die Verzögerung der betroffenen Pfade wird durch den Befehl im obigen Beispiel nicht auf 3 ns begrenzt. Der Wert 3 ns wird als zulässige Zeitdifferenz zwischen Taktflanken angewendet. Und diese Zeitdifferenz wird nicht an den Takteingängen der synchronen Elemente gemessen, sondern am Ursprung dieser Takte. Das bedeutet, dass die Verzögerungen der PLLs, der Taktpuffer und der Taktverteilung in die Berechnungen einbezogen werden: Ähnlich wie bei einer Taktperioden-Vorgabe werden die Taktverzögerungen in der Timing-Analyse berücksichtigt.
Die Bedeutung von -from, -to, -through und anderer Argumente ist dieselbe wie bei set_false_path. Aber allgemein gesprochen sind set_min_delay und set_max_delay als Anpassungen zu einer Taktperioden-Vorgabe gedacht. Dementsprechend wird normalerweise angenommen, dass sich auf beiden Seiten des Pfads sequentielle Elemente befinden. -from und -to sollten also synchrone Elemente repräsentieren. Es gibt viele Möglichkeiten, sich darauf zu beziehen: ein Cell-Objekt, das das synchrone Element selbst repräsentiert, ein Taktobjekt usw.
Bei set_min_delay gibt es eine ähnliche Geschichte: Eine weitere Folge einer Taktperioden-Vorgabe ist, dass die Tools thold-Anforderungen erfüllen müssen. Dazu setzen die Tools minimale Verzögerungen auf allen Pfaden zwischen demselben Takt oder zwischen zusammenhängenden Takten (related clocks) durch. Wenn die Timing-Berechnung für einen Pfad nur aus create_clock resultiert (mit demselben Takt auf beiden Seiten), entspricht das einem set_min_delay mit dem Wert null. Das spiegelt die Vorstellung wider, dass dieselbe Taktflanke an beiden sequentiellen Elementen ankommt. Das bedeutet aber nicht, dass diese Taktflanke an diesen sequentiellen Elementen gleichzeitig ankommt. Vielmehr startet die Taktflanke für jedes sequentielle Element zur selben Zeit am Taktursprung. Die Verzögerung vom jeweiligen Taktursprung zum sequentiellen Element wird in der Berechnung berücksichtigt (ähnlich wie bei der Berechnung für tsetup).
Mit set_min_delay kann man den Zeitpunkt der Taktflanke, die am zweiten sequentiellen Element ankommt, verändern. Der obige Befehl lässt diese Taktflanke am zweiten Flipflop beispielsweise um 1 ns später ankommen. Dadurch wird die Timing-Anforderung für thold schwerer zu erfüllen. Siehe dazu das Beispiel eines Timing-Reports weiter unten.
Es gibt zwei mögliche Gründe für die Verwendung von set_min_delay und set_max_delay:
- Wenn die Timing-Anforderung, die die Tools sonst durchsetzen würden, für eine Gruppe bestimmter Pfade ungeeignet ist. Zum Beispiel, wenn die Timing-Anforderung auf Pfaden, die an einem Metastabilitäts-Schutzregister beginnen, strenger sein muss.
- Wenn für die Pfade keine zugehörige Timing-Vorgabe existiert. Wenn Sie set_max_delay für diesen Zweck verwenden möchten, fragen Sie sich, ob Sie nicht stattdessen eine Taktperioden-Vorgabe oder Multicycle-Pfade (multi-cycle paths) benötigen.
Wenn diese beiden Befehle verwendet werden, überprüfen Sie in den Timing-Reports immer sorgfältig die Timing-Analyse der betreffenden Pfade. Achten Sie insbesondere darauf, welche Rolle der Taktpfad in der Berechnung spielt.
Am Ende dieser Seite finden Sie Beispiele für Timing-Reports, die die Ergebnisse von set_min_delay und set_max_delay zeigen.
Genauere Steuerung der Verzögerung
Der Grad der Steuerung, den set_max_delay und set_min_delay bieten, ist nicht wesentlich besser als bei einer Taktperioden-Vorgabe (so wie bisher dargestellt). Aber was, wenn wir nicht wollen, dass die Taktpfadverzögerung unsere Definition der Verzögerung beeinflusst? Was, wenn wir die Verzögerung eines bestimmten Abschnitts des Pfads steuern wollen?
Einige FPGA-Tools bieten für diese Bedürfnisse keine Lösung an. Quartus bietet zum Beispiel keine solche Möglichkeit (soweit ich weiß). Vivado hingegen hat einige Funktionen, die ich kurz besprechen werde.
Eine solche Funktion ist die Option datapath_only: Manchmal möchte man set_max_delay so verwenden, dass die Timing-Berechnung die Taktpfade nicht einbezieht. Wenn ein Pfad zum Beispiel zwischen unabhängigen Takten (unrelated clocks) liegt, ist es bedeutungslos, die Taktpfade zu berücksichtigen.
Bei Verwendung von datapath_only wird das Timing so berechnet, als wäre die Taktpfadverzögerung beider synchroner Elemente null. Die Berechnung besteht also nur aus den Verzögerungen der Logikelemente des Pfads. Die Summe dieser Verzögerungen muss kleiner sein als die im set_max_delay-Befehl angegebene Zahl (siehe Beispiel des Timing-Reports weiter unten).
Wenn set_max_delay also mit datapath_only verwendet wird, ist seine Bedeutung näher an dem, was der Name dieses Befehls vermuten lässt. Beachten Sie jedoch, dass der Pfad weiterhin an einem synchronen Element beginnen und enden muss.
Datapath_only hat außerdem ein paar Eigenheiten: Wenn es verwendet wird, setzen die Tools keinerlei Timing-Anforderungen bezüglich thold der betreffenden Pfade durch. Mit anderen Worten: Die Tools verhalten sich so, als gäbe es eine False-Path-Vorgabe, die nur auf das thold-Szenario angewendet wird. Selbst wenn für die betreffenden Pfade ein set_min_delay-Befehl hinzugefügt wird, wird dieser Befehl ignoriert. Es ist nicht klar, warum Vivado sich weigert, auf den von datapath_only betroffenen Pfaden eine Mindestverzögerung durchzusetzen.
datapath_only kann in keinem Szenario als Argument für set_min_delay verwendet werden.
Irreführende Funktionen
Wie der Titel dieses Abschnitts andeutet, sind das ein paar Möglichkeiten, die wahrscheinlich keinen Nutzen bringen. Sie können gerne zum nächsten Abschnitt springen.
Vivado erlaubt eine noch höhere Kontrollebene: Es ist möglich, Beschränkungen für die Verzögerung eines bestimmten Abschnitts eines Pfads durchzusetzen. Was passiert zum Beispiel, wenn Logikelemente, die keine sequentiellen Elemente sind, mit -from und -to verwendet werden? Wie sieht es mit Pins und Netzen aus? Was werden set_min_delay und set_max_delay dann tun?
Das hängt natürlich vom verwendeten FPGA-Tool ab. Die Tools können solche Vorgaben stillschweigend ignorieren, weil keine Pfade zu der Anforderung passen. Vivado ignoriert solche Vorgaben jedoch nicht, obwohl das Ergebnis nicht das ist, was man natürlich erwarten würde: Vivado betrachtet diese Situation als „Path Segmentation“ (Pfdabschnittsbildung) und gibt als Reaktion darauf eine kritische Warnung (critical warning) aus. In den meisten Fällen ist die Verwendung dieser Funktion die damit verbundenen Komplikationen nicht wert. Weitere Informationen finden Sie in der Dokumentation.
Und hier ist eine weitere Funktion, die irreführend sein kann: Quartus hat einen Befehl namens set_net_delay. Damit kann man eine minimale und maximale Verzögerung zwischen verschiedenen Logikelementen im Design definieren. Es scheint jedoch, dass die Tools diese Timing-Anforderungen während der Implementierung nicht zu erreichen versuchen. Stattdessen ist es möglich, einen Report mit „report_net_delay“ (oder über die GUI) zu erzeugen. Aus diesem Report lässt sich also ableiten, ob die mit set_net_delay definierten Bedingungen erfüllt wurden. set_net_delay kann also zum Gewinnen von Informationen verwendet werden, ist aber als Timing-Vorgabe nicht nützlich. Mit anderen Worten: set_max_delay und set_min_delay wirken als Timing-Vorgaben, set_net_delay dagegen nicht.
Zusammenfassend wird es nicht viel besser als die einfache Verwendung von set_max_delay und set_min_delay. Die einzige wirklich interessante Funktion scheint Vivados datapath_only zu sein.
Prioritätsreihenfolge von Timing-Vorgaben
Das Hauptproblem bei komplizierten Timing-Vorgaben ist, dass es oft Pfade gibt, die von mehr als einer Vorgabe betroffen sind. Diese Vorgaben haben für diese Pfade meist widersprüchliche Timing-Anforderungen. Welche Vorgabe gewinnt also?
Jedes FPGA-Tool hat seine eigenen Regeln zur Lösung solcher Konflikte. Es hängt meist in erster Linie von der Art der Vorgabe ab. Andere Faktoren können ebenfalls eine Rolle spielen, insbesondere die Spezifität der Pfadauswahl.
Für Timing-Vorgaben, die auf SDC basieren, hängt die Priorität von der Art der Vorgabe ab. Vivado löst einen Konflikt zum Beispiel nach dieser Prioritätsreihenfolge. Die Befehle sind von höchster zu niedrigster Priorität aufgelistet:
- set_clock_groups (Gruppen zusammenhängender und unabhängiger Takte)
- set_false_path (False Path)
- set_min_delay und set_max_delay (Mindestverzögerungen und Maximalverzögerungen)
- set_multicycle_path (Multicycle-Pfad)
- create_clock (Taktperiode)
Beachten Sie, dass die ersten beiden Befehle (set_clock_groups und set_false_path) False Paths erzeugen und die höchste Priorität haben. Es ist daher besonders wichtig zu prüfen, dass kein Pfad versehentlich von diesen Befehlen betroffen ist. Ein solcher Fehler schaltet stillschweigend die gesamte Durchsetzung von Timing-Anforderungen auf den betreffenden Pfaden ab.
Wenn derselbe Befehl für denselben Pfad mehr als einmal verwendet wird, gewinnt der spezifischste Befehl. Wenn der eine Befehl zum Beispiel „-from“ und „-to“ hat, der zweite aber nur „-from“, gewinnt der erste Befehl. Ein weiteres Beispiel: Wenn der eine Befehl die Pfade anhand von Logikelementen definiert (z.B. mit get_cells) und der zweite die Pfade anhand von Takten (mit get_clocks), gewinnt der erste Befehl.
Wenn zwei Befehle so ähnlich sind, dass es keinen Unterschied in der Priorität gibt, entscheidet die Reihenfolge des Auftretens: Der letzte Befehl gewinnt.
Ähnliche Prioritätsregeln verwendet Quartus und andere SDC-basierte Tools.
Aber unabhängig davon, welches Tool Sie verwenden: Es ist am besten, jeden Widerspruch zwischen Timing-Vorgaben zu vermeiden (außer zum Übersteuern von create_clock). Komplizierte Timing-Vorgaben sind der Ort, an dem verheerende Fehler gedeihen können.
Bei einigen FPGA-Tools ist es möglich, die Prioritätsregeln zu umgehen: Mit dem Attribut -reset_path übersteuert der Befehl, der dieses Attribut verwendet, die früheren Timing-Ausnahmen auf allen Pfaden, auf die er sich bezieht. Zum Beispiel:
set_max_delay -reset_path -from [get_cells source_reg] 2
Fazit
Ich habe diese Seite damit begonnen, dass Timing-Vorgaben kurz, einfach und prägnant sein sollten. Durch das Hinzufügen von Timing-Ausnahmen werden die Timing-Vorgaben nicht nur länger, sondern auch komplizierter und schwerer verständlich. Verwenden Sie Timing-Ausnahmen also, wenn es nötig ist, aber schreiben Sie sie sorgfältig und halten Sie sie sauber.
Versuchen Sie, die Timing-Ausnahme-Befehle so zu schreiben, dass sie ihren Zweck und die dahinterstehende Idee widerspiegeln. Die FPGA-Tools bieten normalerweise GUI-Assistenten zum Erstellen von Timing-Vorgaben an. Sie können als Ausgangspunkt nützlich sein. Verwenden Sie aber keine vom Assistenten erzeugte Timing-Vorgabe, bevor Sie sie nicht sorgfältig durchdacht haben. Selbst wenn diese Vorgabe im Moment ihrer Erzeugung richtig ist: Wird sie auch dann zuverlässig funktionieren, wenn sich das Logikdesign weiterentwickelt und neue Logik hinzugefügt wird?
Lesen Sie immer die Timing-Reports für die Pfade, die von einer Timing-Ausnahme betroffen sind. Wenn für einen Pfad mehr als eine Timing-Vorgabe existiert, ist das noch wichtiger. Erstellen Sie außerdem gezielte Timing-Reports für Pfade, bei denen die Möglichkeit falscher Timing-Anforderungen besteht.
Denken Sie daran: Das Erstellen und Lesen von Timing-Reports ist keine Zeitverschwendung. Egal wie sorgfältig Sie die Dokumentation lesen (was immer eine gute Idee ist), es besteht immer die Möglichkeit von Fehlern. Insbesondere False Paths können dort auftreten, wo man sie am wenigsten erwartet.
Bonus: Beispiele für Timing-Reports
Um das Verständnis von set_min_delay und set_max_delay zu erleichtern, folgen hier einige mit Vivado erzeugte Timing-Reports.
Zur Erinnerung: Der Verilog-Code hinter diesen Reports lautet:
always @(posedge clk)
y <= x;
Und die Timing-Vorgaben:
set_max_delay -from [get_cells x_reg] -to [get_cells y_reg] 3 set_min_delay -from [get_cells x_reg] -to [get_cells y_reg] 1
Der Report für tsetup:
Slack (MET) : 0.360ns (required time - arrival time)
Source: x_reg/C
(rising edge-triggered cell FDRE clocked by clk {rise@0.000ns fall@2.000ns period=4.000ns})
Destination: y_reg/D
(rising edge-triggered cell FDRE clocked by clk {rise@0.000ns fall@2.000ns period=4.000ns})
Path Group: clk
Path Type: Setup (Max at Slow Process Corner)
Requirement: 3.000ns (MaxDelay Path 3.000ns)
Data Path Delay: 2.617ns (logic 0.139ns (5.311%) route 2.478ns (94.689%))
Logic Levels: 0
Clock Path Skew: -0.053ns (DCD - SCD + CPR)
Destination Clock Delay (DCD): 2.644ns
Source Clock Delay (SCD): 3.224ns
Clock Pessimism Removal (CPR): 0.527ns
Clock Uncertainty: 0.035ns ((TSJ^2 + TIJ^2)^1/2 + DJ) / 2 + PE
Total System Jitter (TSJ): 0.071ns
Total Input Jitter (TIJ): 0.000ns
Discrete Jitter (DJ): 0.000ns
Phase Error (PE): 0.000ns
Clock Net Delay (Source): 1.392ns (routing 0.002ns, distribution 1.390ns)
Clock Net Delay (Destination): 1.216ns (routing 0.002ns, distribution 1.214ns)
Timing Exception: MaxDelay Path 3.000ns
Location Delay type Incr(ns) Path(ns) Netlist Resource(s)
------------------------------------------------------------------- -------------------
(clock clk rise edge) 0.000 0.000 r
AG12 0.000 0.000 r clk (IN)
net (fo=0) 0.000 0.000 clk_IBUF_inst/I
AG12 INBUF (Prop_INBUF_HRIO_PAD_O)
0.738 0.738 r clk_IBUF_inst/INBUF_INST/O
net (fo=1, routed) 0.105 0.843 clk_IBUF_inst/OUT
AG12 IBUFCTRL (Prop_IBUFCTRL_HRIO_I_O)
0.049 0.892 r clk_IBUF_inst/IBUFCTRL_INST/O
net (fo=1, routed) 0.839 1.731 clk_IBUF
BUFGCE_X1Y0 BUFGCE (Prop_BUFCE_BUFGCE_I_O)
0.101 1.832 r clk_IBUF_BUFG_inst/O
X2Y0 (CLOCK_ROOT) net (fo=4, routed) 1.392 3.224 clk_IBUF_BUFG
SLICE_X49Y57 FDRE r x_reg/C
------------------------------------------------------------------- -------------------
SLICE_X49Y57 FDRE (Prop_DFF_SLICEL_C_Q)
0.139 3.363 r x_reg/Q
net (fo=2, routed) 2.478 5.841 x
SLICE_X49Y57 FDRE r y_reg/D
------------------------------------------------------------------- -------------------
max delay 3.000 3.000
AG12 0.000 3.000 r clk (IN)
net (fo=0) 0.000 3.000 clk_IBUF_inst/I
AG12 INBUF (Prop_INBUF_HRIO_PAD_O)
0.515 3.515 r clk_IBUF_inst/INBUF_INST/O
net (fo=1, routed) 0.066 3.581 clk_IBUF_inst/OUT
AG12 IBUFCTRL (Prop_IBUFCTRL_HRIO_I_O)
0.034 3.615 r clk_IBUF_inst/IBUFCTRL_INST/O
net (fo=1, routed) 0.722 4.337 clk_IBUF
BUFGCE_X1Y0 BUFGCE (Prop_BUFCE_BUFGCE_I_O)
0.091 4.428 r clk_IBUF_BUFG_inst/O
X2Y0 (CLOCK_ROOT) net (fo=4, routed) 1.216 5.644 clk_IBUF_BUFG
SLICE_X49Y57 FDRE r y_reg/C
clock pessimism 0.527 6.171
clock uncertainty -0.035 6.136
SLICE_X49Y57 FDRE (Setup_EFF2_SLICEL_C_D)
0.065 6.201 y_reg
-------------------------------------------------------------------
required time 6.201
arrival time -5.841
-------------------------------------------------------------------
slack 0.360
Beachten Sie, dass der Verzögerungswert (3 ns) als Startzeit für den Taktpfad des zweiten Flipflops verwendet wird. Mit anderen Worten: Es ist genau so, als gäbe es eine Perioden-Vorgabe für 3 ns.
Beachten Sie außerdem, dass das Netz im Datenpfad eine enorme Verzögerung hat: 2,478 ns. Das ist das Ergebnis des set_min_delay-Befehls: Die Tools sind gezwungen, auf diesem Netz eine lange Verzögerung einzufügen, um die thold-Anforderung zu erfüllen.
Apropos: Das ist der Timing-Report für thold:
Slack (MET) : 0.057ns (arrival time - required time)
Source: x_reg/C
(rising edge-triggered cell FDRE clocked by clk {rise@0.000ns fall@2.000ns period=4.000ns})
Destination: y_reg/D
(rising edge-triggered cell FDRE clocked by clk {rise@0.000ns fall@2.000ns period=4.000ns})
Path Group: clk
Path Type: Hold (Min at Fast Process Corner)
Requirement: 1.000ns (MinDelay Path 1.000ns)
Data Path Delay: 1.141ns (logic 0.049ns (4.294%) route 1.092ns (95.706%))
Logic Levels: 0
Clock Path Skew: 0.029ns (DCD - SCD - CPR)
Destination Clock Delay (DCD): 1.684ns
Source Clock Delay (SCD): 1.258ns
Clock Pessimism Removal (CPR): 0.398ns
Clock Net Delay (Source): 0.502ns (routing 0.002ns, distribution 0.500ns)
Clock Net Delay (Destination): 0.585ns (routing 0.002ns, distribution 0.583ns)
Timing Exception: MinDelay Path 1.000ns
Location Delay type Incr(ns) Path(ns) Netlist Resource(s)
------------------------------------------------------------------- -------------------
(clock clk rise edge) 0.000 0.000 r
AG12 0.000 0.000 r clk (IN)
net (fo=0) 0.000 0.000 clk_IBUF_inst/I
AG12 INBUF (Prop_INBUF_HRIO_PAD_O)
0.339 0.339 r clk_IBUF_inst/INBUF_INST/O
net (fo=1, routed) 0.025 0.364 clk_IBUF_inst/OUT
AG12 IBUFCTRL (Prop_IBUFCTRL_HRIO_I_O)
0.015 0.379 r clk_IBUF_inst/IBUFCTRL_INST/O
net (fo=1, routed) 0.350 0.729 clk_IBUF
BUFGCE_X1Y0 BUFGCE (Prop_BUFCE_BUFGCE_I_O)
0.027 0.756 r clk_IBUF_BUFG_inst/O
X2Y0 (CLOCK_ROOT) net (fo=4, routed) 0.502 1.258 clk_IBUF_BUFG
SLICE_X49Y57 FDRE r x_reg/C
------------------------------------------------------------------- -------------------
SLICE_X49Y57 FDRE (Prop_DFF_SLICEL_C_Q)
0.049 1.307 r x_reg/Q
net (fo=2, routed) 1.092 2.399 x
SLICE_X49Y57 FDRE r y_reg/D
------------------------------------------------------------------- -------------------
min delay 1.000 1.000
AG12 0.000 1.000 r clk (IN)
net (fo=0) 0.000 1.000 clk_IBUF_inst/I
AG12 INBUF (Prop_INBUF_HRIO_PAD_O)
0.595 1.595 r clk_IBUF_inst/INBUF_INST/O
net (fo=1, routed) 0.042 1.637 clk_IBUF_inst/OUT
AG12 IBUFCTRL (Prop_IBUFCTRL_HRIO_I_O)
0.022 1.659 r clk_IBUF_inst/IBUFCTRL_INST/O
net (fo=1, routed) 0.409 2.068 clk_IBUF
BUFGCE_X1Y0 BUFGCE (Prop_BUFCE_BUFGCE_I_O)
0.031 2.099 r clk_IBUF_BUFG_inst/O
X2Y0 (CLOCK_ROOT) net (fo=4, routed) 0.585 2.684 clk_IBUF_BUFG
SLICE_X49Y57 FDRE r y_reg/C
clock pessimism -0.398 2.286
SLICE_X49Y57 FDRE (Hold_EFF2_SLICEL_C_D)
0.055 2.341 y_reg
-------------------------------------------------------------------
required time -2.341
arrival time 2.399
-------------------------------------------------------------------
slack 0.057
Auch hier: Der Verzögerungswert (1 ns) wird als Startzeit für den Taktpfad des zweiten Flipflops verwendet. Wenn es keinen set_min_delay-Befehl gibt (also nur eine Taktperioden-Vorgabe), ist das 0 ns.
Die Verzögerung des Netzes im Datenpfad beträgt 1,092 ns. Das reicht gerade aus, um die thold-Anforderung zu erfüllen. Warum waren es vorher 2,478 ns? Weil die Worst-Case-Berechnung für tsetup für „Max at Slow Process Corner“ durchgeführt wurde. 2,478 ns ist also die längstmögliche Verzögerung für das betreffende Netz, und 1,092 ns ist die kürzestmögliche Verzögerung („Min at Fast Process Corner“). Siehe dazu die Besprechung der Multi-Corner-Timing-Analyse.
Das dritte Beispiel demonstriert datapath_only, also lautet die Vorgabe:
set_max_delay -datapath_only -from [get_cells x_reg] -to [get_cells y_reg] 3
Es gibt kein set_min_delay, weil es ohnehin ignoriert wird (selbst wenn es nach dem set_max_delay-Befehl geschrieben wird).
Der Report für tsetup lautet nun:
Slack (MET) : 2.482ns (required time - arrival time)
Source: x_reg/C
(rising edge-triggered cell FDRE clocked by clk {rise@0.000ns fall@2.000ns period=4.000ns})
Destination: y_reg/D
(rising edge-triggered cell FDRE clocked by clk {rise@0.000ns fall@2.000ns period=4.000ns})
Path Group: clk
Path Type: Setup (Max at Slow Process Corner)
Requirement: 3.000ns (MaxDelay Path 3.000ns)
Data Path Delay: 0.583ns (logic 0.139ns (23.842%) route 0.444ns (76.158%))
Logic Levels: 0
Timing Exception: MaxDelay Path 3.000ns -datapath_only
Location Delay type Incr(ns) Path(ns) Netlist Resource(s)
------------------------------------------------------------------- -------------------
SLICE_X49Y57 0.000 0.000 r x_reg/C
SLICE_X49Y57 FDRE (Prop_DFF_SLICEL_C_Q)
0.139 0.139 r x_reg/Q
net (fo=2, routed) 0.444 0.583 x
SLICE_X49Y57 FDRE r y_reg/D
------------------------------------------------------------------- -------------------
max delay 3.000 3.000
SLICE_X49Y57 FDRE (Setup_EFF2_SLICEL_C_D)
0.065 3.065 y_reg
-------------------------------------------------------------------
required time 3.065
arrival time -0.583
-------------------------------------------------------------------
slack 2.482
Beachten Sie, dass die Struktur dieses Timing-Reports wie zuvor ist, aber alles, was mit den Taktpfaden zu tun hat, entfernt wurde.
Die Verzögerung des Netzes ist klein, weil die Tools keinen Grund hatten, eine lange Verzögerung einzufügen: Es gibt keine thold-Anforderung.
Und ich zeige den Timing-Report für thold nicht, weil es keine Timing-Anforderung gibt (die Mindestverzögerung wird wie ein False Path behandelt).
Damit ist die allgemeine Besprechung der Timing-Ausnahmen abgeschlossen. Die nächste Seite fährt mit den Timing-Ausnahmen fort, die für einen Taktdomänenübergang (clock domain crossing) notwendig sind.