| 1 | {{{ |
| 2 | #!html |
| 3 | <h1>TP2 -- Placement/Routage de Cellules Précaractérisées</h1> |
| 4 | }}} |
| 5 | |
| 6 | [[PageOutline]] |
| 7 | |
| 8 | Dans ce TP, nous souhaitons réaliser un générateur de circuit {{{addaccu}}} amélioré avec |
| 9 | comme paramètre, entre autres, le nombre de bits. Ce générateur sera, dans un premier |
| 10 | temps, conçu avec les cellules de {{{sxlib}}}, puis avec les cellules de {{{dp_sxlib}}}. |
| 11 | |
| 12 | Nous verrons dans ce TP comment Stratus permet de décrire des netlists paramétrables et de |
| 13 | les utiliser. Les Netlists seront placés-routés de différentes manières pour montrer |
| 14 | l'intérêt du placement procédural. |
| 15 | |
| 16 | {{{ |
| 17 | #!QABox type=Note |
| 18 | #!question |
| 19 | Documentation de '''{{{Stratus}}}''' |
| 20 | #!answer |
| 21 | Elle est accessible à l'adresse suivante: |
| 22 | |
| 23 | [file:///soc/coriolis2/share/doc/coriolis2/en/html/stratus/index.html] |
| 24 | |
| 25 | Ce lien n'est disponible que depuis l' ''intérieur'' du département. |
| 26 | }}} |
| 27 | |
| 28 | |
| 29 | == 1 Introduction == |
| 30 | |
| 31 | === 1.1 Circuit addaccu === |
| 32 | |
| 33 | Dans le circuit '''{{{addaccu}}}''' sont instanciés trois blocs '''{{{mux}}}''', |
| 34 | '''{{{accu}}}''' et '''{{{adder}}}'''. |
| 35 | |
| 36 | [[Image(addaccu.jpg, nolink)]] |
| 37 | |
| 38 | Les deux blocs '''{{{mux}}}''' et '''{{{accu}}}''' sont des générateurs paramétrables |
| 39 | décrits dans le langage '''Stratus''', ce sont des interconnexions de portes de bases, |
| 40 | fournies par la bibliothèque de cellules pré-caractérisées '''{{{SxLib}}}'''. |
| 41 | |
| 42 | Le bloc '''{{{adder}}}''', également décrit dans le langage '''{{{Stratus}}}''', répète un |
| 43 | motif '''{{{full_adder}}}'''. Le motif '''{{{full_adder}}}''' sera créé à l'aide d'une |
| 44 | fonction {{{Python}}}. ''Ce n'est pas une instantiation''. |
| 45 | |
| 46 | Le circuit '''{{{addaccu}}}''' comporte donc deux niveaux de hiérarchie: |
| 47 | 1. - Le niveau des blocs ({{{mux}}}, {{{accu}}}, {{{adder}}}). |
| 48 | 2. - Le niveau du circuit complet ({{{addaccu}}}). |
| 49 | |
| 50 | {{{ |
| 51 | #!QABox type=Note |
| 52 | #!question |
| 53 | Nom du signal d'horloge |
| 54 | #!answer |
| 55 | Pour un circuit aussi petit, nous n'utiliserons pas de stratégie spécifique pour router le |
| 56 | signal d'horloge. Pour que ce signal soit routé comme un signal ordinaire, il est |
| 57 | nécessaire de lui donner un nom ne contenant pas '''{{{ck}}}''', on prendra |
| 58 | '''{{{horloge}}}'''. |
| 59 | }}} |
| 60 | |
| 61 | |
| 62 | === 1.2 La bibliothèque sxlib === |
| 63 | |
| 64 | Une cellule pré-caractérisée (en anglais ''standard cell'') est une fonction élémentaire |
| 65 | pour laquelle on dispose des différentes "vues" permettant son utilisation par des outils |
| 66 | CAO : |
| 67 | |
| 68 | * Vue physique: dessin des masques, permettant d'automatiser le placement et le routage. |
| 69 | * Vue logique: schéma en transistors permettant la caractérisation (surface, |
| 70 | consommation, temps de propagation), |
| 71 | * Vue comportementale: description {{{VHDL}}} permettant la simulation logique des |
| 72 | circuits utilisant cette bibliothèque. |
| 73 | |
| 74 | La bibliothèque de cellules utilisée dans ce TME est la bibliothèque '''{{{SxLib}}}''', |
| 75 | développée par le laboratoire {{{LIP6}}}, pour la chaîne de {{{CAO}}} '''Alliance'''. La |
| 76 | particularité de cette bibliothèque est d'être __portable__: le dessin des masques de |
| 77 | fabrication utilise une technique de dessin symbolique, qui permet d'utiliser cette |
| 78 | bibliothèque de cellules pour n'importe quel procédé de fabrication {{{CMOS}}} possédant |
| 79 | au moins trois niveaux d'interconnexion. |
| 80 | |
| 81 | Évidemment, les caractéristiques physiques (surface occupée, temps de propagation) |
| 82 | dépendent du procédé de fabrication. Les cellules que vous utiliserez dans ce TME ont été |
| 83 | caractérisées pour un procédé de fabrication CMOS 0.35 micron. |
| 84 | |
| 85 | La liste des cellules disponibles dans la bibliothèque '''{{{SxLib}}}''' peut être obtenue |
| 86 | en consultant la page de manuel: |
| 87 | {{{ |
| 88 | > man sxlib |
| 89 | }}} |
| 90 | |
| 91 | Comme vous pourrez le constater, il existe plusieurs cellules réalisant la même fonction |
| 92 | logique. Les deux cellules ''{{{na2_x1}}}'' et ''{{{na2_x4}}}'' réalisent toutes les deux |
| 93 | la fonction {{{NAND}}} à 2 entrées, et ne diffèrent entre elles que par leur puissance |
| 94 | électrique: la cellule ''{{{na2_x4}}}'' est capable de charger une capacité de charge 4 |
| 95 | fois plus grande que la cellule ''{{{na2_x1}}}''. Évidemment, plus la cellule est |
| 96 | puissante, plus la surface de silicium occupée est importante. Vous pouvez visualiser le |
| 97 | dessin des masques de ces cellules en utilisant l'éditeur graphique de la chaîne |
| 98 | '''Alliance''' '''{{{graal}}}'''. |
| 99 | |
| 100 | |
| 101 | == 1.3 Schémas des Blocs == |
| 102 | |
| 103 | === 1.3.1 Multiplexeur === |
| 104 | |
| 105 | Un multiplexeur 4 bits peut être réalisé en utilisant 4 cellules ''{{{mx2_x2}}}'' suivant |
| 106 | le schéma ci-dessous : |
| 107 | |
| 108 | [[Image(mux.jpg, nolink)]] |
| 109 | |
| 110 | Vous pouvez consulter le modèle comportemental de la cellule ''{{{mx2_x2}}}'': |
| 111 | [attachment:mx2_x2.vbe mx2_x2.vbe]. |
| 112 | |
| 113 | |
| 114 | === 1.3.2 Registre === |
| 115 | |
| 116 | Un registre 4 bits peut être réalisé en utilisant 4 cellules ''{{{sff1_x4}}}'' suivant le |
| 117 | schéma ci-dessous: |
| 118 | |
| 119 | [[Image(reg.jpg, nolink)]] |
| 120 | |
| 121 | La cellule ''{{{sff1_x4}}}'' est une bascule D à échantillonnage sur front montant. Vous |
| 122 | pouvez consulter le modèle comportemental de cette cellule: [attachment:sff1_x4.vbe |
| 123 | sff1_x4.vbe]. |
| 124 | |
| 125 | |
| 126 | === 1.3.3 Additionneur === |
| 127 | |
| 128 | Un additionneur 4 bits peut être réalisé en interconnectant 4 additionneurs 1 bit, suivant |
| 129 | le schéma ci-dessous: |
| 130 | |
| 131 | [[Image(adder.jpg, nolink)]] |
| 132 | |
| 133 | Un additionneur 1 bit (encore appelé ''Full Adder'') possède 3 entrées a,b,c, et deux |
| 134 | sorties {{{s}}} et {{{r}}}. La table de vérité est définie par le tableau ci-dessous. Le |
| 135 | bit de ''somme'' s vaut {{{1}}} lorsque le nombre de bits d'entrée égal à {{{1}}} est |
| 136 | impair. Le bit de ''retenue'' est égal à 1 lorsqu'au moins deux bits d'entrée valent 1. |
| 137 | |
| 138 | ||= a =||= b =||= c =||= s =||= r =|| |
| 139 | || 0 || 0 || 0 ||= 0 =||= 0 =|| |
| 140 | || 0 || 0 || 1 ||= 1 =||= 0 =|| |
| 141 | || 0 || 1 || 0 ||= 1 =||= 0 =|| |
| 142 | || 0 || 1 || 1 ||= 0 =||= 1 =|| |
| 143 | || 1 || 0 || 0 ||= 1 =||= 0 =|| |
| 144 | || 1 || 0 || 1 ||= 0 =||= 1 =|| |
| 145 | || 1 || 1 || 0 ||= 0 =||= 1 =|| |
| 146 | || 1 || 1 || 1 ||= 1 =||= 1 =|| |
| 147 | |
| 148 | Ceci donne les expressions suivantes : |
| 149 | |
| 150 | * {{{s <= a XOR b XOR c}}} |
| 151 | * {{{r <= (a AND b) OR (a AND c) OR (b AND c)}}} |
| 152 | |
| 153 | Il existe plusieurs schémas possibles pour réaliser un ''Full Adder''. Nous vous |
| 154 | proposons d'utiliser le schéma ci-dessous, qui utilise trois cellules ''{{{na2_x1}}}'' |
| 155 | ({{{NAND}}} 2 entrées), et deux cellules ''{{{xr2_x1}}}'' ({{{XOR}}} 2 entrées) : |
| 156 | |
| 157 | [[Image(full_adder.jpg, nolink)]] |
| 158 | |
| 159 | |
| 160 | == 2 Travail à effectuer == |
| 161 | |
| 162 | === 2.1 Initialisation de l'Environnement === |
| 163 | |
| 164 | Afin de pouvoir travailler avec '''Alliance''' et '''Coriolis 2''' il vous faut |
| 165 | ''sourcer'' les deux scripts suivant: |
| 166 | {{{ |
| 167 | > . /soc/alliance/etc/alc_env.sh |
| 168 | > . /soc/coriolis2/etc/coriolis2/coriolis2.sh |
| 169 | }}} |
| 170 | |
| 171 | {{{ |
| 172 | #!QABox type=Note |
| 173 | #!question |
| 174 | Différence entre ''sourcer'' et ''exécuter'' un script. |
| 175 | #!answer |
| 176 | * Lorsque vous ''exécutez'' un script ou un programme, celui-çi va être lancé dans un |
| 177 | processus séparé, fils du processus courant. L'environnement du processus fils est |
| 178 | une copie de celui du père et les modifications n'affecteront pas le processus |
| 179 | parent (i.e. le ''shell''). |
| 180 | * Lorsque vous ''sourcez'' un script, ''il n'y a pas de création de processus fils'', |
| 181 | les commandes contenues dans le script sont directement exécutés dans l'environnement |
| 182 | courant, exactement comme si elles étaient tapées manuellement au prompt. |
| 183 | Elles vont donc modifier l'environnement du ''shell''. |
| 184 | * La notation '''{{{.}}}''' est un raccourci pour '''{{{source}}}''' en {{{bash}}}. |
| 185 | }}} |
| 186 | |
| 187 | |
| 188 | === 2.1 Bloc Mux === |
| 189 | |
| 190 | 1. Récupérer les deux fichiers permettant de créer le bloc '''{{{mux}}}''' et les étudier: |
| 191 | * [attachment:mux.py Netlist en '''{{{Stratus}}}''' du bloc '''{{{mux}}}'''] |
| 192 | * [attachment:generate_mux.py Script pour la création de la netlist] |
| 193 | |
| 194 | Ce bloc a la fonctionnalité suivante : |
| 195 | {{{ |
| 196 | si (cmd==0) alors s <= i0 sinon s <= i1 |
| 197 | }}} |
| 198 | {{{i0}}}, {{{i1}}} et {{{s}}} ayant un nombre de bit paramétrable |
| 199 | |
| 200 | 2. Créer une instance de mux sur 4 bits. |
| 201 | Pour ce faire, il faut exécuter le script fourni avec le bon paramètre : |
| 202 | * soit en exécutant la commande suivante : |
| 203 | {{{ |
| 204 | > python gen_mux.py -n 2 |
| 205 | }}} |
| 206 | * soit en modifiant les droits du fichier : |
| 207 | {{{ |
| 208 | > chmod u+x generate_mux.py |
| 209 | > ./generate_mux.py -n 2 |
| 210 | }}} |
| 211 | |
| 212 | Si le script s'exécute sans erreur, un fichier '''{{{.vst}}}''' est normalement généré. |
| 213 | Vous pouvez vérifier qu'il décrit bien le circuit voulu. |
| 214 | |
| 215 | |
| 216 | === 2.2 Bloc Registre (Accumulateur) === |
| 217 | |
| 218 | * En s'inspirant du multiplexeur, écrire le bloc '''{{{accu}}}''' avec '''{{{Stratus}}}''' |
| 219 | en utilisant exclusivement les cellules de la bibliothèque '''{{{SxLib}}}'''. Ce bloc |
| 220 | prend lui aussi comme paramètre le nombre de bits. En outre, il vérifie que son |
| 221 | paramètre est compris entre 2 et 64 (ce n’est pas fait dans mux). |
| 222 | * Écrire le script {{{Python}}} permettant de créer l'instance du registre. |
| 223 | |
| 224 | |
| 225 | === 2.3 Bloc Additionneur === |
| 226 | |
| 227 | * Écrire la fonction '''{{{fullAdder()}}}''' en utilisant exclusivement les cellules de |
| 228 | la bibliothèque '''{{{SxLib}}}'''. |
| 229 | * Écrire le bloc '''{{{adder}}}''' appelant la fonction '''{{{fullAdder()}}}''' . Ce |
| 230 | bloc prend lui aussi comme paramètre le nombre de bits et vérifie que son paramètre est |
| 231 | compris entre 2 et 64 (ce n’est pas fait dans '''{{{mux}}}'''). |
| 232 | * Écrire le script {{{Python}}} permettant de créer l'instance de l'additionneur. |
| 233 | |
| 234 | |
| 235 | === 2.4 Circuit Addaccu === |
| 236 | |
| 237 | * Ecrire le circuit '''{{{addaccu}}}''' avec '''{{{Stratus}}}'''. Ce circuit instancie |
| 238 | les trois blocs précédents ('''{{{mux}}}''', '''{{{accu}}}''' et '''{{{adder}}}'''). Le |
| 239 | circuit '''{{{addaccu}}}''' prend également comme paramètre le nombre de bits. |
| 240 | * Écrire le script python permettant de créer des instances de l'addaccu. |
| 241 | * Écrire un fichier ''{{{Makefile}}} paramétrable'' permettant de produire chaque composant |
| 242 | et le circuit '''{{{addaccu}}}''' en choisissant le nombre de bits. |
| 243 | * Générer le circuit sur 4 bits. |
| 244 | * Visualiser la netlist obtenue avec '''{{{xsch}}}'''. |
| 245 | |
| 246 | |
| 247 | === 2.5 Fonction Generate === |
| 248 | |
| 249 | Il n'est pas toujours très pratique d'avoir à générer avec plusieurs scripts les |
| 250 | différents blocs d'un circuit. Le langage '''{{{Stratus}}}''' fournit donc une |
| 251 | alternative: la fonction '''{{{Generate}}}'''. |
| 252 | |
| 253 | Par exemple, pour générer une instance du multiplexeur fourni, il suffit d'ajouter la |
| 254 | ligne suivante dans le fichier '''{{{addaccu}}}''' : |
| 255 | {{{ |
| 256 | Generate ( "mux.mux", "mux_%d" % self.n, param={'nbit':self.n} ) |
| 257 | }}} |
| 258 | |
| 259 | Dans cette fonction, le premier argument représente la classe '''{{{Stratus}}}''' créée |
| 260 | (format: {{{nom_de_fichier.nom_de_classe}}}), le deuxième argument est le nom du modèle |
| 261 | généré, le dernier argument est un dictionnaire initialisant les différents paramètres de |
| 262 | cette classe. |
| 263 | |
| 264 | * Modifier le fichier décrivant l' '''{{{addaccu}}}''' et le {{{Makefile}}} de façon à |
| 265 | pouvoir créer les instances de ce circuit en n'ayant besoin que d'un script. |