Ottieni orologi che alimentano un pin

author-image

di

Questo esempio di progettazione mostra una procedura personalizzata, che è possibile utilizzare nei file SDC, che restituisce un elenco di tutti i clock che alimentano un pin. La procedura può essere utile se è necessario creare clock generati senza conoscere altri nomi di clock in un progetto. L'esempio di progettazione Semplifica il riutilizzo della progettazione con vincoli SDC dinamici fornisce maggiori dettagli e un esempio di come utilizzare la procedura personalizzata descritta in questa pagina.

Il codice completo della procedura è nella parte inferiore della pagina, seguendo una spiegazione completa del funzionamento della procedura. Per utilizzare la procedura personalizzata get_clocks_driving_pins in un file SDC, assicurarsi che la procedura sia stata definita, quindi chiamarla come qualsiasi altro comando SDC. Esistono due modi semplici per garantire che la procedura sia stata definita prima dell'uso:

  • Salvare il codice di procedura in un file SDC separato e includere il file SDC nel progetto.
  • Copiare e incollare il codice di procedura nella parte superiore di qualsiasi file SDC, prima che venga utilizzata la procedura personalizzata get_clocks_driving_pins.

File SDC separato

Il salvataggio del codice di procedura in un file SDC separato mantiene il codice separato dal resto dei vincoli e rende più semplice il riutilizzo in altri progetti. Se si utilizza un file SDC separato, è necessario aggiungere il file SDC con la procedura all'elenco dei file nel progetto e deve apparire sopra tutti i file SDC che utilizzano la procedura. Elencarlo sopra altri file SDC assicura che il software Quartus® II definisca la procedura prima di utilizzarla, ogni volta che vengono letti i file SDC.

Copiare e incollare

La copia e l'incolla del codice di procedura nello stesso file SDC in cui viene utilizzato comporta un minor numero di file SDC in un progetto. Se si sta creando un file SDC per un modulo che verrà riutilizzato da altri progettisti, potrebbe essere più semplice includere tutti i vincoli e il codice di supporto in un singolo file SDC. È necessario includere il codice di procedura nel file SDC prima del primo utilizzo della procedura in modo che sia definito prima dell'utilizzo. In genere, lo si mette nella parte superiore del file per soddisfare questo requisito.

Operazione script

Ottenere un elenco di tutti gli orologi in un design che alimenta un pin richiede tre passaggi principali:

  1. Ottieni tutti i clock e crea una mappatura dai loro nodi di destinazione ai clock sui nodi di destinazione.
  2. Ottieni un elenco di nodi con clock su di essi che si trovano sul percorso della ventola al pin specificato.
  3. Da quell'elenco di nodi, trovare il nodo più vicino al pin specificato e restituire i clock su quel nodo.

Passaggio 1. Ottieni tutti i clock e crea mappatura

Il seguente codice Tcl ottiene tutti i clock nella progettazione e crea il mapping (con un array Tcl) da un nodo ai clock sul nodo.

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

# Iterate over each clock in the design
foreach_in_collection clock_id [all_clocks] {

    set clock_name [get_clock_info -name $clock_id]

    # Ogni clock viene applicato ai nodi. Ottieni la raccolta di nodi di destinazione
    foreach_in_collection target_id [get_clock_info -targets $clock_id] {

        # Associare il nome del clock al relativo nodo di destinazione
        impostato target_name [get_node_info -name $target_id]
        nodes_with_clocks($target_name) $clock_name
    }
}

I clock virtuali non hanno obiettivi, quindi non viene mai effettuata alcuna mappatura con un clock virtuale. Nel codice di procedura completo elencato di seguito, le informazioni sul tipo di nodi di destinazione (registro, pin, cella o porta) vengono salvate per un utilizzo successivo.

Passaggio 2. Ottieni nodi con clock nel percorso fanin

Il secondo passo è trovare il sottoinsieme di nodi con clock che si trovano sul percorso fanin del pin specificato. Per ciascun nodo con clock (trovato nel passaggio 1), portare la ventola al pin specificato tramite il nodo. Se è presente una ventola, il nodo si trova nel percorso della ventola al pin. Se non c'è ventola, il nodo non è sul percorso della ventola del pin.

