01signal.com

Exceptions de timing

Cette page fait partie d’une série de pages consacrée au timing. Les pages précédentes ont expliqué la théorie derrière les calculs de timing, abordé la contrainte de période d’horloge, présenté les principes de la convergence temporelle (timing closure) et introduit quelques commandes Tcl importantes. Cette page explique comment définir des contraintes temporelles pour des chemins spécifiques.

Introduction

L’objectif lors de l’écriture des contraintes temporelles (timing constraints) est qu’elles soient courtes, concises et faciles à comprendre. Cela réduit le risque de confusion et d’erreurs. Si possible, les contraintes temporelles pour les chemins internes du FPGA ne devraient comporter que deux types : les contraintes de période d’horloge (par exemple create_clock) et les contraintes de groupes d’horloges (par exemple set_clock_groups).

Mais souvent, des chemins spécifiques nécessitent des règles spécifiques. Ces règles spécifiques sont appelées exceptions de timing. Comme leur nom l’indique, ces contraintes temporelles sont principalement destinées à remplacer les contraintes temporelles existantes. Elles peuvent aussi servir à définir des exigences de timing pour des chemins qui n’en auraient sinon aucune.

Les commandes servant à cela dans la syntaxe SDC sont principalement celles-ci :

Les outils qui utilisent une syntaxe différente ont probablement des commandes similaires.

Les arguments de ces commandes définissent (entre autres) quels chemins doivent être concernés. Ceci est expliqué plus bas.

Deux sujets connexes sont traités sur d’autres pages :

Les chemins faux (false paths)

Un chemin faux (false path) est un chemin que les outils ignorent à la suite d’une contrainte temporelle qui le demande. Autrement dit, les outils n’appliquent délibérément aucune exigence de timing à un chemin faux, parce que c’est ce qu’on leur a demandé.

Il ne faut pas confondre cela avec les chemins non contraints : ce sont des chemins pour lesquels les outils ne disposent d’aucune contrainte temporelle. Tout comme pour les chemins faux, les outils n’appliquent aucune exigence de timing à ces chemins, mais la raison est différente : cette absence d’application n’est pas un choix, mais le fait que les outils ne savent pas quelle exigence appliquer.

Il ne devrait y avoir aucun chemin non contraint dans un design FPGA. Cela dit, il existe souvent des chemins que nous souhaitons voir ignorés par les outils. Ces chemins doivent être marqués comme chemins faux au moyen de contraintes temporelles. La logique est la suivante : lorsque nous lisons le rapport de timing, nous devrions toujours constater que le nombre de chemins non contraints est nul. Si ce nombre n’est pas nul, il faut chercher une erreur. Si nous nous habituons à accepter un nombre non nul de chemins non contraints, il devient plus facile de laisser passer des problèmes de contraintes temporelles.

Il y a donc deux raisons possibles de déclarer des chemins faux :

En pratique, peu importe lequel de ces scénarios s’applique. Si aucune exigence de timing n’est nécessaire sur un chemin, il doit être déclaré comme chemin faux.

C’est une erreur fréquente d’utiliser set_false_path en rapport avec les changements de domaine d’horloge (clock domain crossing). Ce sujet est traité plus en détail plus loin. En réalité, il n’y a pas beaucoup de situations où il est correct d’utiliser set_false_path, si ce n’est avec les ports d’entrées-sorties.

Sélection des chemins pour set_false_path

Il existe de nombreuses manières de sélectionner les chemins auxquels la commande s’applique. Malgré la grande variété des possibilités, la sélection se fait généralement à l’aide de deux arguments : -from et -to. Par exemple :

set_false_path -from [get_cells source_reg] -to [get_cells dest_reg]

Dans cet exemple, la commande set_false_path s’applique au chemin qui commence au registre @source et se termine au registre @dest.

Notez que get_cells fournit pour -from et -to des objets qui représentent des éléments logiques. Les autres commandes évoquées sur la page précédente peuvent aussi être utilisées : get_pins, get_nets, get_ports et get_clocks. Cependant, chaque outil FPGA a ses propres règles quant à ce qui est acceptable pour -from et pour -to.

Sachez que les outils peuvent ne pas interpréter la référence à des objets comme on pourrait naturellement s’y attendre. Ils peuvent aussi ignorer une partie ou la totalité des objets sans émettre d’avertissement. En fait, si aucun objet n’est trouvé par la commande get_* (par exemple à cause d’une erreur dans le motif de recherche), aucun chemin n’est inclus dans l’exception de timing. Cela peut même se produire sans le moindre avertissement.

Il est donc important d’utiliser le rapport de timing pour vérifier que les exceptions de timing sont appliquées comme prévu. Cela signifie que les bons chemins sont concernés et que l’analyse de timing remplit exactement son rôle (aucune application d’exigence de timing).

Il existe un autre argument utile pour sélectionner des chemins : -through. Comme son nom l’indique, cet argument sélectionne les chemins qui passent par les éléments logiques indiqués.

Il vaut la peine de prendre le temps de lire la documentation officielle afin de connaître toutes les possibilités. Par exemple, il est aussi possible de limiter l’effet de la commande aux seuls fronts montants ou descendants de l’horloge. Une autre possibilité est de limiter la commande à l’analyse du seul tsu ou du seul thold.

La commande set_false_path exige au moins un des arguments -from, -to ou -through (ou un autre argument de sens équivalent). Lorsqu’il y a plus d’un argument, l’exception de timing ne s’applique qu’aux chemins qui satisfont aux conditions de tous les arguments.

Le danger de set_false_path

Le problème des chemins faux est la facilité avec laquelle on peut faire des erreurs. En particulier, il y a un risque d’inclure plus de chemins que prévu. Lorsque cela arrive, certains éléments séquentiels peuvent ne pas fonctionner correctement : nous croyons à tort que les outils garantissent leurs exigences de tsu et de thold. En réalité, les outils se comportent comme si les chemins menant à ces éléments séquentiels étaient des chemins faux. Ils ne prennent donc pas la peine de faire une analyse de timing pour eux. C’est une situation dangereuse, car elle donne l’illusion que tout va bien lorsque les outils annoncent que les contraintes temporelles sont respectées. En réalité, des bascules et d’autres éléments séquentiels sont exposés à des violations de timing sans aucune protection.

Pour aggraver les choses, si un chemin est déclaré comme chemin faux, cette déclaration a en général la plus haute priorité. Si un chemin est accidentellement déclaré comme chemin faux, cela outrepassera probablement toute autre contrainte demandant le contraire. C’est généralement vrai même si set_false_path apparaît avant l’autre contrainte. set_false_path est donc interprété comme « ce sont des chemins faux, quoi que j’aie exigé avant ou exigerai après ».

set_min_delay et set_max_delay

J’ai commencé par les chemins faux, qui suppriment les exigences de timing pour un groupe de chemins sélectionnés. Il arrive souvent que l’on ait besoin de définir des exigences de timing plutôt que de les annuler. C’est le rôle de set_min_delay et de set_max_delay. Par exemple, considérons ce code Verilog :

reg x, y;

always @(posedge clk)
  y <= x;

Et les contraintes temporelles :

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

Quelle est donc la signification de ces commandes ? Commençons par set_max_delay. L’explication courte de cette exception de timing est qu’elle ressemble à une contrainte de période d’horloge (create_clock) destinée uniquement à certains chemins.

Rappelons que lorsqu’une contrainte de période d’horloge est définie, les outils appliquent automatiquement les exigences de timing nécessaires : les délais maximaux des chemins concernés sont limités afin de satisfaire la condition sur tsu. De même, les délais minimaux sont limités au titre de thold.

Dans l’exemple ci-dessus, la valeur qui apparaît dans la commande set_max_delay est 3. Elle équivaut à une commande create_clock pour une période de 3 ns. Mais l’influence de set_max_delay est limitée à un groupe précis de chemins : c’est là toute la différence.

Quant à set_min_delay, c’est un peu plus compliqué ; nous y reviendrons plus bas.

Notez que le nom de la commande set_max_delay est trompeur : cette commande ne définit pas directement le délai maximal du chemin lui-même. Le délai des chemins concernés n’est pas limité à 3 ns par la commande de l’exemple ci-dessus. La valeur de 3 ns est appliquée comme différence de temps autorisée entre les fronts d’horloge. Et cette différence n’est pas mesurée aux entrées d’horloge des éléments synchrones, mais plutôt à l’origine de ces horloges. Cela signifie que les délais des PLL, des buffers d’horloge et du routage d’horloge sont inclus dans les calculs : comme pour une contrainte de période, les délais d’horloge sont pris en compte dans l’analyse.

