Commit cde11008 authored by Mickael Fiorentino's avatar Mickael Fiorentino
Browse files

Suppression des backups de wiki sur la branche master

parent d7b9eaa5
====== Conception & simulation des circuits analogiques ======
— //[[mickael.fiorentino@polymtl.ca|Mickael Fiorentino]] 2019/07/20// ; //[[erika.miller-jolicoeur@polymtl.ca|Erika Miller-Jolicoeur]] 2019/07/20// —
La conception d'un circuit intégré analogique CMOS passe par deux étapes complémentaires: la **conception du schéma**, qui permet de dimensionner le circuit en accord avec les performances définies au cahier des charges, et l'**édition du dessin des masques**, qui permet d'agencer les transistors et leurs interconnexions au niveau physique. Un circuit intégré est réalisé à partir d'un procédé de fabrication mis au point par un //fondeur//, tel que TSMC, Intel ou STMicroelectronics. Le procédé de fabrication est abstrait par un ensemble de //règles de dessin//, telles que la largeur minimale des interconnexions ou la largeur minimale des transistors, qui garantissent au concepteur que son circuit sera fonctionnel si elles sont respectées. Les outils de conception assistée par ordinateur (//Computer Aided Design (CAD) tools//) sont une interface entre les abstractions du procédé et les concepteurs de circuits intégrés. L’intégration de milliards de transistors dans un circuit intégré réalisant une fonction complexe ne serait pas réalisable sans eux. Plusieurs étapes de vérification sont nécessaires avant la mise en production d'un circuit intégré. Dans un premier temps, la simulation fonctionnelle du schéma permet de dimensionner les transistors de sorte que le circuit atteigne les performances désirées. Ensuite, le dessin des masques est validé par vérification des règles de dessin (//Design Rules Check (DRC)//). Enfin, après extraction de son modèle électrique, la simulation post-implémentation du dessin des masques permet de vérifier que le circuit se comporte toujours tel que prévu lorsqu’on prend en compte les effets parasites (capacités parasites, effet d’antenne, etc).
Dans le cadre de ces tutoriels nous utiliserons l’environnement de simulation et d’édition de dessin des masques **Virtuoso** de //Cadence// à travers la conception d’un inverseur CMOS. Nous utiliserons le kit de développement ''GPDK45'' (//Generic Process Design Kit - 45nm//) de //Cadence//.
Cette première partie du tutoriel traite de la conception et de la simulation du schéma de l'inverseur. Le répertoire de travail associé à ce tutoriel se situe à l’emplacement ''~/Labs/tutoriel_analogique/inverseur''.
===== Environnement de travail =====
//Virtuoso// s’exécute sur les postes de travail Linux dans un environnement ''tcsh''. Il est préférable de lancer //Virtuoso// à partir de votre répertoire de travail. Pour les outils de //Cadence//, deux fichiers de configurations sont en général nécessaires:
* ''setup.csh'': Script qui défini les chemins des exécutables et la hiérarchie du projet.
* ''cds.lib'': Fichier de configuration qui défini les emplacements des librairies de travail.
==== Démarrer l’outil ====
* Se placer a la racine du projet et configurer l'environnement
<code:bash>
[shell]% cd ~/Labs/tutoriel_analogique/inverseur/
[shell]% source setup.csh
</code>
* Démarrer //Virtuoso//
<code:bash>
[shell]% virtuoso &
</code>
Après avoir exécuté ces commandes, vous allez voir apparaitre la fenêtre de contrôle de //Virtuoso//, appelée //Command Interpreter Window// (CIW) tel qu’illustré à la <imgref fig:log>. Elle contient l’historique de toutes les opérations que vous réaliserez, ainsi qu’un menu à partir duquel vous pouvez lancer les différents outils de //Virtuoso//.
<imgcaption fig:log| Fenêtre de contrôle de Virtuoso (CIW)>
{{1_log.png?nolink|Fenêtre de contrôle de Virtuoso (CIW)}}
</imgcaption>
L’accès aux circuits réalisés dans //Virtuoso// est géré par le //gestionnaire de librairies//, tel qu’illustré à la <imgref fig:libman>. Il contient des librairies standards (''analogLib'', ''basic''), des librairies spécifiques au kit (''gpdk045'', ''gpdk045_tech''), ainsi que des libraires créées par l’utilisateur (''ele8304''). Une librairie contient un ensemble de circuits appelés //cellules//. Chaque cellule est décrite par différentes représentations (//schematic, layout, symbol//, etc.).
<imgcaption fig:libman| Gestionnaire de librairies>
{{1_libman.png?nolink|Gestionnaire de librairies}}
</imgcaption>
Pour lancer le gestionnaire de librairie à partir de la fenêtre de contrôle de //Virtuoso// sélectionnez: ''Tools -> Library Manager''. Pour créer la librairie de travail de ce laboratoire sélectionnez: ''File -> New -> Library'', appelez là: ''ele8304'', puis sélectionnez: ''attach to an existing technology library'', et sélectionnez la technologie: ''gsclib045_tech''.
==== Obtenir de l’aide ====
En complément de ce guide vous avez également accès à l’intégralité de la documentation de //Virtuoso// directement dans l’aide //Cadence//. Pour lancer l’aide sélectionnez: ''Help -> User Guide''. Vous obtiendrez une fenêtre similaire à la <imgref fig:cdnshelp>. Vous pouvez parcourir les différents dossier en sélectionnant ''View -> Show Navigation''.
<imgcaption fig:cdnshelp| Documentation de Virtuoso>
{{1_help.png?nolink|Documentation de Virtuoso}}
</imgcaption>
===== Édition du schéma =====
<imgcaption fig:cell| Nouvelle cellule>
{{1_cell.png?nolink|Nouvelle cellule}}
</imgcaption>
Dans cette partie nous allons nous intéresser à la conception et à la simulation du schéma de l’inverseur. Pour ce faire nous allons commencer par créer une cellule: Positionnez-vous dans la librairie ''ele8304'', puis sélectionnez: ''File -> New -> Cell View'', et appelez là ''INV''. Assurez-vous que la vue ''schematic'' est bien sélectionnée, et que l’outil ''schematic L'' sera utilisé pour l’édition du schéma, comme le montre la <imgref fig:cell>.
Pour plus de clarté, on vous suggère d’organiser votre espace de travail, composé du CIW, du gestionnaire de librairies, et de l’éditeur de schéma, comme le montre la <imgref fig:sch>.
<imgcaption fig:sch| Éditeur de schéma>
{{1_sch.png?nolink|Éditeur de schéma}}
</imgcaption>
==== Raccourcis claviers ====
L’éditeur de schéma de //Virtuoso// s’utilise principalement à partir des raccourcis claviers décrits dans le tableau ci-dessous. Le principe est le suivant: Chaque touche (raccourcis) utilisée modifie le **mode** dans lequel l’éditeur se trouve. Par exemple en mode ''m'' (//move//), chaque fois que vous sélectionnez un élément, vous appliquerez la commande //move// sur celui-ci. Pour sortir d’un mode il faut utiliser la touche ''ESC'' (//echap//). D’autre part, vous n’avez pas besoin de maintenir le clic sur un élément pour y appliquer une action: cliquez une fois pour activer l’action associée au mode, et une deuxième fois pour l’appliquer.
^**Raccourci** ^ **Description** ^
|''ESC'' |//Echap//: Sortir d’un mode |
|''f'' |//Focus//: Visualiser l’ensemble du schéma |
|''z'' |//Zoom//: Zoomer sur la zone sélectionnée. ''Shift-Z'' (zoom), ''Ctrl-Z'' (dézoom) |
|''q'' |//Properties//: Éditer les propriétés des objets |
|''i'' |//Instanciate//: Instancier des éléments du gestionnaire de librairie |
|''w'' |//Wire//: Créer des liaisons entres les objets |
|''p'' |//Pins//: Instancier les pins d’entrées/sorties |
==== Schéma ====
Dans cette partie nous allons créer le schéma de l’inverseur. Pour commencer, vous devez instancier deux transistors (//nmos// et //pmos//). Utilisez la touche ''i'' dans l’éditeur de schémas et sélectionnez ''pmos1v'' puis ''nmos1v'' dans la librairie ''gpdk045''.
Utilisez la touche ''w'' pour créer les connexions entre les transistors de façon à obtenir le schéma d’un inverseur. N’oubliez-pas de connecter les //bulk// du //nmos// et du //pmos// à leur source. Ensuite, utilisez la touche ''p'' pour ajouter des pins d’entrées/sorties. Vous devrez ajouter une pin d’entrée ''in'' (//input//), une pin de sortie ''out'' (//output//), une pin pour l’alimentation ''vdd'' (//inputoutput//) et une pin ''vss'' (//inputoutput//) pour la masse.
Vous devriez obtenir le schéma de la <imgref fig:invsch>. Pour valider votre schéma cliquez sur ''Check and Save'' en haut à gauche.
<imgcaption fig:invsch| Schéma de l'inverseur>
{{1_invsch.png?nolink|Schéma de l'inverseur}}
</imgcaption><imgcaption fig:invsymb| Symbole de l'inverseur>
{{1_invsymb.png?nolink|Symbole de l'inverseur}}
</imgcaption>
Pour pouvoir intégrer cet inverseur dans un banc d’essai, nous allons créer un symbole associé au schéma. À terme nous aurons donc trois vues différentes de l’inverseur: //schematic//, //symbol//, et //layout//. Sélectionnez: ''Create -> Cellview -> From Cellview''. Après avoir choisi la position des pins sur le symbole, vous pouvez choisir de garder son apparence par défaut, ou vous pouvez choisir de la modifier, tel que le montre la <imgref fig:invsymb>. Les seuls éléments que vous ne devez pas supprimer sont les pins.
===== Simulations du schéma =====
Dans cette partie nous allons nous intéresser à la simulation fonctionnelle de l’inverseur à partir de son symbole. Nous aborderons deux aspects:
- //Le banc d’essai//: Il s’agit d’un circuit permettant de générer les stimuli nécessaires à l’obtention des courbes caractéristiques de l’inverseur.
- //L’environnement de simulation//: Il s’agit d’un ensemble d’outils permettant d’évaluer le comportement d’un circuit à partir de son modèle électrique.
==== Banc d’essai ====
Pour créer le banc d’essai de l’inverseur, placez-vous dans la librairie ''ele8304'', créez une nouvelle cellule: ''File -> New -> Cellview'', et nommez là ''INV_TB''. Une nouvelle fenêtre s’ouvre dans laquelle vous pouvez instancier tous les composants du banc d’essai, comme le montre la <imgref fig:invtb>. Les composants utiles à la réalisation du banc d’essai sont listés dans le tableau ci-dessous. Utilisez la touche ''l'' pour apposer un label sur les fils. Faites-le pour les signaux d’entrées et de sorties (''vin'' et ''vout'') comme le montre la <imgref fig:invtb>.
^**Instance** ^**Librairie** ^**Vue** ^**Description** ^
|''INV'' |ele8304 |symbol |DUT: //Device Under Test// |
|''vdc'' |analogLib |symbol |Alimentation fixe de $1V$ |
|''vpulse'' |analogLib |symbol |Signal périodique rectangulaire: $V1=0V$, $V2=1V$, $T=1\mu s$ |
|''gnd'' |analogLib |symbol |Masse du circuit |
|''cap'' |analogLib |symbol |Capacité de sortie (charge) du circuit: $C=10pf$ |
<imgcaption fig:invtb| Banc d’essai de l’inverseur>
{{1_invtb.png?nolink|Banc d’essai de l’inverseur}}
</imgcaption>
==== Configuration ====
Pour démarrer l’environnement de simulation à partir de l’éditeur schéma, sélectionnez: ''Launch -> ADE L''. Par défaut, les simulations s’exécutent dans votre dossier //home//, mais comme ce répertoire se situe sur le réseau le temps d’accès aux fichiers est plus long, ce qui ralenti les simulations. D’autre part, les fichiers générés par les simulations peuvent être de taille importante. Nous allons donc créer un dossier pour les simulations sur les machines locales:
<code:bash>
[shell]% mkdir -p /export/tmp/<user>/simulations
</code>
Dans la fenêtre ''ADE L'', sélectionnez: ''Setup -> Simulator/Directory/Host''. Assurez vous de sélectionner le simulateur ''spectre'', et de pointer le répertoire sur: ''/export/tmp/<user>/simulations''.
Afin que cette configuration devienne celle par défaut, et ainsi éviter d’avoir à la modifier pour chacune des simulations, nous allons éditer deux fichiers que //Virtuoso// utilise pour configurer le comportement des différents outils au démarrage:
* Les fichiers ''.cdsinit'' sont utilisés pour lancer des scripts de configuration.
* Les fichiers ''.cdsenv'' sont utilisés pour configurer toutes les options de l’environnement.
Les fichiers ''.cdsenv'' sont chargés en premier, leur configuration peut donc être écrasée par celle des fichiers ''.cdsinit''. //Virtuoso// lit les fichiers ''.cdsenv'' dans l’ordre présenté dans le tableau ci-dessous (le fichier le plus bas a la priorité la plus élevée)
^**Niveau** ^**Chemin** ^
|Par défaut (pour chaque outils) |''/CMC/tools/cadence/<IC_dir>/tools/dfII/etc/<tool>/.cdsenv'' |
|Tous les utilisateurs |''/CMC/tools/cadence/<IC_dir>/tools/dfII/local/.cdsenv'' |
|Mon utilisateur |''~/.cdsenv'' |
|Ce projet |''<Project_dir>/.cdsenv'' |
Pour configurer le chemin par défaut du répertoire de simulation il faut éditer le fichier ''.cdsenv'' du répertoire ''~/Labs/Tuto/inverseur''. Décommentez la ligne suivante, et remplacez le chemin par celui du répertoire créé précédemment
<code>
asimenv.startup projectDir string "/export/tmp/<user>/simulations"
</code>
Le comportement de //Virtuoso// est légèrement différent lors du chargement du fichier ''.cdsinit''. //Virtuoso// parcours d’abord le répertoire du projet, puis le répertoire //home//, et s’arrête dès que le premier fichier est trouvé. À titre d’exemple, nous allons configurer le fichier ''.cdsinit'' pour qu’il lance automatiquement le gestionnaire de librairie au démarrage de //Virtuoso//. Notez que toutes ces modifications n’entreront en vigueur qu’au prochain démarrage de //Virtuoso//.
<code>
when ( isFile("./cds.lib")
printf("\nFYI: Launched library manager.")
ddsOpenLibManager()
)
</code>
==== Simulation transitoire ====
La simulation transitoire permet d’évaluer le comportement dynamique d’un circuit lorsqu’il est soumis à un ensemble de stimuli, comme c’est le cas par exemple de l’inverseur lorsqu’il est soumis aux stimuli du signal rectangulaire périodique généré par l’alimentation ''vpulse''.
Pour configurer le type de simulation à effectuer, sélectionnez ''Analyses -> Choose'', puis choisissez: ''Analysis -> tran'', et: ''Stop Time -> 4u'' pour définir le temps de simulation (ce qui correspond à 4 périodes du signal périodique rectangulaire ''vpulse''). Enfin, sélectionnez: ''Accuracy -> moderate''.
Pour sélectionner les signaux à observer, sélectionnez: ''outputs -> to be plotted -> select on design'', et sélectionnez les signaux ''vin'' et ''vout'' du banc d’essai. Finalement, pour lancer la simulation cliquez sur le bouton vert. Vous devriez obtenir un résultat similaire au chronogramme de la <imgref fig:tran>. Notez que pour séparer les courbes vous devez sélectionner: ''Graph -> Split All Strips''.
La <imgref fig:tran> montre que la réponse de l’inverseur à un signal périodique n’est pas parfaite. D’une part on observe une réponse $RC$ importante, qui est principalement due à la capacité de sortie du banc d’essai (observez la différence pour $C = 1pf$). D’autre part, le temps de montée est différent du temps de descente. Ceci est dû au fait que l’inverseur n’est pas balancé. À dimensions égales, le courant qui traverse le //nmos// est plus important que le courant qui traverse le //pmos// (mobilité des électrons //vs// mobilité des trous).
<imgcaption fig:tran| Simulation transitoire>
{{1_tran.png?nolink|Simulation transitoire}}
</imgcaption>
==== Simulation statique paramétrique ====
Le but de la simulation statique paramétrique est de déterminer les rapports $\frac{W}{L}$ des transistors de façon à ce que leurs points de fonctionnement satisfassent au cahier des charges. En règle générale, on ne modifie jamais la longueur $L$ des transistors, qui restent à leurs tailles minimales (45nm ici). Dans le cas de l’inverseur, le but est de déterminer la largeur $W_p$ du //pmos// telle que l’inverseur soit balancé, c’est à dire que sa sortie vaille $VDD / 2$ lorsque son entrée vaut $VDD / 2$. Une approche analytique (résolution approximative des équations) peut être utilisée en complément des simulations. Les résultats analytiques peuvent cibler le(s) transistor(s) à modifier, et donner un ordre de grandeur de la valeur à utiliser. Les simulations, qui utilisent des modèles plus élaborés, permettent de resserrer l’espace des solutions et d’obtenir des valeurs plus précises. Ici, nous allons simuler le comportement de l’inverseur lorsqu’il est soumis à une rampe de tension de $0 V$ à $1 V$ (simulation statique), le tout pour plusieurs valeurs de $W_p$ (simulation paramétrique).
=== Simulation statique ===
Supprimez d’abord la simulation transitoire, puis sélectionnez: ''Analyses -> Choose -> Analysis -> dc''. Puis, sélectionnez: ''Sweep Variable -> Component Parameter'', puis: ''Select Component'', et choisissez ''vpulse'' sur le banc d’essai. Sélectionnez: ''Parameter Name -> dc''. Enfin, configurez la rampe de tension avec: ''Sweep Range -> start: 0, stop: 1''.
=== Simulation paramétrique ===
Dans un premier temps il faut créer la variable ''wp'' qui servira de paramètre variable à la largeur du transistor //pmos//. Pour cela, sélectionnez l’inverseur dans le banc d’essai et utilisez la combinaison de touche ''shift+e'' pour descendre d’un niveau dans la hiérarchie (cela vous conduira au schéma de l’inverseur). Sélectionnez le //pmos// et utilisez la touche ''q'' pour modifier ses paramètres. Inscrivez: ''Total Width -> wp'' à la place de la valeur par défaut. Sauvegardez (''Check and Save''), puis revenez au banc d’essai avec la combinaison de touche ''ctrl+e''. Pour importer la variable créée dans l’environnement de simulation ''ADE L'' sélectionnez: ''Variables -> Copy From Cellview''. Vous devriez voir ''wp'' apparaitre dans le panneau latéral. Pour réaliser la simulation statique paramétrique, sélectionnez: ''Tools -> Parametric Analysis''. Puis sélectionnez la variable ''wp'' et faites là varier: ''From: 120n – To: 300n'', avec: ''Step Mode -> Linear Steps'', et: ''Step Size -> 20n''. Enfin, sélectionnez: ''Analysis -> Start'' pour visualiser la réponse de l’inverseur à l’échelon de tension pour 10 valeurs de ''wp'' différentes.
La <imgref fig:param> montre que $W_p = 140nm$ correspond au point de fonctionnement pour lequel l’inverseur est le plus balancé. Vous pouvez donc remplacer: ''wp -> 140n'' dans les propriétés du transistor //pmos// pour la suite.
<imgcaption fig:param| Simulation paramétrique>
{{1_param.png?nolink|Simulation paramétrique}}
</imgcaption>
==== Sauvegarder l’environnement de simulation ====
Afin de conserver les résultats et la configuration de la simulation, vous pouvez sauvegarder l’état de l’environnement de simulation en suivant ''Session -> Save state''. Sélectionnez: ''Save state option -> Cellview'' et donnez un nom à votre configuration. Remarquez qu’une vue s’est ajoutée dans le gestionnaire de librairie, et peut donc maintenant être directement accédée de cet endroit.
====== Édition du dessin des masques des circuits analogiques ======
— //[[mickael.fiorentino@polymtl.ca|Mickael Fiorentino]] 2019/07/20// ; //[[erika.miller-jolicoeur@polymtl.ca|Erika Miller-Jolicoeur]] 2019/07/20// —
Cette deuxième partie du tutoriel traite de l’édition du dessin des masques de l’inverseur. Avant de commencer, assurez-vous d'avoir complété la [[tutoriels:analogique:1_schema|première partie]].
Nous utiliserons une méthode semi-automatique pour concevoir le dessin des masques de l’inverseur à partir de son schéma. Ensuite, nous passerons au travers des étapes de vérifications physiques:
* Vérification des règles de dessins avec l’outil **DRC** (//Design Rules Check//).
* Vérification de l'intégrité électrique du circuit avec l'outil **LVS** (//Layout vs Schematic//).
Enfin, nous allons exporter le modèle du circuit final, incluant les capacités parasites, afin de réaliser une simulation post-implémentation. Pour démarrer l’éditeur de dessin des masques de //Virtuoso// sélectionnez: ''Launch -> Layout XL'' à partir de la fenêtre d’édition de schéma de l’inverseur.
<imgcaption fig:layxl| Éditeur de dessin des masques>
{{2_layxl2.png?nolink|Éditeur de dessin des masques}}
</imgcaption>
===== Raccourcis clavier =====
Le tableau ci-dessou liste les raccourcis clavier que vous serez amené à utiliser dans le cadre de ces laboratoires.
^**Raccourci** ^**Description** ^
|''ESC'' |//Echap//: Sortir d’un mode |
|''f'' |//Focus//: Visualiser l’ensemble du dessin des masques |
|''z'' |//Zoom//: Zoomer sur la zone sélectionnée. ''Shift-Z'' (zoom), ''Ctrl-Z'' (dézoom) |
|''q'' |//Properties//: Éditer les propriétés des objets |
|''i'' |//Instance//: Instancier des éléments du gestionnaire de librairies |
|''m'' |//Move//: Déplacer les objets. |
|''s'' |//Stretch//: Déplacer les objets. |
|''p'' |//Path//: Créer un chemin de largeur minimale pour la couche sélectionnée |
|''r'' |//Rectangle//: Créer un rectangle de la couche sélectionnée |
|''k'' |//Ruler//: Tracer des règles sur le dessin des masques. ''Shift-K'' pour les effacer |
|''o'' |//Contact//: Instancier des contacts de la librairie |
==== Affichage ====
<imgcaption fig:display| Options d'affichage>
{{2_display.png?nolink|Options d'affichage}}
</imgcaption>
En suivant: ''Options -> Display'' (ou en utilisant le raccourcis ''e'') vous pouvez modifier les options d’affichage de //Virtuoso//. Modifiez la résolution de la grille (''Grid Controls'') et les modes d’amorçage (''Snap Modes'') tel que le montre la <imgref fig:display>.
//Remarque: Les snap-spacing doivent être inférieur à 0.005, faute de quoi vous aurez des erreurs de DRC de type off-grid//.
==== Génération du dessin des masques ====
Il est possible de générer le dessin des masques des transistors de l’inverseur à partir de son schéma. Cela vous permettra, d’une part de ne pas avoir à le faire à la main, mais surtout d’automatiser la modification des tailles du transistor en fonction des paramètres que vous sélectionnez dans l’éditeur de schéma et dans le dessin des masques.
Sélectionnez: ''Connectivity -> Generate -> All From Source'', et assurez-vous de (dé)sélectionner les options, comme le montre la <imgref fig:laygen>. En particulier, décochez la case ''PR Boundary'', et utilisez la couche ''Metal1 pin'' pour les pins d’entrées/sorties. Dans l’onglet ''I/O Pins'' sélectionnez: ''Create Label As -> Label'', puis: ''Options -> Layer Name/Layer Pins -> Same as Pin''. Vous devriez voir apparaitre à l’écran le dessin des masques des deux transistors, ainsi que les 4 pins d’entrées/sorties. Utilisez la combinaison de touches ''Shift+F'' pour afficher le détail des couches physiques. Pour remplacer ou ajouter un transistor, sélectionnez le dans l’éditeur de schéma, puis dans l’éditeur de dessin des masques faites: ''Connectivity -> Generate -> Selected From Source''. Pour afficher les connexions entre les différents points du circuit faites: ''Connectivity -> Incomplete Nets -> Show/Hide All''.
<imgcaption fig:laygen| Génération du dessin des masques à partir du schéma>
{{2_laygen.png?nolink|Génération du dessin des masques à partir du schéma}}
</imgcaption>
=== Modèle de cellule standard ===
Les délimitations d’une cellule sont définies par sa //Boundary Box//. Il s’agit d’une couche virtuelle permettant de délimiter la taille de la cellule. Les cellules standards sont conçues dans un canevas (//Template//), dont la hauteur est définie et doit rester fixe, et dont la largeur peut varier. Cette pratique est utile en conception numérique, car elle facilite l’automatisation du placement et du routage des cellules.
Pour concevoir le dessin des masques de l’inverseur, nous allons utiliser le //template// de la librairie standard ''gsclib045_tech''. Pour l’instancier sélectionnez: ''i -> Library -> gsclib045_tech'', puis: ''Cell -> cellTmpl'', avec: ''View -> layout''. Positionnez le //exactement// à l’origine du dessin des masques, et adaptez sa largeur en modifiant la propriété: ''Cell Width -> 0.5''.
=== Placement et routage manuel ===
<imgcaption fig:invlayout| Dessin des masques>
{{2_invlayout.png?nolink|Dessin des masques}}
</imgcaption>
À ce stade, il ne vous reste plus qu’à effectuer le placement et le routage de l’inverseur. Sélectionnez les couches pertinentes dans le menu ''Layers'' avant chaque édition. Utilisez la touche ''p'' pour tracer les chemins des connexions. Utilisez la touche ''r'' pour créer des rectangles si nécessaires. Utilisez la touche ''o'' pour instancier des contacts.
La convention veut qu’on utilise du ''Metal2'' pour les connexions entre les cellules et du ''Metal1'' pour les alimentations et les connexions internes. Vous devrez donc utiliser des contacts ''M1_M2'' et ''M1_PO'' pour les entrées/sorties. Assurez-vous de positionner les pins d’entrées/sorties aux bons endroits du dessin, et positionnez vos transistors au milieu du //template//. D’une manière générale, //soyez précis// dans le positionnement des différentes couches. La <imgref fig:invlayout> vous donne une cible à atteindre.
===== Vérifications =====
Une fois que votre dessin des masques est terminé, il est essentiel de procéder aux deux étapes de vérification suivantes:
* **Design Rule Check**: Le DRC permet de s’assurer que les règles de dessin sont respectées. Ces règles constituent une abstraction des contraintes physique de la technologie utilisée. En vérifiant que le dessin des masques satisfait à ces contraintes, on s’assure que le procédé de fabrication n’altérera pas le fonctionnement du circuit.
* **Layout Versus Schematic**: Le LVS permet de s’assurer que le dessin des masques est électriquement équivalent au schéma du circuit. Elle permet d’éviter les circuits ouverts et les courts circuits qui peuvent apparaitre par inadvertance dans le dessin des masques.
Nous utiliserons l’outil PVS (//Physical Verification System//) de //Cadence// pour réaliser ces deux étapes de vérification. Si le fichier de configuration ''setup.csh'' a été utilisé pour initialiser l’environnement, le menu PVS devrait être intégré dans //Virutoso//. Pour le LVS et le DRC, nous allons configurer l’outil à partir de fichiers (''.rul'') contenant des règles spécifiques à la technologie ''GPDK45''.
Par défaut, le DRC et le LVS s’exécutent respectivement dans les dossiers ''PVSDRC'' et ''PVSLVS''. De même que pour la simulation, ces dossiers sont sur le réseau ce qui peut ralentir l’exécution des outils et prendre beaucoup de place dans votre compte utilisateur. Nous allons donc créer deux dossiers pour les vérifications, ''drc'' et ''lvs'', sur les machines locales:
<code:bash>
[shell]% mkdir -p /export/tmp/<user>/verifications/{drc,lvs}
</code>
==== DRC ====
Pour démarrer l’outil de DRC, sélectionnez: ''PVS -> Run DRC''. Avant de lancer la procédure, nous allons modifier le dossier d’exécution et configurer les règles comme le montre la <imgref fig:drc>.
* Dans le menu ''Run Data'' Sélectionnez: ''Run directory -> /export/tmp/<user>/verifications/drc''
* Dans le menu ''Rules'' Sélectionnez: ''Technology Mapping File -> /CMC/kits/GPDK45/ tech/gpdk045/pvtech.lib''. Puis, sélectionnez ''gpdk045_pvs'' dans le menu déroulant. Le fichier contenant les règles pour le DRC devrait être: ''/CMC/kits/GPDK45/tech/gpdk045/pvs/pvlDRC.rul''.
Parcourez les autres menus pour vous convaincre que les informations qu’ils contiennent sont pertinentes. Finalement, pour lancer la procédure de DRC cliquez sur ''Submit''.
<imgcaption fig:drc| Configuration de l'outil DRC>
{{2_drc.png?nolink|Configuration de l'outil DRC}}
</imgcaption>
Pendant l’exécution du DRC, une nouvelle fenêtre contenant les //logs// de PVS s’ouvre. Elle permet de vérifier que l’exécution du DRC s’est bien passée, et donne des indications sur la nature des problèmes le cas échéant. À la fin de l’exécution, le DRC //Debug Environment// s’ouvre. Cette fenêtre contient la liste des erreurs de DRC trouvées par l’outil en analysant votre dessin des masques, comme le montre la <imgref fig:lvsdebug>. En cliquant sur une ligne vous obtenez le détail de l’erreur, et //Virtuoso// zoom automatiquement sur la zone concernée dans votre dessin des masques. Vous devez corrigez vos erreurs et relancer le DRC jusqu’à ce qu’il n’y en ai plus aucune.
<imgcaption fig:drcdebug| Environnement de débogage DRC>
{{2_drcdebug.png?nolink| Environnement de débogage DRC}}
</imgcaption>
==== LVS ====
Pour démarrer l’outil de LVS, sélectionnez: ''PVS -> Run LVS''. De même que précédemment, nous allons modifier le dossier d’exécution, configurer les règles et les fichiers de sortie comme le montre la <imgref fig:lvs>.
* Dans le menu ''Run Data'' Sélectionnez: ''Run directory -> /export/tmp/<user>/verifications/lvs''
* Dans le menu ''Rules'' Sélectionnez: ''Technology Mapping File -> /CMC/kits/GPDK45/ tech/gpdk045/pvtech.lib''. Puis, sélectionnez ''gpdk045_pvs'' dans le menu déroulant. Le fichier contenant les règles pour le DRC devrait être: ''/CMC/kits/GPDK45/tech/gpdk045/pvs/ pvlLVS.rul''. En complément des règles de la technologie, il faut ajouter le fichier de contrôle: ''/CMC/kits/GPDK45/tech/gpdk045/pvs/pvs_control_file''.
* Dans le menu ''Output'' Cochez: ''Additional Output -> Create Quantus QRC Input Data''.
<imgcaption fig:lvs| Configuration de l'outil LVS>
{{2_lvs.png?nolink| Configuration de l'outil LVS}}
</imgcaption>
Pendant l’exécution du LVS, un nouvel onglet s’ouvre dans la fenêtre des //logs// de PVS. À la fin de l’exécution, le LVS //Debug Environment// liste les erreurs de LVS trouvées par l’outil en analysant votre dessin des masques, comme le montre la <imgref fig:lvsdebug>. Ici par exemple on observe une différence entre les labels du schéma et ceux du //layout// (inexistant). Les noms des objets sont des liens qui vous guideront vers les zones concernées de votre schéma ou de votre //layout//. C’est à vous de juger de l’importance des erreurs de LVS. Corrigez ce qui vous semble nécessaire pour obtenir un circuit fonctionnel.
<imgcaption fig:lvsdebug| LVS Debug Environment>
{{2_lvsdebug.png?nolink|LVS Debug Environment}}
</imgcaption>
===== Simulation du dessin des masques =====
La simulation du dessin des masques (aussi appelée simulation post-implémentation) permet de prendre en compte les éléments //parasites// qui résultent de l’interaction entre les couches physiques composant le circuit. Ces simulations sont importantes pour évaluer de manière plus exacte les délais et la puissance consommée par le circuit (entre autre). La procédure pour simuler le dessin des masques se déroule donc en deux étapes: La première étape consiste à extraire les résistances et les capacités parasites du circuit, et la deuxième étape consiste à simuler le circuit en prenant en compte les parasites.
==== Extraction des parasites ====
L’extraction des parasites nécessite un résultat sans erreur du LVS, et sera réalisée avec l’outil //Quantus QRC Extraction//. Pour ce faire, sélectionnez ''QRC -> Run PVS - Quantus QRC''. Dans la fenêtre qui s’ouvre, sélectionnez: ''PVS Data Directory -> /export/tmp/<user>/verifications/lvs/svdb'', puis: ''Quantus QRC Tech Lib -> /CMC/kits/GPDK45/tech/gpdk045/pvtech.lib'', et finalement: ''Technology -> gpdk045_pvs''. Dans la nouvelle fenêtre qui s’ouvre:
* Dans le menu ''Setup'' Sélectionnez: ''Ruleset -> rcx_typical''. On veut créer une vue //extracted//, dans ''Output -> Extracted View'', assurez vous que c’est la bonne cellule et librairie, la vue est ''view -> av_extracted''.
* Dans le menu ''Extraction'' Sélectionnez ''Extraction Type -> RC'' puis ''Name Space -> Schematic Names''. Choisissez ''Cap Coupling Mode -> Coupled'' ainsi que ''Ref Node -> vss'', ou le nom de la pin de référence dans votre schéma.
* Dans le menu ''Netlisting'' Sélectionnez ''Parasitic Capacitor Models -> Do Not Include'' ainsi que ''Parasitic Resistor Models -> Do Not Include'' afin d’utiliser les composants de la librairie ''analogLib''.
<imgcaption fig:qrcdata| Configuration du QRC (setup)>
{{2_qrcsetup.png?nolink| Configuration du QRC (setup)}}
</imgcaption><imgcaption fig:qrcextract| Configuration du QRC (extraction)>
{{2_qrcextract.png?nolink| Configuration du QRC (extraction)}}
</imgcaption><imgcaption fig:qrcnetlist| Configuration du QRC (netlist)>
{{2_qrcnetlist.png?nolink| Configuration du QRC (netlist)}}
</imgcaption>
À la fin de l’exécution de QRC, une fenêtre devrait vous annoncer que la vue a été créée. Dans le gestionnaire de librairie, ouvrez la nouvelle vue générée (''av_extracted''). Faites ''Shift+F'' pour afficher le détail du dessin des masques. Si vous zoomez suffisamment, vous pouvez voir les différents parasites, tel que le montre la <imgref fig:parasites>.
<imgcaption fig:parasites| Parasites extraits>
{{2_qrcextracted.png?nolink|Parasites extraits}}
</imgcaption>
==== Configuration de la simulation ====
Il faut créer une vue //config// qui permettra de choisir la vue à utiliser pour simuler la cellule. Dans le ''Library Manager'', placez vous dans la cellule du banc d’essai (''INV_TB''), puis sélectionnez: ''File -> New -> Cell View'', avec: ''Type -> config''. Dans la nouvelle fenêtre, sélectionnez: ''Use Template -> spectre''. Modifiez les champs: ''View -> schematic'', et: ''Library List -> ele8304'' pour identifier les cellules et librairies nécessaires. Modifiez ''View List'' pour ajouter la vue ''av_extracted''. Vous devriez obtenir un résultat similaire à la <imgref fig:configeditor>. Dans la fenêtre du ''Hierarchy Editor'' vous pouvez choisir la vue qui sera simulée en faisant un clic droit sur la cellule de l’inverseur, puis en sélectionnant: ''Set Cell View -> av_extracted''. Enfin, mettez à jour les vues avec: ''View -> Update''. Vous remarquez que les nouveaux composants contenant les éléments parasites ont été ajouté à la hiérarchie. Notez qu’il faut que l’environnement de simulation soit lié à la fenêtre //config//. Pour ce faire, il faut ouvrir ''ADE L'' via la vue //config//. Le simulateur par défaut est //AMS//, changez pour //spectre// avant de continuer. Sélectionnez: ''Setup -> Simulator/Directory/Host -> Simulator: spectre; Project Directory:/export/tmp/<user>/simulations''.
<imgcaption fig:configeditor| Nouvelle configuration>
{{2_configeditor.png?nolink|Nouvelle configuration}}
</imgcaption>
Chargez la configuration que vous avez sauvegardée précédemment avec: ''Session -> Load State''. Si vous n’avez pas de sauvegarde, configurez l’environnement comme à la section, et [[tutoriels:analogique:1_schema:#Simulation transitoire|configurez la simulation transitoire]]. Faites ensuite une nouvelle sauvegarde de votre environnement, de façon à le conserver dans un fichier distinct.
Augmentez la finesse de la simulation en sélectionnant ''Choose Analyses -> Accuracy: conservative''. Puis lancez la simulation avec: ''Netlist and Run''. Vous obtenez la simulation incluant les parasites spécifiques au dessin des masques. Pour vous en assurer, vérifiez que les parasites sont bien inclus dans la //netlist// (''Simulation -> Netlist -> Display''). Puis, comparez les résultats par rapport à la simulation sans parasites. Ouvrez en parallèle la vue ''config'' et changez la vue de la cellule ''INV'' pour ''schematic''. Mettez à jour la hiérarchie et sauvegardez. Enfin dans ''ADE L'', modifiez: ''plotting mode -> append'' pour ajouter la nouvelle simulation à la précédente puis: ''Netlist and Run''. Utilisez la barre de défilement en haut des chronogrammes pour afficher une transition de l’inverseur. Vous devriez obtenir un résultat similaire à la <imgref fig:simupara>. On remarque une très légère différence entre les deux courbes.
<imgcaption fig:simupara| Simulation des vues schematic et av_extracted>
{{2_simupara.png?nolink|Simulation des vues schematic et av_extracted}}
</imgcaption>
\ No newline at end of file
This diff is collapsed.
#!/usr/bin/python3
#-----------------------------------------------------------------------------
# Project : Tutoriels - Conception de circuits intégrés analogiques
#-----------------------------------------------------------------------------
# File : sync.py
# Authors : Mickael Fiorentino <mickael.fiorentino@polymtl.ca>
# Lab : GRM - Polytechnique Montréal
# Date : <2019-07-24 Wed>
#-----------------------------------------------------------------------------
# Description: Synchronisation de la documentation sur le Wiki du GRM
# - Interface à partir de l'API XML-RPC de DokuWiki
# - module dokuwiki: https://python-dokuwiki.readthedocs.io
# Usage : Sur les machines du GRM:
# % stpython37
# % pip3 install dokuwiki --user
# % python3 sync.py 'username' 'passwd'
#-----------------------------------------------------------------------------
import dokuwiki
import argparse
import os
# Arguments
parser = argparse.ArgumentParser()
parser.add_argument("login", type=str, help="Nom d'utilisateur sur le Wiki du GRM")
parser.add_argument("passwd", type=str, help="Mot de passe sur le Wiki du GRM")
args = parser.parse_args()
# Parameters
username = args.login
password = args.passwd
namespace = ':tutoriels:analogique:'
wiki_url = 'https://intranet.grm.polymtl.ca/wiki'
img_dir = 'img'
page_dir = 'pages'
# Login
try:
wiki = dokuwiki.DokuWiki(wiki_url, username, password, cookieAuth=True)
except (DokuWikiError, Exception) as err:
print('unable to connect: %s' % err)
# Cleaning up directories before backup
for d in [img_dir, page_dir]:
if not os.path.exists(d):
os.mkdir(d)
# Backup pages
for p in wiki.pages.list(namespace):
page = wiki.pages.get(p['id'])
name = page_dir + '/' + p['id'].split(':')[-1] + '.dwiki'
with open(name, 'w') as f:
f.write(page)
# Backup Media
for m in wiki.medias.list(namespace):
name = m['id'].split(':')[-1]
wiki.medias.get(m['id'], dirpath=img_dir, filename=name, overwrite=True)
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment