Simplifique la reutilización del diseño con restricciones de SDC dinámicas

author-image

Por

Cuando se crea un bloque de diseño o un componente HDL que se puede reutilizar en muchos diseños, puede ser necesario crear restricciones de SDC para acompañarlo. Es útil crear restricciones que no requieran edición por parte del diseñador que reutiliza el componente. Las restricciones deben ser genéricas, por lo que funcionan independientemente de dónde se cree una instancia del bloque en la jerarquía del diseño y dinámicas, de modo que funcionen independientemente de cómo esté conectado el bloque de diseño. Si las restricciones deben aplicarse manualmente a fin de reflejar los cambios de diseño, se quedarán fuera de sincronización si el diseñador realiza cambios de diseño sin actualizar las restricciones.

Este ejemplo de diseño cubre las técnicas para crear restricciones de SDC dinámicas que abordan los dos problemas siguientes:

  • Determinar el nombre de una E/S de nivel superior conectada directamente a un módulo de bajo nivel
  • Creación de relojes generados en la lógica en módulos de bajo nivel

El diagrama de la Figura 1 muestra un diseño muy simple para este ejemplo. Incluye dos instancias de un bloque de diseño reutilizable denominado reusable_block, que se muestra en amarillo. La Figura 2 muestra el contenido del diseño reusable_block. reusable_block funciona como un reloj de velocidad de datos doble para un bus de salida sincrónico de origen. Su salida debe estar conectada a una salida de nivel superior. Las restricciones para reusable_block deben incluir relojes generados, porque la salida funciona como un reloj de origen sincrónico.

Figura 1. Ejemplo de circuito para el diseño.

Figura 2. Contenidos de reusable_block.

Determinar los nombres de E/S de nivel superior

Las restricciones para reusable_block deben adaptarse a los cambios en los nombres de E/S de nivel superior. Por lo tanto, se debe determinar el nombre de E/S de nivel superior durante la compilación o el análisis de la sincronización. El comando get_fanouts Tcl devuelve una colección de identificadores que representan puertos o registros que son fanouts de un nombre especificado. El comando get_fanouts Tcl utiliza una lista de conexiones de temporización que existe durante la compilación o el análisis de sincronización, de modo que determina dinámicamente la conectividad, independientemente de los nombres de los nodos de fanout. El siguiente código Tcl muestra cómo utilizar get_fanouts para obtener la salida de nivel superior que es un ventilador directo de un registro de bajo nivel.

foreach_in_collection fanout_id [get_fanouts $low_level_register_name] { break }
establecer top_level_io_name [get_node_info -name $fanout_id]

No es necesario conocer el nombre de la jerarquía completa del registro de bajo nivel, ya que se puede utilizar una oratorio y una parte conocida de la jerarquía que existe en el bloque de diseño reutilizable para que coincida con él. El último ejemplo de código de esta página muestra un ejemplo de cómo coincidir con el nombre del registro de bajo nivel.

En el diseño de la Figura 1, el pin de salida del módulo de bajo nivel se conecta directamente a una salida de nivel superior. El siguiente código Tcl agrega la comprobación de errores para asegurarse de que los ventiladores del registro de bajo nivel se registren en solo una ubicación y que la ubicación del ventilador sea un puerto de salida. Este código Tcl debe formar parte del archivo SDC que limita la reusable_block.

# Obtenga los ventiladores del conjunto de registro de bajo nivel
fanout_collection [get_fanouts $low_level_register_name] # Asegúrese de que solo haya un conjunto de

ventiladores
num_fanouts [get_collection_size $fanout_collection]
si { 1 != $num_fanouts } { error de
    código de devolución "$low_level_register_name fans fuera a $num_fanouts \
        nodos, pero debe ventilar en uno."
}

# Obtenga el nombre del nodo de ventilador
foreach_in_collection fanout_id $fanout_collection { break }
establecer fanout_name [get_node_info -name $fanout_id]

# Asegúrese de que el nodo fanout sea un puerto de salida si {
[catch { get_port_info -is_output_port $fanout_id } is_output] } { # Hubo un error: no aparece un error de
    devolución de código de puerto
    "$low_level_register_name fans hacia $fanout_name \
        que no es un puerto" }
elseif { ! $is_ output } { # No hay error, pero el puerto no es un error de devolución de puerto de
    salida
    -code "$fanout_name no es un puerto de salida"
} else { set
    top_level_io_name $fanout_name
} # top_level_io_name es el único ventilador de low_level_register_name y no es un puerto de
salida

Creación de relojes generados

Un reloj de salida sincrónico de origen se debe definir como un reloj generado, basado en el reloj que alimenta los registros de salida de la velocidad de datos doble. El reloj generado se debe crear sin ninguna información ingresada manualmente sobre relojes en el diseño, porque el bloque de diseño podría crearse una instancia en cualquier diseño con cualquier esquema de temporificación.