Le sens de -from, -to, -through et des autres arguments est le même que pour set_false_path. Mais d’une manière générale, set_min_delay et set_max_delay sont conçus comme des ajustements d’une contrainte de période d’horloge. Il est donc généralement supposé qu’il y a des éléments séquentiels des deux côtés du chemin. Par conséquent, -from et -to doivent représenter des éléments synchrones. Il existe de nombreuses manières de les désigner : un objet cellule représentant l’élément synchrone lui-même, un objet d’horloge, etc.

En ce qui concerne set_min_delay, l’histoire est analogue : une autre conséquence d’une contrainte de période est que les outils doivent respecter les exigences de thold. À cette fin, les outils imposent des délais minimaux sur tous les chemins entre la même horloge ou entre des horloges liées (related clocks). Si le calcul de timing d’un chemin n’est dû qu’à create_clock (avec la même horloge des deux côtés), cela équivaut à un set_min_delay de valeur zéro. Cela traduit l’idée que le même front d’horloge arrive aux deux éléments séquentiels. Cela ne signifie pas pour autant que ce front arrive en même temps sur ces éléments. Le front de chaque élément séquentiel part au même instant de l’origine de l’horloge. Le délai entre chaque origine et l’élément séquentiel est pris en compte dans le calcul (comme c’est le cas pour tsu).

set_min_delay permet d’ajuster l’instant du front d’horloge qui arrive au second élément séquentiel. Par exemple, la commande ci-dessus fait arriver ce front 1 ns plus tard sur la seconde bascule. Cela rend l’exigence de thold plus difficile à satisfaire : voir l’exemple de rapport plus bas.

Il y a deux raisons possibles d’utiliser set_min_delay et set_max_delay :

Lorsque ces deux commandes sont utilisées, vérifiez toujours attentivement l’analyse de timing des chemins dans les rapports de timing. Accordez une attention particulière au rôle que joue le chemin d’horloge dans le calcul.

Des exemples de rapports de timing figurent en bas de cette page ; ils montrent les résultats de set_min_delay et de set_max_delay.

Un contrôle plus précis du délai

Le niveau de contrôle offert par set_max_delay et set_min_delay n’est guère meilleur que celui d’une contrainte de période d’horloge (telle que présentée jusqu’ici). Mais que faire si l’on ne veut pas que le délai du chemin d’horloge interfère avec notre définition du délai ? Que faire si l’on veut contrôler le délai d’un segment précis du chemin ?

Certains outils FPGA n’apportent aucune solution à ces besoins. Quartus, par exemple, n’offre pas une telle possibilité (à ma connaissance). Vivado, en revanche, possède quelques fonctionnalités que je vais décrire brièvement.

L’une de ces fonctionnalités est l’option datapath_only : on souhaite parfois utiliser set_max_delay de manière à ce que le calcul de timing n’inclue pas les chemins d’horloge. Par exemple, si un chemin se trouve entre des horloges non liées (unrelated clocks), il n’a pas de sens de prendre les chemins d’horloge en compte.

Lorsque datapath_only est utilisé, le calcul se fait comme si le délai du chemin d’horloge des deux éléments synchrones était nul. Le calcul ne comporte donc que les délais des éléments logiques du chemin. La somme de ces délais doit être inférieure au nombre donné dans la commande set_max_delay (voir exemple de rapport plus bas).

Ainsi, lorsque set_max_delay est employé avec datapath_only, son sens se rapproche de ce que son nom laisse entendre. Notez cependant que le chemin doit toujours commencer et se terminer sur un élément synchrone.

En outre, datapath_only a quelques particularités : s’il est utilisé, les outils n’appliquent aucune exigence de timing concernant le thold des chemins concernés. Autrement dit, les outils se comportent comme s’il existait une contrainte de chemin faux appliquée uniquement au scénario de thold. Même si une commande set_min_delay est ajoutée pour les chemins concernés, cette commande est ignorée. On ne voit pas clairement pourquoi Vivado refuse d’imposer un délai minimal sur les chemins affectés par datapath_only.

