01signal.com

Die Taktperioden-Vorgabe und Taktobjekte

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 und die Prinzipien des Timing-Closure vorgestellt. Nun ist es an der Zeit, mit den technischen Details der Timing-Vorgaben (timing constraints) zu beginnen.

Die Bedeutung von create_clock als Tcl-Befehl

Auf den bisherigen Seiten drehte sich alles um diese Timing-Vorgabe:

create_clock -period 4 -name clk [get_ports clk]

Ich habe die Syntax dieser Zeile bewusst bisher nicht besprochen. Es ist also an der Zeit zu erklären, was das tatsächlich bedeutet.

Diese Timing-Vorgabe ist im SDC-Format (Synopsys Design Constraints) geschrieben, dem am weitesten verbreiteten Format für Timing-Vorgaben. Vivado und Quartus verwenden dieses Format, ebenso wie einige andere FPGA-Tools.

Eine SDC-Datei ist im Wesentlichen ein Skript (script), das in Tcl geschrieben ist. Der Inhalt einer SDC-Datei ist also ein kurzes Computerprogramm und nicht nur eine Sammlung von Informationen. Die Möglichkeiten einer SDC-Datei als Skript sind jedoch auf eine kleine Teilmenge von Befehlen beschränkt, die zum Schreiben von Vorgaben gedacht sind: Nicht alles, was in einem Tcl-Skript erlaubt ist, kann in einer SDC-Datei getan werden.

Der Befehl create_clock wird verwendet, um eine Timing-Vorgabe zu definieren. Tatsächlich weist dieser Befehl die FPGA-Tools jedoch an, ein neues Taktobjekt (clock object) zu erzeugen. Das Wort „Objekt“ bedeutet hier, was es in der Softwaretechnik üblicherweise bedeutet. Das neue Taktobjekt ist also etwas, das im Speicher des Tcl-Interpreters als Objekt mit eigenen Eigenschaften abgelegt ist.

Zum Beispiel setzt der Teil des create_clock-Befehls, der „-name clk“ lautet, die Eigenschaft namens „name“ auf den Wert „clk“. Zur Erinnerung von einer der vorherigen Seiten: Dieser Name wurde in den Timing-Reports verwendet. Der Name „clk“ erschien zusammen mit Timing-Pfaden (paths), die wegen dieser Vorgabe (oder genauer: wegen dieses Taktobjekts) berechnet wurden.

Später haben wir gesehen, dass es weitere Taktnamen gab, zum Beispiel clk_out1_clk_wiz_1 und clk_out2_clk_wiz_1. Das waren in Wirklichkeit Namen weiterer Taktobjekte, die automatisch von den Tools erzeugt wurden.

Es gibt einen Tcl-Befehl zum Auflisten aller Takte: get_clocks. Beim Beispiel mit zwei Takten von der vorherigen Seite sieht eine Sitzung auf Vivados Tcl-Konsole also so aus:

> get_clocks
clk clkfbout_clk_wiz_1 clk_out1_clk_wiz_1 clk_out2_clk_wiz_1

get_clocks und ähnliche Befehle werden auf der nächsten Seite genauer erklärt.

Man kann sich auch die Eigenschaften dieser Objekte ansehen. Es ist nicht nötig, alle diese Eigenschaften zu verstehen; ich zeige das nur, um zu verdeutlichen, dass ein Takt ein Objekt ist. Ich persönlich hatte nie das Bedürfnis, eine Objekteigenschaft direkt zu verändern.

> report_property [get_clocks clk]
Property           Type     Read-only  Value
CLASS              string   true       clock
INPUT_JITTER       double   true       0.040
IS_GENERATED       bool     true       0
IS_PROPAGATED      bool     true       1
IS_USER_GENERATED  bool     true       0
IS_VIRTUAL         bool     true       0
NAME               string   true       clk
PERIOD             double   true       4.000
SOURCE_PINS        string*  true       clk
SYSTEM_JITTER      double   true       0.050
WAVEFORM           double*  true       0.000 2.000