El siguiente comando SDC muestra una manera sencilla de crear un reloj generado para el reloj de salida sincrónico de origen para el diseño en la Figura 1, cuando no se conoce la ubicación en la jerarquía.

create_generated_clock -name reusable_generated -source [get_pins \
    *|reusable_block_clock_out|altddio_out_component|auto_generated|ddio_outa[0]|muxsel] \
    $top_level_io_name

Es un enfoque directo que funciona para una sola creación de instancias de reusable_block en cualquier lugar de la jerarquía de diseño, pero no maneja múltiples instancias o situaciones de bloqueo múltiple. Cuando se desconocido el esquema de temporación, la restricción de reloj generada debería ser capaz de manejar situaciones en las que se han definido varios relojes en una sola señal de reloj que alimenta el bloque de diseño. A menudo existen múltiples relojes en una sola señal de reloj en diseños que admiten diferentes velocidades de protocolo de E/S, o diseños que admiten el cambio de reloj para redundancia. El ejemplo de reloj generado simple de arriba falla en situaciones de bloqueo múltiple porque no incluye la opción -master_clock para distinguir entre múltiples relojes de origen.

Para gestionar varias instancias, utilice un bucle para crear relojes generados únicos para cada creación de instancias. Para gestionar situaciones de bloqueo múltiple, utilice un procedimiento personalizado llamado get_clocks_driving_pin, que se describe en el ejemplo de diseño "Relojes que desastrzo un pin". Para utilizar el procedimiento personalizado, debe copiarlo desde la página de ejemplo de diseño De relojes que conchan un pin. Puede guardarlo como un archivo SDC independiente que se agrega al proyecto, o copiarlo y pegado en un archivo SDC con todas las demás restricciones que limitan un bloque reutilizable. Si lo guarda como un archivo de SDC que se agrega al proyecto, asegúrese de que aparece antes que cualquier archivo SDC que utilice el procedimiento personalizado get_clocks_driving_pin.

El siguiente código Tcl muestra cómo crear restricciones de reloj generadas en salidas de nivel superior impulsadas por registros de bajo nivel en el diseño que se muestra en la Figura 1. Los relojes generados utilizan las salidas de nivel superior como sus objetivos, y los pines muxsel de altddio_output se registran como sus fuentes. El código utiliza un bucle para iterar a través de todas las instancias de reusable_block en el diseño y un bucle anidado para manejar situaciones de bloqueo múltiple con el get_clocks_driving_pin procedimiento personalizado. Da por sentado que el procedimiento de get_clocks_driving_pin ya se ha definido.

El número get_pins devuelve un pin de muxsel por cada creación de instancias de
reusable_block cantidad de foreach_in_collection itera sobre cada pin de muxsel foreach_in_collection pin_id
[get_pins -compatibility_mode \
    *|reusable_block_clock_out|altddio_out_component|auto_generated|ddio_outa[5]0]|muxsel] {

    # pin_name tiene la jerarquía de diseño completa del pin muxsel para una
    creación de instancias de reusable_block conjunto pin_name
    [get_node_info -name $pin_id]
    
    # Utilice el código que se muestra anteriormente, sin comprobar los errores, para obtener
    el nombre del resultado de nivel superior foreach_in_collection port_id
    [get_fanouts $pin_name] { break }
    set port_name [get_node_info -name $port_id] # Puede haber varios relojes de representación en
    
    el registro altddio_output se requiere un reloj generado para cada reloj que alimenta #
    un
    pin muxsel. Cada reloj que representa el pin muxsel es un reloj maestro.
    foreconferencia master_clock [get_clocks_feeding_pin $pin_name] {

        post_message "Crear un reloj generado en $port_name alimentado por $pin_name"
        # Cree el reloj generado con el reloj maestro adecuado.
        # La fuente es el pin muxsel de la celda altddio_output en
        # la creación de instancias actual de reusable_block.
        # El nombre es una combinación del reloj maestro y el
        nombre # de jerarquía completa del pin muxsel.
        # El objetivo es el puerto de nivel superior que es el ventilador del pin muxsel.
        create_generated_clock -add -master_clock $master_clock \
            -source [get_pins $pin_name] -name ${master_clock}-${pin_name} \
            [get_ports $port_name]
    }

Con este código en un archivo SDC incluido en el proyecto, todas las instancias de reusable_block se limitan automáticamente a los relojes generados. Los relojes generados siempre son correctos y actualizados, incluso en las siguientes situaciones:

  • reusable_block se crea una instancia de o se mueve a otros puntos de la jerarquía de diseño
  • Se renombran las E/S de nivel superior
  • El diseñador utiliza varias definiciones de reloj en el diseño

El contenido de esta página es una combinación de la traducción humana y automática del contenido original en inglés. Este contenido se ofrece únicamente para su comodidad como información general y no debe considerarse completa o precisa. Si hay alguna contradicción entre la versión en inglés de esta página y la traducción, prevalecerá la versión en inglés. Consulte la versión en inglés de esta página.