Il seguente codice Tcl scorre tutti i nodi con clock dal passaggio 1 e utilizza il comando get_fanins per determinare se ciascun nodo si trova sul percorso fanin del pin specificato. Se il nodo si trova sul percorso fanin del pin specificato, il nodo viene salvato nell'elenco pin_drivers.

impostare pin_drivers [elenco]

# Iterate su tutti i nodi nel mapping creato nel passaggio 1
foreach node_with_clocks [nomi di array nodes_with_clocks] {

    # Ottieni qualsiasi ventola sul pin specificato tramite il nodo corrente
    impostato fanin_col [get_fanins -clock -through $node_with_clock $pin_name]

    # Se è presente almeno un nodo fanin, il nodo corrente si trova sul
    percorso # fanin del pin specificato,  quindi salvarlo.
    if { 0 < [get_collection_size $fanin_col] } {
        lappend pin_drivers $node_with_clocks
} }

Il codice di procedura completo elencato di seguito utilizza ulteriori informazioni sul tipo di nodo per specificare una raccolta specifica del tipo per il valore -through nel comando get_fanins.

Passaggio 3. Trova il nodo più vicino al pin specificato

La variabile pin_drivers ora ha un elenco di tutti i nodi con clock che si trovano sul percorso fanin del pin specificato. Questo passaggio trova il nodo più vicino al pin specificato. Sebbene nell'elenco pin_drivers sia presente più di un nodo, il codice prende i primi due nodi nell'elenco e verifica se uno è sul percorso della ventola rispetto all'altro. Se si trova sul percorso della ventola, il primo nodo deve essere più lontano dal pin rispetto al secondo nodo, in modo che possa essere rimosso dall'elenco.

while { 1 < [llength $pin_drivers] } {

    # Ottieni i primi due nodi nell'elenco pin_drivers
    impostato node_a [lindex $pin_drivers 0]
    impostato node_b [lindex $pin _drivers 1]

    # Verificare se node_b si trova sul percorso fanin di node_a
    impostato fanin_col [get_fanins -clock -through $node_b $node_a]

    # Se è presente almeno un nodo fanin,  node_b deve essere più
    distante dal pin specificato rispetto a node_a.
    # Se non c'è alcun nodo fanin, node_b deve essere più vicino al
    pin # specificato di node_a.
    se { 0 < [get_collection_size] } {

        # node_a è più vicino al pin.
        # Rimuovere node_b dall'elenco pin_drivers
        impostato pin_drivers [lreplace $pin_drivers 1 1]

    } altrimenti { # node_b è più vicino al

        pin.
        # Rimuovi node_a dall'elenco pin_drivers
        impostato pin_drivers [lreplace $pin_drivers 0] }
}

} # L'unico nodo rimasto in pin_drivers è il nodo che guida il set di pin specificato
node_driving_pin [lindex $pin_drivers 0]