> report_property [get_clocks clk_out1_clk_wiz_1]
Property           Type     Read-only  Value
CLASS              string   true       clock
EDGES              int*     true       1 2 3
EDGE_SHIFT         double*  true       0.000 2.000 4.000
INPUT_JITTER       double   true       0.000
IS_GENERATED       bool     true       1
IS_INVERTED        bool     true       0
IS_PROPAGATED      bool     true       1
IS_RENAMED         bool     true       0
IS_USER_GENERATED  bool     true       0
IS_VIRTUAL         bool     true       0
MASTER_CLOCK       clock    true       clk
NAME               string   true       clk_out1_clk_wiz_1
PERIOD             double   true       8.000
SOURCE             pin      true       pll_i/inst/mmcme3_adv_inst/CLKIN1
SOURCE_PINS        string*  true       pll_i/inst/mmcme3_adv_inst/CLKOUT0
SYSTEM_JITTER      double   true       0.050
WAVEFORM           double*  true       0.000 4.000

Das Wichtige ist zu erkennen, dass create_clock nur ein Objekt erzeugt. Die Parameter dieses Befehls bestimmen lediglich, wie die Eigenschaften dieses Objekts gesetzt werden. Zum Beispiel bedeutet der Teil „-period 4“ (in der Timing-Vorgabe, die ich wiederholt gezeigt habe) nur, dass eine bestimmte Eigenschaft namens „PERIOD“ den Wert 4 haben soll.

Falls Sie diese Tcl-Befehle selbst ausprobieren möchten, beachten Sie, dass es Unterschiede zwischen den FPGA-Tools gibt.

In Vivado können diese Befehle erst nach dem Öffnen des Implemented Design verwendet werden.

In Quartus öffnen Sie zuerst den TimeQuest Timing Analyzer, und klicken Sie dann Create Timing Netlist, Read SDC File und Update Timing Netlist. Probieren Sie dann einige Befehle auf der Tcl-Konsole aus, zum Beispiel:

> join [ query_collection -all [ get_clocks ] ] "\n"
> get_clock_info -waveform [get_clocks clk]

Die Bedeutung des Begriffs „clock“

Wenn FPGA-Tools das Wort „clock“ verwenden, meinen sie damit üblicherweise ein Taktobjekt und nicht das physische Signal im FPGA. Das gilt insbesondere für Timing-Reports.

Zur Erinnerung von der vorherigen Seite: Ich habe dort mehrfach den Begriff „theoretische Takte“ verwendet. Das sind in Wirklichkeit Taktobjekte. Sie werden im Timing-Report als „Takte“ bezeichnet, aber ihre Verwendung in der Timing-Analyse zeigt, dass sie nur Container für Informationen sind.

Was ist also die Verbindung zwischen diesen Taktobjekten und realen Signalen? Wir haben die Namen der Taktobjekte bereits in der Timing-Analyse gesehen. Wie passt das alles zusammen?

Wenn die Tools die statische Timing-Analyse des Designs durchführen, werden alle Pfade untersucht. Wenn ein Pfad an einem Flipflop beginnt, untersuchen die Tools das Signal (also das Netz), das mit dem Takteingang des Flipflops verbunden ist: Gibt es ein Taktobjekt, das zu diesem Signal gehört? Wenn das Signal zum Beispiel @clk ist, ist das zugehörige Taktobjekt dasjenige, dem mit dem Befehl create_clock der Name „clk“ gegeben wurde. Nachdem das zutreffende Taktobjekt gefunden wurde, können die Tools die nötigen Informationen aus den Eigenschaften dieses Objekts holen.

Dasselbe geschieht mit dem Flipflop am Ende des Pfads. Die Tools haben also nun die beiden Taktobjekte, die zu diesem Pfad gehören. Mit den Informationen aus diesen Objekten führen die Tools die Timing-Analyse durch.

Und natürlich gilt dasselbe Verfahren für jedes sequentielle Element, nicht nur für Flipflops.

Warum ist es wichtig, das zu verstehen? Unter anderem, weil im Timing-Report manchmal eine Fehlermeldung steht, dass es Register ohne Takt gibt. Das bedeutet normalerweise nicht, dass ein Flipflop vorhanden ist, an dessen Takteingang nichts angeschlossen ist. Vielmehr bedeutet es, dass die Tools kein Taktobjekt gefunden haben, das zu diesem Takteingang gehört. Mit anderen Worten: Die Tools haben keine Informationen über den Takteingang dieses Flipflops gefunden. Das Problem liegt also meist nicht im Logikdesign, sondern eine Timing-Vorgabe fehlt (oder ist falsch geschrieben).

