01signal.com

Uso de comodines y -hierarchical en las restricciones de temporización SDC

Esta página es un complemento a otra página que debería leerse antes que esta. Ambas páginas forman parte de una serie de páginas que explica la teoría de los cálculos de temporización, muestra cómo escribir varias restricciones de temporización (timing constraints) y analiza los principios del cierre de temporización (timing closure).

No uses patrones de búsqueda sencillos a menos que sea necesario

Esta página explica cómo usar comodines (wildcards) para escribir restricciones de temporización (timing constraints) en formato SDC. Aunque los comodines pueden usarse con varios comandos Tcl, esta página se centra en los comandos que normalmente soportan la opción "-hierarchical": get_cells, get_pins y get_nets. Estos comandos Tcl se explican en otra página. Ten en cuenta, sin embargo, que algunas herramientas de FPGA no soportan "-hierarchical" con los tres comandos.

Desgraciadamente, la capacidad de búsqueda de estos tres comandos es bastante limitada y puede resultar confusa: sin entender exactamente cómo funciona el comodín, los resultados de búsqueda pueden ser inesperados. En particular, cuando se usa "-hierarchical", los resultados pueden ser sorprendentes, como se muestra a continuación.

Por esta razón, siempre es mejor usar la opción "-filter" cuando la herramienta de FPGA concreta la soporta para el comando en cuestión. Si no hay ese soporte, no queda más remedio que usar los comodines sencillos.

Todos los ejemplos de esta página están basados en el mismo código Verilog que esa otra página relacionada.

Patrones de búsqueda sencillos

Los comandos que encuentran elementos lógicos y otros objetos pueden usarse con o sin patrón de búsqueda. Sin patrón de búsqueda, se encuentran todos los objetos relevantes. Por ejemplo, para encontrar todos los pines en la jerarquía de nivel superior:

get_pins

Y el comando que encuentra todos los pines de todo el diseño para FPGA es:

get_pins -hierarchical

Si se usa un patrón de búsqueda, los resultados se limitan a ese patrón. Por ejemplo, para encontrar un pin concreto con un nombre conocido y una posición conocida en la jerarquía:

> 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

El patrón también puede incluir comodines, por ejemplo:

> 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

El comportamiento del comodín

Hay dos comodines habituales:

Sin embargo, estos dos comodines nunca se aplican al separador de jerarquía. En otras palabras, «*» y «?» no sustituyen a «/» (ni a «|» con Quartus). Esto es siempre cierto con los comodines, se use o no la opción «-hierarchical» (pero ten en cuenta que si se usan «-filter» o «-regexp», es otra historia).

Como resultado, la posición exacta del objeto en la jerarquía debe escribirse explícitamente:

> 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

Observa que distintas herramientas pueden usar caracteres diferentes para el separador de jerarquía. Como se acaba de mencionar, Quartus usa el carácter de barra vertical («|»), y no «/», para este fin.

La opción «-hierarchical» permite encontrar elementos lógicos en cualquier lugar de la jerarquía del diseño. Esto elimina la necesidad de indicar la posición exacta en la jerarquía y también permite encontrar elementos lógicos en todo el diseño de la FPGA con un solo comando.

Así que repitamos las mismas expresiones con «-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» significa que el patrón de búsqueda se aplica en todas las posiciones de la jerarquía del diseño. En el ejemplo anterior, «*/clk_*» se aplicó primero en la jerarquía de nivel superior, así que se encontró, por ejemplo, «pll_i/clk_in1». Después, el mismo patrón se aplicó dentro de «pll_i/», por lo que se encontró «pll_i/inst/clk_in1».

