| 8 | | = 1 Objectif = |
| 9 | | |
| 10 | | Nous avons vu dans le TP6 comment dessiner une cellule précaractérisée respectant |
| 11 | | le gabarit de le bibliothèque '''SXLIB'''. |
| 12 | | Le but de ce TP7 est de réaliser le dessin des masques d'un bloc combinatoire |
| 13 | | résultant de l'intreconnexion d'une quinzaine de cellules de la biblioyhèque '''SXLIB'''. |
| 14 | | |
| 15 | | On va donc effectuer ''à la main'' (c'est à dire en utilisant l'éditeur interactif '''graal'''), |
| 16 | | le placement et le routage de cet opérateur, pour mieux comprendre les problèmes |
| 17 | | que doivent résoudre les outils de placement/routage automatiques. |
| 18 | | |
| 19 | | = 2 Spécification fonctionnelle = |
| 20 | | |
| 21 | | On souhaite réaliser le décodeur 3 vers 4 tel que décrit ci-dessous. |
| 22 | | |
| 23 | | [[Image(compteur.jpg,nolink)]] |
| 24 | | |
| 25 | | La sortie Zi prend la valeur 1 quand le nombre de bits d'entrée ayant la valeur 1 est |
| 26 | | égal à i. Les 3 autres sorties prennent la valeur 0. |
| 27 | | |
| 28 | | Les équations sont les suivantes: |
| 29 | | * Z0=/A./B/./C |
| 30 | | |
| 31 | | * Z1=(A./B./C)+(/A.B./C)+(/A./B/.C) |
| 32 | | |
| 33 | | * Z2= (A.B./C) +(A./B.C)+ (/A.B.C) |
| 34 | | |
| 35 | | * Z3=A.B.C |
| 36 | | |
| 37 | | De ces équations , on déduit le schéma en portes logiques inverseuses |
| 38 | | [[Image(schema.jpg,nolink)]] |
| 39 | | |
| 40 | | Le bloc à réaliser contient donc 10 portes NAND3 et 5 inverseurs. Regardons |
| 41 | | plus précisément les caractéristiques de chaque cellule : |
| 42 | | |
| 43 | | * La cellule na3_x1 a une largeur de 5 pitchs. |
| 44 | | Les 3 signaux d'entrée E1, E2 et E3 sont accessibles |
| 45 | | sur 6 pistes de routage. |
| 46 | | Le signal de sortie S est accessible sur 7 pistes de |
| 47 | | routage. |
| 48 | | [[Image(nand3.jpg,nolink)]] |
| 49 | | * La cellule inv_x1 a une largeur de 3 pitchs. |
| 50 | | Le signal d'entrée E est accessible sur 6 pistes de |
| 51 | | routage. Le signal de sortie S est accessible sur 7 pistes de |
| 52 | | routage. |
| 53 | | |
| 54 | | [[Image(tp3.jpg,nolink)]] |
| 55 | | |
| 56 | | On propose le placement ci-dessous pour cet opérateur, mais vous pouvez |
| 57 | | choisir un autre placement si vous le souhaitez : |
| 58 | | |
| 59 | | [[Image(place.jpg,nolink)]] |
| 60 | | |
| 61 | | Le dessin ci-dessous illustre un routage partiel correspondant à quelques signaux |
| 62 | | et utilisant des fils de Metal2 , Metal3, ainsi que des via12 et des vias23. |
| 63 | | |
| 64 | | [[Image(routage.jpg,nolink)]] |
| 65 | | |
| 66 | | = 3 Saisie du schéma = |
| 67 | | |
| 68 | | Utiliser le langage '''STRATUS''' pour décrire le schéma proposé ci dessus, et générer le fichier |
| 69 | | ''decodeur.vst'' correspondant à la description structurelle VHDL de cet opérateur. |
| 70 | | Valider ce schéma en écrivant quelques stimuli, et en simulant sous '''asimut'''. |
| 71 | | |
| 72 | | |
| 73 | | = 4 Placement / Routage = |
| 74 | | |
| 75 | | Saisir sous '''graal''' le dessin du bloc ''decoder'' en instanciant les 5 portes inv_x1 et |
| 76 | | les 10 portes na3_x1. |
| 77 | | Dessiner les fils de routage sous '''graal''', et utiliser la commande ''equi'' pour vérifier |
| 78 | | la connectivité de chacun des signaux. |
| 79 | | |
| 80 | | Vérifier l'absence de violation des règles de dessin |
| 81 | | en lançant la commande ''druc'' sous '''graal'''. |
| 82 | | Pour que cette vérification soit significative, il faut préalablement "mettre à plat" |
| 83 | | le bloc ''decoder'', en utilisant la commande ''real flat''. |
| 84 | | |
| 85 | | = 5 Validation du routage = |
| 86 | | |
| 87 | | Extraire la netlist du bloc ''decoder'' au format .al avec l'outil '''cougar''', |
| 88 | | mais sans descendre au niveau des transistors : On veut obtenir une ''net-list'' de cellules, |
| 89 | | et non une ''net-list'' de transistors. |
| 90 | | |
| 91 | | Vérifier que les deux net-lists définies par les fichiers decoder.vst et ''decoder.al'' sont isomorphes |
| 92 | | en utilisant l'outil '''lvx'''. |
| 93 | | |
| | 9 | = 1 Objectif = |
| | 10 | |
| | 11 | Le but de ce TP est d'utiliser les outils de placement / routage automatique du flot Coriolis/Alliance ainsi que tous les outils de vérification vus dans les TPs précédents, pour générer le dessin des masques du circuit AM2901. |
| | 12 | |
| | 13 | Le TP4 vous a permis d'utiliser le langage '''Stratus''' pour décrire la netlist hiérarchique du circuit AM2901. |
| | 14 | |
| | 15 | On va maintenant utiliser le langage '''Stratus''' pour introduire des directives de placement dans les différents fichiers ''.py'' décrivant la netlist. |
| | 16 | |
| | 17 | Il est par exemple possible d'exploiter la régularité des opérateurs du chemin de données pour imposer un placement en colonnes : tous les bits d'un même opérateur sont placés en colonne, et il est possible d'imposer un placement relatifn des colonnes les unes par rapport aux autres. |
| | 18 | On va également définir le placement des plots d'entrée/sortie sur la périphérie du circuit. |
| | 19 | |
| | 20 | Par ailleurs, on va également utiliser '''Stratus''' pour effectuer le routage de certains signaux particuliers comme les alimentations Vdd et Vss. |
| | 21 | |
| | 22 | Le routage final sera effectué par l'outil '''nero'''. |
| | 23 | |
| | 24 | Vous utiliserez aussi '''cougar''' pour obtenir une netlist extraite, et '''lvx''', pour comparer la netlist extraite à la netlist initiale. |
| | 25 | |
| | 26 | Vous utiliserez conjointement les cellules de la bibliothèque '''SXLIB''' et les macro-cellules génériques de la bibliothèque '''DP_SXLIB'''. |
| | 27 | |
| | 28 | = 2 Variables d'environnement = |
| | 29 | |
| | 30 | Vous devez positionner les variables d'environnement suivantes : |
| | 31 | |
| | 32 | {{{ |
| | 33 | > export VH_MAXERR=10 |
| | 34 | > export MBK_WORK_LIB=. |
| | 35 | > export MBK_CATA_LIB=$ALLIANCE_TOP/cells/sxlib |
| | 36 | > export MBK_CATA_LIB=$MBK_CATA_LIB :$ALLIANCE_TOP/cells/dp_sxlib |
| | 37 | > export MBK_CATA_LIB=$MBK_CATA_LIB :$ALLIANCE_TOP/cells/pxlib |
| | 38 | > export MBK_CATA_LIB=$MBK_CATA_LIB :. |
| | 39 | > export MBK_CATAL_NAME=CATAL |
| | 40 | > export MBK_IN_LO=vst |
| | 41 | > export MBK_OUT_LO=vst |
| | 42 | > export MBK_IN_PH=ap |
| | 43 | > export MBK_OUT_PH=ap |
| | 44 | > export CRL_OUT_LO=vst |
| | 45 | > export CRL_OUT_PH=ap |
| | 46 | > export PYTHONPATH=/opt/coriolis/lib/python2.3/site-packages/stratus |
| | 47 | > export PYTHONPATH=/opt/coriolis/lib/python2.3/site-packages/isobar :$PYTHONPATH |
| | 48 | > export PYTHONPATH=/opt/coriolis/lib/python2.3/site-packages :$PYTHONPATH |
| | 49 | }}} |
| | 50 | |
| | 51 | NB : Ces variables d'environnement sont positionnées par défaut, mais il est utile de les vérifier. |
| | 52 | |
| | 53 | D'une manière générale, les fichiers décrivant une netlist logique doivent porter le même nom que le fichier correspondant décrivant la vue physique. |
| | 54 | |
| | 55 | C'est à dire que le fichier am2901_dpt.vst (vue logique) doit correspondre au fichier am2901_dpt.ap (vue physique). |
| | 56 | Il en va de même pour am2901_core. |
| | 57 | |
| | 58 | = 3 Fonctions de placement fournies par '''Stratus''' = |
| | 59 | |
| | 60 | Pour définir les directives de placement, le langage '''Stratus''' fournit les fonctions' suivantes : |
| | 61 | * Place() |
| | 62 | * !PlaceRight(), !PlaceTop(), !PlaceLeft(), !PlaceBottom() |
| | 63 | * !SetRefIns() |
| | 64 | * !DefAb(), !ResizeAb() |
| | 65 | |
| | 66 | Vous pouvez consulter le manuel de ''Stratus'' en ligne : |
| | 67 | |
| | 68 | https://www-asim.lip6.fr/recherche/coriolis/doc/en/html/stratus/index.html |
| | 69 | |
| | 70 | |
| | 71 | Toutes ces fonctions doivent être utilisées dans la méthode ''Layout'' associée au bloc considéré. |
| | 72 | A titre d'exemple, on donne le code suivant pour le fichier circuit.py : |
| | 73 | {{{ |
| | 74 | #!/usr/bin/env python |
| | 75 | from stratus import * |
| | 76 | # definition du bloc de nom "circuit" |
| | 77 | class circuit ( Model ): |
| | 78 | ... |
| | 79 | # on suppose que les instances i1, i2, i3 ont été créées |
| | 80 | def Layout ( self ): |
| | 81 | Place ( self.i1, NOSYM, XY ( 0, 0 ) ) |
| | 82 | PlaceRight ( self.i2, NOSYM ) |
| | 83 | PlaceRight ( self.i3, NOSYM ) |
| | 84 | }}} |
| | 85 | |
| | 86 | Ensuite pour générer le fichier circuit.ap, il faut rajouter l'appel à la méthode ''Layout'' |
| | 87 | dans le fichier ''test_circuit.py'' et ne pas oublier de sauvegarder le résultat sur disque : |
| | 88 | {{{ |
| | 89 | # creation de la vue physique (placement) |
| | 90 | my_circuit.Layout() |
| | 91 | |
| | 92 | # sauver les fichiers ''mon_circuit.vst'' et ''mon_circuit.ap'' |
| | 93 | my_circuit.Save ( PHYSICAL ) |
| | 94 | }}} |
| | 95 | |
| | 96 | = 4 Travail à effectuer = |
| | 97 | |
| | 98 | == 4.1 Placement explicite des opérateurs du chemin de données == |
| | 99 | |
| | 100 | Reprendre le fichier ''am2901_dpt.py'' du TP4. Pour l'instant, ce fichier ne comporte qu'une description de la netlist, qui a permis de générer un fichier ''am2901_dpt.vst''. |
| | 101 | * Placer explicitement les colonnes représentants les différents opérateurs 4 bits du chemin de données les unes par rapport aux autres, en ajoutant une méthode ''Layout'' dans ce fichier. |
| | 102 | * Après avoir modifié le fichier ''am2901_dpt.py'', générer le fichier de placement ''am2901_dpt.ap'' : |
| | 103 | {{{ |
| | 104 | > ./execute_amd2901_dpt.py |
| | 105 | }}} |
| | 106 | |
| | 107 | == 4.2 Placement du coeur == |
| | 108 | |
| | 109 | Reprendre le fichier ''am2901_core.py'' décrivant le coeur du circuit AM2901 et introduire les étapes suivantes dans la méthode ''Layout'' : |
| | 110 | * Placer le chemin de données : fonction Place() |
| | 111 | * Agrandir la boite d'aboutement du coeur : fonction !ResizeAb() |
| | 112 | Cette étape est utile pour réserver la place nécessaire au placement des cellules de la partie contrôle. |
| | 113 | La logique "irrégulière" constituant la partie contrôle n'a pas besoin d'être placée explicitement. Cela sera fait automatiquement par la suite ! |
| | 114 | * Placer les rails de rappels d'alimentation dans le coeur : fonctions !AlimVerticalRail() et !AlimHorizontalRail() |
| | 115 | * Placer les connecteurs du coeur : fonction !AlimConnectors() |
| | 116 | * Vérifier le résultat : |
| | 117 | {{{ |
| | 118 | > ./execute_am2901_core.py |
| | 119 | }}} |
| | 120 | |
| | 121 | == 4.3 Placement de la couronne de plots autour du coeur == |
| | 122 | |
| | 123 | Reprendre le fichier ''am2901_chip.py'' du TP4 (circuit complet avec les plots), et introduire les étapes suivantes dans la méthode ''Layout'' : |
| | 124 | * Définir la taille de la boîte d'aboutement globale du circuit de façon à ce que les plots puissent être placés à la périphérie : fonction !DefAb() |
| | 125 | (On peut commencer par définir une boite d'aboutement de 4000 par 4000 et essayer ensuite de la réduire) |
| | 126 | * Placer le coeur du circuit au centre de la boîte d'aboutement du chip : fonction !PlaceCentric() |
| | 127 | * Définir sur quelle face et dans quel ordre placer les plots. |
| | 128 | Cela se fait à l'aide des 4 fonctions : !PadNorth(), !PadSouth(), !PadEast() et !PadWest(). |
| | 129 | * Vérifier le résultat : |
| | 130 | {{{ |
| | 131 | > ./execute_amd2901_chip.py |
| | 132 | }}} |
| | 133 | |
| | 134 | == 4.4 Routage des alimentations == |
| | 135 | |
| | 136 | * Créer la grille d'alimentation : fonction !PowerRing() |
| | 137 | * Vérifier le résultat : |
| | 138 | {{{ |
| | 139 | > ./execute_amd2901_chip.py |
| | 140 | }}} |
| | 141 | |
| | 142 | == 4.5 Placement de la logique irrégulière == |
| | 143 | |
| | 144 | C'est le placeur '''mistral''' qui se charge de placer automatiquement les cellules non encore placées. |
| | 145 | Il détecte quelles sont les cellules qui n'ont pas été placées et complète le placement en utilisant les zones "vides". |
| | 146 | Pour appeler le placeur '''mistral''', faire appel à la fonction ''!PlaceGlue ()'' |
| | 147 | |
| | 148 | [[Image(zoomPlaceGlue.jpg,nolink)]] |
| | 149 | |
| | 150 | Attention : Pour pouvoir placer automatiquement la logique "irrégulière", il faut avoir préalablement défini la position des plots d'entrée/sortie sur les 4 faces du circuit. |
| | 151 | L'outil de placement automatique place les cellules non placées en se basant sur les attirances vers les plots ainsi que vers les cellules déjà placées. |
| | 152 | |
| | 153 | * Vérifier le résultat : |
| | 154 | {{{ |
| | 155 | > ./execute_amd2901_chip.py |
| | 156 | }}} |
| | 157 | |
| | 158 | * Effectuer le placement automatique de cellules de bourrage : fonction !FillCell() |
| | 159 | |
| | 160 | [[Image(zoomFillCell.jpg,nolink)]] |
| | 161 | |
| | 162 | * Vérifier le résultat : |
| | 163 | {{{ |
| | 164 | > ./execute_amd2901_chip.py |
| | 165 | }}} |
| | 166 | |
| | 167 | == 4.6 Routage des signaux d'horloge = |
| | 168 | |
| | 169 | * Construire le réseau maillé correspondant au signal d'horloge interne : fonction !RouteCk() |
| | 170 | * Vérifier le résultat : |
| | 171 | {{{ |
| | 172 | > ./execute_amd2901_chip.py |
| | 173 | }}} |
| | 174 | |
| | 175 | [[Image(zoomCk.jpg,nolink)]] |
| | 176 | |
| | 177 | == 4.7 Routage des signaux logiques == |
| | 178 | |
| | 179 | L'appel au routeur automatique '''nero''' n'est pas encore intégré dans le langage '''Stratus'''. |
| | 180 | Pour effectuer le routage de tous les signaux autres que le signal d'horloge et les signaux d'alimentation, il faut lancer '''nero''' de la manière suivante : |
| | 181 | {{{ |
| | 182 | > nero -V -p amd2901_chip amd2901_chip amd2901_chip_r |
| | 183 | }}} |
| | 184 | |
| | 185 | L'option -p indique que vous fournissez un fichier de placement en argument. Le |
| | 186 | deuxième argument est le fichier définissant la ''net-list'', le troisième est le |
| | 187 | nom du fichier résultat. |
| | 188 | |
| | 189 | == 4.8 Validation == |