Es ist noch einmal erwähnenswert: Wenn in einem Timing-Report von „clock“ die Rede ist, bedeutet das nicht, dass es im Logikdesign ein Signal mit diesem Namen gibt, sondern dass ein Taktobjekt mit diesem Namen erzeugt wurde. Woher wissen wir, zu welchem Signal es gehört? Das ist das nächste Thema.

Zu welchem Signal gehört dieser Takt?

Eine der Dinge, die den Timing-Report schwer lesbar machen, sind die Namen der Takte. Die meisten Taktsignale in einem Logikdesign werden von einer PLL erzeugt, und wir haben bereits gesehen, dass der Name im Timing-Report wenig hilfreich sein kann. Die meisten FPGA-Tools erlauben es, die Taktobjekte durch zusätzliche Befehle in der SDC-Datei umzubenennen, aber in den meisten Projekten wird das nicht getan. Und Goldene Regel #4 besagt, Dinge zu vermeiden, die nur in Ihrem Projekt speziell sind.

Das Problem mit den Namen wird noch schwieriger, wenn die Quelle des Takts ein IP-Core (IP core) ist (z.B. ein Gigabit-Transceiver, ein PCIe-Block oder ein On-Chip-Prozessorkern). In diesem Fall sagt der Name des Takts oft nur wenig darüber aus, woher er stammt und womit er zusammenhängt.

Wie wird dieses Problem also gelöst? Beginnen wir mit der einfachsten Situation, wenn der Taktname aus dem create_clock-Befehl in unserer eigenen SDC-Datei stammt. Es ist wieder dieselbe Timing-Vorgabe:

create_clock -period 4 -name clk [get_ports clk]

Der letzte Teil dieses Befehls ist „[get_ports clk]“. In der Tcl-Sprache bedeuten eckige Klammern, dass der Inhalt der Klammern als Tcl-Befehl ausgeführt und das Ergebnis dieses Befehls anstelle der Klammern verwendet wird.

Der Befehl get_ports findet einen I/O-Port mit dem Namen „clk“. Das Ergebnis dieses Befehls ist das Objekt, das diesen Port repräsentiert. In dem obigen create_clock-Befehl ist dieses Objekt also ein Argument dieses Befehls. Auf diese Weise stellt create_clock die Verbindung zwischen dem Taktobjekt und einem realen Signal her.

Beachten Sie, dass sowohl der Name des Ports als auch der Name des Objekts „clk“ lauten. Es ist nicht erforderlich, dass sie gleich sind, aber es ist empfehlenswert: Der Name des Objekts erscheint in den Timing-Reports. Der Name des Ports ist daher meist die beste Wahl.

Es ist auch möglich, Netzobjekte (net objects) und Pinobjekte (pin objects) als Kennung eines Signals zu verwenden. Das ist bei Timing-Vorgaben üblich, die automatisch im Namen von IP-Cores erzeugt werden. Wenn Sie jedoch das Bedürfnis verspüren, das in Ihren eigenen Vorgaben zu tun, ist die Wahrscheinlichkeit groß, dass Sie etwas falsch machen.

Wenn also in einer SDC-Datei ein create_clock-Befehl verwendet wurde, lässt sich leicht sagen, zu welchem Signal das Taktobjekt gehört. Aber was ist mit Taktobjekten, die automatisch von den Tools erzeugt wurden?

In diesem Fall erkennt man den Takt am besten im Timing-Report. Welches Taktobjekt gehört zum Beispiel zu @pll_clk_8 im Beispiel von der vorherigen Seite? Eine einfache Methode ist, im Timing-Report eine Textsuche durchzuführen. Bei der Suche nach „pll_clk_8“ findet man den folgenden Ausschnitt:

Location          Delay type                Incr(ns)  Path(ns)    Netlist Resource(s)
--------------------------------------------------------------  -------------------
                  (clock clk_out1_clk_wiz_1 rise edge)
                                              16.000    16.000
