Taktfrequenzen für das Füttern eines Pins

author-image

Von

Dieses Designbeispiel zeigt ein benutzerdefiniertes Verfahren, das Sie in SDC-Dateien verwenden können, das eine Liste aller Takte zurückgibt, die eine Pin füttern. Das Verfahren kann hilfreich sein, wenn Sie generierte Taktfrequenzen erstellen müssen, ohne andere Taktnamen in einem Design zu kennen. Das Designbeispiel "Vereinfachte Design-Wiederverwendung mit dynamischen SDC-Beschränkungen" enthält weitere Einzelheiten und ein Beispiel für die Verwendung des benutzerdefinierten Verfahrens, das auf dieser Seite beschrieben wird.

Der vollständige Code für das Verfahren befindet sich unten auf der Seite und folgt einer vollständigen Erklärung darüber, wie das Verfahren funktioniert. Um das get_clocks_driving_pins benutzerdefinierte Verfahren in einer SDC-Datei zu verwenden, stellen Sie sicher, dass das Verfahren definiert wurde, und rufen Sie es dann wie jeden anderen SDC-Befehl auf. Es gibt zwei einfache Möglichkeiten, um sicherzustellen, dass das Verfahren vor der Verwendung definiert wurde:

  • Speichern Sie den Verfahrenscode in einer separaten SDC-Datei und fügen Sie die SDC-Datei in das Projekt ein.
  • Kopieren Und fügen Sie den Verfahrenscode oben in einer SDC-Datei ein, bevor das get_clocks_driving_pins angepasste Verfahren verwendet wird.

Separate SDC-Datei

Durch das Speichern des Verfahrenscodes in einer separaten SDC-Datei wird der Code von den restlichen Beschränkungen getrennt und es wird einfacher, ihn in anderen Projekten wiederzuverwenden. Wenn Sie eine separate SDC-Datei verwenden, müssen Sie die SDC-Datei mit dem Verfahren zur Liste der Dateien im Projekt hinzufügen, und sie muss über allen SDC-Dateien angezeigt werden, die das Verfahren verwenden. Durch die Auflistung über anderen SDC-Dateien wird sichergestellt, dass die Quartus® II Software das Verfahren vor der Verwendung definiert, wenn SDC-Dateien gelesen werden.

Kopieren und Einfügen

Das Kopieren und Einfügen des Verfahrenscodes in derselben SDC-Datei, in der er verwendet wird, führt zu weniger SDC-Dateien in einem Projekt. Wenn Sie eine SDC-Datei für ein Modul erstellen, das von anderen Designern wiederverwendet wird, ist es möglicherweise am einfachsten, alle Beschränkungen und den unterstützenden Code in einer einzigen SDC-Datei aufzunehmen. Vor der ersten Verwendung des Verfahrens müssen Sie den Verfahrenscode in die SDC-Datei einbeziehen, damit er vor der Verwendung definiert wird. In der Regel würden Sie sie oben in der Datei verwenden, um diese Anforderung zu erfüllen.

Skript-Vorgang

Eine Liste aller Taktfrequenzen in einem Design, die eine Pin füttern, führt zu den drei wichtigsten Schritten:

  1. Holen Sie sich alle Taktfrequenzen und erstellen Sie eine Zuordnung von ihren Zielknoten zu den Taktfrequenzen auf den Zielknoten.
  2. Hier erhalten Sie eine Liste der Knoten mit Taktfrequenzen, die sich auf dem Fanin-Pfad zum angegebenen Stift befinden.
  3. Suchen Sie aus dieser Liste der Knoten den Knoten, der sich in nächster Nähe zum angegebenen Stift befindet, und senden Sie die Taktfrequenzen auf diesem Knoten zurück.

Schritt 1. Holen Sie sich alle Taktfrequenzen und erstellen Sie Mapping

Der folgende Tcl-Code holt alle Takte im Design und erstellt die Zuordnung (mit einem Tcl-Array) von einem Knoten zu den Taktfrequenzen auf dem Knoten.

catch { array unset nodes_with_clocks }
Array set nodes_with_clocks [list]