Pero, ¿por qué no se encontró nada con «*/*/clk_*» cuando se aplicó «-hierarchical»? El mismo patrón produjo algunos resultados sin esta opción. ¿No debería haber siempre más resultados cuando se usa «-hierarchical»?

El uso de -hierarchical limita el patrón de búsqueda

Curiosamente, la opción «-hierarchical» no solo cambia dónde se aplica el patrón de búsqueda, sino que también limita qué patrones están permitidos. Por desgracia, las herramientas no responden con un error cuando se usa un patrón no permitido. En su lugar, la respuesta es que no se encuentra nada.

Cada uno de los tres comandos Tcl (get_cells, get_pins y get_nets) tiene su propia regla que limita el patrón de búsqueda. Para conocer las limitaciones exactas, consulta la documentación de tu herramienta de FPGA. La interpretación estándar (según se detalla en la documentación de Synopsys) se resume a continuación.

Observa que la abreviatura «-hier» se usa a menudo en lugar de «-hierarchical». El significado es exactamente el mismo.

get_cells -hierarchical

Cuando se usa get_cells con -hierarchical, el patrón solo coincide con el nombre del objeto. Si hay un separador de jerarquía en el patrón, el resultado siempre es vacío. Por ejemplo:

> 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'.

Observa que es un error si hay una «/» en el patrón, porque nunca se encuentra nada con un patrón así. Sin embargo, las herramientas no responden con un error, sino que el comando no produce ningún resultado.

Como el separador de jerarquía no está permitido en el patrón, get_cells se limita a las siguientes posibilidades:

Este ejemplo muestra cómo declarar caminos falsos (false paths) para todas las celdas con un formato de nombre concreto:

set_false_path -to [get_cells -hierarchical *metaguard*]

Con una restricción de temporización como esta, basta con usar un nombre que incluya la palabra «metaguard» para todos los registros que se utilicen como protección contra la metaestabilidad (metastability). El riesgo de esta restricción es, sin embargo, que la expresión puede coincidir sin querer con algún elemento lógico no relacionado en algún lugar del diseño. Por tanto, es mejor elegir algo menos común que «metaguard».

get_nets -hierarchical

get_nets sigue la misma regla que get_cells: sin -hierarchical, get_nets encuentra todas las redes (nets) en la jerarquía de nivel superior que coinciden con el patrón. Con -hierarchical, el patrón solo coincide con el nombre del objeto. Si hay un separador de jerarquía en el patrón, el resultado siempre es vacío.

> 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

Cuando se usa get_pins con -hierarchical, el patrón coincide con el nombre completo del pin, p. ej. baz_reg/Q, clkout1_buf/I, etc. La «/» se considera parte del nombre, y no un separador de jerarquía. En otras palabras, el carácter que hay entre el nombre de la celda y el identificador del pin puede ser sustituido por un comodín. Esto es cierto solo respecto al último separador de jerarquía, y solo cuando se usa -hierarchical.

Así, por ejemplo:

> 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'.

Observa que clkout1_bu* coincidió con clkout1_buf/O (entre otros). El «*» puede sustituirse por «/O» solo gracias a -hierarchical.

Al igual que con get_cells, si hay un separador de jerarquía en el patrón, el resultado siempre es vacío. Esto no contradice el ejemplo anterior: como se ha dicho, la última «/» se considera parte del nombre del pin.

> 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

Observa que cuando no se usa -hierarchical, un comodín nunca coincide con un separador de jerarquía, ni siquiera con el último:

> 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

Con estos ejemplos resulta evidente lo confuso que es get_pins. Como antes, usa -filter o -regexp en su lugar, si están soportadas.

Resumen

Aunque los comodines están disponibles como método para encontrar elementos lógicos, los resultados de búsqueda no siempre son lo que uno esperaría de forma natural. Del mismo modo, la opción -hierarchical puede ser útil en algunos escenarios, pero esta posibilidad conlleva una limitación en el patrón de búsqueda y un comportamiento aún más confuso.

Por tanto, se recomienda usar otros métodos para seleccionar elementos lógicos: si la herramienta soporta -filter, -regexp o -of_objects, una de estas opciones es probablemente una solución mejor. El uso de comodines sencillos solo tiene sentido si ninguna de estas otras opciones está disponible, o si ninguna resulta útil en el escenario concreto. En esa situación, es importante ser especialmente cuidadoso con el significado del patrón de búsqueda.

Esta página se ha traducido del inglés mediante traducción automática. En caso de duda, consulta el texto original.
Copyright © 2021-2026. All rights reserved. (dcc38493)