AG12                                           0.000    16.000  clk (IN)
                  net (fo=0)                   0.000    16.000  pll_i/inst/clkin1_ibuf/I
AG12              INBUF (Prop_INBUF_HRIO_PAD_O)
                                               0.738    16.738  pll_i/inst/clkin1_ibuf/INBUF_INST/O
                  net (fo=1, routed)           0.105    16.843  pll_i/inst/clkin1_ibuf/OUT
AG12              IBUFCTRL (Prop_IBUFCTRL_HRIO_I_O)
                                               0.049    16.892  pll_i/inst/clkin1_ibuf/IBUFCTRL_INST/O
                  net (fo=1, routed)           0.975    17.867  pll_i/inst/clk_in1_clk_wiz_1
MMCME3_ADV_X1Y0   MMCME3_ADV (Prop_MMCME3_ADV_CLKIN1_CLKOUT0)
                                              -4.438    13.429  pll_i/inst/mmcme3_adv_inst/CLKOUT0
                  net (fo=1, routed)           0.501    13.930  pll_i/inst/clk_out1_clk_wiz_1
BUFGCE_X1Y1       BUFGCE (Prop_BUFCE_BUFGCE_I_O)
                                               0.101    14.031  pll_i/inst/clkout1_buf/O
X2Y0 (CLOCK_ROOT) net (fo=1, routed)           1.369    15.400  pll_clk_8
SLICE_X49Y58      FDRE                                          foo_reg_reg/C

Das ist der Quell-Taktpfad für clk_out1_clk_wiz_1, und dort steht die Antwort auf die Frage.

Eine andere Methode ist, die Information mit einem Tcl-Befehl zu beschaffen. Wie das genau funktioniert, ist von FPGA-Tool zu FPGA-Tool unterschiedlich. In Vivado kann nach dem Öffnen des Implemented Design etwa der folgende Befehl verwendet werden:

> get_clocks -of_objects [ get_nets pll_clk_8 ]
clk_out1_clk_wiz_1

Diese Methode erfordert, dass man den Namen des Netzes kennt. Manchmal ist das so einfach wie in diesem Beispiel, manchmal muss man den Namen dieses Netzes erst herausfinden. Die FPGA-Tools bieten dafür üblicherweise eine Möglichkeit in der grafischen Oberfläche (GUI). Es ist auch möglich, dafür Tcl-Befehle zu verwenden.

Ich hoffe, die wenigen Tcl-Beispiele haben Sie davon überzeugt, wie wichtig es ist, richtig mit Tcl umgehen zu können. Genau darum geht es auf der nächsten Seite.

Die Bedeutung von get_port

Im obigen Beispiel stützt sich der create_clock-Befehl auf get_port, um die Verbindung zwischen dem Taktobjekt und einem physischen Eingangspin herzustellen. Wie oben erwähnt, ist diese Verbindung notwendig, um zu wissen, welche Logikelemente an diesem Takt angeschlossen sind (oder an Takten, die daraus erzeugt werden).

Aber die Verwendung von get_port ist nicht die einzige Möglichkeit. Man kann sich zum Beispiel auch auf den Ausgangspin eines globalen Taktpuffers beziehen. Zum Beispiel so:

create_clock -name clk -period 4 [get_pins my_BUFG_inst/O]

Der Unterschied besteht darin, dass die Tools den Ausgangspin des globalen Taktpuffers als Ursprung des Takts betrachten. Mit anderen Worten: Die Berechnung der Taktpfade beginnt an dieser Position. Die erste Taktflanke an diesem Ursprung tritt bei 0 ns auf; dieser Ausgangspin wird also zur Zeitreferenz.

Das ist eine zulässige Timing-Vorgabe, aber sie hat zwei wichtige Nachteile:

Daher sollte nach Möglichkeit immer get_port verwendet werden. Andernfalls sollte das Timing des Takts im Verhältnis zu allem außer sich selbst als unbekannt betrachtet werden.


Auf dieser Seite wurden viele Tcl-Befehle gezeigt, aber nicht ausreichend erklärt. Die nächste Seite füllt diese Lücke.

Diese Seite wurde maschinell aus dem Englischen übersetzt. Im Zweifelsfall siehe den Originaltext.
Copyright © 2021-2026. All rights reserved. (dcc38493)