# Iterate über jede Taktfrequenz im Design
foreach_in_collection clock_id [all_clocks] {

    set clock_name [get_clock_info -name $clock_id]

    # Jede Taktung wird auf Knoten angewendet. Holen Sie sich die Sammlung von Zielknoten
    foreach_in_collection target_id [get_clock_info -targets $clock_id] {

        # Verknüpfen Sie den Taktnamen mit seinem Zielknotensatz
        target_name [get_node_info -name $target_id]
        lappend nodes_with_clocks($target_name) $clock_name
    }
}

Virtuelle Taktfrequenzen haben keine Ziele. Daher wird nie eine Zuordnung mit einer virtuellen Uhr vorgenommen. Im unten aufgeführten vollständigen Verfahrenscode werden Informationen zum Typ der Zielknoten (Register, Pin, Zelle oder Port) zur späteren Verwendung gespeichert.

Schritt 2. Knoten mit Taktfrequenzen im Fanin-Pfad erhalten

Der zweite Schritt besteht darin, den Untersatz von Knoten mit Taktfrequenzen zu finden, die sich auf dem Lüfterpfad zum angegebenen Stift befinden. Für jeden Knoten mit Taktfrequenzen (die in Schritt 1 zu finden sind), holen Sie sich den Lüfter über den Knoten auf den angegebenen Pin. Wenn ein Fanin vorhanden ist, befindet sich der Knoten im Fanin-Pfad zum Pin. Wenn kein Fanin vorhanden ist, befindet sich der Knoten nicht auf dem Fanin-Pfad zum Stift.

Der folgende Tcl-Code iteriert durch alle Knoten mit Takten aus Schritt 1 und verwendet den get_fanins Befehl, um festzustellen, ob sich jeder Knoten auf dem Fanin-Pfad des angegebenen Pins befindet. Wenn sich der Knoten auf dem Lüfterpfad des angegebenen Pins befindet, wird der Knoten in der Liste pin_drivers gespeichert.

setzen Sie pin_drivers [list]

# Iterate über alle Knoten in der in Schritt 1
foreach erstellten Zuordnung node_with_clocks [array names nodes_with_clocks] {

    # Holen Sie sich alle Fanins auf den angegebenen Pin durch den aktuellen Knoten
    gesetzt fanin_col [get_fanins -clock -through $node_with_clock $pin_name]

    # Wenn mindestens ein Fanin-Knoten vorhanden ist, der aktuelle Knoten sich auf dem
    Fanin-Pfad zum angegebenen Stift befindet,  Speichern Sie es also.
    wenn { 0 < [get_collection_size $fanin_bmc] } {
        lappend pin_drivers $node_with_clocks
} }

Der unten aufgeführte vollständige Verfahrenscode verwendet zusätzliche Informationen zum Knotentyp, um eine typspezifische Sammlung für den Wert -through im Befehl get_fanins anzugeben.

Schritt 3. Knoten finden, der der angegebenen Pin am nächsten kommt

Die pin_drivers Variable hat jetzt eine Liste aller Knoten mit Taktfrequenzen, die sich auf dem Lüfterpfad zum angegebenen Stift befinden. Dieser Schritt findet den Knoten, der sich in nächster Nähe zum angegebenen Stift befindet. Während sich in der liste der pin_drivers mehr als ein Knoten befindet, nimmt der Code die ersten beiden Knoten in der Liste und überprüft, ob sich einer auf dem Fanin-Pfad zum anderen befindet. Wenn es sich auf dem Fanin-Pfad befindet, muss der erste Knoten weiter von der Pin entfernt sein als der zweite Knoten, damit er aus der Liste entfernt werden kann.