datapath_only ne peut en aucun cas être utilisé comme argument de set_min_delay.

Des fonctionnalités trompeuses

Comme le titre de cette section l’indique, voici quelques possibilités qui ne feront vraisemblablement aucun bien. N’hésitez pas à passer directement à la section suivante.

Vivado permet un niveau de contrôle encore plus fin : il est possible d’imposer des restrictions sur le délai d’un segment précis d’un chemin. Par exemple, que se passe-t-il si l’on utilise avec -from et -to des éléments logiques qui ne sont pas des éléments séquentiels ? Et avec des broches (pins) ou des fils (nets) ? Que feront alors set_min_delay et set_max_delay ?

Cela dépend bien entendu de l’outil FPGA utilisé. Les outils peuvent ignorer silencieusement de telles contraintes, car aucun chemin ne correspond à l’exigence. Mais Vivado ne les ignore pas, bien que le résultat ne soit pas celui que l’on pourrait naturellement attendre : Vivado considère cette situation comme une « segmentation de chemin » et émet en réponse un avertissement critique (critical warning). Dans la plupart des cas, l’utilisation de cette fonctionnalité ne vaut pas la peine des complications qu’elle entraîne. Reportez-vous à la documentation pour en savoir plus.

Et voici une autre fonctionnalité qui peut être trompeuse : Quartus possède une commande appelée set_net_delay. Elle permet de définir un délai minimal et maximal entre différents éléments logiques du design. Il semble cependant que les outils ne cherchent pas à respecter ces exigences de timing pendant l’implémentation. Il est en revanche possible de générer un rapport avec « report_net_delay » (ou avec l’interface graphique). On peut donc déduire de ce rapport si les conditions définies par set_net_delay ont été satisfaites. set_net_delay peut donc servir à obtenir des informations, mais n’est pas utile comme contrainte temporelle. Autrement dit : set_max_delay et set_min_delay sont efficaces en tant que contraintes temporelles, mais set_net_delay ne l’est pas.

En résumé, on ne fait guère mieux que l’utilisation classique de set_max_delay et set_min_delay. Apparemment, la seule fonctionnalité intéressante est datapath_only de Vivado.

Ordre de priorité des contraintes temporelles

Le principal problème des contraintes temporelles complexes est qu’il existe souvent des chemins affectés par plusieurs contraintes à la fois. Ces contraintes ont en général des exigences contradictoires pour ces chemins. Alors, quelle contrainte l’emporte ?

Chaque outil FPGA possède ses propres règles pour résoudre ce type de conflit. Cela dépend en général principalement du type de la contrainte. D’autres facteurs peuvent aussi entrer en jeu, en particulier la spécificité de la sélection des chemins.

Pour les contraintes temporelles fondées sur SDC, la priorité dépend du type de contrainte. Vivado, par exemple, résout les conflits selon cet ordre de priorité, du plus prioritaire au moins prioritaire :

Notez que les deux premières commandes (set_clock_groups et set_false_path) créent des chemins faux et possèdent la plus haute priorité. Il est donc d’autant plus important de vérifier qu’aucun chemin n’est affecté par erreur par ces commandes. Une telle erreur désactive silencieusement toute application d’exigences de timing sur les chemins concernés.

Lorsque la même commande est utilisée plusieurs fois pour le même chemin, la plus spécifique l’emporte. Par exemple, si une commande comporte « -from » et « -to », alors que la seconde n’a que « -from », la première l’emporte. Autre exemple : si une commande définit les chemins d’après des éléments logiques (par exemple avec get_cells), et que la seconde les définit d’après des horloges (avec get_clocks), la première l’emporte.

Si deux commandes sont si semblables qu’aucune différence de priorité ne les départage, l’ordre d’apparition résout le conflit : c’est la dernière commande qui l’emporte.

Des règles de priorité analogues sont utilisées par Quartus et d’autres outils fondés sur SDC.

Mais quel que soit l’outil utilisé, le mieux est d’éviter toute contradiction entre les contraintes temporelles (sauf lorsqu’il s’agit d’outrepasser create_clock). Les contraintes temporelles compliquées sont le terrain de prédilection des bogues dévastateurs.

Avec certains outils FPGA, il est possible de contourner les règles de priorité : en utilisant l’attribut -reset_path, la commande qui l’emploie supplante les exceptions de timing précédentes sur tous les chemins auxquels elle s’applique. Par exemple :

