Esta página pertenece a una serie de páginas sobre temporización (timing). Las páginas anteriores explicaron la teoría de los cálculos de temporización, analizaron la restricción del periodo de reloj, mostraron los principios del cierre de temporización (timing closure) e introdujeron algunos comandos Tcl importantes. Esta página explica cómo definir restricciones de temporización (timing constraints) para caminos (paths) específicos.
Introducción
El objetivo al escribir restricciones de temporización es que sean cortas, concisas y fáciles de entender. Así se reduce el riesgo de confusión y de errores. Cuando sea posible, las restricciones de temporización para los caminos internos de la FPGA deberían consistir solo en dos tipos: restricciones de periodo de reloj (por ejemplo, create_clock) y restricciones de grupos de reloj (por ejemplo, set_clock_groups).
Pero a menudo hay caminos que necesitan reglas específicas. Estas reglas específicas se denominan excepciones de temporización (timing exceptions). Como su nombre indica, estas restricciones de temporización sirven sobre todo para anular las restricciones existentes. También pueden usarse para especificar los requisitos de temporización de caminos que de otro modo no tendrían tales requisitos.
Los comandos para estos fines en la sintaxis SDC son principalmente estos:
- set_false_path: informa a las herramientas de que no deben imponer requisitos de temporización en los caminos seleccionados.
- set_max_delay: define el requisito para la aplicación de tsetup.
- set_min_delay: define el requisito para la aplicación de thold.
- set_multicycle_path: relaja los requisitos para la lógica controlada por una señal de habilitación de reloj (clock enable).
Las herramientas que usan una sintaxis distinta probablemente tengan comandos similares.
Los argumentos de estos comandos definen (entre otras cosas) qué caminos deben verse afectados. Esto se explica a continuación.
Hay dos temas relacionados que se tratan en otras páginas:
- Hay una página aparte para las restricciones de temporización de E/S. Por tanto, la discusión siguiente se limita al uso de estos comandos con caminos internos (es decir, caminos que van desde un elemento secuencial hasta otro elemento secuencial en el tejido lógico).
- set_multicycle_path se trata en otra página aparte.
Caminos falsos
Un camino falso (false path) es un camino que las herramientas ignoran como resultado de una restricción de temporización que lo pide. En otras palabras, las herramientas no imponen deliberadamente ningún requisito de temporización en un camino falso, porque eso es lo que les hemos pedido que hagan.
Esto no debe confundirse con los caminos sin restricciones (unconstrained paths): son caminos para los que las herramientas no tienen ninguna restricción de temporización. Igual que los caminos falsos, las herramientas no imponen requisitos de temporización sobre ellos, pero la razón es distinta: esa falta de aplicación no es una decisión, sino que las herramientas no saben qué requisito aplicar.
No debería haber caminos sin restricciones en un diseño para FPGA. Dicho esto, a menudo hay caminos que queremos que las herramientas ignoren. Esos caminos deben marcarse como caminos falsos mediante restricciones de temporización. La razón: cuando leamos el informe de temporización, deberíamos ver siempre que el número de caminos sin restricciones es cero. Si ese número no es cero, deberíamos buscar un error. Si nos acostumbramos a aceptar un número distinto de cero de caminos sin restricciones, es más fácil pasar por alto problemas con las restricciones de temporización.
Así pues, hay dos razones posibles para declarar caminos falsos:
- Cuando de otro modo las herramientas impondrían requisitos de temporización en el camino, un camino falso les dice que, en su lugar, lo ignoren.
- Cuando no hay ninguna restricción de temporización para el camino. En ese caso, el propósito del camino falso es mantener el número de caminos sin restricciones en cero.
En la práctica, no importa cuál de estos dos escenarios esté en vigor. Si no hacen falta requisitos de temporización en un camino, debe declararse como camino falso.
Es un error habitual usar set_false_path en relación con los cruces de dominios de reloj (clock domain crossing). Este tema se trata con más detalle más adelante. De hecho, no hay muchas situaciones en las que sea correcto usar set_false_path, salvo con puertos de E/S.
Selección de caminos para set_false_path
Hay muchas formas de seleccionar a qué caminos se aplica el comando. A pesar de la gran variedad de posibilidades, la selección suele hacerse con dos argumentos: -from y -to. Por ejemplo:
set_false_path -from [get_cells source_reg] -to [get_cells dest_reg]
En este ejemplo, el comando set_false_path se aplica al camino que comienza en un registro @source y termina en el registro @dest.
Observa que get_cells proporciona a -from y a -to objetos que representan elementos lógicos. Los otros comandos analizados en la página anterior también pueden usarse: get_pins, get_nets, get_ports y get_clocks. Sin embargo, cada herramienta de FPGA tiene sus propias reglas sobre lo que es aceptable para usar con -from y con -to.
Ten en cuenta que las herramientas pueden no interpretar la referencia a los objetos como uno esperaría de forma natural. Las herramientas también pueden ignorar algunos o todos los objetos sin emitir ningún aviso. De hecho, si el comando get_* no encuentra ningún objeto (por ejemplo, por un error en el patrón de búsqueda), ningún camino queda incluido en la excepción de temporización. Esto puede ocurrir incluso sin aviso.
Por tanto, es importante usar el informe de temporización para verificar que las excepciones de temporización se aplican como se pretende. Es decir, que los caminos afectados son los correctos, y que el análisis de tiempos cumple su propósito exacto (no imponer requisitos de temporización).
Hay otro argumento útil para seleccionar caminos: -through. Como su nombre indica, este argumento selecciona los caminos que pasan por los elementos lógicos especificados.
Merece la pena dedicar tiempo a leer la documentación oficial para conocer todas las características. Por ejemplo, también es posible limitar el efecto del comando solo a los flancos de subida o solo a los de bajada. Otra posibilidad es limitar el comando al análisis de solo tsetup o solo thold.
El comando set_false_path requiere al menos uno de los argumentos -from, -to o -through (u otro argumento con significado similar). Cuando hay más de un argumento, la excepción de temporización se aplica solo a los caminos que cumplen las condiciones de todos los argumentos.
El peligro de set_false_path
El problema con los caminos falsos es lo fácil que resulta cometer errores. En particular, existe el riesgo de incluir más caminos de los previstos. Cuando esto ocurre, hay elementos secuenciales que pueden no funcionar correctamente: esperamos por error que las herramientas garanticen sus requisitos de tsu y thold. Pero en realidad, las herramientas se comportan como si los caminos hacia esos elementos secuenciales fueran falsos. Por tanto, no se molestan en hacer ningún análisis de tiempos para ellos. Esto es peligroso, porque crea la ilusión de que todo está bien cuando las herramientas dicen que se han cumplido las restricciones. Pero en realidad hay flip-flops y otros elementos secuenciales expuestos a violaciones de temporización sin ninguna protección.
Para empeorar las cosas, si un camino se declara como falso, esa declaración suele tener la máxima prioridad. Por tanto, si un camino se declara accidentalmente como falso, probablemente anulará otras restricciones que exijan lo contrario. Esto suele ser cierto incluso si set_false_path aparece antes que la otra restricción. Así que set_false_path se interpreta como «estos son caminos falsos, independientemente de lo que haya pedido antes o pediré después».
set_min_delay y set_max_delay
He empezado hablando de los caminos falsos, que eliminan los requisitos de temporización de un grupo de caminos seleccionados. A menudo, la necesidad es especificar los requisitos de temporización, más que anularlos. Eso se hace con set_min_delay y set_max_delay. Por ejemplo, considera este código Verilog:
reg x, y;
always @(posedge clk)
y <= x;
Y las restricciones de temporización:
set_max_delay -from [get_cells x_reg] -to [get_cells y_reg] 3 set_min_delay -from [get_cells x_reg] -to [get_cells y_reg] 1
Entonces, ¿qué significan estos comandos? Empecemos por set_max_delay. La explicación breve de esta excepción de temporización es que es similar a una restricción de periodo de reloj (create_clock) pensada solo para caminos específicos.
Recuerda que cuando se define una restricción de periodo de reloj, las herramientas imponen automáticamente los requisitos de temporización necesarios: los retardos máximos de los caminos relevantes quedan limitados para cumplir el requisito de tsetup. Del mismo modo, los retardos mínimos quedan limitados en nombre de thold.
En el ejemplo anterior, el valor que aparece en el comando set_max_delay es 3. Esto equivale a un comando create_clock con un periodo de reloj de 3 ns. Pero la influencia de set_max_delay se limita a un grupo concreto de caminos. Esa es la diferencia.
En cuanto a set_min_delay, es un poco más complicado, así que habrá más detalles abajo.
Observa que el nombre del comando set_max_delay es engañoso: este comando no define directamente el retardo máximo del camino en sí. El retardo de los caminos afectados no queda limitado a 3 ns por el comando del ejemplo anterior. El valor de 3 ns se aplica como la diferencia temporal permitida entre flancos de reloj. Y esa diferencia no se mide en las entradas de reloj de los elementos síncronos, sino en el origen de esos relojes. Esto significa que los retardos de las PLL, los buffers de reloj y el enrutado del reloj se incluyen en los cálculos: igual que con una restricción de periodo, los retardos del reloj se tienen en cuenta en el análisis de tiempos.
El significado de -from, -to, -through y otros argumentos es el mismo que en set_false_path. Pero, en general, set_min_delay y set_max_delay están pensados como ajustes para una restricción de periodo de reloj. En consecuencia, suele suponerse que hay elementos secuenciales a ambos lados del camino. Por tanto, -from y -to deberían representar elementos síncronos. Hay muchas formas de referirse a ellos: un objeto celda que represente el propio elemento síncrono, un objeto de reloj, etc.
En cuanto a set_min_delay, la historia es parecida: otra consecuencia de una restricción de periodo es que las herramientas deben cumplir los requisitos de thold. Para ello, las herramientas imponen retardos mínimos en todos los caminos entre el mismo reloj o entre relojes relacionados (related clocks). Si el cálculo de temporización de un camino es el resultado únicamente de create_clock (con el mismo reloj a ambos lados), esto equivale a un set_min_delay con el valor cero. Eso refleja la idea de que el mismo flanco de reloj llega a ambos elementos secuenciales. Sin embargo, esto no significa que ese flanco llegue al mismo tiempo a esos elementos. Más bien, el flanco para cada elemento secuencial parte al mismo tiempo del origen del reloj. El retardo desde cada origen hasta el elemento secuencial se tiene en cuenta en el cálculo (de forma parecida a como se hace para tsetup).
set_min_delay permite ajustar el instante del flanco de reloj que llega al segundo elemento secuencial. Por ejemplo, el comando anterior hace que ese flanco llegue 1 ns más tarde al segundo flip-flop. Eso hace más difícil cumplir el requisito de thold: ver el ejemplo de informe más abajo.
Hay dos razones posibles para usar set_min_delay y set_max_delay:
- Cuando el requisito de temporización que las herramientas impondrían de otro modo es inadecuado para un grupo de caminos concreto. Por ejemplo, cuando el requisito debe ser más estricto en caminos que comienzan en una protección contra metaestabilidad (metastability).
- Cuando no hay ninguna restricción de temporización relacionada con esos caminos. Si quieres usar set_max_delay con ese fin, pregúntate si no necesitas en realidad una restricción de periodo o caminos de varios ciclos (multicycle paths).
Cuando se usen estos dos comandos, comprueba siempre con cuidado el análisis de tiempos de los caminos en los informes de temporización. En particular, presta atención al papel que juega el camino del reloj en el cálculo.
Al final de esta página hay ejemplos de informes de temporización que muestran los resultados de set_min_delay y set_max_delay.
Un control más preciso del retardo
El nivel de control que ofrecen set_max_delay y set_min_delay no es mucho mejor que el de una restricción de periodo de reloj (tal como se ha presentado hasta ahora). Pero, ¿y si no queremos que el retardo del camino del reloj interfiera en nuestra definición del retardo? ¿Y si queremos controlar el retardo de un segmento concreto del camino?
Algunas herramientas de FPGA no ofrecen ninguna solución para estas necesidades. Por ejemplo, Quartus no ofrece esa posibilidad (hasta donde yo sé). Vivado, en cambio, tiene algunas características que comentaré brevemente.
Una de ellas es la opción datapath_only: a veces se desea usar set_max_delay de modo que el cálculo de temporización no incluya los caminos del reloj. Por ejemplo, si un camino está entre relojes no relacionados (unrelated clocks), no tiene sentido tener en cuenta los caminos del reloj.
Cuando se usa datapath_only, la temporización se calcula como si el retardo del camino del reloj de ambos elementos síncronos fuera cero. Por tanto, el cálculo consiste solo en los retardos de los elementos lógicos del camino. Se exige que la suma de esos retardos sea menor que el número indicado en el comando set_max_delay (ver ejemplo de informe más abajo).
Así pues, cuando se usa set_max_delay con datapath_only, su significado se acerca más a lo que sugiere el nombre del comando. Observa sin embargo que el camino debe seguir empezando y terminando en un elemento síncrono.
También, datapath_only tiene algunas peculiaridades: si se usa, las herramientas no imponen ningún requisito de temporización en cuanto al thold de los caminos afectados. En otras palabras, las herramientas se comportan como si hubiera una restricción de camino falso aplicada solo al escenario de thold. Incluso si se añade un comando set_min_delay para los caminos afectados, ese comando se ignora. No está claro por qué Vivado se niega a imponer un retardo mínimo en los caminos afectados por datapath_only.
datapath_only no puede usarse como argumento de set_min_delay en ningún escenario.
Características engañosas
Como indica el título de esta sección, son algunas posibilidades que probablemente no aporten nada bueno. Si quieres, salta a la sección siguiente.
Vivado permite un nivel de control aún mayor: es posible imponer restricciones sobre el retardo de un segmento concreto de un camino. Por ejemplo, ¿qué ocurre si se usan elementos lógicos que no son secuenciales con -from y -to? ¿Y qué pasa con pines y redes? ¿Qué harán set_min_delay y set_max_delay?
Eso depende, por supuesto, de la herramienta de FPGA. Las herramientas pueden ignorar silenciosamente esas restricciones, porque ningún camino cumple el requisito. Pero Vivado no las ignora, aunque el resultado no es lo que uno esperaría de forma natural: Vivado considera esta situación como «segmentación de caminos» (path segmentation) y emite un aviso crítico (critical warning) en respuesta. En la mayoría de los casos, usar esta funcionalidad no merece las complicaciones que causa. Consulta la documentación para más información.
Y aquí hay otra característica que puede inducir a error: Quartus tiene un comando llamado set_net_delay. Permite definir un retardo mínimo y máximo entre distintos elementos lógicos del diseño. Sin embargo, parece que las herramientas no intentan cumplir esos requisitos durante la implementación. En su lugar, es posible generar un informe con "report_net_delay" (o con la interfaz gráfica). Por tanto, se puede deducir de ese informe si se cumplieron las condiciones definidas con set_net_delay. Así que set_net_delay puede usarse para obtener información, pero no es útil como restricción de temporización. En otras palabras: set_max_delay y set_min_delay son eficaces como restricciones, pero set_net_delay no lo es.
En resumen, no hay mucho más allá del uso sencillo de set_max_delay y set_min_delay. Al parecer, la única característica interesante es el datapath_only de Vivado.
Orden de precedencia de las restricciones de temporización
El principal problema con las restricciones complicadas es que a menudo hay caminos afectados por más de una restricción. Estas restricciones suelen tener requisitos contradictorios para esos caminos. Entonces, ¿qué restricción gana?
Cada herramienta de FPGA tiene sus propias reglas para resolver conflictos de este tipo. Normalmente depende sobre todo del tipo de restricción. También pueden influir otros factores, en particular el grado de especificidad de la selección de caminos.
Para las restricciones basadas en SDC, la precedencia depende del tipo de restricción. Por ejemplo, Vivado resuelve un conflicto según este orden de precedencia. Los comandos se listan de mayor a menor precedencia:
- set_clock_groups (grupos de relojes relacionados y no relacionados)
- set_false_path (camino falso)
- set_min_delay y set_max_delay (retardos mínimos y máximos)
- set_multicycle_path (camino multicycle)
- create_clock (periodo de reloj)
Observa que los dos primeros comandos (set_clock_groups y set_false_path) crean caminos falsos y tienen la máxima prioridad. Por tanto, es especialmente importante verificar que ningún camino se vea afectado por error por esos comandos. Ese error apaga silenciosamente toda aplicación de requisitos de temporización sobre los caminos afectados.
Cuando se usa el mismo comando más de una vez para el mismo camino, gana el comando más específico. Por ejemplo, si un comando tiene "-from" y "-to", pero el segundo solo tiene "-from", gana el primero. Otro ejemplo: si un comando define los caminos basándose en elementos lógicos (por ejemplo, con get_cells), y el segundo los define basándose en relojes (con get_clocks), gana el primero.
Si dos comandos son tan similares que no hay diferencia de prioridad, el orden de aparición resuelve el conflicto: gana el último.
Quartus y otras herramientas basadas en SDC usan reglas de precedencia similares.
Pero sea cual sea la herramienta, lo mejor es evitar cualquier contradicción entre restricciones de temporización (salvo para anular create_clock). Las restricciones complicadas son el lugar donde pueden prosperar errores devastadores.
Con algunas herramientas de FPGA es posible sortear las reglas de prioridad: usando el atributo -reset_path, el comando que lo usa anula las excepciones de temporización anteriores en todos los caminos a los que se aplica. Por ejemplo:
set_max_delay -reset_path -from [get_cells source_reg] 2
Conclusión
He empezado esta página diciendo que las restricciones de temporización deberían ser cortas, sencillas y concisas. Al añadir excepciones de temporización, las restricciones no solo se hacen más largas, sino también más complicadas y difíciles de entender. Así que usa excepciones cuando sea necesario, pero escríbelas con cuidado y mantenlas ordenadas.
Intenta escribir los comandos de excepción de forma que reflejen su propósito y expresen la idea que hay detrás. Las herramientas de FPGA suelen ofrecer asistentes gráficos para crear restricciones de temporización. Pueden ser útiles como punto de partida. Pero no uses una restricción creada por un asistente sin pensarlo antes detenidamente. Aunque sea correcta cuando se crea, ¿seguirá funcionando fielmente cuando el diseño lógico evolucione y se añada lógica nueva?
Lee siempre los informes de temporización de los caminos afectados por una excepción. Si hay más de una restricción para un camino, esto es aún más importante. Crea también informes específicos para los caminos que puedan tener requisitos de temporización incorrectos.
Recuerda: crear y leer informes de temporización no es una pérdida de tiempo. Por mucho que leas la documentación con cuidado (lo cual es siempre buena idea), siempre hay posibilidades de error. En particular, pueden aparecer caminos falsos donde menos se espera.
Extra: ejemplos de informes de temporización
Para ayudar a entender set_min_delay y set_max_delay, aquí tienes algunos informes de temporización creados con Vivado.
Recuerda que el código Verilog que hay detrás de estos informes es:
always @(posedge clk)
y <= x;
Y las restricciones de temporización:
set_max_delay -from [get_cells x_reg] -to [get_cells y_reg] 3 set_min_delay -from [get_cells x_reg] -to [get_cells y_reg] 1
El informe para tsetup:
Slack (MET) : 0.360ns (required time - arrival time)
Source: x_reg/C
(rising edge-triggered cell FDRE clocked by clk {rise@0.000ns fall@2.000ns period=4.000ns})
Destination: y_reg/D
(rising edge-triggered cell FDRE clocked by clk {rise@0.000ns fall@2.000ns period=4.000ns})
Path Group: clk
Path Type: Setup (Max at Slow Process Corner)
Requirement: 3.000ns (MaxDelay Path 3.000ns)
Data Path Delay: 2.617ns (logic 0.139ns (5.311%) route 2.478ns (94.689%))
Logic Levels: 0
Clock Path Skew: -0.053ns (DCD - SCD + CPR)
Destination Clock Delay (DCD): 2.644ns
Source Clock Delay (SCD): 3.224ns
Clock Pessimism Removal (CPR): 0.527ns
Clock Uncertainty: 0.035ns ((TSJ^2 + TIJ^2)^1/2 + DJ) / 2 + PE
Total System Jitter (TSJ): 0.071ns
Total Input Jitter (TIJ): 0.000ns
Discrete Jitter (DJ): 0.000ns
Phase Error (PE): 0.000ns
Clock Net Delay (Source): 1.392ns (routing 0.002ns, distribution 1.390ns)
Clock Net Delay (Destination): 1.216ns (routing 0.002ns, distribution 1.214ns)
Timing Exception: MaxDelay Path 3.000ns
Location Delay type Incr(ns) Path(ns) Netlist Resource(s)
------------------------------------------------------------------- -------------------
(clock clk rise edge) 0.000 0.000 r
AG12 0.000 0.000 r clk (IN)
net (fo=0) 0.000 0.000 clk_IBUF_inst/I
AG12 INBUF (Prop_INBUF_HRIO_PAD_O)
0.738 0.738 r clk_IBUF_inst/INBUF_INST/O
net (fo=1, routed) 0.105 0.843 clk_IBUF_inst/OUT
AG12 IBUFCTRL (Prop_IBUFCTRL_HRIO_I_O)
0.049 0.892 r clk_IBUF_inst/IBUFCTRL_INST/O
net (fo=1, routed) 0.839 1.731 clk_IBUF
BUFGCE_X1Y0 BUFGCE (Prop_BUFCE_BUFGCE_I_O)
0.101 1.832 r clk_IBUF_BUFG_inst/O
X2Y0 (CLOCK_ROOT) net (fo=4, routed) 1.392 3.224 clk_IBUF_BUFG
SLICE_X49Y57 FDRE r x_reg/C
------------------------------------------------------------------- -------------------
SLICE_X49Y57 FDRE (Prop_DFF_SLICEL_C_Q)
0.139 3.363 r x_reg/Q
net (fo=2, routed) 2.478 5.841 x
SLICE_X49Y57 FDRE r y_reg/D
------------------------------------------------------------------- -------------------
max delay 3.000 3.000
AG12 0.000 3.000 r clk (IN)
net (fo=0) 0.000 3.000 clk_IBUF_inst/I
AG12 INBUF (Prop_INBUF_HRIO_PAD_O)
0.515 3.515 r clk_IBUF_inst/INBUF_INST/O
net (fo=1, routed) 0.066 3.581 clk_IBUF_inst/OUT
AG12 IBUFCTRL (Prop_IBUFCTRL_HRIO_I_O)
0.034 3.615 r clk_IBUF_inst/IBUFCTRL_INST/O
net (fo=1, routed) 0.722 4.337 clk_IBUF
BUFGCE_X1Y0 BUFGCE (Prop_BUFCE_BUFGCE_I_O)
0.091 4.428 r clk_IBUF_BUFG_inst/O
X2Y0 (CLOCK_ROOT) net (fo=4, routed) 1.216 5.644 clk_IBUF_BUFG
SLICE_X49Y57 FDRE r y_reg/C
clock pessimism 0.527 6.171
clock uncertainty -0.035 6.136
SLICE_X49Y57 FDRE (Setup_EFF2_SLICEL_C_D)
0.065 6.201 y_reg
-------------------------------------------------------------------
required time 6.201
arrival time -5.841
-------------------------------------------------------------------
slack 0.360
Observa que el valor del retardo (3 ns) se usa como tiempo de inicio para el camino del reloj del segundo flip-flop. En otras palabras, es exactamente como si hubiera una restricción de periodo de 3 ns.
Observa también que la red del camino de datos tiene un retardo enorme: 2,478 ns. Es el resultado del comando set_min_delay: las herramientas se ven obligadas a insertar un retardo largo en esa red para cumplir el requisito de thold.
Hablando de lo cual, este es el informe de temporización para thold:
Slack (MET) : 0.057ns (arrival time - required time)
Source: x_reg/C
(rising edge-triggered cell FDRE clocked by clk {rise@0.000ns fall@2.000ns period=4.000ns})
Destination: y_reg/D
(rising edge-triggered cell FDRE clocked by clk {rise@0.000ns fall@2.000ns period=4.000ns})
Path Group: clk
Path Type: Hold (Min at Fast Process Corner)
Requirement: 1.000ns (MinDelay Path 1.000ns)
Data Path Delay: 1.141ns (logic 0.049ns (4.294%) route 1.092ns (95.706%))
Logic Levels: 0
Clock Path Skew: 0.029ns (DCD - SCD - CPR)
Destination Clock Delay (DCD): 1.684ns
Source Clock Delay (SCD): 1.258ns
Clock Pessimism Removal (CPR): 0.398ns
Clock Net Delay (Source): 0.502ns (routing 0.002ns, distribution 0.500ns)
Clock Net Delay (Destination): 0.585ns (routing 0.002ns, distribution 0.583ns)
Timing Exception: MinDelay Path 1.000ns
Location Delay type Incr(ns) Path(ns) Netlist Resource(s)
------------------------------------------------------------------- -------------------
(clock clk rise edge) 0.000 0.000 r
AG12 0.000 0.000 r clk (IN)
net (fo=0) 0.000 0.000 clk_IBUF_inst/I
AG12 INBUF (Prop_INBUF_HRIO_PAD_O)
0.339 0.339 r clk_IBUF_inst/INBUF_INST/O
net (fo=1, routed) 0.025 0.364 clk_IBUF_inst/OUT
AG12 IBUFCTRL (Prop_IBUFCTRL_HRIO_I_O)
0.015 0.379 r clk_IBUF_inst/IBUFCTRL_INST/O
net (fo=1, routed) 0.350 0.729 clk_IBUF
BUFGCE_X1Y0 BUFGCE (Prop_BUFCE_BUFGCE_I_O)
0.027 0.756 r clk_IBUF_BUFG_inst/O
X2Y0 (CLOCK_ROOT) net (fo=4, routed) 0.502 1.258 clk_IBUF_BUFG
SLICE_X49Y57 FDRE r x_reg/C
------------------------------------------------------------------- -------------------
SLICE_X49Y57 FDRE (Prop_DFF_SLICEL_C_Q)
0.049 1.307 r x_reg/Q
net (fo=2, routed) 1.092 2.399 x
SLICE_X49Y57 FDRE r y_reg/D
------------------------------------------------------------------- -------------------
min delay 1.000 1.000
AG12 0.000 1.000 r clk (IN)
net (fo=0) 0.000 1.000 clk_IBUF_inst/I
AG12 INBUF (Prop_INBUF_HRIO_PAD_O)
0.595 1.595 r clk_IBUF_inst/INBUF_INST/O
net (fo=1, routed) 0.042 1.637 clk_IBUF_inst/OUT
AG12 IBUFCTRL (Prop_IBUFCTRL_HRIO_I_O)
0.022 1.659 r clk_IBUF_inst/IBUFCTRL_INST/O
net (fo=1, routed) 0.409 2.068 clk_IBUF
BUFGCE_X1Y0 BUFGCE (Prop_BUFCE_BUFGCE_I_O)
0.031 2.099 r clk_IBUF_BUFG_inst/O
X2Y0 (CLOCK_ROOT) net (fo=4, routed) 0.585 2.684 clk_IBUF_BUFG
SLICE_X49Y57 FDRE r y_reg/C
clock pessimism -0.398 2.286
SLICE_X49Y57 FDRE (Hold_EFF2_SLICEL_C_D)
0.055 2.341 y_reg
-------------------------------------------------------------------
required time -2.341
arrival time 2.399
-------------------------------------------------------------------
slack 0.057
Una vez más, observa que el valor del retardo (1 ns) se usa como tiempo de inicio para el camino del reloj del segundo flip-flop. Cuando no hay ningún comando set_min_delay (es decir, solo hay una restricción de periodo), ese valor es 0 ns.
El retardo de la red en el camino de datos es de 1,092 ns. Es justo lo necesario para cumplir el requisito de thold. ¿Por qué antes era de 2,478 ns? Porque el cálculo en el peor caso para tsetup se hizo en la condición «Max at Slow Process Corner». Así que 2,478 ns es el retardo más largo posible de esa red, y 1,092 ns es el más corto posible («Min at Fast Process Corner»). Consulta la discusión sobre el análisis de tiempos multi-corner para más información.
El tercer ejemplo demuestra datapath_only, así que la restricción es:
set_max_delay -datapath_only -from [get_cells x_reg] -to [get_cells y_reg] 3
No hay ningún set_min_delay, porque de todos modos se ignora (aunque se escriba después del comando set_max_delay).
El informe para tsetup queda ahora así:
Slack (MET) : 2.482ns (required time - arrival time)
Source: x_reg/C
(rising edge-triggered cell FDRE clocked by clk {rise@0.000ns fall@2.000ns period=4.000ns})
Destination: y_reg/D
(rising edge-triggered cell FDRE clocked by clk {rise@0.000ns fall@2.000ns period=4.000ns})
Path Group: clk
Path Type: Setup (Max at Slow Process Corner)
Requirement: 3.000ns (MaxDelay Path 3.000ns)
Data Path Delay: 0.583ns (logic 0.139ns (23.842%) route 0.444ns (76.158%))
Logic Levels: 0
Timing Exception: MaxDelay Path 3.000ns -datapath_only
Location Delay type Incr(ns) Path(ns) Netlist Resource(s)
------------------------------------------------------------------- -------------------
SLICE_X49Y57 0.000 0.000 r x_reg/C
SLICE_X49Y57 FDRE (Prop_DFF_SLICEL_C_Q)
0.139 0.139 r x_reg/Q
net (fo=2, routed) 0.444 0.583 x
SLICE_X49Y57 FDRE r y_reg/D
------------------------------------------------------------------- -------------------
max delay 3.000 3.000
SLICE_X49Y57 FDRE (Setup_EFF2_SLICEL_C_D)
0.065 3.065 y_reg
-------------------------------------------------------------------
required time 3.065
arrival time -0.583
-------------------------------------------------------------------
slack 2.482
Observa que la estructura de este informe es como la anterior, pero se ha eliminado todo lo relacionado con los caminos del reloj.
El retardo de la red es pequeño, porque las herramientas no tenían motivo para insertar un retardo largo: no hay ningún requisito de thold.
Y no muestro el informe para thold, porque no hay ningún requisito de temporización (el retardo mínimo se trata como un camino falso).
Con esto concluye la discusión general sobre las excepciones de temporización. La página siguiente continúa con las excepciones de temporización necesarias para los cruces de dominios de reloj (clock domain crossing).