während { 1 < [llength $pin_drivers] } {

    # Get the first two nodes in the pin_drivers list set node_a
    [$pin_drivers 0]
    set node_b [$pin_drivers 1]

    # Überprüfen Sie, ob node_b sich auf dem Fanin-Pfad node_a
    gesetzten fanin_col befindet [get_fanins -clock -through $node_b $node_a]

    # Wenn mindestens ein Fanin-Knoten vorhanden ist,  node_b muss weiter
    als node_a vom angegebenen Stift entfernt sein.
    # Wenn kein Fanin-Knoten vorhanden ist, muss node_b näher am angegebenen Pin sein
    als node_a.
    wenn { 0 < [get_collection_size] } {

        # node_a näher am Pin ist.
        # Entfernen Sie node_b aus dem pin_drivers
        Listensatz pin_drivers [lreplace $pin_drivers 1 1]

    } else { # node_b befindet sich näher am

        Pin.
        Anzahl node_a aus der pin_drivers liste entfernen, die
        pin_drivers [lreplace $pin_drivers 0 0]
    } } # Der einzige

Knoten, der in pin_drivers bleibt, ist der Knoten, der den angegebenen
Pin-Satz treibt node_driving_pin [$pin_drivers 0] # Schauen Sie sich

die Taktfrequenzen auf dem Knoten im Mapping aus Schritt 1 an und schicken Sie
sie zurück $nodes_with_clocks($node_driving_pin

Der unten aufgeführte vollständige Verfahrenscode verwendet zusätzliche Informationen zum Knotentyp, um eine typspezifische Sammlung für den Wert -through im Befehl get_fanins anzugeben.

Vollständiger Verfahrenscode

Der vollständige Code für das get_clocks_driving_pin benutzerdefinierte Verfahren ist unten aufgeführt. Dazu gehören zusätzliche Fehlerüberprüfungen und Supportfunktionen, die oben nicht detailliert beschrieben sind.

proc get_clocks_feeding_pin { pin_name } {

    # Vor Schritt 1 führen Sie eine Fehlerüberprüfung durch, um sicherzustellen, dass pin_name
    #, die dem Verfahren übergeben wurde, mit nur einer Pin übereinstimmt.
    # Geben Sie einen Fehler zurück, wenn er nicht mit einer und nur einer Pin übereinstimmt.
    setzen Sie pin_col [get_pins -compatibility_mode $pin_name], wenn
    { 0 == [get_collection_size $pin_ascii] } {
        return -code error "No pins match $pin_name"
    } elseif { 1 < [get_collection_size $pin_ascii] } {
        return -code error "$pin_name matches [get_collection_size $pin_ascii]\
            pins but must match only one"
    } #
    
    Initialize variables used in the procedure catch
    {array unset nodes_with_clocks }
    catch { array unset node_types } array set
    nodes_with_clocks [list]
    array set node_types [list]
    set pin_drivers [list]
    
    # Step 1. Holen Sie sich alle Taktfrequenzen im Design und erstellen Sie eine Zuordnung von
    der Anzahl der Zielknoten zu den Takten auf den Zielknoten

    # Iterate über jede Taktfrequenz im
    Design-foreach_in_collection clock_id [all_clocks] {

        set clock_name [get_clock_info -name $clock_id]
        festgelegt clock_target_col [get_clock_info -targets $clock_id]
        
        # Jeder Takt wird auf Knoten angewendet. Holen Sie sich die Sammlung von Zielknoten
        foreach_in_collection target_id [get_clock_info -targets $clock_id] {

            # Den Clock-Namen mit seinem Zielknoten verknüpfen target_name
            [get_node_info -name $target_id]
            lappend nodes_with_clocks($target_name) $clock_name

            # Speichern Sie den Typ des Zielknotens zum späteren Einsatz
            target_type [get_node_info -type $target_id]
            set node_types($target_name) $target_type
        }
    }

    Anzahl Schritt 2. Holen Sie sich eine Liste der Knoten mit Takten auf ihnen, die sich auf dem
    #fanin-Pfad zur angegebenen

    Pin#Iterate über allen Knoten in der in Schritt 1 foreach erstellten Zuordnung
    befinden node_with_clocks [Array-Namen nodes_with_clocks] {

        # Verwenden Sie den Typ des Zielknotens, um eine typspezifische
        Anzahlsammlung für den Wert -through im get_fanins Befehl zu erstellen.
        switch -exact -- $node_types($node_with_clocks) {
            "pin" {  set through_col [get_pins $node_with_clocks] }
            "port" { set through_col [get_ports $node_with_clocks] }
            "cell" { set through_col [get_cells $node_with_clocks] }
            "reg" {  set through_col [get_registers $node_with_clocks] }
            default { return -code error "$node_types($node_with_clocks) is nothand\
                as a fanin type by the script"
        }

        # Holen Sie sich alle Fanins zum angegebenen Pin über den aktuellen
        Knotensatz fanin_col [get_fanins -clock -through $through_$pin_name]

        # Wenn mindestens ein Fanin-Knoten vorhanden ist, befindet sich der aktuelle Knoten auf dem Pfad
        #fanin zum angegebenen Stift. Speichern Sie ihn also.
        wenn { 0 < [get_collection_size $fanin_bmc] } {
            lappend pin_drivers $node_with_clocks
    }

    # Vor Schritt 3, führen Sie eine Fehlerüberprüfung durch, um sicherzustellen, dass mindestens eine
    Anzahl der Knoten mit Taktfrequenzen im Design auf dem Fanin-Pfad zu der
    angegebenen Pin ist.
    wenn { 0 == [llength $pin_drivers] } {
        return -code error "Can not find any node with clocks that drives $pin_name"
    } # Step
    
    3. Suchen Sie aus der Liste der in Schritt 2 erstellten Knoten die
    Knotennummer, die sich in nächster Nähe zur angegebenen Pin befindet, und senden Sie die Taktfrequenzen an den knoten zurück.

    while { 1 < [llength $pin_drivers] } {

        # Get the first two nodes in the pin_drivers list set node_a
        [$pin_drivers
        0] set node_b [$pin_drivers 1]
        
        # Verwenden Sie den Typ des Zielknotens, um eine typspezifische Sammlung für den Wert -through im Befehl get_fanins zu
        erstellen.
        switch -exact -- $node_types($node_b) {
            "pin" {  set through_col [get_pins $node_b] }
            "port" { set through_col [get_ports $node_b] }
            "cell" { set through_col [get_cells $node_b] }
            "reg" { set through_col  [get_registers $node_b] } default { return
            -code error "$node_types($node_b) is not handled\ as a
                fanin type by the script" } } # Überprüfen

        Sie, ob sich node_b auf dem Fanin-Pfad von node_a        
        setzen Sie fanin_col [get_fanins -clock -through $through_$node_a]

        # Wenn mindestens ein Lüfterknoten vorhanden ist, muss node_b weiter
        nr. vom angegebenen Pin entfernt sein, als node_a ist.
        # Wenn kein Fanin-Knoten vorhanden ist, muss node_b näher am angegebenen Pin sein
        als node_a.
        wenn { 0 < [get_collection_size $fanin_node_a] } {

            # node_a näher am Pin ist.
            # Entfernen sie node_b aus der pin_drivers Liste, die
            pin_drivers [lreplace $pin_drivers 1 1]

        } else { # node_b näher an der
            Pin-Nr. Node_a aus der pin_drivers Liste
            entfernt ist pin_drivers [lrange $pin_drivers 1 end] } } # Der einzige
    
    Knoten, der im pin_drivers links ist, ist der Knoten, der den angegebenen
    Pinsatz node_driving_pin [$pin_drivers 0]

    # Die Taktfrequenzen auf dem Knoten im Mapping ab Schritt 1 ansieht und schicken Sie
    sie zurück $nodes_with_clocks($node_driving_pin)
}

Der Inhalt dieser Seite ist eine Kombination aus menschlicher und computerbasierter Übersetzung des originalen, englischsprachigen Inhalts. Dieser Inhalt wird zum besseren Verständnis und nur zur allgemeinen Information bereitgestellt und sollte nicht als vollständig oder fehlerfrei betrachtet werden. Sollte eine Diskrepanz zwischen der englischsprachigen Version dieser Seite und der Übersetzung auftreten, gilt die englische Version. Englische Version dieser Seite anzeigen.