{{{ #!html

TP2 -- Placement/Routage de Cellules Précaractérisées

}}} [[PageOutline]] Dans ce TP, nous souhaitons réaliser un générateur de circuit {{{addaccu}}} amélioré avec comme paramètre, entre autres, le nombre de bits. Ce générateur sera, dans un premier temps, conçu avec les cellules de {{{sxlib}}}, puis avec les cellules de {{{dp_sxlib}}}. Nous verrons dans ce TP comment Stratus permet de décrire des netlists paramétrables et de les utiliser. Les Netlists seront placés-routés de différentes manières pour montrer l'intérêt du placement procédural. {{{ #!QABox type=Note #!question Documentation de '''{{{Stratus}}}''' #!answer Elle est accessible à l'adresse suivante: [file:///soc/coriolis2/share/doc/coriolis2/en/html/stratus/index.html] Ce lien n'est disponible que depuis l' ''intérieur'' du département. }}} == 1 Introduction == === 1.1 Circuit addaccu === Dans le circuit '''{{{addaccu}}}''' sont instanciés trois blocs '''{{{mux}}}''', '''{{{accu}}}''' et '''{{{adder}}}'''. [[Image(addaccu.jpg, nolink, center)]] Les deux blocs '''{{{mux}}}''' et '''{{{accu}}}''' sont des générateurs paramétrables décrits dans le langage '''Stratus''', ce sont des interconnexions de portes de bases, fournies par la bibliothèque de cellules pré-caractérisées '''{{{SxLib}}}'''. Le bloc '''{{{adder}}}''', également décrit dans le langage '''{{{Stratus}}}''', répète un motif '''{{{full_adder}}}'''. Le motif '''{{{full_adder}}}''' sera créé à l'aide d'une fonction {{{Python}}}. ''Ce n'est pas une instantiation''. Le circuit '''{{{addaccu}}}''' comporte donc deux niveaux de hiérarchie: 1. - Le niveau des blocs ({{{mux}}}, {{{accu}}}, {{{adder}}}). 2. - Le niveau du circuit complet ({{{addaccu}}}). {{{ #!QABox type=Note #!question Nom du signal d'horloge #!answer Pour un circuit aussi petit, nous n'utiliserons pas de stratégie spécifique pour router le signal d'horloge. Pour que ce signal soit routé comme un signal ordinaire, il est nécessaire de lui donner un nom ne contenant pas '''{{{ck}}}''', on prendra '''{{{horloge}}}'''. }}} === 1.2 La bibliothèque sxlib === Une cellule pré-caractérisée (en anglais ''standard cell'') est une fonction élémentaire pour laquelle on dispose des différentes "vues" permettant son utilisation par des outils CAO : * Vue physique: dessin des masques, permettant d'automatiser le placement et le routage. * Vue logique: schéma en transistors permettant la caractérisation (surface, consommation, temps de propagation), * Vue comportementale: description {{{VHDL}}} permettant la simulation logique des circuits utilisant cette bibliothèque. La bibliothèque de cellules utilisée dans ce TME est la bibliothèque '''{{{SxLib}}}''', développée par le laboratoire {{{LIP6}}}, pour la chaîne de {{{CAO}}} '''Alliance'''. La particularité de cette bibliothèque est d'être __portable__: le dessin des masques de fabrication utilise une technique de dessin symbolique, qui permet d'utiliser cette bibliothèque de cellules pour n'importe quel procédé de fabrication {{{CMOS}}} possédant au moins trois niveaux d'interconnexion. Évidemment, les caractéristiques physiques (surface occupée, temps de propagation) dépendent du procédé de fabrication. Les cellules que vous utiliserez dans ce TME ont été caractérisées pour un procédé de fabrication CMOS 0.35 micron. La liste des cellules disponibles dans la bibliothèque '''{{{SxLib}}}''' peut être obtenue en consultant la page de manuel: {{{ > man sxlib }}} Comme vous pourrez le constater, il existe plusieurs cellules réalisant la même fonction logique. Les deux cellules ''{{{na2_x1}}}'' et ''{{{na2_x4}}}'' réalisent toutes les deux la fonction {{{NAND}}} à 2 entrées, et ne diffèrent entre elles que par leur puissance électrique: la cellule ''{{{na2_x4}}}'' est capable de charger une capacité de charge 4 fois plus grande que la cellule ''{{{na2_x1}}}''. Évidemment, plus la cellule est puissante, plus la surface de silicium occupée est importante. Vous pouvez visualiser le dessin des masques de ces cellules en utilisant l'éditeur graphique de la chaîne '''Alliance''' '''{{{graal}}}'''. == 1.3 Schémas des Blocs == === 1.3.1 Multiplexeur === Un multiplexeur 4 bits peut être réalisé en utilisant 4 cellules ''{{{mx2_x2}}}'' suivant le schéma ci-dessous : [[Image(mux.jpg, nolink, center)]] Vous pouvez consulter le modèle comportemental de la cellule ''{{{mx2_x2}}}'': [attachment:mx2_x2.vbe mx2_x2.vbe]. === 1.3.2 Registre === Un registre 4 bits peut être réalisé en utilisant 4 cellules ''{{{sff1_x4}}}'' suivant le schéma ci-dessous: [[Image(reg.jpg, nolink, center)]] La cellule ''{{{sff1_x4}}}'' est une bascule D à échantillonnage sur front montant. Vous pouvez consulter le modèle comportemental de cette cellule: [attachment:sff1_x4.vbe sff1_x4.vbe]. === 1.3.3 Additionneur === Un additionneur 4 bits peut être réalisé en interconnectant 4 additionneurs 1 bit, suivant le schéma ci-dessous: [[Image(adder.jpg, nolink, center)]] Un additionneur 1 bit (encore appelé ''Full Adder'') possède 3 entrées a,b,c, et deux sorties {{{s}}} et {{{r}}}. La table de vérité est définie par le tableau ci-dessous. Le bit de ''somme'' s vaut {{{1}}} lorsque le nombre de bits d'entrée égal à {{{1}}} est impair. Le bit de ''retenue'' est égal à 1 lorsqu'au moins deux bits d'entrée valent 1. ||= a =||= b =||= c =||= s =||= r =|| || 0 || 0 || 0 ||= 0 =||= 0 =|| || 0 || 0 || 1 ||= 1 =||= 0 =|| || 0 || 1 || 0 ||= 1 =||= 0 =|| || 0 || 1 || 1 ||= 0 =||= 1 =|| || 1 || 0 || 0 ||= 1 =||= 0 =|| || 1 || 0 || 1 ||= 0 =||= 1 =|| || 1 || 1 || 0 ||= 0 =||= 1 =|| || 1 || 1 || 1 ||= 1 =||= 1 =|| Ceci donne les expressions suivantes : * {{{s <= a XOR b XOR c}}} * {{{r <= (a AND b) OR (a AND c) OR (b AND c)}}} Il existe plusieurs schémas possibles pour réaliser un ''Full Adder''. Nous vous proposons d'utiliser le schéma ci-dessous, qui utilise trois cellules ''{{{na2_x1}}}'' ({{{NAND}}} 2 entrées), et deux cellules ''{{{xr2_x1}}}'' ({{{XOR}}} 2 entrées) : [[Image(full_adder.jpg, nolink, center)]] == 2 Travail à effectuer == === 2.1 Initialisation de l'Environnement === Afin de pouvoir travailler avec '''Alliance''' et '''Coriolis 2''' il vous faut ''sourcer'' les deux scripts suivant: {{{ > . /soc/alliance/etc/alc_env.sh > . /soc/coriolis2/etc/coriolis2/coriolis2.sh }}} {{{ #!QABox type=Note #!question Différence entre ''sourcer'' et ''exécuter'' un script. #!answer * Lorsque vous ''exécutez'' un script ou un programme, celui-çi va être lancé dans un processus séparé, fils du processus courant. L'environnement du processus fils est une copie de celui du père et les modifications n'affecteront pas le processus parent (i.e. le ''shell''). * Lorsque vous ''sourcez'' un script, ''il n'y a pas de création de processus fils'', les commandes contenues dans le script sont directement exécutés dans l'environnement courant, exactement comme si elles étaient tapées manuellement au prompt. Elles vont donc modifier l'environnement du ''shell''. * La notation '''{{{.}}}''' est un raccourci pour '''{{{source}}}''' en {{{bash}}}. }}} === 2.1 Bloc Mux === 1. Récupérer les deux fichiers permettant de créer le bloc '''{{{mux}}}''' et les étudier: * [attachment:mux.py Netlist en Stratus du bloc mux] * [attachment:generate_mux.py Script pour la création de la netlist] {{{ #!QABox type=Note #!question Patterns & Simulation #!answer Les fichiers fournis contiennent aussi la génération des ''patterns'' et l'appel au simulateur. Ce point est détaillé en [#secPatterns 2.6] et peut être ignoré ici. }}} Ce bloc a la fonctionnalité suivante : {{{ si (cmd==0) alors s <= i0 sinon s <= i1 }}} {{{i0}}}, {{{i1}}} et {{{s}}} ayant un nombre de bit paramétrable 2. Créer une instance de mux sur 4 bits. Pour ce faire, il faut exécuter le script fourni avec le bon paramètre : * soit en exécutant la commande suivante : {{{ > python gen_mux.py -n 2 }}} * soit en modifiant les droits du fichier : {{{ > chmod u+x generate_mux.py > ./generate_mux.py -n 2 }}} Si le script s'exécute sans erreur, un fichier '''{{{.vst}}}''' est normalement généré. Vous pouvez vérifier qu'il décrit bien le circuit voulu. === 2.2 Bloc Registre (Accumulateur) === * En s'inspirant du multiplexeur, écrire le bloc '''{{{accu}}}''' avec '''{{{Stratus}}}''' en utilisant exclusivement les cellules de la bibliothèque '''{{{SxLib}}}'''. Ce bloc prend lui aussi comme paramètre le nombre de bits. En outre, il vérifie que son paramètre est compris entre 2 et 64 (ce n’est pas fait dans mux). * Écrire le script {{{Python}}} permettant de créer l'instance du registre. === 2.3 Bloc Additionneur === * Écrire la fonction '''{{{fullAdder()}}}''' en utilisant exclusivement les cellules de la bibliothèque '''{{{SxLib}}}'''. * Écrire le bloc '''{{{adder}}}''' appelant la fonction '''{{{fullAdder()}}}''' . Ce bloc prend lui aussi comme paramètre le nombre de bits et vérifie que son paramètre est compris entre 2 et 64 (ce n’est pas fait dans '''{{{mux}}}'''). * Écrire le script {{{Python}}} permettant de créer l'instance de l'additionneur. === 2.4 Circuit Addaccu === * Ecrire le circuit '''{{{addaccu}}}''' avec '''{{{Stratus}}}'''. Ce circuit instancie les trois blocs précédents ('''{{{mux}}}''', '''{{{accu}}}''' et '''{{{adder}}}'''). Le circuit '''{{{addaccu}}}''' prend également comme paramètre le nombre de bits. * Écrire le script python permettant de créer des instances de l'addaccu. * Écrire un fichier ''{{{Makefile}}} paramétrable'' permettant de produire chaque composant et le circuit '''{{{addaccu}}}''' en choisissant le nombre de bits. * Générer le circuit sur 4 bits. * Visualiser la netlist obtenue avec '''{{{xsch}}}'''. === 2.5 Fonction Generate === Il n'est pas toujours très pratique d'avoir à générer avec plusieurs scripts les différents blocs d'un circuit. Le langage '''{{{Stratus}}}''' fournit donc une alternative: la fonction '''{{{Generate}}}'''. Par exemple, pour générer une instance du multiplexeur fourni, il suffit d'ajouter la ligne suivante dans le fichier '''{{{addaccu}}}''' : {{{ Generate ( "mux.mux", "mux_%d" % self.n, param={'nbit':self.n} ) }}} Dans cette fonction, le premier argument représente la classe '''{{{Stratus}}}''' créée (format: {{{nom_de_fichier.nom_de_classe}}}), le deuxième argument est le nom du modèle généré, le dernier argument est un dictionnaire initialisant les différents paramètres de cette classe. * Modifier le fichier décrivant l' '''{{{addaccu}}}''' et le {{{Makefile}}} de façon à pouvoir créer les instances de ce circuit en n'ayant besoin que d'un script. === 2.6 Description de Patterns === #secPatterns La chaîne de {{{CAO}}} '''Alliance''' fournit un outil permettant de décrire des séquences de stimuli : '''{{{genpat}}}'''. '''{{{Stratus}}}''' comporte le même service pour la chaîne de CAO '''{{{Coriolis}}}'''. De plus, '''{{{Stratus}}}''' encapsule l'appel au simulateur '''{{{asimut}}}'''. * Récupérer les deux fichiers décrivant le bloc mux avec création du fichier de patterns et simulation, et les étudier : * '''{{{mux.py}}}''' contient la génération des ''patterns''. * '''{{{generate_mux.py}}}''' contient l'appel au simulateur. * Créer les patterns et effectuer la simulation des deux autres blocs de la même façon.nce * Une fois tous les sous blocs validés, créer les patterns et effectuer la simulation du bloc '''{{{addaccu}}}'''. === 2.8 Bibliothèque {{{DpGen}}} === '''{{{Stratus}}}''' propose aussi une bibliothèque d'opérateurs de chemins de données (''datapath''). Sa documentation est accessible [file:///soc/coriolis2/share/doc/coriolis2/en/html/stratus/index.html ici] * Ré-écrire un '''{{{addaccu}}}''' paramétrable en utilisant les opérateurs de chemins de données. * Valider ce bloc avec les mêmes patterns que le bloc précédent. === 2.9 Placement & Routage === A l'aide de {{{cgt}}}, effectuer un placement/routage des circuits. Pour rendre les différences plus significatives, générer des '''{{{addaccu}}}''' à 64 bits. Procéder aux essais suivants: * Circuit ''glue logique'' placé/routé avec les paramètres par défauts. * Circuit ''glue logique'' avec 10% de marge de surface. * Circuit ''glue logique'' avec 10% de marge de surface et le recuit simulé traditionnel activé. * Circuit ''chemin de données''. == 3 Compte-Rendu == Vous rédigerez un compte-rendu d'une page ''maximum'' pour ce {{{TME}}}. * Vous présenterez un schéma de la hiérarchie du circuit '''{{{addaccu}}}'''. * Vous décrirez quels générateurs de la bibliothèque '''{{{DpGen}}}''' vous avez utilisé et pourquoi. * Vous commenterez les différence en longueur de fils et surfaces des approches chemins de données et ''standard cells''. * Vous fournirez tous les fichiers écrits, avec les '''{{{Makefile}}}''' permettant d'effectuer la génération des deux circuits (et l'effacement des fichiers générés).