Diese Seite ist eine Ergänzung zu einer anderen Seite, die zuerst gelesen werden sollte. Beide Seiten sind Teil einer Serie von Seiten, die die Theorie hinter Timing-Berechnungen erklärt, das Schreiben mehrerer Timing-Vorgaben (timing constraints) zeigt und die Prinzipien des Timing-Closure bespricht.
Verwenden Sie einfache Suchmuster nur, wenn es sein muss
Diese Seite erklärt den Umgang mit Platzhaltern (Wildcards) beim Schreiben von Timing-Vorgaben im SDC-Format. Platzhalter können zwar mit mehreren Tcl-Befehlen verwendet werden, aber diese Seite konzentriert sich auf Befehle, die üblicherweise die Option „-hierarchical“ unterstützen: get_cells, get_pins und get_nets. Diese Tcl-Befehle werden auf einer anderen Seite erklärt. Beachten Sie jedoch, dass einige FPGA-Tools „-hierarchical“ nicht mit allen drei Befehlen unterstützen.
Leider ist die Suchfunktion dieser drei Befehle ziemlich eingeschränkt und möglicherweise verwirrend: Wenn man nicht genau versteht, wie der Platzhalter funktioniert, können die Suchergebnisse unerwartet sein. Insbesondere bei Verwendung von „-hierarchical“ können die Ergebnisse überraschend sein, wie unten gezeigt wird.
Aus diesem Grund ist es immer besser, die Option „-filter“ zu verwenden, wenn das jeweilige FPGA-Tool sie für den betreffenden Befehl unterstützt. Wenn eine solche Unterstützung fehlt, bleibt keine andere Wahl, als die einfachen Platzhalter zu verwenden.
Alle Beispiele auf dieser Seite basieren auf demselben Verilog-Code wie die andere Seite, die damit zusammenhängt.
Einfache Suchmuster
Die Befehle zum Auffinden von Logikelementen und anderen Objekten können mit oder ohne Suchmuster verwendet werden. Ohne Suchmuster werden alle relevanten Objekte gefunden. Um zum Beispiel alle Pins in der obersten Hierarchieebene zu finden:
get_pins
Der Befehl, der alle Pins im gesamten FPGA-Design findet, lautet:
get_pins -hierarchical
Wenn ein Suchmuster verwendet wird, werden die Ergebnisse auf dieses Muster eingeschränkt. Um zum Beispiel einen bestimmten Pin mit bekanntem Namen und bekannter Position in der Hierarchie zu finden:
> get_pins foo_reg_reg/Q foo_reg_reg/Q > get_pins pll_i/clk_in1 pll_i/clk_in1 > get_pins pll_i/inst/clk_in1 pll_i/inst/clk_in1
Das Muster kann auch Platzhalter enthalten, zum Beispiel:
> get_pins foo_reg_reg/* foo_reg_reg/Q foo_reg_reg/C foo_reg_reg/CE foo_reg_reg/D foo_reg_reg/R > get_pins pll_i/* pll_i/clk_in1 pll_i/clk_out1 pll_i/clk_out2 > get_pins pll_i/inst/* pll_i/inst/clk_in1 pll_i/inst/clk_out1 pll_i/inst/clk_out2 > get_pins pll_i/*/* pll_i/inst/clk_in1 pll_i/inst/clk_out1 pll_i/inst/clk_out2 > get_pins pll_i/*/clk* pll_i/inst/clk_in1 pll_i/inst/clk_out1 pll_i/inst/clk_out2
Das Verhalten der Platzhalter
Es gibt zwei übliche Platzhalter:
- Der Stern („*“), der eine beliebige Anzahl von Zeichen ersetzt.
- Das Fragezeichen („?“), das genau ein Zeichen ersetzt.
Diese beiden Platzhalter gelten jedoch nie für den Hierarchietrenner. Mit anderen Worten: „*“ und „?“ ersetzen kein „/“ (bzw. bei Quartus kein „|“). Das gilt für Platzhalter immer, unabhängig davon, ob die Option „-hierarchical“ verwendet wird oder nicht (beachten Sie aber, dass es bei „-filter“ oder „-regexp“ eine andere Sache ist).
Daher muss die genaue Position des Objekts in der Hierarchie ausdrücklich angegeben werden:
> get_pins */clk_* pll_i/clk_in1 pll_i/clk_out1 pll_i/clk_out2 > get_pins */*/clk_* pll_i/inst/clk_in1 pll_i/inst/clk_out1 pll_i/inst/clk_out2
Beachten Sie, dass verschiedene Tools unterschiedliche Zeichen für den Hierarchietrenner verwenden können. Wie eben erwähnt, verwendet Quartus dafür den Balken („|“) und nicht „/“.
Die Option „-hierarchical“ erlaubt es, Logikelemente an beliebiger Stelle in der Designhierarchie zu finden. Dadurch entfällt die Notwendigkeit, die genaue Position in der Hierarchie anzugeben; außerdem lassen sich mit einem einzigen Befehl Logikelemente im gesamten FPGA-Design finden.
Wiederholen wir also dieselben Ausdrücke mit „-hierarchical“:
> get_pins -hierarchical */clk_* pll_i/clk_in1 pll_i/clk_out1 pll_i/clk_out2 pll_i/inst/clk_in1 pll_i/inst/clk_out1 pll_i/inst/clk_out2 > get_pins -hierarchical */*/clk_* WARNING: [Vivado 12-508] No pins matched '*/*/clk_*'.
„-hierarchical“ bedeutet, dass das Suchmuster an allen Positionen in der Designhierarchie angewendet wird. Im obigen Beispiel wurde „*/clk_*“ zuerst in der obersten Hierarchieebene angewendet, sodass zum Beispiel „pll_i/clk_in1“ gefunden wurde. Dasselbe Muster wurde dann innerhalb von „pll_i/“ angewendet, sodass „pll_i/inst/clk_in1“ gefunden wurde.
Warum aber wurde mit „*/*/clk_*“ bei Verwendung von „-hierarchical“ nichts gefunden? Dasselbe Muster lieferte ohne diese Option einige Suchergebnisse. Sollte es mit „-hierarchical“ nicht immer mehr Suchergebnisse geben?
Die Verwendung von -hierarchical schränkt das Suchmuster ein
Merkwürdigerweise ändert die Option „-hierarchical“ nicht nur, wo das Suchmuster angewendet wird, sondern auch, welche Muster zulässig sind. Leider reagieren die Tools nicht mit einem Fehler, wenn ein unzulässiges Muster verwendet wird. Stattdessen ist die Antwort, dass nichts gefunden wird.
Jeder der drei Tcl-Befehle (get_cells, get_pins und get_nets) hat seine eigene Regel, die das Suchmuster einschränkt. Die genauen Einschränkungen finden Sie in der Dokumentation Ihres FPGA-Tools. Die Standard-Interpretation (wie in Synopsys’ Dokumentation ausgeführt) ist unten beschrieben.
Beachten Sie, dass häufig die Abkürzung „-hier“ anstelle von „-hierarchical“ verwendet wird. Die Bedeutung ist exakt dieselbe.
get_cells -hierarchical
Wenn get_cells mit -hierarchical verwendet wird, passt das Muster nur auf den Namen des Objekts. Wenn ein Hierarchietrenner im Muster vorkommt, ist das Ergebnis immer leer. Zum Beispiel:
> get_cells -hierarchical *_buf pll_i/inst/clkf_buf pll_i/inst/clkout1_buf pll_i/inst/clkout2_buf > get_cells -hierarchical inst/*_buf WARNING: [Vivado 12-180] No cells matched 'inst/*_buf'.
Beachten Sie, dass es ein Fehler ist, wenn ein „/“ im Muster steht, weil mit einem solchen Muster nie etwas gefunden wird. Die Tools antworten jedoch nicht mit einem Fehler, sondern der Befehl liefert schlicht keine Ergebnisse.
Weil der Hierarchietrenner im Muster nicht zulässig ist, ist get_cells auf folgende Möglichkeiten beschränkt:
- Eine Suche nach Cells an einer bestimmten Position der Hierarchie (wenn -hierarchical nicht verwendet wird).
- Eine Suche nach Cells im gesamten FPGA-Design durch Verwendung von -hierarchical.
- Verwenden Sie stattdessen -filter oder -regexp, wenn diese unterstützt werden. Diese Optionen unterliegen keiner solchen Einschränkung.
Dieses Beispiel zeigt, wie man False Paths (false paths) für alle Cells mit einem bestimmten Namensformat deklariert:
set_false_path -to [get_cells -hierarchical *metaguard*]
Bei einer solchen Timing-Vorgabe reicht es, für alle Register, die als Metastabilitäts-Schutzregister verwendet werden, einen Namen zu wählen, der das Wort „metaguard“ enthält. Das Risiko dieser Timing-Vorgabe besteht jedoch darin, dass der Ausdruck versehentlich auf ein nicht zusammenhängendes Logikelement irgendwo im FPGA-Design passt. Es ist daher besser, etwas zu wählen, das seltener vorkommt als „metaguard“.
get_nets -hierarchical
get_nets folgt derselben Regel wie get_cells: Ohne -hierarchical findet get_nets alle Netze in der obersten Hierarchieebene, die zum Muster passen. Mit -hierarchical passt das Muster nur auf den Namen des Objekts. Wenn ein Hierarchietrenner im Muster steht, ist das Ergebnis immer leer.
> get_nets pll_i/clk_i* pll_i/clk_in1 > get_nets clk_i* WARNING: [Vivado 12-507] No nets matched 'clk_i*'. > get_nets -hierarchical clk_i* pll_i/clk_in1 pll_i/inst/clk_in1 > get_nets -hierarchical pll_i/clk_i* WARNING: [Vivado 12-507] No nets matched 'pll_i/clk_i*'.
get_pins -hierarchical
Wenn get_pins mit -hierarchical verwendet wird, passt das Muster auf den vollständigen Namen des Pins, z.B. baz_reg/Q, clkout1_buf/I usw. Das „/“ wird als Teil des Namens betrachtet und nicht als Hierarchietrenner. Mit anderen Worten: Das Zeichen zwischen dem Namen der Cell und der Pin-Kennung kann durch einen Platzhalter ersetzt werden. Das gilt nur für den letzten Hierarchietrenner und nur bei Verwendung von -hierarchical.
Also zum Beispiel:
> get_pins -hierarchical clkout1_buf/* pll_i/inst/clkout1_buf/O pll_i/inst/clkout1_buf/CE pll_i/inst/clkout1_buf/I > get_pins -hierarchical clkout1_bu* pll_i/inst/clkout1_buf/O pll_i/inst/clkout1_buf/CE pll_i/inst/clkout1_buf/I > get_pins -hierarchical clkout1_buf WARNING: [Vivado 12-508] No pins matched 'clkout1_buf'.
Beachten Sie, dass „clkout1_bu*“ unter anderem auf „clkout1_buf/O“ passte. Das „*“ kann nur wegen -hierarchical mit „/O“ ersetzt werden.
Wie bei get_cells gilt: Wenn ein Hierarchietrenner im Muster steht, ist das Ergebnis immer leer. Das widerspricht dem obigen Beispiel nicht: Wie erwähnt, gilt das letzte „/“ als Teil des Pinnamens.
> get_pins pll_i/inst/clkout1*/I pll_i/inst/clkout1_buf/I > get_pins -hierarchical pll_i/inst/clkout1*/I WARNING: [Vivado 12-508] No pins matched 'pll_i/inst/clkout1*/I'. > get_pins -hierarchical pll_i/inst/*/* WARNING: [Vivado 12-508] No pins matched 'pll_i/inst/*/*'. > get_pins -hierarchical pll_i/*/*/* WARNING: [Vivado 12-508] No pins matched 'pll_i/*/*/*'. > get_pins -hierarchical pll_i/*/* WARNING: [Vivado 12-508] No pins matched 'pll_i/*/*'. > get_pins -hierarchical pll_i/* pll_i/clk_in1 pll_i/clk_out1 pll_i/clk_out2 > get_pins pll_i/* pll_i/clk_in1 pll_i/clk_out1 pll_i/clk_out2
Beachten Sie, dass ein Platzhalter ohne -hierarchical nie mit einem Hierarchietrenner übereinstimmt, auch nicht mit dem letzten:
> get_pins pll_i/inst/clkout1_buf/I pll_i/inst/clkout1_buf/I > get_pins pll_i/inst/clkout1_buf/* pll_i/inst/clkout1_buf/O pll_i/inst/clkout1_buf/CE pll_i/inst/clkout1_buf/I > get_pins pll_i/inst/clkout1_bu* WARNING: [Vivado 12-508] No pins matched 'pll_i/inst/clkout1_bu*'. > get_pins pll_i/inst/clkout1_bu*/* pll_i/inst/clkout1_buf/O pll_i/inst/clkout1_buf/CE pll_i/inst/clkout1_buf/I
An diesen Beispielen wird deutlich, wie verwirrend get_pins ist. Verwenden Sie daher, wie schon empfohlen, stattdessen -filter oder -regexp, wenn diese unterstützt werden.
Zusammenfassung
Auch wenn Platzhalter als Methode zum Auffinden von Logikelementen verfügbar sind, sind die Suchergebnisse nicht immer das, was man natürlich erwartet. Ebenso kann die Option -hierarchical in manchen Szenarien hilfreich sein, aber diese Möglichkeit geht mit einer Einschränkung des Suchmusters und mit noch verwirrenderem Verhalten einher.
Es wird daher empfohlen, andere Methoden zur Auswahl von Logikelementen zu verwenden: Wenn -filter, -regexp oder -of_objects von den FPGA-Tools unterstützt werden, ist eine dieser Optionen wahrscheinlich die bessere Lösung. Die Verwendung einfacher Platzhalter ist nur dann sinnvoll, wenn keine dieser anderen Optionen verfügbar ist oder wenn im konkreten Szenario keine davon nützlich ist. In dieser Situation ist es wichtig, bei der Bedeutung des Suchmusters besonders wachsam zu sein.