set_max_delay -reset_path -from [get_cells source_reg] 2

Conclusion

J’ai commencé cette page en disant que les contraintes temporelles devaient être courtes, simples et concises. En ajoutant des exceptions de timing, elles deviennent non seulement plus longues, mais aussi plus compliquées et plus difficiles à comprendre. Utilisez donc les exceptions de timing lorsque c’est nécessaire, mais écrivez-les avec soin et gardez-les propres.

Essayez d’écrire les commandes d’exception de timing d’une manière qui reflète leur but et exprime l’idée qui les sous-tend. Les outils FPGA proposent généralement des assistants graphiques pour créer des contraintes temporelles. Ils peuvent servir de point de départ. Mais n’utilisez pas une contrainte créée par un assistant sans y avoir mûrement réfléchi. Même si cette contrainte est correcte au moment de sa création, continuera-t-elle à fonctionner fidèlement lorsque la conception logique évoluera et que de la nouvelle logique sera ajoutée ?

Lisez toujours les rapports de timing des chemins affectés par une exception de timing. S’il y a plusieurs contraintes temporelles pour un même chemin, cela est encore plus important. Créez aussi des rapports de timing spécifiques pour les chemins susceptibles de recevoir des exigences incorrectes.

Rappelez-vous : créer et lire des rapports de timing n’est pas une perte de temps. Quelle que soit la prudence avec laquelle vous lisez la documentation (ce qui est toujours une bonne idée), il y a toujours un risque d’erreur. En particulier, les chemins faux peuvent apparaître là où on les attend le moins.

Bonus : exemples de rapports de timing

Pour aider à comprendre set_min_delay et set_max_delay, voici quelques rapports de timing créés avec Vivado.

Rappelons que le code Verilog derrière ces rapports est :

always @(posedge clk)
  y <= x;

Et les contraintes temporelles :

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

Le rapport pour 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

Notez que la valeur du délai (3 ns) est utilisée comme instant de départ du chemin d’horloge de la seconde bascule. Autrement dit, c’est exactement comme s’il existait une contrainte de période de 3 ns.

Notez aussi que le fil du chemin de données a un énorme délai : 2,478 ns. C’est le résultat de la commande set_min_delay : les outils sont obligés d’insérer un long délai sur ce fil pour satisfaire l’exigence de thold.

À ce propos, voici le rapport de timing pour 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

Encore une fois, la valeur du délai (1 ns) est utilisée comme instant de départ du chemin d’horloge de la seconde bascule. En l’absence de commande set_min_delay (c’est-à-dire avec une simple contrainte de période), cette valeur est 0 ns.

Le délai du fil du chemin de données est de 1,092 ns : il suffit tout juste à satisfaire l’exigence de thold. Pourquoi était-il de 2,478 ns auparavant ? Parce que le calcul du pire cas pour tsetup a été fait pour « Max at Slow Process Corner ». 2,478 ns est donc le délai le plus long possible pour ce fil, et 1,092 ns est le délai le plus court possible (« Min at Fast Process Corner »). Voir la discussion sur l’analyse de timing multi-corner pour plus de détails.

Le troisième exemple illustre datapath_only ; la contrainte est donc :

set_max_delay -datapath_only -from [get_cells x_reg] -to [get_cells y_reg] 3

Il n’y a pas de set_min_delay, car il serait de toute façon ignoré (même s’il était écrit après la commande set_max_delay).

Le rapport pour tsetup est maintenant :

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

Notez que la structure de ce rapport de timing est identique à la précédente, mais que tout ce qui concerne les chemins d’horloge a été supprimé.

Le délai du fil est faible, car les outils n’avaient aucune raison d’insérer un long délai : il n’y a pas d’exigence de thold.

Et je ne montre pas le rapport de timing pour thold, car il n’y a pas d’exigence de timing (le délai minimal est traité comme un chemin faux).


Ceci conclut la discussion générale sur les exceptions de timing. La page suivante poursuit avec les exceptions de timing nécessaires pour un changement de domaine d’horloge.

Cette page a été traduite de l’anglais par une machine. En cas de doute, veuillez vous reporter au texte original
Copyright © 2021-2026. All rights reserved. (dcc38493)