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 == |