# Cerca i clock sul nodo nel mapping dal passaggio 1 e
restituiscili $nodes_with_clocks($node_driving_pin

Il codice di procedura completo elencato di seguito utilizza informazioni aggiuntive sul tipo di nodo per specificare una raccolta specifica del tipo per il valore -through nel comando get_fanins.

Codice di procedura completo

Il codice completo per la procedura personalizzata get_clocks_driving_pin è elencato di seguito. Include ulteriori funzionalità di controllo degli errori e supporto che non sono descritte nei dettagli sopra.

proc get_clocks_feeding_pin { pin_name } {

    # Prima del passaggio 1, eseguire un controllo di errore per assicurarsi che pin_name # passato alla procedura corrisponda a un solo
    pin.
    # Restituire un errore se non corrisponde a un solo pin.
    set pin_col [get_pins -compatibility_mode $pin_name]
    se { 0 == [get_collection_size $pin_col] } {
        return -code error "No pins match $pin_name"
    } elseif { 1 < [get_collection_size $pin_col] } {
        return -code error "$pin_name matches [get_collection_size $pin_col]\
            pin ma deve corrispondere solo a uno" }
    # Inizializza le variabili utilizzate nella procedura catch {
    
    array
    unset nodes_with_clocks }
    catch { array unset node_types } set
    di array nodes_with_clocks [list]
    set di array node_types
    [elenco] impostato pin_drivers [elenco]
    
    # Passaggio 1. Ottieni tutti i clock nella progettazione e crea un mapping dai
    nodi di destinazione ai clock sui nodi di destinazione #

    Iterate su ogni clock nella
    progettazione foreach_in_collection clock_id [all_clocks] {

        impostare clock_name [get_clock_info -name $clock_id]
        impostato clock_target_col [get_clock_info -targets $clock_id]
        
        # Ogni clock viene applicato ai nodi. Ottieni la raccolta di nodi di destinazione
        foreach_in_collection target_id [get_clock_info -targets $clock_id] {

            # Associare il nome del clock al relativo nodo di destinazione
            impostato target_name nodes_with_clocks($target $target) [get_node_info -name $target_id]
            nome_) $clock_name

            # Salvare il tipo di nodo di destinazione per l'uso successivo
            impostato target_type [get_node_info -type $target_id]
            impostato node_types($target_name) $target_type
        }
    }

    # Passaggio 2. Ottieni un elenco di nodi con clock su di essi che si trovano sul
    percorso # fanin del pin specificato

    # Iterate su tutti i nodi nel mapping creato nel passaggio 1
    foreach node_with_clocks [nomi di array nodes_with_clocks] {

        # Utilizza il tipo del nodo di destinazione per creare una raccolta di numeri specifica del tipo
        per il valore -through nel comando get_fanins.
        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) non è gestito\
                come tipo fanin dallo script"
        } }

        # Ottieni tutte le ventola sul pin specificato tramite il nodo corrente
        impostato fanin_col [get_fanins -clock -through $through_col $pin_name]

        # Se è presente almeno un nodo fanin, il nodo corrente si trova sul percorso #
        fanin del pin specificato, quindi salvalo.
        se { 0 < [get_collection_size $fanin_col] } {
            lappend pin_drivers $node_with_clocks
    } } # Prima del

    passaggio 3, eseguire un controllo di errore per assicurarsi che almeno un
    numero di nodi con clock nella progettazione sia sul percorso fanin per
    # il pin specificato.
    if { 0 == [llength $pin_drivers] } {
        return -code error "Impossibile trovare alcun nodo con clock che unità $pin_name"
    } # Passaggio
    
    3. Dall'elenco dei nodi creati nel passaggio 2, trovare il
    nodo #più vicino al pin specificato e restituire i clock su quel nodo.

    while { 1 < [llength $pin_drivers] } {

        # Ottieni i primi due nodi nell'elenco pin_drivers
        impostato node_a [lindex $pin_drivers 0]
        impostato node_b [lindex $pin_drivers 1]
        
        # Utilizzare il tipo del nodo di destinazione per creare un insieme di numeri specifico del tipo
        per il valore -through nel comando get_fanins.
        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) non è gestito\
                come tipo fanin dallo script"
        } } # Verificare se node_b si trova sul percorso

        fanin di node_a        
        set fanin_col [get_fanins -clock -through $through_col $node_a]

        # Se è presente almeno un nodo fanin, node_b deve essere più lontano dal pin specificato rispetto a
        node_a.
        # Se non c'è alcun nodo fanin, node_b deve essere più vicino al
        pin # specificato di node_a.
        se { 0 < [get_collection_size $fanin_col] } {

            # node_a è più vicino al pin.
            # Rimuovi node_b dall'elenco pin_drivers
            impostato pin_drivers [lreplace $pin_drivers 1 1]

        } else {

            # node_b è più vicino al pin # Rimuovi node_a
            dall'elenco pin_drivers
            impostato pin_drivers [lrange $pin_drivers 1
        end] } } #
    
    L'unico nodo rimasto in pin_drivers è il nodo che guida il set di pin specificato
    node_driving_pin [lindex $pin_drivers 0]

    # Cerca i clock sul nodo nel mapping dal passaggio 1 e restituire
    $nodes_with_clocks ($node_driving_pin)
}

Il contenuto di questa pagina è il risultato della combinazione tra la traduzione umana e quella automatica del contenuto originale in lingua inglese. Questo contenuto è fornito soltanto a titolo di informazione generale e non ha pretese di completezza o accuratezza. In presenza di contraddizioni tra la versione in lingua inglese di questa pagina e la sua traduzione, fa fede la versione inglese. Visualizza la versione in lingua inglese di questa pagina.